Hi,
I am trying to use dfdInterpolateEx1d to approximate a function by a linear interpolation and i get some troubles.
The function dfdInterpolateEx1d seems to be unable to do the interpolation if the site value is equal to the latest breakpoint.
There is my code:
int linear_extrap_func( MKL_INT* n, MKL_INT cell[], const double site[], double r[], void *params ) { double *ordinateRef = (double*)params; for(MKL_INT i=0; i<*n; i++) r[i] = *ordinateRef; return 0; } void LinearInterpolation( double*Z, const double* X, const int lenghtX, const double* ordinateRef, const int lenghtOrdinateRef, const double minAbscissaRef, const double maxAbscissaRef) { DFTaskPtr task; // Data Fitting task descriptor MKL_INT nx; // number of break points MKL_INT xhint; // additional info about break points MKL_INT ny; // number of functions MKL_INT yhint; // additional info about function MKL_INT nsite; // total number of interpolation sites MKL_INT sitehint; // additional info about interpolation MKL_INT ndorder; // size of array describing derivative // orders MKL_INT dorder[] = { 1 }; // only value to calculate // will be computed MKL_INT rhint; // interpolation results storage format MKL_INT stype, sorder; double *datahint; // additional info about structure // of arrays x and y double *scoeff; int errcode = 0; int errnums = 0; sorder = DF_PP_LINEAR; stype = DF_PP_DEFAULT; datahint = 0; double x_ref[2]; nx = lenghtOrdinateRef; xhint = DF_UNIFORM_PARTITION; x_ref[0] = minAbscissaRef; x_ref[1] = maxAbscissaRef; scoeff = new double[DF_PP_LINEAR*(nx-1)]; ny = 1; yhint = DF_MATRIX_STORAGE_ROWS; datahint = NULL; nsite = lenghtX; sitehint = DF_NON_UNIFORM_PARTITION; ndorder = 1; rhint = DF_MATRIX_STORAGE_ROWS; errcode = dfdNewTask1D( &task, nx, x_ref, xhint, ny, ordinateRef, yhint ); errcode = dfdEditPPSpline1D( task, sorder, stype, DF_NO_BC, 0, DF_NO_IC, 0, scoeff, DF_NO_HINT ); errcode = dfdConstruct1D( task, DF_PP_SPLINE, DF_METHOD_STD ); dfdInterpCallBack extraFunc; extraFunc = reinterpret_cast<dfdInterpCallBack> (linear_extrap_func); /*errcode = dfdInterpolate1D( task, DF_INTERP, DF_METHOD_PP, nsite, X, sitehint, ndorder, dorder, datahint, Z, rhint, NULL);*/ errcode = dfdInterpolateEx1D( task, DF_INTERP, DF_METHOD_PP, nsite, X, sitehint, ndorder, dorder, datahint, Z, rhint, 0, extraFunc, &ordinateRef[0], extraFunc, &ordinateRef[lenghtOrdinateRef-1], 0, 0, 0, 0); errcode = dfDeleteTask( &task ); delete [] scoeff; } int main() { const int lenghtX = 10; const double minAbscissaRef = 12.0; const double maxAbscissaRef = 28.0; const int lenghtOrdinateRef = 250; // output double *Z = new double[lenghtX]; //ref values double *ordinateRef = new double[lenghtOrdinateRef]; for (int i = 0; i < lenghtOrdinateRef; i++) ordinateRef[i] = i * 1.5 + 0.5 * M_PI; //y = a*x+b double a = (ordinateRef[lenghtOrdinateRef - 1] - ordinateRef[0]) / (maxAbscissaRef - minAbscissaRef); double b = ordinateRef[0] - minAbscissaRef * a; //Init X values double *X = new double[lenghtX]; const double X_incr = (maxAbscissaRef - minAbscissaRef) / (lenghtX - 3); for (int i = 0; i < lenghtX; i++) X[i] = minAbscissaRef + (i - 1) * X_incr; LinearInterpolation( Z, X, lenghtX, ordinateRef, lenghtOrdinateRef, minAbscissaRef, maxAbscissaRef); for (int i = 0; i < lenghtX; ++i) { double expected = std::min( std::max(X[i]*a+b, ordinateRef[0]), ordinateRef[lenghtOrdinateRef - 1]); printf("%d %f %f %f",i, X[i], expected, Z[i]); } delete [] X; delete [] Z; delete [] ordinateRef; return 0; }
and the output:
i X[i] expected result 0 9.71428571428572 1.5707963267949 1.5707963267949 1 12 1.5707963267949 1.5707963267949 2 14.2857142857143 54.9279391839377 54.9279391839377 3 16.5714285714286 108.285082041081 108.285082041081 4 18.8571428571429 161.642224898223 161.642224898223 5 21.1428571428571 214.999367755366 214.999367755366 6 23.4285714285714 268.356510612509 268.356510612509 7 25.7142857142857 321.713653469652 321.713653469652 8 28 375.070796326795 4.01711400191502E-270 9 30.2857142857143 375.070796326795 375.070796326795
The 9th result (when i=8, site = 28. = latest breakpoint) is a kind of NaN (4.017..E-270).
I guess that I did a mistake with the boundary condition or maybe in the extrapolation function...
Can someone help me ?
PS: The simple dfdInterpolate1D function works well, but I would like to use my own extrapolation function.
Thanks in advance for your help.