De Boor's algorithm

From Wikipedia, the free encyclopedia
(Redirected from De Boor algorithm)
Jump to navigation Jump to search

In the mathematical subfield of numerical analysis, de Boor's algorithm[1] is a polynomial-time and numerically stable algorithm for evaluating spline curves in B-spline form. It is a generalization of de Casteljau's algorithm for BΓ©zier curves. The algorithm was devised by German-American mathematician Carl R. de Boor. Simplified, potentially faster variants of the de Boor algorithm have been created but they suffer from comparatively lower stability.[2][3]

Introduction

[edit | edit source]

A general introduction to B-splines is given in the main article. Here we discuss de Boor's algorithm, an efficient and numerically stable scheme to evaluate a spline curve 𝐒(x) at position x. The curve is built from a sum of B-spline functions Bi,p(x) multiplied with potentially vector-valued constants 𝐜i, called control points, 𝐒(x)=βˆ‘i𝐜iBi,p(x). B-splines of order p+1 are connected piece-wise polynomial functions of degree p defined over a grid of knots t0,,ti,,tm (we always use zero-based indices in the following). De Boor's algorithm uses O(p2) + O(p) operations to evaluate the spline curve. Note: the main article about B-splines and the classic publications[1] use a different notation: the B-spline is indexed as Bi,n(x) with n=p+1.

Local support

[edit | edit source]

B-splines have local support, meaning that the polynomials are positive only in a compact domain and zero elsewhere. The Cox-de Boor recursion formula[4] shows this: Bi,0(x):={1if ti≀x<ti+10otherwise Bi,p(x):=xβˆ’titi+pβˆ’tiBi,pβˆ’1(x)+ti+p+1βˆ’xti+p+1βˆ’ti+1Bi+1,pβˆ’1(x).

Let the index k define the knot interval that contains the position, x∈[tk,tk+1). We can see in the recursion formula that only B-splines with i=kβˆ’p,,k are non-zero for this knot interval. Thus, the sum is reduced to: 𝐒(x)=βˆ‘i=kβˆ’pk𝐜iBi,p(x).

It follows from iβ‰₯0 that kβ‰₯p. Similarly, we see in the recursion that the highest queried knot location is at index k+1+p. This means that any knot interval [tk,tk+1) which is actually used must have at least p additional knots before and after. In a computer program, this is typically achieved by repeating the first and last used knot location p times. For example, for p=3 and real knot locations (0,1,2), one would pad the knot vector to (0,0,0,0,1,2,2,2,2).

The algorithm

[edit | edit source]

With these definitions, we can now describe de Boor's algorithm. The algorithm does not compute the B-spline functions Bi,p(x) directly. Instead it evaluates 𝐒(x) through an equivalent recursion formula.

Let 𝐝i,r be new control points with 𝐝i,0:=𝐜i for i=kβˆ’p,,k. For r=1,,p the following recursion is applied: 𝐝i,r=(1βˆ’Ξ±i,r)𝐝iβˆ’1,rβˆ’1+Ξ±i,r𝐝i,rβˆ’1;i=kβˆ’p+r,,k Ξ±i,r=xβˆ’titi+1+pβˆ’rβˆ’ti.

Once the iterations are complete, we have 𝐒(x)=𝐝k,p, meaning that 𝐝k,p is the desired result.

De Boor's algorithm is more efficient than an explicit calculation of B-splines Bi,p(x) with the Cox-de Boor recursion formula, because it does not compute terms which are guaranteed to be multiplied by zero.

Optimizations

[edit | edit source]

The algorithm above is not optimized for the implementation in a computer. It requires memory for (p+1)+p++1=(p+1)(p+2)/2 temporary control points 𝐝i,r. Each temporary control point is written exactly once and read twice. By reversing the iteration over i (counting down instead of up), we can run the algorithm with memory for only p+1 temporary control points, by letting 𝐝i,r reuse the memory for 𝐝i,rβˆ’1. Similarly, there is only one value of Ξ± used in each step, so we can reuse the memory as well.

Furthermore, it is more convenient to use a zero-based index j=0,,p for the temporary control points. The relation to the previous index is i=j+kβˆ’p. Thus we obtain the improved algorithm:

Let 𝐝j:=𝐜j+kβˆ’p for j=0,,p. Iterate for r=1,,p: 𝐝j:=(1βˆ’Ξ±j)𝐝jβˆ’1+Ξ±j𝐝j;j=p,,r Ξ±j:=xβˆ’tj+kβˆ’ptj+1+kβˆ’rβˆ’tj+kβˆ’p. Note that j must be counted down. After the iterations are complete, the result is 𝐒(x)=𝐝p.

Example implementation

[edit | edit source]

The following code in the Python programming language is a naive implementation of the optimized algorithm.

def deBoor(k: int, x: int, t, c, p: int):
    """Evaluates S(x).

    Arguments
    ---------
    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]

See also

[edit | edit source]
[edit | edit source]

Computer code

[edit | edit source]
  • PPPACK: contains many spline algorithms in Fortran
  • GNU Scientific Library: C-library, contains a sub-library for splines ported from PPPACK
  • SciPy: Python-library, contains a sub-library scipy.interpolate with spline functions based on FITPACK
  • TinySpline: C-library for splines with a C++ wrapper and bindings for C#, Java, Lua, PHP, Python, and Ruby
  • Einspline: C-library for splines in 1, 2, and 3 dimensions with Fortran wrappers

References

[edit | edit source]
  1. ^ a b C. de Boor [1971], "Subroutine package for calculating with B-splines", Techn.Rep. LA-4728-MS, Los Alamos Sci.Lab, Los Alamos NM; p. 109, 121.
  2. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
  3. ^ Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).
  4. ^ C. de Boor, p. 90

Works cited

  • Lua error in Module:Citation/CS1/Configuration at line 2172: attempt to index field '?' (a nil value).