10 views (last 30 days)

Show older comments

i am using natural cubic spline interpolation using csape fucntion

z=[ -3.7

-2

-1.2

-0.6

0.7

1.8

2.7

3.4

3.6

3.9];

p=[ 0.4

3.9

3.9

4.8

4.8

4.3

3.8

2.4

1.2

0];

pp = csape(z,p,'variational')

but the coeeficients i am geting are incorrect using this method..coefficeients for x^3 terms match only .rest are all diff from correct ans.how to coreect this plz help????

John D'Errico
on 30 Apr 2021

Edited: John D'Errico
on 30 Apr 2021

PLEASE DO NOT SEND ME E-MAIL ASKING FOR HELP. I ask people not to do this. (Note that for those people who might decide to do so anyway despite my explicit request to not contact me directly, I then add their addresses to my list of people to forever ignore.) And, to be honest, my response should be to not answer your question. But since there will be few people who might know the answer and I have some free time, I'll give you one.

"but the coeeficients i am geting are incorrect using this method..coefficeients for x^3 terms match only .rest are all diff from correct ans."

WRONG. The coefficients are in fact perfectly correct (I just checked that fact using my own code to verify they are indeed correct for a natural cubic spline interpolant on that support.)

pp.coefs

ans =

-0.3182 -2.2204e-16 2.9784 0.4

1.6853 -1.6228 0.21965 3.9

-2.2557 2.4219 0.85893 3.9

0.47393 -1.6384 1.329 4.8

-0.13005 0.2099 -0.52807 4.8

0.22244 -0.21927 -0.53838 4.3

-3.8252 0.3813 -0.39256 3.8

25.303 -7.6517 -5.4818 2.4

-8.367 7.5303 -5.5061 1.2

Your problem is you do not understand what the coefficients mean, and how they are to be interpreted. The array of coefficients above is indeed correct. So why do you THINK they are wrong?

I'll hazard a guess that you think these are the coefficients of a polynomial defined on the intervals between the breaks.

z

z =

-3.7

-2

-1.2

-0.6

0.7

1.8

2.7

3.4

3.6

3.9

So, between the first pair of breaks, thus the interval [-3.7, -2], you THINK the polynomial should be interpreted as this polynomial:

syms x

vpa(pp.coefs(1,:)*x.^[3 2 1 0].',5)

ans =

- 0.3182*x^3 - 2.2204e-16*x^2 + 2.9784*x + 0.4

WRONG.

In fact, those coefficients are intended to be used as a polynomial in the form:

- 0.3182*(x-3.7)^3 - 2.2204e-16*(x-3.7)^2 + 2.9784*(x-3.7) + 0.4

In fact, each of those piecewise polynomial segments are only evaluated by first subtracting the LOWER end of the interval off of x.

But why in the name of god and little green apples would they do that?

Look back at the polynomial you think should exist.

- 0.3182*x^3 - 2.2204e-16*x^2 + 2.9784*x + 0.4

Suppose the breaks for that interval were, instead of [-3.7,-2], suppose they were [1000, 1001.7]. Or, suppose they were even more heavily shifted? Perhaps [10000000000, 10000000001.7]? In each case, the interval is of length 1.7 units.

The problem is that cubic polynomial will become highly ill-conditioned to evaluate, because now you are raising large numbers to powers as large as 3. And if your spline were perhaps a higher order spline, things would be even worse.

For this reason, the coefficients are designed for a cubic segment on the interval [a,b], they will be evaluated on the interval [0,b-a]. Essentially, you subtract the lower endpoint of that interval from x BEFORE you pass that into the polynomial.

The only possible reason why you would think those coefficients are incorrect is because you do not understand this fact.

You can find my SLM toolbox on the file exchange, in there, you would find the utility slmpar, which can create the various polynomials as they would be interpreted, converting them between forms. Honestly though, there should be no need to do so, as long as you understand this fact.

Can you test my claim? Trivially done in fact. Consider these two splines:

pp = csape(z,p,'variational')

pp =

struct with fields:

form: 'pp'

breaks: [-3.7 -2 -1.2 -0.6 0.7 1.8 2.7 3.4 3.6 3.9]

coefs: [9×4 double]

pieces: 9

order: 4

dim: 1

You can see the breaks, and he coefficients are as I showed.

pp.coefs

ans =

-0.3182 -2.2204e-16 2.9784 0.4

1.6853 -1.6228 0.21965 3.9

-2.2557 2.4219 0.85893 3.9

0.47393 -1.6384 1.329 4.8

-0.13005 0.2099 -0.52807 4.8

0.22244 -0.21927 -0.53838 4.3

-3.8252 0.3813 -0.39256 3.8

25.303 -7.6517 -5.4818 2.4

-8.367 7.5303 -5.5061 1.2

But now create a shifted spline, identical to the last, except now I have added 100 to z.

pp100 = csape(z + 100,p,'variational')

pp100 =

struct with fields:

form: 'pp'

breaks: [96.3 98 98.8 99.4 100.7 101.8 102.7 103.4 103.6 103.9]

coefs: [9×4 double]

pieces: 9

order: 4

dim: 1

pp100.coefs

ans =

-0.3182 -2.2204e-16 2.9784 0.4

1.6853 -1.6228 0.21965 3.9

-2.2557 2.4219 0.85893 3.9

0.47393 -1.6384 1.329 4.8

-0.13005 0.2099 -0.52807 4.8

0.22244 -0.21927 -0.53838 4.3

-3.8252 0.3813 -0.39256 3.8

25.303 -7.6517 -5.4818 2.4

-8.367 7.5303 -5.5061 1.2

You should see the coefficient array is now identical to the first. And that makes the spline able to be evaluated robustly.

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!