This notebook is part of https://github.com/AudioSceneDescriptionFormat/splines, see also http://splines.readthedocs.io/.

# Finite Difference Splines

Idea: average velocity between the two adjoining line segments:

\begin{equation}
\boldsymbol{\dot{x}}_i = \frac{1}{2} \left(
\frac{\boldsymbol{x}_i - \boldsymbol{x}_{i-1}}{t_i - t_{i-1}} +
\frac{\boldsymbol{x}_{i + 1} - \boldsymbol{x}_i}{t_{i + 1} - t_i}
\right)
\end{equation}

According to [Wikipedia](https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Finite_difference), this is called "finite difference" or "three-point difference".

In the uniform case, this can be simplified to

\begin{equation}
\boldsymbol{\dot{x}}_\text{0,uniform} = \frac{\boldsymbol{x}_1 - \boldsymbol{x}_{-1}}{2}
\end{equation}

... which is equivalent to uniform [Catmull--Rom splines](catmull-rom.ipynb).


```python
%matplotlib inline
import sympy as sp
sp.init_printing()
```


```python
from utility import NamedExpression, NamedMatrix
```


```python
x_1, x0, x1, x2 = sp.symbols('xbm_-1 xbm:3')
```


```python
t, t_1, t0, t1, t2 = sp.symbols('t t_-1 t:3')
```


```python
control_values_FD = sp.Matrix([x_1, x0, x1, x2])
control_values_FD
```


```python
xd0 = NamedExpression('xdotbm0', ((x0 - x_1) / (t0 - t_1) + (x1 - x0) / (t1 - t0)) / 2)
xd0
```


```python
xd1 = NamedExpression('xdotbm1', ((x1 - x0) / (t1 - t0) + (x2 - x1) / (t2 - t1)) / 2)
xd1
```


```python
control_values_H = sp.Matrix(sp.symbols('xbm:2 xdotbm:2'))
control_values_H
```


```python
M_H = NamedMatrix(
    r'{M_\text{H}}', 
    sp.S('Matrix([[2, -2, Delta0, Delta0], [-3, 3, -2*Delta0, -Delta0], [0, 0, Delta0, 0], [1, 0, 0, 0]])'))
M_H
```


```python
M_FDtoH = NamedMatrix(r'{M_{\text{FD$\to$H}}}', 4, 4)
```


```python
M_FD = NamedMatrix(r'{M_\text{FD}}', M_H.name * M_FDtoH.name)
M_FD
```


```python
sp.Eq(control_values_H, M_FDtoH.name * control_values_FD)
```


```python
M_FDtoH.expr = sp.Matrix([[expr.expand().coeff(cv) for cv in control_values_FD]
                          for expr in control_values_H.subs([xd0.args, xd1.args])])
M_FDtoH
```


```python
deltas = [
    (t_1, -sp.Symbol('Delta_-1')),
    (t0, 0),
    (t1, sp.Symbol('Delta0')),
    (t2, sp.Symbol('Delta0') + sp.Symbol('Delta1'))
]
```


```python
M_FDtoH.subs(deltas)
```


```python
M_HtoFD = NamedMatrix(r'{M_{\text{H$\to$FD}}}', M_FDtoH.I.expr)
M_HtoFD.subs(deltas).expand()
```


```python
M_FD = M_FD.subs([M_H, M_FDtoH]).doit()
M_FD.subs(deltas).expand()
```


```python
M_FD.subs(deltas).I.expand()
```


```python
uniform = [
    (sp.Symbol('Delta_-1'), 1),
    (sp.Symbol('Delta0') , 1),
    (sp.Symbol('Delta1') , 1),
    #(M_FD.name, sp.Symbol('{M_\text{FD,uniform}}')),
]
```


```python
M_FD.subs(deltas).subs(uniform).pull_out(sp.S.Half).expr
```


```python

```

61d102abb3a593195967bbd5b73f3d095f4f0bb2
ipynb
Jupyter Notebook
doc/finite-difference.ipynb
mgeier/splines
f54b09479d98bf13f00a183fd9d664b5783e3864
MIT
doc/finite-difference.ipynb
mgeier/splines
f54b09479d98bf13f00a183fd9d664b5783e3864
MIT
doc/finite-difference.ipynb
mgeier/splines
f54b09479d98bf13f00a183fd9d664b5783e3864
MIT
Qwen/Qwen-72B
1. YES
2. YES