Non-Uniform Natural Splines#
The derivation is similar to the uniform case, but this time the parameter intervals can have arbitrary values.
[1]:
import sympy as sp
sp.init_printing(order='grevlex')
[2]:
from utility import NamedExpression, dotproduct
[3]:
t = sp.symbols('t')
Just like in the uniform case, we are considering two adjacent spline segments, but now we must allow arbitrary parameter values:
[4]:
t3, t4, t5 = sp.symbols('t3:6')
[6]:
coefficients3 = sp.symbols('a:dbm3')[::-1]
coefficients4 = sp.symbols('a:dbm4')[::-1]
[7]:
[9]:
equations = [
p3.evaluated_at(t, t3).with_name('xbm3'),
p3.evaluated_at(t, t4).with_name('xbm4'),
p4.evaluated_at(t, t4).with_name('xbm4'),
p4.evaluated_at(t, t5).with_name('xbm5'),
pd3.evaluated_at(t, t3).with_name('xbmdot3'),
pd3.evaluated_at(t, t4).with_name('xbmdot4'),
pd4.evaluated_at(t, t4).with_name('xbmdot4'),
pd4.evaluated_at(t, t5).with_name('xbmdot5'),
]
We introduce a few new symbols to simplify the display, but we keep calculating with \(t_i\):
[11]:
for e in equations:
display(e.subs(deltas))
[12]:
coefficients = sp.solve(equations, coefficients3 + coefficients4)
[13]:
for c, e in coefficients.items():
display(NamedExpression(c, e.factor().subs(deltas).simplify()))
[15]:
[16]:
_.subs(coefficients).subs(deltas).simplify()
[16]:
Like in the uniform case, we can generalize by renaming index \(4\) to \(i\):
\begin{equation*} \frac{1}{\Delta_{i-1}} \dot{\boldsymbol{x}}_{i-1} + \left(\frac{2}{\Delta_{i-1}} + \frac{2}{\Delta_i}\right) \dot{\boldsymbol{x}}_i + \frac{1}{\Delta_i} \dot{\boldsymbol{x}}_{i+1} = \frac{3 (\boldsymbol{x}_i - \boldsymbol{x}_{i-1})}{{\Delta_{i-1}}^2} + \frac{3 (\boldsymbol{x}_{i+1} - \boldsymbol{x}_i)}{{\Delta_i}^2} \end{equation*}
We are not showing the full matrix here, because it would be quite a bit more complicated and less instructive than in the uniform case.
End Conditions#
Like in the uniform case, we can come up with a few end conditions in order to define the missing matrix rows.
The Python class splines.Natural uses “natural” end conditions by default.
“Natural” end conditions are derived in a separate notebook, yielding these expressions:
\begin{align*} 2 \Delta_0 \dot{\boldsymbol{x}}_0 + \Delta_0 \dot{\boldsymbol{x}}_1 &= 3 (\boldsymbol{x}_1 - \boldsymbol{x}_0) \\ \Delta_{N-2} \dot{\boldsymbol{x}}_{N-2} + 2 \Delta_{N-2} \dot{\boldsymbol{x}}_{N-1} &= 3 (\boldsymbol{x}_{N-1} - \boldsymbol{x}_{N-2}) \end{align*}
Other end conditions can be derived as shown in the notebook about uniform “natural” splines.