Interpolación
Contexto
Suponemos que tenemos una función dada por una tabla, donde se indican un conjunto de valores(xi,yi).
El problema consiste en estimar qué valores puede tomar Y para x que no coinciden con los de la tabla.
Si xi<x<xi+1, esta estimación es a lo que llamamos interpolación. Si está fuera del intervalo,
se llama extrapolación.
Interpolación con polinomios de Lagrange
Consiste en determinar el polinomio que pasa por los puntos de la tabla. Este polinomio se puede determinar planteando un sistema de ecuaciones, o bien por una técnica de Lagrange. Ver aquí.Librería
En interpolacion.js está desarrollado el código para calcular el polinomio de Lagrange.Se utiliza la librería ../Polinomios/polinomios.js que debe incluirse en el HTML.
Como datos de entrada debemos introducir el array con los datos, de la siguiente manera:
[[x0,y0],[x1,y1],[x2,y2],..,[x(n-1), y(n-1)]] Se utiliza la función
function interpolacionLagrange(datos) que devuelve un array
unidimensional con los coeficientes del polinomio resultante, que podemos escribir con la función polinomioToString(polinomio)
y evaluarlo con evalPol(polinomio,x).Ver siguiente ejemplo:
let salida = "";
let datos = [[-4,10],[-3,0],[-2,0],[-1,0],[1,0],[2,0],[3,0],[4,-10]];
for (let dato of datos) salida += "P(" + dato[0] + ") = " + dato[1] + "\n"
let polLagrange = interpolacionLagrange(datos);
salida += "\n" + polinomioToString(polLagrange) + "\n";
for (let x = -5; x < 5; x++) salida += "P(" + x + ") = " + evalPol(polLagrange, x) + "\n";
console.log(salida);
Interpolación con splines cúbicos
Desarrollo
Se puede ver un tratado de splines aquí.Tenemos
n+1 puntos (de 0 a n): [[x0,y0],[x1,y1],[x2,y2],..,[x(n), y(n)]] Queremos determinar una función a trozos, de forma que para cada intervalo
xi < x < xi+1
tengamos por un polinomio cúbico de interpolación para los x de ese intervalo.
Para n+1 puntos tendremos n intervalos, y por tanto, polinomios distintos.
El polinomio del intervalo i lo denotamos:
\[Y_i(x) = A_i·x^3 + B_i·x^2 + C_i·x + D_i\] Tenemos
4·n incógnitas. Podemos eliminar una incógnita de cada polinomio escribiendo: \[Y_i(x) = a_i·(x-x_i)^3 + b_i·(x-x_i)^2 + c_i·(x-x_i) + d_i\]
El primer polinomio se puede obtener del segundo mediante las siguientes expresiones:
Ai = ai
Bi = bi-3·ai·xi
Bi = 3·xi2·ai - 2·bi·xi+ci
Di = -ai·xi3 + bi·xi2-c·xi+di
Poniendo como condición que el polinomio contenga el punto (xi, yi)
obtenemos Yi(xi) = yi = di, ∀i ϵ [0,..,n-1] . Llamamos
hi = xi+1-xiLa función y sus derivadas en el intervalo son:
Yi(x) = ai·(x-xi)3 + bi·(x-xi)2 + ci·x + di
Y'i(x) = 3·ai·(x-xi)2 + 2·bi·(x-xi) + ci
Y"i(x) = 6·ai·(x-xi) + 2·bi.
Ponemos la condición de que Yi(xi+1) = yi+1 ⇒ yi+1 = ai·hi3+bihi2+c·hi+di Llamamos
si = Y"i(xi) = 2·bi Ponemos la condición de que la segunda derivada sea continua:
si+1=6·ai·hi+2·bi. De esta dos condiciones deducimos:
bi = si/2 ai=(si+1-si)/(6·hi). Sustituyendo estas expresiones, obtenemos
ci=(yi+1-yi)/hi-(2·hi·si+hi·si+1)/6 Ponemos la última condición:
Y'i-1(xi) = Y'i(xi) Operando se obtiene el siguiente sistema de ecuaciones:
hi-1·si-1 + 2·(hi-1+hi)·si + hi·si+1 = = 6·((yi+1-yi)/hi-(yi-yi-1)/hi-1
[A] · [s] = [b]
[[ h0 2·(h0+h1) h1 ] [[ s0 ]
[ h1 2·(h1+h2) h2 ] [ s1 ]
[ ... ] [ .. ]
[ ... ] x [ .. ] =
[ ... ] [ .. ]
[ hn-2 2·(hn-2+hn-1) hn-1 ]] [ sn ]]
[[ 6·((y2-y1)/h1 - (y1-y0)/h0) ]
[ 6·((y3-y2)/h2 - (y2-y1)/h1) ]
[ ... ]
[ ... ]
[ ... ]
[ 6·((yn-yn-1)/hn-1 - (yn-1-yn-2)/hn-2) ]]
sn podría parecer que se refiere a un polinomio tras el punto (xi,yi),
por lo que conviene aclarar que lo sefinimos como el valor de y"n-1(xn). Ahora hemos obtenido un sistema de
n+1 incógnitas, es decir, lo hemos reducido a la cuarta parte. Si obtenemos los valores de
si calcularemos:
ai = (si+1 - si)/(6·hi)
bi = si/2
ci = (yi+1 - yi) / hi - (2·hi·si + hi·si+1)/6
di = yi
El sistema encontrado:
- Es tridiagonal.
- Es simétrica con diagonal principal dominante.
- Tiene
n-1ecuaciones yn+1incógnitas.
-
Spline natural Esto es asignar
s0 = 0; sn=0. Con ello logramos la función más suave posible, según demuestran en el documento indicado más arriba. Podemos aplicarlo a los dos extremos o aplicarlo a sólo uno de los extremos. Añadir estas ecuaciones es una fila con sólo un 1 en el coeficiente correspondiente, resto ceros, y término independiente 0. -
Si tenemos la mitad de los datos, porque la función es simétrica y derivable, el extremo donde tenemos la simetría
la derivada debe ser cero (pendiente horizontal). Si es en
x0. La función derivada es
Y'i = 3·ai·(x-xi)2+2·bi·(x-xi)+ci
para la última función (yn-1(xn)) sustituyendo los coeficientes en función desiy operando, tenemos que-
Simetría por la izquierda:
y'0(x0) = 0 = c0. Operandoy'i(xi) = (yi+1-yi)/hi - hi/3·si - hi/6·si+1, particularizando parai=0⇒1/3·h0·s0 + 1/6·h0·s1 = (y1-y0)/h0
-
Simetría por la derecha:
y'i(xi+1) = hi/3·si+1 + hi/6·si + (yi+1-yi)/hiParticurarizando parai = n-1obtenemos:
y'n-1(x=xn) = 0 = hn-1/3·sn + hn-1/6·sn-1 + (yn-yn-1)/hn-1
(Sin comprobar).
-
Simetría por la izquierda:
-
Si la función es periódica, tomaremos el punto final igual que el inicial,
y0(x0) = yn(xn)Además haremos coincidir las pendientes (y'0(x0) = y'n-1(xn)), e igualaremos las segundas derivadas (s0 = sn).
En este caso el sistema de ecuaciones sería tridiagonal, salvo por dos ecuaciones:
h0/3·s0 + h0/6·s1 + hn-1/6·sn-1 + hn-1/3·sn = (y1-y0)/h0 - (yn-yn-1)/hn-1
s0 - sn = 0
(sin comprobar) -
Otras condiciones que se suelen usar consiste en mantener las derivadas segundas de las funciones extremas igual que las de sus contiguas:
s0 = s1; sn-1 = sn-2.
Librería
Tenemos como datos de entrada:[[x0,y0],[x1,y1],[x2,y2],..,[x(n-1), y(n-1)]] Se ha definido la clase
SplineCubico cuyo constructor es:
let spline = new SplineCubico(datos, condicionIzda, condicionDcha);
donde:
-
datoses el array de datos de entrada. -
condicionIzdapuede ser"natural"para poner la condicióny"(x0) = 0;"simetrica"que pone la condicióny'(x0) = 0;"parabolica"para poner condicióny"(x0] = y"(x1>)]; y"periódica"para condicióny"(x0] = y"(xn-1>)]yy'(x0] = y'(xn-1>)]. -
condicionDchapuede ser"natural"para poner la condicióny"(xn-1) = 0;"simetrica"que pone la condicióny'(xn-1) = 0;"parabolica"para poner condicióny"(xn-1] = y"(xn-2>)]; y"periódica"para condicióny"(x0] = y"(xn-1>)]yy'(x0] = y'(xn-1>)].
En el caso de que sea periódica, tenemos que introducir los datos de forma que y(x0) = y(xn-1).
Además, si se pone la condición "periodica" en cualquera de los extremos, se aplica también al otro, ignorándose cualquier otra
condición que pudiéramos tener establecida.
Al instanciar el objeto spline se plantea y resuelve el sistema de ecuaciones, para lo que se debe incluir el
fichero sistemaEcuacionesLineales.js. Si se aplica la condición de periodicidad
el sistema se resuelve por Gauss Seidel en el caso general, mientras para el resto de condiciones se resuelve optimizando que
la matriz del sistema de ecuaciones es tridiagonal.
Tras el cálculo del sistema de ecuaciones, el objeto spline guarda lo arrays x[],
a[], b[], c[] y d[], de forma que para un
x busca el intervalo i que cumple x[i] < x <= x[i+1] y devuelve
a[i]*x^3+b[i]^2+c[i]*x+d[i]. Esto es lo que hace el método spline.evalua(x).
El método spline.derivada(x) devuelve la derivada en x del polinomio del splite correspondiente.
Los métodos spline.derivada2(x) y spline.derivada3(x)
devuelven la segunda y tercera derivada.
El método spline.integral(xInf, xSup) devuelve el área bajo la
curva entre xInf y xSup.
El método spline.longitud(xInf, xSup) devuelve la longitud de la
curva entre xInf y xSup.
El método spline.radioCurv(x) devuelve el radio de curvatura en x.
El método spline.centroCurv(x)) devuelve las coordenadas {x,y}
del centro del círculo de curvatura en x.
Interpolación 2D
Planteamiento
Tenemos una malla en el pano X-Y, de forma que en los nodos tenemos un valor asociado
Zi,j = f(xi, yj).
Queremos encontrar una función fi,j(x, y) para ∀ xi ≤ x ≤ xi+1
y ∀ yj ≤ y ≤ yj+1.
Interpolación
Una forma de obtener el valor estimado de f(x,y) es
-
Calcular los
m+1splines asociados a cadaxi, y evaluarf(xi, y).
-
Calcular la spline con los nuevos puntos obtenidos
f(xk,y)y calcular sobre ésta el valor estimado def(x,y).
Pero es procedimiento descrito no nos permite tener una función analítica de interpolación sobre la que podamos, por ejemplo, calcular
derivadas parciales o integrar. Ahora el objetivo es buscar una función analítica para cada celda de la malla que se aproxime a la
función real. Podemos obtener una expresión de la función de aproximación fi,j(x, y) para
∀ xi ≤ x ≤ xi+1 y ∀ yj ≤ y ≤ yj+1 con el siguiente
criterio y procedimiento:
-
Calculamos todos los splines por filas, para cada
fxi(y)aplicado axi.
Si sólo nos interesa la celda(i,j)calcularemos los splines paraxiyxi+1. -
Calculamos los splines por columnas, para cada
fyj(x)aplicado ayj. Si sólo nos interesa la celda(i,j)calcularemos los splines parayjeyj+1. -
Cada celda tiene definido su contorno por cuatro funciones polinómicas de 3 grado. Nos planteamos buscar una función polinómica
de dos variables que contenga en su contorno a estas cuatro funciones, que por simplificar las denotaremos con los subíndices
1, 2, 3 y 4.
Por tanto, buscamos
Z(x,y)tal que cumpla:-
Z(x=xi, y) = Z1(y) = a1·y3 + b1·y2 + c1·y + d1, dondea1,b1,c1yd1los hemos calculado en el paso 1. -
Z(x=xi+1, y) = Z2(y) = a2·y3 + b2·y2 + c2·y + d2, dondea2,b2,c2yd2los hemos calculado en el paso 1. -
Z(x, y=yj) = Z3(x) = a3·x3 + b3·x2 + c3·x + d3, dondea3,b3,c3yd3los hemos calculado en el paso 2. -
Z(x, y=yj+1) = Z4(x) = a4·x3 + b4·x2 + c4·x + d4, dondea4,b4,c4yd4los hemos calculado en el paso 2.
Esta función es:
Zi,j(x,y) = s1·x3·y3 + s2·x3·y2 + s3·x2·y3 + s4·x3·y + s5·x2·y2 + s6·x·y3 + s7·x3 + s8·x2·y + s9·x·y5 + s10·y3 + s11·x2 + s12·x·y + s13·y2 + s14·x + s15·y + s16
Función polinómica con 16 coeficientes que son incógnitas. Este polinomio lo podemos reescribir de dos maneras:
Zi,j(x,y) = P1(x)·y3 + P2(x)·y2 + P3(x)·y + P4(x) = P5(y)·x3 + P6(y)·x2 + P7(y)·x + P8(x)
Operando obtememos:-
P1(x) = s1·x3 + s3·x2 + s6·x + s10 -
P2(x) = s2·x3 + s5·x2 + s9·x + s13 -
P3(x) = s4·x3 + s8·x2 + s12·x + s14 -
P4(x) = s7·x3 + s11·x2 + s14·x + s16 -
P5(y) = s1·y3 + s2·y2 + s4·y + s7 -
P6(y) = s3·y3 + s5·y2 + s8·y + s11 -
P7(y) = s6·y3 + s9·y2 + s12·y + s15 -
P8(y) = s10·y3 + s13·y2 + s15·y + s16
Z1(y) = Zi,j(xi,y)Z2(y) = Zi,j(xi+1,y)Z3(x) = Zi,j(x,yj)Z4(x) = Zi,j(x,yj+1)a1 = P1(xi)
b1 = P2(xi)
c1 = P3(xi)
d1 = P4(xi)
a2 = P1(xi+1)
b2 = P2(xi+1)
c2 = P3(xi+1)
d2 = P4(xi+1)
a3 = P5(yj)
b3 = P6(yj)
c3 = P7(yj)
d3 = P8(yj)
a4 = P5(yj+1)
b4 = P6(yj+1)
c4 = P7(yj+1)
d4 = P8(yj+1)
-
-
Con todo lo visto, resolvemos el sistema de ecuaciones (los ceros los omitimos):
xi3 xi2 xi 1 xi3 xi2 xi 1 xi3 xi2 xi 1 xi3 xi2 xi 1 xi+13 xi+12 xi+1 1 xi+13 xi+12 xi+1 1 xi+13 xi+12 xi+1 1 xi+13 xi+12 xi+1 1 yj3 yj2 yj 1 yj3 yj2 yj 1 yj3 yj2 yj 1 yj3 yj2 yj 1 yj+13 yj+12 yj+1 1 yj+13 yj+12 yj+1 1 yj+13 yj+12 yj+1 1 yj+13 yj+12 yj+1 1 xs1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 =a1 b1 c1 d1 a2 b2 c2 d2 a3 b3 c3 d3 a4 b4 c4 d4
No ha sido comprobado, puede haber algún error. Es evidente que el conjunto de funciones Zij(x,y) es
continua en cualquier dirección. Que es derivable y que la derivada segunda es continua para las líneas xi e yj,
pero no está comprobado para el resto de líneas, o para las derivadas parciales 𝜕2f(x,y)/(𝜕x·𝜕y). Pero lo que creo que
es claro que la función polinómica con el grado expresado, es la que mejor nos puede encajar para el ajuste de los datos de la malla,
siempre que se entienda por "mejor", que la función sea continua, respecto a que lo sean sus derivadas, y 2ª derivadas en
cualquier dirección.
Tenemos la forma de evaluar con datos numéricos una función R2🠖R.
Resueltos los coeficientes de la ecuación zi,j(x,y) tendremos una suma de 16 términos de la forma:
Zk=sk·xm·yn.
Podemos calcular:
Divergencia y rotacional
La divergencia y el rotacional se aplican a campos vectoriales, que se salen del objeto de este documento.Plano tangente a un punto de una superficie. Vector normal en un punto de una superficie
Integral de volumen de una función 2D en cartesianas
Resueltos los coeficientes de la ecuaciónzi,j(x,y) tendremos una suma de 16 términos
Zk=sk·xm·yn. La integral es la suma de las integrales de
cada término. La integral de cada término la podemos calcular:
\[\int^{y_{j+1}}_{y_j}{\int^{x_{i+1}}_{x_i}{s_k·x^m·y^n·dx}·dy} = \frac{s_k}{(m+1)·(n-1)}·(x_{i+1}^{m+1}-x_i^{m+1})·(y_{j+1}^{n+1}-y_j^{n+1})\]
Integral de superficie de un campo escalar
Integrales de superficieIntegrakes de superficie en Wikipedia.
Tratado de integrales de superficie
...