/*****************************************************************************
    This routine must ensure that the psSpline1DEvalVector() function works
    properly.  It creates a spline with psSpline1DAlloc(), (1-D functions
    are used for the spline polynomials) creates a set of data values, sets
    the spline polynomials with psVectorFitSpline1D(), then calls
    psSpline1DEvalVector() on new data values and ensures that the results
    are correct.
 
    XXX: Only F32 types are tested here.  F64 types are tested elsewhere.
 *****************************************************************************/
#include <stdio.h>
#include <math.h>
#include "pslib.h"
#include "psTest.h"
#include "psMemory.h"
#include "psFunctions.h"
#define N 8
#define SPLINE_ORDER 1

psS32 main()
{
    psS32 testStatus = true;
    psS32 memLeaks=0;
    psS32 i;
    psS32  currentId = psMemGetId();
    psSpline1D *tmpSpline;
    psVector *data;
    psVector *x;
    psVector *y;

    psTraceSetLevel(".", 0);
    /****************************************************************************/
    /****************************************************************************/
    testStatus = true;
    printPositiveTestHeader(stdout,
                            "psFunction functions",
                            "psSpline1DAlloc()");
    data = psVectorAlloc(N+1, PS_TYPE_F32);
    x = psVectorAlloc(N+1, PS_TYPE_F32);
    tmpSpline = psSpline1DAlloc(N, SPLINE_ORDER, 1.0, 10.0);

    for (i=0;i<N+1;i++) {
        data->data.F32[i] = tmpSpline->knots->data.F32[i];
    }

    psVectorFitSpline1D(tmpSpline, data, data, NULL);

    for (i=0;i<N+1;i++) {
        x->data.F32[i] = 0.5 + (float) i+1;
    }

    y = psSpline1DEvalVector(
            tmpSpline,
            x
        );

    for (i=0;i<N+1;i++) {
        if (fabs(x->data.F32[i]-y->data.F32[i]) > FLT_EPSILON) {
            printf("ERROR: f(%f) is %f\n", x->data.F32[i], y->data.F32[i]);
            testStatus = true;
        }
    }

    psFree(tmpSpline);

    psFree(x);
    psFree(y);
    psFree(data);

    psMemCheckCorruption(1);
    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
    if (0 != memLeaks) {
        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
    }

    printFooter(stdout,
                "psFunctions functions",
                "psSpline1DAlloc()",
                testStatus);

    return (!testStatus);
}
