This page was generated from doc/euclidean/natural-uniform.ipynb. Interactive online version: Binder badge.

Uniform Natural Splines§

non-uniform

[1]:
import sympy as sp
sp.init_printing(order='rev-lex')

utility.py

[2]:
from utility import NamedExpression
[3]:
t = sp.symbols('t')
[4]:
a3, a4, b3, b4, c3, c4, d3, d4 = sp.symbols('a:dbm3:5')
[5]:
b_monomial = sp.Matrix([t**3, t**2, t, 1]).T
[6]:
p3 = NamedExpression('pbm3', d3 * t**3 + c3 * t**2 + b3 * t + a3)
p4 = NamedExpression('pbm4', d4 * t**3 + c4 * t**2 + b4 * t + a4)
display(p3, p4)
$\displaystyle \boldsymbol{p}_{3} = \boldsymbol{d}_{3} t^{3} + \boldsymbol{c}_{3} t^{2} + \boldsymbol{b}_{3} t + \boldsymbol{a}_{3}$
$\displaystyle \boldsymbol{p}_{4} = \boldsymbol{d}_{4} t^{3} + \boldsymbol{c}_{4} t^{2} + \boldsymbol{b}_{4} t + \boldsymbol{a}_{4}$
[7]:
pd3 = p3.diff(t)
pd4 = p4.diff(t)
display(pd3, pd4)
$\displaystyle \frac{d}{d t} \boldsymbol{p}_{3} = 3 \boldsymbol{d}_{3} t^{2} + 2 \boldsymbol{c}_{3} t + \boldsymbol{b}_{3}$
$\displaystyle \frac{d}{d t} \boldsymbol{p}_{4} = 3 \boldsymbol{d}_{4} t^{2} + 2 \boldsymbol{c}_{4} t + \boldsymbol{b}_{4}$
[8]:
equations = [
    p3.evaluated_at(t, 0).with_name('xbm3'),
    p3.evaluated_at(t, 1).with_name('xbm4'),
    p4.evaluated_at(t, 0).with_name('xbm4'),
    p4.evaluated_at(t, 1).with_name('xbm5'),
    pd3.evaluated_at(t, 0).with_name('xbmdot3'),
    pd3.evaluated_at(t, 1).with_name('xbmdot4'),
    pd4.evaluated_at(t, 0).with_name('xbmdot4'),
    pd4.evaluated_at(t, 1).with_name('xbmdot5'),
]
display(*equations)
$\displaystyle \boldsymbol{x}_{3} = \boldsymbol{a}_{3}$
$\displaystyle \boldsymbol{x}_{4} = \boldsymbol{d}_{3} + \boldsymbol{c}_{3} + \boldsymbol{b}_{3} + \boldsymbol{a}_{3}$
$\displaystyle \boldsymbol{x}_{4} = \boldsymbol{a}_{4}$
$\displaystyle \boldsymbol{x}_{5} = \boldsymbol{d}_{4} + \boldsymbol{c}_{4} + \boldsymbol{b}_{4} + \boldsymbol{a}_{4}$
$\displaystyle \dot{\boldsymbol{x}}_{3} = \boldsymbol{b}_{3}$
$\displaystyle \dot{\boldsymbol{x}}_{4} = 3 \boldsymbol{d}_{3} + 2 \boldsymbol{c}_{3} + \boldsymbol{b}_{3}$
$\displaystyle \dot{\boldsymbol{x}}_{4} = \boldsymbol{b}_{4}$
$\displaystyle \dot{\boldsymbol{x}}_{5} = 3 \boldsymbol{d}_{4} + 2 \boldsymbol{c}_{4} + \boldsymbol{b}_{4}$
[9]:
coefficients = sp.solve(equations, [a3, a4, b3, b4, c3, c4, d3, d4])
for c, e in coefficients.items():
    display(NamedExpression(c, e))
$\displaystyle \boldsymbol{a}_{3} = \boldsymbol{x}_{3}$
$\displaystyle \boldsymbol{b}_{3} = \dot{\boldsymbol{x}}_{3}$
$\displaystyle \boldsymbol{c}_{3} = - \dot{\boldsymbol{x}}_{4} - 2 \dot{\boldsymbol{x}}_{3} + 3 \boldsymbol{x}_{4} - 3 \boldsymbol{x}_{3}$
$\displaystyle \boldsymbol{d}_{3} = \dot{\boldsymbol{x}}_{4} + \dot{\boldsymbol{x}}_{3} - 2 \boldsymbol{x}_{4} + 2 \boldsymbol{x}_{3}$
$\displaystyle \boldsymbol{a}_{4} = \boldsymbol{x}_{4}$
$\displaystyle \boldsymbol{b}_{4} = \dot{\boldsymbol{x}}_{4}$
$\displaystyle \boldsymbol{c}_{4} = - \dot{\boldsymbol{x}}_{5} - 2 \dot{\boldsymbol{x}}_{4} + 3 \boldsymbol{x}_{5} - 3 \boldsymbol{x}_{4}$
$\displaystyle \boldsymbol{d}_{4} = \dot{\boldsymbol{x}}_{5} + \dot{\boldsymbol{x}}_{4} - 2 \boldsymbol{x}_{5} + 2 \boldsymbol{x}_{4}$

NB: these are the same constants as in \(M_H\) (see Uniform Hermite Splines)!

[10]:
pdd3 = pd3.diff(t)
pdd4 = pd4.diff(t)
display(pdd3, pdd4)
$\displaystyle \frac{d^{2}}{d t^{2}} \boldsymbol{p}_{3} = 6 \boldsymbol{d}_{3} t + 2 \boldsymbol{c}_{3}$
$\displaystyle \frac{d^{2}}{d t^{2}} \boldsymbol{p}_{4} = 6 \boldsymbol{d}_{4} t + 2 \boldsymbol{c}_{4}$
[11]:
sp.Eq(pdd3.expr.subs(t, 1), pdd4.expr.subs(t, 0))
[11]:
$\displaystyle 6 \boldsymbol{d}_{3} + 2 \boldsymbol{c}_{3} = 2 \boldsymbol{c}_{4}$
[12]:
_.subs(coefficients).simplify()
[12]:
$\displaystyle 3 \boldsymbol{x}_{3} = - \dot{\boldsymbol{x}}_{5} - 4 \dot{\boldsymbol{x}}_{4} - \dot{\boldsymbol{x}}_{3} + 3 \boldsymbol{x}_{5}$

generalize by setting index \(4 \to i\)

\begin{equation*} \dot{\boldsymbol{x}}_{i-1} + 4 \dot{\boldsymbol{x}}_{i} + \dot{\boldsymbol{x}}_{i+1} = 3 (\boldsymbol{x}_{i+1} - \boldsymbol{x}_{i-1}) \end{equation*}
\begin{equation*} \left[ \begin{matrix} 1 & 4 & 1 && \cdots & 0 \\ & 1 & 4 & 1 && \vdots \\ && \ddots & \ddots && \\ \vdots && 1 & 4 & 1 & \\ 0 & \cdots && 1 & 4 & 1 \end{matrix} \right] \left[ \begin{matrix} \dot{\boldsymbol{x}}_0\\ \dot{\boldsymbol{x}}_1\\ \vdots\\ \dot{\boldsymbol{x}}_{N-2}\\ \dot{\boldsymbol{x}}_{N-1} \end{matrix} \right] = \left[ \begin{matrix} 3 (\boldsymbol{x}_2 - \boldsymbol{x}_0)\\ 3 (\boldsymbol{x}_3 - \boldsymbol{x}_1)\\ \vdots\\ 3 (\boldsymbol{x}_{N-2} - \boldsymbol{x}_{N-4})\\ 3 (\boldsymbol{x}_{N-1} - \boldsymbol{x}_{N-3}) \end{matrix} \right] \end{equation*}

\(N\) columns, \(N-2\) rows

End Conditions§

add first and last row

end conditions can be mixed, e.g. “clamped” at the beginning and “natural” at the end.

The Python class splines.Natural uses “natural” end conditions by default.

Natural§

notebook about “natural” end conditions

Get the uniform case by setting \(\Delta_i = 1\).

\begin{align*} 2 \dot{\boldsymbol{x}}_0 + \dot{\boldsymbol{x}}_1 &= 3 (\boldsymbol{x}_1 - \boldsymbol{x}_0) \\ \dot{\boldsymbol{x}}_{N-2} + 2 \dot{\boldsymbol{x}}_{N-1} &= 3 (\boldsymbol{x}_{N-1} - \boldsymbol{x}_{N-2}) \end{align*}
\begin{equation*} \left[ \begin{matrix} 2 & 1 &&& \cdots & 0\\ 1 & 4 & 1 &&& \vdots \\ & 1 & 4 & 1 && \\ && \ddots & \ddots && \\ && 1 & 4 & 1 & \\ \vdots &&& 1 & 4 & 1\\ 0 & \cdots &&& 1 & 2 \end{matrix} \right] \left[ \begin{matrix} \dot{\boldsymbol{x}}_0\\ \dot{\boldsymbol{x}}_1\\ \vdots\\ \dot{\boldsymbol{x}}_{N-2}\\ \dot{\boldsymbol{x}}_{N-1} \end{matrix} \right] = \left[ \begin{matrix} 3 (\boldsymbol{x}_1 - \boldsymbol{x}_0)\\ 3 (\boldsymbol{x}_2 - \boldsymbol{x}_0)\\ 3 (\boldsymbol{x}_3 - \boldsymbol{x}_1)\\ \vdots\\ 3 (\boldsymbol{x}_{N-2} - \boldsymbol{x}_{N-4})\\ 3 (\boldsymbol{x}_{N-1} - \boldsymbol{x}_{N-3})\\ 3 (\boldsymbol{x}_{N-1} - \boldsymbol{x}_{N-2}) \end{matrix} \right] \end{equation*}

Clamped§

clamped (end tangents are given)

\begin{align*} \dot{\boldsymbol{x}}_0 &= D_\text{begin}\\ \dot{\boldsymbol{x}}_{N-1} &= D_\text{end} \end{align*}
\begin{equation*} \left[ \begin{matrix} 1 &&&& \cdots & 0\\ 1 & 4 & 1 &&& \vdots \\ & 1 & 4 & 1 && \\ && \ddots & \ddots && \\ && 1 & 4 & 1 & \\ \vdots &&& 1 & 4 & 1\\ 0 & \cdots &&&& 1 \end{matrix} \right] \left[ \begin{matrix} \dot{\boldsymbol{x}}_0\\ \dot{\boldsymbol{x}}_1\\ \vdots\\ \dot{\boldsymbol{x}}_{N-2}\\ \dot{\boldsymbol{x}}_{N-1} \end{matrix} \right] = \left[ \begin{matrix} D_\text{begin}\\ 3 (\boldsymbol{x}_2 - \boldsymbol{x}_0)\\ 3 (\boldsymbol{x}_3 - \boldsymbol{x}_1)\\ \vdots\\ 3 (\boldsymbol{x}_{N-2} - \boldsymbol{x}_{N-4})\\ 3 (\boldsymbol{x}_{N-1} - \boldsymbol{x}_{N-3})\\ D_\text{begin} \end{matrix} \right] \end{equation*}

Closed§

\begin{equation*} \left[ \begin{matrix} 4 & 1 && \cdots & 0 & 1\\ 1 & 4 & 1 && 0 & 0 \\ & 1 & 4 & 1 && \vdots \\ && \ddots & \ddots && \\ \vdots && 1 & 4 & 1 & \\ 0 & 0 && 1 & 4 & 1\\ 1 & 0 & \cdots && 1 & 4 \end{matrix} \right] \left[ \begin{matrix} \dot{\boldsymbol{x}}_0\\ \dot{\boldsymbol{x}}_1\\ \vdots\\ \dot{\boldsymbol{x}}_{N-2}\\ \dot{\boldsymbol{x}}_{N-1} \end{matrix} \right] = \left[ \begin{matrix} 3 (\boldsymbol{x}_1 - \boldsymbol{x}_{N-1})\\ 3 (\boldsymbol{x}_2 - \boldsymbol{x}_0)\\ 3 (\boldsymbol{x}_3 - \boldsymbol{x}_1)\\ \vdots\\ 3 (\boldsymbol{x}_{N-2} - \boldsymbol{x}_{N-4})\\ 3 (\boldsymbol{x}_{N-1} - \boldsymbol{x}_{N-3})\\ 3 (\boldsymbol{x}_{0} - \boldsymbol{x}_{N-2}) \end{matrix} \right] \end{equation*}