Content deleted Content added
Hdembinski (talk | contribs) this is an article about the de Boor algorithm, "calculation of the degrees of freedom for interpolation and approximation" is unrelated to the de Boor algorithm |
Hdembinski (talk | contribs) Rewrite of article, addressing the issues, improved notation, added optimized version better suited for computer implementation, added Python implementation, more references to software |
||
Line 1:
In the [[mathematics|mathematical]] subfield of [[numerical analysis]] '''de Boor's algorithm''' is a fast and [[numerically stable]] [[algorithm]] for evaluating [[spline curve]]s in [[B-spline]] form. It is a generalization of [[de Casteljau's algorithm]] for [[Bézier curve]]s. The algorithm was devised by [[Carl R. de Boor]]. Simplified, potentially faster variants of the de Boor algorithm have been created but they suffer from comparatively lower stability.<ref>{{cite journal |last=Lee |first=E. T. Y. |date=December 1982 |title=A Simplified B-Spline Computation Routine |journal=Computing |volume=29 |issue=4 |pages=365–371 |publisher=Springer-Verlag|doi=10.1007/BF02246763}}</ref><ref>{{cite journal | author = Lee, E. T. Y. | journal = Computing | issue = 3 |
▲In the [[mathematics|mathematical]] subfield of [[numerical analysis]] '''de Boor's algorithm''' is a fast and [[numerically stable]] [[algorithm]] for evaluating [[spline curve]]s in [[B-spline]] form. It is a generalization of [[de Casteljau's algorithm]] for [[Bézier curve]]s. The algorithm was devised by [[Carl R. de Boor]]. Simplified, potentially faster variants of the de Boor algorithm have been created but they suffer from comparatively lower stability.<ref>{{cite journal |last=Lee |first=E. T. Y. |date=December 1982 |title=A Simplified B-Spline Computation Routine |journal=Computing |volume=29 |issue=4 |pages=365–371 |publisher=Springer-Verlag|doi=10.1007/BF02246763}}</ref><ref>{{cite journal | author = Lee, E. T. Y. | journal = Computing | issue = 3 | pages = 229–238 | publisher = Springer-Verlag | doi=10.1007/BF02240069|title = Comments on some B-spline algorithms | volume = 36 | year = 1986}}</ref>
== Introduction ==
==
B-splines have local support, meaning that the polynomials are positive only in a finite ___domain and zero elsewhere. The Cox-de Boor recursion formula<ref>de Boor, p. 131</ref> shows this:
▲:<math> \mathbf{s}(x) = \sum_{i=0}^{p-1} \mathbf{d}_i N_i^n(x) , </math>
:<math>B_{i,0}(x) := \left\{
\begin{matrix}
1 & \mathrm{if} \quad t_i \leq x < t_{i+1} \\
0 & \mathrm{otherwise}
\end{matrix}
\right.
</math>
:<math>
Let the index <math> k </math> define the knot interval that contains the position, <math> x \in [t_{k},t_{k+1}) </math>. We can see in the recursion formula that only B-splines with <math> i \in [k-p, k] </math> are non-zero for this knot interval. Thus, the sum is reduced to:
▲:<math> \mathbf{s}(x) = \sum_{i=\ell-n}^{\ell} \mathbf{d}_i N_i^n(x) </math>
It follows from <math> i \geq 0 </math> that <math> k \geq p </math>. Similarly, we see in the recursion that the highest queried knot ___location is at index <math> k + 1 + p </math>. This means that any knot interval <math> [t_k,t_{k+1}) </math> which is actually used must have at least <math> p </math> additional knots before and after. In a computer program, this is typically achieved by repeating the first and last used knot ___location <math> p </math> times. For example, for <math> p = 3 </math> and real knot locations <math> 0, 1, 2 </math>, one would pad the knot vector to <math> 0,0,0,0,1,2,2,2,2 </math>.
== The algorithm ==
With these definitions, we can now describe de Boor's algorithm. The algorithm does not compute the B-spline functions <math> B_{i,p}(x) </math> directly. Instead it evaluates <math> \mathbf{S}(x) </math> through an equivalent recursion formula.
:<math> \mathbf{d}_{i,r} = (1-\alpha_{i,r}) \mathbf{d}_{i-1,r-1} + \alpha_{i,r} \mathbf{d}_{i,k-1}; \quad i=k-p+r,\dots,k </math>
:<math> \alpha_{
De Boor's algorithm is more efficient than an explicit calculation of B-splines <math> B_{i,p}(x) </math> with the Cox-de Boor recursion formula, because it does not compute terms which are guaranteed to be multiplied by zero.
== Optimizations ==
The algorithm above is not optimized for the implementation in a computer. It requires memory for <math> (p + 1) + p + \dots + 1 = (p + 1)(p + 2)/2 </math> temporary control points <math> \mathbf{d}_{i,r} </math>. Each temporary control points is written exactly once and read twice. By reversing the iteration over <math> i </math> (counting down instead of up), we can run the algorithm with memory for only <math> p + 1 </math> temporary control points, by letting <math> \mathbf{d}_{i,r} </math> reuse the memory cell for <math> \mathbf{d}_{i,r-1} </math>. Similarly, there is only one value of <math> \alpha </math> used in each step, so we can reuse the memory cell and drop the indices.
Furthermore, it is more convenient to use an index <math> j \in [0,p] </math> for the temporary control points. The relation to the previous index is <math> i = j + k - p </math>. Thus we obtain the improved algorithm:
Let <math> \mathbf{d}_{j} := \mathbf{c}_{j+k - p} </math> for <math> j = 0, \dots, p</math>. Iterate for <math> r = 1, \dots, p </math>:
:<math> \alpha := \frac{x-t_{j + k - p}}{t_{j+1+k-r}-t_{j+k-p}}, </math>
:<math> \mathbf{d}_{j} := (1-\alpha) \mathbf{d}_{j-1} + \alpha \mathbf{d}_{j}; \quad j=p, \dots, r \quad </math> (<math> j </math> must be counted down)
After the iterations are complete, the result is <math>\mathbf{S}(x) = \mathbf{d}_{p} </math>.
== Example implementation ==
The following code in the [[Python (programming language)|Python programming language]] is a naive implementation of the optimized algorithm.
<source lang="python">
def deBoor(k, x, t, c, p):
"""
Evaluates S(x).
Args
----
k: index of knot interval that contains x
x: position
t: array of knot positions, needs to be padded as described above
c: array of control points
p: degree of B-spline
"""
d = [c[j + k - p] for j in range(0, p+1)]
for r in range(1, p+1):
for j in range(p, r-1, -1):
alpha = (x - t[j+k-p]) / (t[j+1+k-r] - t[j+k-p])
d[j] = (1.0 - alpha) * d[j-1] + alpha * d[j]
return d[p]
</source>
== See also ==
Line 54 ⟶ 92:
== Computer code ==
* [http://www.netlib.org/pppack/ PPPACK]: contains many spline algorithms in [[Fortran]]
[https://github.com/msteinbeck/tinyspline TinySpline: Open source C-library for splines which implements De Boor's algorithm]▼
* [https://www.gnu.org/software/gsl/ GNU Scientific Library]: C-library, contains a sub-library for splines ported from [[Netlib|PPPACK]]
* [https://www.scipy.org/ SciPy]: Python-library, contains a sub-library ''scipy.interpolate'' with spline functions based on [[Netlib|FITPACK]]
▲* [https://github.com/msteinbeck/tinyspline TinySpline]:
* [http://einspline.sourceforge.net/ Einspline]: C-library for splines in 1, 2, and 3 dimensions with Fortran wrappers
== References ==
<references/>
'''Works cited'''
*{{cite book | author = Carl de Boor | title = A Practical Guide to Splines | publisher = Springer-Verlag | year = 1978|ISBN=3-540-90356-9}}
[[Category:Numerical analysis]]
|