Algoritmo de De Boor

De testwiki
Ir a la navegación Ir a la búsqueda

En el subcampo matemático del análisis numérico, el algoritmo de De Boor[1] es un algoritmo de tiempo polinomial y numéricamente estable para evaluar curvas spline en forma B-spline. Es una generalización del algoritmo Casteljau para las curvas de Bézier. El algoritmo fue ideado por Carl R. De Boor. Se han creado variantes simplificadas y potencialmente más rápidas del algoritmo de De Boor, pero sufren una estabilidad comparativamente menor.[2][3]

Introducción

El algoritmo de De Boor es un esquema eficiente y numéricamente estable para evaluar una curva spline 𝐒(x) en posición x. La curva se construye a partir de una suma de funciones B-spline Bi,p(x) multiplicada con valores vectoriales potencialmente constantes 𝐜i, llamados puntos de control.

𝐒(x)=i𝐜iBi,p(x).

Las B-splines de orden p+1 son funciones polinómicas unitarias de grado p definidas sobre una cuadrícula de nudos t0,,ti,,tm (se utilizan índices basados en cero en adelante). El algoritmo de De Boor utiliza operaciones O(p2) + O(p) para evaluar la curva de spline. Nota: El artículo principal sobre B-splines y las publicaciones clásicas[1] utilizan una notación diferente: la B-spline es indexada como Bi,n(x)n=p+1.

Soporte local

Las B-splines tienen soporte local, lo que significa que los polinomios son positivos solamente en un ámbito finito y cero en otros lugares. La fórmula de recursión Cox-De Boor[4] muestra esto::

Bi,0(x):={1sitix<ti+10deotraforma
Bi,p(x):=xtiti+ptiBi,p1(x)+ti+p+1xti+p+1ti+1Bi+1,p1(x).

Permitiendo que el índice k defina el intervalo de nudos que contiene la posición, x[tk,tk+1]. Podemos ver en la fórmula de recursión que solo B-splines con i=kp,,k no son ceros para este intervalo de nudos. Así, la suma se reduce a:

𝐒(x)=i=kpk𝐜iBi,p(x).

De i0 se deduce que kp. Del mismo modo, vemos en la recursividad que la ubicación del nudo más alto está en el índice k+1+p . Esto significa que cualquier intervalo de nudos [tk,tk+1) que se use realmente debe tener al menos p nudos adicionales antes y después. En un programa de computadora, esto generalmente se logra repitiendo la primera y la última ubicación de nudo utilizada p veces. Por ejemplo, para p=3 y ubicaciones de nudos reales (0,1,2), uno podría rellenar el vector de nudos como (0,0,0,0,1,2,2,2,2).

El algoritmo

Con estas definiciones, ahora podemos describir el algoritmo de De Boor . El algoritmo no calcula las funciones de las B-splines Bi,p(x) directamente. En cambio evalúa 𝐒(x) a través de una fórmula de recursión equivalente.

Deja a 𝐝i,r ser un nuevo punto de control con 𝐝i,0:=𝐜i para i=kp,,k. Para r=1,,p la siguiente recursión es aplicada:

𝐝i,r=(1αi,r)𝐝i1,r1+αi,r𝐝i,r1;i=kp+r,,k
αi,r=xtiti+1+prti.

Una vez las iteraciones están completas, tenemos 𝐒(x)=𝐝k,p, esto significa que 𝐝k,p es el resultado deseado.

El algoritmo De Boor es más eficaz que un cálculo explícito de B-splines Bi,p(x) con la fórmula de recursión Cox-De Boor, porque no calcula términos que están garantizados para ser multiplicados por cero.

Optimizaciones

El algoritmo anterior no está optimizado para la implementación en un ordenador. Requiere memoria para (p+1)+p++1=(p+1)(p+2)/2 puntos de control provisional 𝐝i,r. Cada punto de control provisional es escrito exactamente una vez y leídos dos veces. Al invertir la iteración sobre i (contando hacia abajo, en vez de hacia arriba), podemos ejecutar el algoritmo con memoria para solo p+1 puntos de control provisionales, permitiendo a 𝐝i,r reutilizar la memoria para 𝐝i,r1. De modo parecido, hay solo un valor de α utilizado en cada paso, de manera que podemos reutilizar la memoria también.

Además, es más conveniente utilizar un índice basado en cero j=0,,p para los puntos de control provisionales. La relación al índice anterior es i=j+kp. Por ello obtenemos el algoritmo mejorado:

Sea 𝐝j:=𝐜j+kp para j=0,,p. Iterar para r=1,,p:

𝐝j:=(1αj)𝐝j1+αj𝐝j;j=p,,r(j debe ser contado hacia abajo)

αj:=xtj+kptj+1+krtj+kp.

Después que las iteraciones se completan, el resultado es 𝐒(x)=𝐝p.

Implementación de ejemplo

El código siguiente en el lenguaje de programación de Python es una implementación inocente ("naive") del algoritmo optimizado.

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]

Véase también

Enlaces externos

Código de ordenador

  • PPPACK: Contiene muchos spline algoritmos en Fortran
  • GNU Biblioteca científica: C-biblioteca, contiene un sub-biblioteca para splines ported de PPPACK
  • SciPy: Pitón-biblioteca, contiene un sub-biblioteca scipy.interpolate Con spline las funciones basaron en FITPACK
  • TinySpline: C-biblioteca para splines con un C++ wrapper y encuadernaciones para C#, Java, Lua, PHP, Pitón, y Ruby
  • Einspline: C-biblioteca para splines en 1, 2, y 3 dimensiones con Fortran wrappers

Referencias

Plantilla:Listaref

Bibliografía

Plantilla:Control de autoridades

  1. 1,0 1,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. Plantilla:Cita publicación
  3. Plantilla:Cita publicación
  4. C. de Boor, p. 90