Странное поведение опции InterpolationOrder Интерполяции - PullRequest
4 голосов
/ 10 октября 2011

При попытке воссоздать InterpolationFunction, созданный NDSolve, я столкнулся с очень странной проблемой с параметром InterpolationOrder, равным Interpolation. Рассмотрим следующее InterpolationFunction (пример функции из документации ):

ifun = First[
  x /. NDSolve[{x'[t] == Exp[x[t]] - x[t], x[0] == 1}, x, {t, 0, 10}]]

Теперь давайте попробуем восстановить его. Вот данные:

Needs["DifferentialEquations`InterpolatingFunctionAnatomy`"]
data = Transpose@{InterpolatingFunctionGrid[ifun], 
   InterpolatingFunctionValuesOnGrid[ifun]};

А вот и InterpolationOrder:

interpolationOrder = InterpolatingFunctionInterpolationOrder[ifun]
(*=> {3}*)

Теперь мы попытаемся построить InterpolatingFunction:

Interpolation[data, InterpolationOrder -> interpolationOrder];

и получите ошибку Message:

Interpolation :: inord: значение параметра InterpolationOrder -> {3} должно быть неотрицательным целым числом машинного размера или списком целых чисел с длина равна числу измерений 1. >>

Но если мы укажем InterpolationOrder руками, все в порядке:

Interpolation[data, InterpolationOrder -> {3}]
(*=> InterpolatingFunction[{{0.,0.516019}},<>]*)

Может кто-нибудь объяснить, почему InterpolationOrder -> interpolationOrder не работает, пока InterpolationOrder -> {3} работает, хотя interpolationOrder необходимо заменить на {3} ДО вызова Interpolation в соответствии с стандартной последовательностью оценки ?

P.S. Проблема возникает в Mathematica 7.0.1 и 8.0.1, но не в Mathematica 5.2.

UPDATE

Я нашел один обходной путь для этой ошибки:

Interpolation[data, 
 ToExpression@ToString[InterpolationOrder -> interpolationOrder]]

работает как положено.

Кажется, что выражения, сгенерированные в результате вычисления Rule[InterpolationOrder,interpolationOrder] и Rule[InterpolationOrder,{3}], имеют разную внутреннюю структуру, несмотря на то, что они идентичны:

ByteCount // Attributes
ByteCount[InterpolationOrder -> interpolationOrder]
ByteCount[InterpolationOrder -> {3}]
Order[InterpolationOrder -> interpolationOrder, 
 InterpolationOrder -> {3}]

(*=> 
{Protected}
192
112    
0
*)

Ответы [ 2 ]

5 голосов
/ 10 октября 2011

Кажется, я нашел причину такого поведения.Это потому, что функция InterpolatingFunctionInterpolationOrder возвращает PackedArray:

Developer`PackedArrayQ@InterpolatingFunctionInterpolationOrder[ifun]
(*=> True*)

Мы можем преобразовать {3} в PackedArray сами:

Interpolation[data, 
  InterpolationOrder -> Developer`ToPackedArray@{3}];

(*=> gives the error Message*)

Так что причина в том, что Interpolateне поддерживает PackedArray как значение для опции InterpolationOrder.Обходной путь - распаковать его вручную:

Interpolation[data, 
 InterpolationOrder -> Developer`FromPackedArray@interpolationOrder]
(*=> InterpolatingFunction[{{0.,0.516019}},<>]*)
2 голосов
/ 10 октября 2011

Очень странное поведение. Что-то вроде

a = {3};
Interpolation[data, InterpolationOrder -> a]

работает нормально, и оба ??interpolationOrder и OwnValues[interpolationOrder], кажется, указывают, что interpolationOrder просто равно {3}. Еще более странно, что это похоже на работу

interpolationOrder = 2 InterpolatingFunctionInterpolationOrder[ifun]/2
Interpolation[data, InterpolationOrder -> interpolationOrder]
...