De Boor's algorithm explained

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

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

S(x)

at position

x

. The curve is built from a sum of B-spline functions

Bi,p(x)

multiplied with potentially vector-valued constants

ci

, called control points, \mathbf(x) = \sum_i \mathbf_i B_(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 use a different notation: the B-spline is indexed as

Bi,n(x)

with

n=p+1

.

Local support

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[4] shows this:B_(x) :=\begin1 & \text \quad t_i \leq x < t_ \\0 & \text\endB_(x) := \frac B_(x) + \frac B_(x).

Let the index

k

define the knot interval that contains the position,

x\in[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: \mathbf(x) = \sum_^ \mathbf_i B_(x).

It follows from

i\geq0

that

k\geqp

. 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

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

S(x)

through an equivalent recursion formula.

Let

di,r

be new control points with

di,0:=ci

for

i=k-p,...,k

. For

r=1,...,p

the following recursion is applied: \mathbf_ = (1-\alpha_) \mathbf_ + \alpha_ \mathbf_; \quad i=k-p+r,\dots,k \alpha_ = \frac.

Once the iterations are complete, we have

S(x)=dk,p

, meaning that

dk,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

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

di,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

di,r

reuse the memory for

di,r-1

. Similarly, there is only one value of

\alpha

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

dj:=cj+k

for

j=0,...,p

. Iterate for

r=1,...,p

: \mathbf_ := (1-\alpha_j) \mathbf_ + \alpha_j \mathbf_; \quad j=p, \dots, r \quad \alpha_j := \frac. Note that must be counted down. After the iterations are complete, the result is

S(x)=dp

.

Example implementation

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

External links

Computer code

References

Works cited

Notes and References

  1. 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. Lee . E. T. Y. . December 1982 . A Simplified B-Spline Computation Routine . Computing . 29 . 4 . 365–371 . Springer-Verlag . 10.1007/BF02246763. 2407104 .
  3. Lee, E. T. Y. . Computing . 3 . 229–238 . Springer-Verlag . 10.1007/BF02240069. Comments on some B-spline algorithms . 36 . 1986. 7003455 .
  4. C. de Boor, p. 90