2011-05-25 18 views
5

estoy ingeniería inversa de cómo Mathematica hace la lista de interpolación:identificar las funciones de interpolación a partir de gráficos de Mathematica (no Hermite)

(* Fortunately, Mathematica WILL interpolate an arbitrary list *) 

tab = Table[a[i], {i,1,100}] 

f = Interpolation[tab] 

(* get the coefficient of each term by setting others to zero *) 

Plot[{f[42+x] /. {a[42] -> 0, a[43] ->0, a[44] -> 0, a[41] -> 1}}, 
{x,0,1}] 

Plot[{f[42+x] /. {a[41] -> 0, a[43] ->0, a[44] -> 0, a[42] -> 1}}, 
{x,0,1}] 

Plot[{f[42+x] /. {a[42] -> 0, a[41] ->0, a[44] -> 0, a[43] -> 1}}, 
{x,0,1}] 

Plot[{f[42+x] /. {a[42] -> 0, a[43] ->0, a[41] -> 0, a[44] -> 1}}, 
{x,0,1}] 

(* above is neither Hermite, nor linear, though some look close *) 

(* these are available at oneoff.barrycarter.info/STACK/ *) 

Table[f[42+x] /. {a[42] -> 0, a[43] ->0, a[44] -> 0, a[41] -> 1}, 
{x,0,1, 1/100}] >> /home/barrycarter/BCINFO/ONEOFF/STACK/coeff41.txt 

Table[f[42+x] /. {a[41] -> 0, a[43] ->0, a[44] -> 0, a[42] -> 1}, 
{x,0,1, 1/100}] >> /home/barrycarter/BCINFO/ONEOFF/STACK/coeff42.txt 

Table[f[42+x] /. {a[41] -> 0, a[42] ->0, a[44] -> 0, a[43] -> 1}, 
{x,0,1, 1/100}] >> /home/barrycarter/BCINFO/ONEOFF/STACK/coeff43.txt 

Table[f[42+x] /. {a[41] -> 0, a[42] ->0, a[43] -> 0, a[44] -> 1}, 
{x,0,1, 1/100}] >> /home/barrycarter/BCINFO/ONEOFF/STACK/coeff44.txt 

EDIT: Gracias, whuber! Eso hizo exactamente lo que yo quería. Para referencia, los coeficientes son (en orden):

(x-2)*(x-1)*x/-6 
(x-2)*(x-1)*(x+1)/2 
x*(x+1)*(x-2)/-2 
(x-1)*x*(x+1)/6 
+0

Para facilitar la lectura, ayudaría a eliminar todas las tramas excepto una, o a hacerlas mucho más pequeñas. –

Respuesta

7

De acuerdo con la documentación del interpolador es polinomial a trozos. Eso es un poco vago, entonces hay algo que investigar aquí.

Puede establecer experimentalmente que el interpolador es una función lineal de los datos. Una buena base para todos los datos posibles consiste en vectores de la forma {1,0, ..., 0}, {0,1,0, ..., 0}, ..., {0, ..., 0,1}. Con este fin, vamos a construir una función pequeña para producir estos vectores de longitud $ n $:

test[n_, i_] := Module[{x = ConstantArray[0,n]},x[[i]] = 1; x] 

Puede confirmar la linealidad al tratar algunos ejemplos como éste, con coeficientes $ a $ y $ b $ actuando en el $ i^\ text {ésimo} $ y $ j^\ text {ésimo} $ vectores de la base de longitud $ n $:

With[{a=1, b=2.5, n=5, i=2, j=3}, 
    Plot[{Interpolation[a test[n,i] + b test[n,j]][x], 
     a Interpolation[test[n,i]][x] + b Interpolation[test[n,j]][x]}, {x, 1, n}] 
] 

sólo habrá una única curva debido a que las dos funciones se superponen.

Habiendo establecido la linealidad, bastará con analizar los valores del interpolador en los vectores base $ n $. Puedes determinar los grados de los polinomios por diferenciación. Por defecto, el grado es 3, pero puede modificarlo con el parámetro "InterpolatingOrder". El siguiente código trazar una tabla de curvas obviamente a trozos constantes resultantes de los derivados de la interpolador para interpolar órdenes 1 a ioMax, utilizando todos los vectores de la base de datos de longitud $ n $:

With[{n=7, ioMax = 5}, 
    Table[ 
     Module[{fns}, 
      fns = Table[Interpolation[test[n,i], InterpolationOrder->io], {i,1,n}]; 
      Table[Plot[[email protected][f[#], {#,io}]&[x], {x,1,n}, 
       PlotRange->Full, PlotStyle->Thick, ImageSize->150], {f, fns}] 
     ], {io, 1, ioMax} 
    ] 
] // TableForm 

Los espectáculos de salida que las rupturas ocurren en los valores enteros del argumento y que hay a lo sumo $ nd $ segmentos distintos para datos de longitud $ n $ y un interpolador de grado $ d $. Esta información debería llevarlo la mayor parte del camino hasta allí.

Cuestiones relacionadas