Message Boards Message Boards

GROUPS:

Solving Cubic Splines Symbolically

Posted 9 years ago
7827 Views
|
9 Replies
|
3 Total Likes
|

Hi Community,

I was wondering if anyone knows how to symbolically solve a system of equations to solve for the coefficients of cubic splines? Cubic splines are 3rd degree polynomials that are equal to the values of the endpoints of the intervals and also are equal to the values of their first derivatives at the end points of the interval they are solved for.

f1(t)=c11+c12t+c13t^2+c14t^3

f2(t)=c21+c22t+c23t^2+c24t^3

f1(t0)=0

f1(t1)=k1

f2(t1)=k1

f1'(t1)=f2'(t1)

Heres my attempt at matlab code. I'd like to do this at each node to reduce the number of parameters in the total of the cubic spline fits for my ordered pair of points.

DSolve[{F1[t] == k1 + k2*t + k3*t^2 + k4*t^4,  F2[t] == k5 + k6*t + k7*t^2 + k8*t^4,  F1[0] == Fi1,  F1[1] == Fi2,  F2[1] == Fi2,  F1'[1] = F2'[1]  }, F1[t], t]

Does anyone have some code maybe with dsolve that could help me?

9 Replies

Thanks Alexey, but I am looking for more of a loop approach. If I have a matrix of 5 columns and 100 rows with the 5 columns giving the interval values for the cubic spline fit and the 100 rows being the 100 cubic spline fits I would like stored for. I would like a loop that would take the 5x100 row matrix and output the parameters for the 100 fits. I don't know Mathematica that well but attempted to do this and failed. I tried the following:

For[i = 1, i < 101, i++,

F1[t_] = k1 + k2t + k3t^2 + k4*t^3;

F2[t_] = k5 + k6t + k7t^2 + k8*t^3;

F3[t_] = k9 + k10t + k11t^2 + k12*t^3;

F4[t_] = k13 + k14t + k15t^2 + k16*t^3;

F5[t_] = k17 + k18t + k19t^2 + k20*t^3

 Data = Solve[{F1[0] == 0, F1'[5] == F2'[5], F1''[5] == F2''[5],

   F2'[15] == F3'[15], F2''[15] == F3''[15],

   F3'[30] == F4'[30], F3''[30] == F4''[30],

   F4'[45] == F5'[45], F4''[45] == F5''[45],

   F5''[0] == 0, F1''[0] == 0, F1[5] == matrix[i,1], F2[5] == matrix[i,1], 

   F2[15] == matrix[i,2], F3[15] == matrix[i,2], F3[30] == matrix[i,3], 

   F4[30] == matrix[i,3], F4[48] == matrix[i,4], F5[48] == matrix[i,4], 

   F5[88] == matrix[i,5]}]

 {F1[t], F2[t], F3[t], F4[t], F5[t]} /. Data

]

Posted 8 years ago

Explicit procedural loops are inefficient in Mathematica. You should avoid them and use functional programming style instead.

I have a matrix of 5 columns and 100 rows with the 5 columns giving the interval values for the cubic spline fit and the 100 rows being the 100 cubic spline fits I would like stored for. I would like a loop that would take the 5x100 row matrix and output the parameters for the 100 fits.

There is unique clamped cubic spline interpolating 5 points which consists of (5-3)=2 cubic parabolas. You can get them in explicit form if you apply PiecewiseExpand to the sp2[x] function defined in this excellent answer.

POSTED BY: Alexey Popkov

Thanks Gianluca, You have been tremendously helpful. I do have another question for you and the wider community. What if I wanted to try and do a larger number say a hundred cubic spline fits? Is there a way I can pass in all this data and get the coefficients calculated for each of these separately. Basically if I run an experiment and get a bunch of different F1 and F2 values from different conditions that I run the experiments?

Posted 8 years ago

What if I wanted to try and do a larger number say a hundred cubic spline fits? Is there a way I can pass in all this data and get the coefficients calculated for each of these separately.

This MMaSE thread contains at least two working solutions for your problem: "Arbitrary precision spline interpolation."

POSTED BY: Alexey Popkov

Yes, you can do a piecewise definition, or else you can combine two separate plots using Show:

F1[t_] = k1 + k2*t + k3*t^2 + k4*t^3;
F2[t_] = k5 + k6*t + k7*t^2 + k8*t^3;
Data = Solve[{F1[0] == 0, F1[5] == 3, F2[5] == 3, F1'[5] == F2'[5], 
    F1''[5] == F2''[5], F2[15] == 11, F1'[0] == 0, F1''[0] == 0}];
{F1[t], F2[t]} /. Data
Show[Plot[F1[t] /. Data, {t, 0, 5}, PlotStyle -> Red],
 Plot[F2[t] /. Data, {t, 5, 15}, PlotStyle -> Blue], PlotRange -> All]
POSTED BY: Gianluca Gorni

What if I have actually got numeric parameter values for the fits like with the code below. How would I then plot the functions together? Do I have to do a piece-wise definition?

F1[t_] = k1 + k2*t + k3*t^2 + k4*t^3;

F2[t_] = k5 + k6*t + k7*t^2 + k8*t^3;

Data = Solve[{F1[0] == 0, F1[5] == 3, F2[5] == 3, F1'[5] == F2'[5], 
   F1''[5] == F2''[5],  F2[15] == 11, F1'[0] == 0, F1''[0] == 0}];

{F1[t], F2[t]} /. sol

Plot[%, {t, 0, 15}]

You can tell Solve what variables you want to solve for:

sol = First@Solve[{F1[0] == Fi1, F1[1] == Fi2, F2[1] == Fi2, 
  F1'[1] == F2'[1]}, {k1, k2, k3, k4, k5, k6, k7, k8}]

You cannot plot the solutions directly, because some constants are still symbolic:

{F1[t], F2[t]} /. sol

You can assign all the remaining parameters the value 1, for example, and then plot the functions:

{F1[t], F2[t]} /. sol /. 
 Thread[{Fi1, Fi2, k1, k2, k3, k4, k5, k6, k7, k8} -> 1]
Plot[%, {t, 0, 2}]
POSTED BY: Gianluca Gorni

Do you know how I would have it solve for the k's instead of the Fi's? Also how could I plot these two functions and save the k's?

I am not sure I understand your question, but perhaps you will get started with this:

Clear[F1, F2, k1, k2, k3, k4, k5, k6, k7, k8];

F1[t_] = k1 + k2*t + k3*t^2 + k4*t^3;
F2[t_] = k5 + k6*t + k7*t^2 + k8*t^3;

Solve[{F1[0] == Fi1, F1[1] == Fi2, F2[1] == Fi2, F1'[1] == F2'[1]}]
POSTED BY: Gianluca Gorni
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract