Определить интерполяционные функции Mathematica из графиков (не Эрмита)
Я реверс-инжиниринг, как Mathematica делает список интерполяции:
(* 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
РЕДАКТИРОВАТЬ: Спасибо, whuber! Это именно то, что я хотел. Для справки, коэффициенты (по порядку):
(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
1 ответ
Согласно документации, интерполятор является кусочно-полиномиальным. Это немного расплывчато, поэтому здесь есть что исследовать.
Вы можете экспериментально установить, что интерполятор является линейной функцией данных. Хорошая основа для всех возможных данных состоит из векторов вида {1,0,...,0}, {0,1,0,...,0}, ..., {0,...,0,1}. Для этого давайте создадим крошечную функцию для получения этих векторов длиной $n$:
test[n_, i_] := Module[{x = ConstantArray[0,n]},x[[i]] = 1; x]
Вы можете подтвердить линейность, попробовав несколько примеров, подобных этому, с коэффициентами $ a $ и $ b $, действующими на базисные векторы $i^\text{th}$ и $j^\text{th}$ длины $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}]
]
Будет только одна кривая, потому что две функции накладываются.
Установив линейность, достаточно проанализировать значения интерполятора на $ n $ базисных векторах. Вы можете определить степени многочленов путем дифференцирования. По умолчанию степень равна 3, но вы можете изменить ее с помощью параметра "InterpolatingOrder". В следующем коде будет построена таблица явно кусочно-постоянных кривых, полученных из производных интерполятора для интерполяции порядков от 1 до ioMax, используя все базисные векторы для данных длины $n$:
With[{n=7, ioMax = 5},
Table[
Module[{fns},
fns = Table[Interpolation[test[n,i], InterpolationOrder->io], {i,1,n}];
Table[Plot[Evaluate@D[f[#], {#,io}]&[x], {x,1,n},
PlotRange->Full, PlotStyle->Thick, ImageSize->150], {f, fns}]
], {io, 1, ioMax}
]
] // TableForm
Выходные данные показывают, что разрывы происходят при целочисленных значениях аргумента и что существует не более $ nd $ различных сегментов для данных длины $ n $ и интерполятора степени $ d $. Эта информация должна помочь вам в этом.