尝试重新创建由InterpolationFunction
制作的NDSolve
时,InterpolationOrder
选项Interpolation
遇到了一个非常奇怪的问题。请考虑以下InterpolationFunction
(示例函数from the Documentation):
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}
才能根据{{3}调用Interpolation
}?
P.S。问题出现在 Mathematica 7.0.1和8.0.1中,但不出现在 Mathematica 5.2中。
我找到了一个针对此错误的解决方法:
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
*)
答案 0 :(得分:5)
似乎我找到了这种行为的原因。这是因为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}},<>]*)
答案 1 :(得分:2)
确实很奇怪的行为。像
这样的东西a = {3};
Interpolation[data, InterpolationOrder -> a]
工作正常,??interpolationOrder
和OwnValues[interpolationOrder]
似乎都表示interpolationOrder
等于{3}
。甚至更奇怪的是,这似乎确实有效
interpolationOrder = 2 InterpolatingFunctionInterpolationOrder[ifun]/2
Interpolation[data, InterpolationOrder -> interpolationOrder]