Как Mathematica создает объект InterpolatingFunction? - PullRequest
3 голосов
/ 16 апреля 2011

Как Mathematica создает объект InterpolatingFunction? Пример:

test1 = FunctionInterpolation[Sin[x],{x,0,2*Pi}]

FullForm test1 длинный, но в основном это x значений с соответствующие значения у. Однако интерполяция не является линейной (так как я не установил InterpolationOrder -> 1)

Я знаю, что Mathematica использует кубические сплайны, отчасти потому, что по умолчанию InterpolationOrder равен 3, но также потому, что:

Plot[D[test1[t],t,t,t,t] /. t->x, {x,0,2*Pi}]

показывает, что 4-я производная равномерно равна 0.

Итак, как Mathematica вычисляет этот кубический сплайн?

Моя цель - использовать объект FunctionInterpolation в Perl.

РЕДАКТИРОВАТЬ: Спасибо, Саша! Это сделал именно то, что я хотел, с несовершеннолетним Сбой. Ниже моя попытка переопределить интерполяцию Эрмита в это легко конвертировать в Perl (также доступно на https://github.com/barrycarter/bcapps/blob/master/bc-approx-sun-ra-dec.m#L234).

Проблема: последние 3 графика имеют небольшие, но ненулевые значения. Я не могу скажите, если я неправильно реализовал Эрмита, или это просто числовой Сбой.

(* the Hermite <h>(not Hermione)</h> polynomials *) 

h00[t_] = (1+2*t)*(1-t)^2 
h10[t_] = t*(1-t)^2 
h01[t_] = t^2*(3-2*t) 
h11[t_] = t^2*(t-1) 

(* 

This confirms my understanding of InterpolatingFunction by calculating 
the value in a different, Perl-friendly, way; this probably does NOT 
work for all InterpolatingFunction's, just the ones I'm using here. 

f = interpolating function, t = value to evaluate at 

*) 

altintfuncalc[f_, t_] := Module[ 
 {xvals, yvals, xint, tisin, tpos, m0, m1, p0, p1}, 

 (* figure out x values *) 
 xvals = Flatten[f[[3]]]; 

 (* and corresponding y values *) 
 yvals = Flatten[f[[4,3]]]; 

 (* and size of each x interval; there are many other ways to do this *) 
 (* <h>almost all of which are better than this?</h> *) 
 xint = (xvals[[-1]]-xvals[[1]])/(Length[xvals]-1); 

 (* for efficiency, all vars above this point should be cached *) 

 (* which interval is t in?; interval i = x[[i]],x[[i+1]] *) 
 tisin = Min[Max[Ceiling[(t-xvals[[1]])/xint],1],Length[xvals]-1]; 

 (* and the y values for this interval, using Hermite convention *) 
 p0 = yvals[[tisin]]; 
 p1 = yvals[[tisin+1]]; 

 (* what is t's position in this interval? *) 
 tpos = (t-xvals[[tisin]])/xint; 

 (* what are the slopes for the intervals immediately before/after this one? *) 
 (* we are assuming interval length of 1, so we do NOT divide by int *) 
 m0 = p0-yvals[[tisin-1]]; 
 m1 = yvals[[tisin+2]]-p1; 

 (* return the Hermite approximation *) 
 (* <h>Whoever wrote the wp article was thinking of w00t</h> *) 
 h00[tpos]*p0 + h10[tpos]*m0 + h01[tpos]*p1 + h11[tpos]*m1 
] 

(* test cases *) 

f1 = FunctionInterpolation[Sin[x],{x,0,2*Pi}] 
f2 = FunctionInterpolation[x^2,{x,0,10}] 
f3 = FunctionInterpolation[Exp[x],{x,0,10}] 

Plot[{altintfuncalc[f1,t] - f1[t]},{t,0,2*Pi}] 
Plot[{altintfuncalc[f2,t] - f2[t]},{t,0,10}] 
Plot[{altintfuncalc[f3,t] - f3[t]},{t,0,10}] 

1 Ответ

3 голосов
/ 16 апреля 2011

Обычно используется кусочная кубическая интерполяция Эрмита . Я не уверен насчет выбора узлов. Кажется, они выбраны равномерно по всему интервалу. Я уверен, что есть результаты для нижних границ интервалов для запрашиваемой точности при условии гладкой функции, но у меня нет подробностей.

...