Intel® oneAPI Math Kernel Library
Ask questions and share information with other developers who use Intel® Math Kernel Library.
6956 Discussions

Not-a-knot spline not working with uniform partition of x

mahalex
Beginner
831 Views

Hi!

I noticed that when trying to construct a natural cubic spline with not-a-knot boundary conditions, I get different results depending on how the partition x is specified.

For example, I want to use x values 1.0, 3.0, 5.0, 7.0, 9.0. If I pass an array x = { 1.0, 3.0, 5.0, 7.0, 9.0 } and specify xhint = DF_NON_UNIFORM_PARTITION, I get a spline that looks like it satisfies the not-a-knot conditions (I can see that the third derivatives are the same for the first two polynomials, and for the last two polynomials). However, if I pass an array x = { 1.0, 9.0 } and specify xhint = DF_UNIFORM_PARTITION instead, I get a different spline, and it does not satisfy the boundary conditions. In my view, the results should be the same, since these are just two different ways of providing the same input data.

The problem does not seem to appear when using other boundary conditions (I tried DF_BC_1ST_LEFT_DER | DF_BC_1ST_RIGHT_DER with both derivative set to zero).

Here's the complete source code:

#include <iostream>
#include <iomanip>
#include <mkl_df.h>

#define nx 5

int main() {
	double x[] = { 1.0, 9.0 };
	int xhint = DF_UNIFORM_PARTITION;
	// double x[] = { 1.0, 3.0, 5.0, 7.0, 9.0 };
	// int xhint = DF_NON_UNIFORM_PARTITION;
	double y[] = { 1.0, 4.0, 3.0, 5.0, 2.0 };
	int ny = 1;
	int nhint = DF_NO_HINT;
	DFTaskPtr task;
	int s_order = DF_PP_CUBIC;
	int s_type = DF_PP_NATURAL;
	int bc_type = DF_BC_NOT_A_KNOT;
	double* bc = NULL;
	int ic_type = DF_NO_IC;
	double* ic = NULL;
	double scoeff[nx * 4];
	int scoeffhint = DF_NO_HINT;
	int status1 = dfdNewTask1D(&task, nx, x, xhint, ny, y, nhint);
	int status2 = dfdEditPPSpline1D(task, s_order, s_type, bc_type, bc,	ic_type, ic, scoeff, scoeffhint);
	int status3 = dfdConstruct1D(task, DF_PP_SPLINE, DF_METHOD_STD);

	int counter = 0;
	for (int i = 0; i < nx - 1; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			std::cout << std::setw(12) << scoeff[counter] << "\t";
			counter++;
		}
		std::cout << std::endl;
	}
}

 The output is

           1      -0.0967262               2       -0.600818
           4        0.693452        -1.60491        0.504092
           3        0.322917         1.41964       -0.540551
           5       -0.485119        -1.82366         0.65811

However, if I replace the first two lines with the commented lines (to get a non-uniform partition), I get

           1         4.29167        -1.84375        0.223958
           4       -0.395833            -0.5        0.223958
           3        0.291667         0.84375       -0.244792
           5        0.729167          -0.625       -0.244792

What am I missing?

0 Kudos
1 Solution
Ruqiu_C_Intel
Moderator
580 Views

Thank you again for reaching us. This issue will be available in oneMKL 2022.2. Let's closing this thread now. If you require additional assistance from Intel, please start a new thread. Any further interaction in this thread will be considered community only. 


View solution in original post

0 Kudos
4 Replies
VidyalathaB_Intel
Moderator
781 Views

Hi,


Thanks for reaching out to us.


We are looking into this issue, we will get back to you soon.


Regards,

Vidya.


0 Kudos
Gennady_F_Intel
Moderator
771 Views

Alex,

it's a bug and we will fix it in one of the next updates. The problem is escalated. This thread will keep being informed of the status.

-Gennady



0 Kudos
mahalex
Beginner
723 Views

Hi Gennady,

thanks for the quick response!

0 Kudos
Ruqiu_C_Intel
Moderator
581 Views

Thank you again for reaching us. This issue will be available in oneMKL 2022.2. Let's closing this thread now. If you require additional assistance from Intel, please start a new thread. Any further interaction in this thread will be considered community only. 


0 Kudos
Reply