Mathematica插值函数[]在超出范围时保持不变

6
我希望通过替换插值函数Interpolation[]的外推部分为常数值来“修改”它(在1维情况下)。换句话说,如果插值域是[1,20],且f[1]==7和f[20]==12,则我想要:
f[x] = 7 for x<=1 
f[x] = 12 for x>=20 
f[x] = Interpolation[...] 

然而,这个失败了:
(* interpolation w cutoff *) 
interpcut[r_] := Module[{s, minpair, maxpair}, 

(* sort array by x coord *) 
s = Sort[r, #1[[1]] < #2[[1]] &]; 

(* find min x value and corresponding y value *) 
minpair = s[[1]]; 

(* ditto for max x value *) 
maxpair = s[[-1]]; 

(* return the pure function representing cutoff interpolation *) 
Piecewise[{ 
{minpair[[2]] &, #1 < minpair[[1]] &}, 
{maxpair[[2]] &, #1 > maxpair[[1]] &}, 
{Interpolation[r], True} 
}]] 

test = Table[{x,Prime[x]},{x,1,10}] 

InputForm[interpcut[test]] 

Piecewise[{{minpair$59[[2]] & , #1 < minpair$59[[1]] & },  
  {maxpair$59[[2]] & , #1 > maxpair$59[[1]] & }},  
 InterpolatingFunction[{{1, 10}}, {3, 1, 0, {10}, {4}, 0, 0, 0, 0},  
  {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}, {{2}, {3}, {5}, {7}, {11}, {13}, {17},  
   {19}, {23}, {29}}, {Automatic}]] 

我相信我错过了一些基础的东西。是什么呢?
3个回答

4

函数定义

interpcut[r_, x_] := 
   Module[{s},(*sort array by x coord*)
       s = SortBy[r, First];
       Piecewise[
        {{First[s][[2]], x < First[s][[1]]},
         {Last [s][[2]], x > Last [s][[1]]},
         {Interpolation[r][x], True}}]]; 

测试

test = Table[{x, Prime[x]}, {x, 1, 10}];
f[x_] := interpcut[test, x]
Plot[f[x], {x, -10, 30}]  

替代文本

编辑

回答您对纯函数的评论。

我这样做只是为了清晰明了,而不是为了欺骗。对于使用纯函数,只需“按照食谱操作”:

interpcut[r_] := Module[{s},
  s = SortBy[r, First];
  Function[Piecewise[
    {{First[s][[2]], # < First[s][[1]]},
     {Last [s][[2]], # > Last [s][[1]]},
     {Interpolation[r][#], True}}]]
  ] 

test = Table[{x, Prime[x]}, {x, 1, 10}];
f = interpcut[test] // InputForm
Plot[interpcut[test][x], {x, -10, 30}]

好的,但那是作弊。我希望它像Interpolation[]一样返回一个纯函数。interpcut应该接受一个数组作为输入,并返回一个纯函数作为输出。否则,我必须重写很多东西。 - user354134
好的,事实证明将函数命名为interpcut1并执行以下操作:interpcut[r_] := Function[x, interpcut1[r,x]]就可以解决问题。 - user354134
@barrycarter 是的,一旦你得到了纯函数,你可以按照自己的意愿重新定义它... - Dr. belisarius
如果您使用柯里化,您可以同时获得“不作弊”和“清晰度”的最佳效果:interpcut[r_][x_] := ...第一个定义... - WReach
@WReach 这就是 Mma 的优点和缺点 - 总有另一种(正确)的方法... - Dr. belisarius
就此而言,构造Module[{s = SortBy[r, First];}, ...]是可行的。至于With[],在这里也可以使用... - user414706

2

让我对这个旧线程进行更新。自从V9版本以来,您可以使用本地(但仍处于实验阶段)的“ExtrapolationHandler”参数。

test = Table[{x, Prime[x]}, {x, 1, 10}];

g = Interpolation[test, "ExtrapolationHandler" -> 
      {If[# <= test[[1, 1]], test[[1, 2]], test[[-1, 2]]] &, 
        "WarningMessage" -> False}];

Plot[g[x], {x, -10, 30}]

enter image description here


1
这是一个可能的 belisarius 答案的替代方案:
interpcut[r_] := Module[{s}, s = SortBy[r, First];
    Composition[Interpolation[r], Clip[#, Map[First, Through[{First, Last}[s]]]] &]]

2
代码高尔夫很棒!“interpcut[r_]:=Composition [Interpolation[r],Clip [#,Map [First,Through [{First,Last} [SortBy[r,First]]]]]&]”(看吧,没有模块!) - user354134
@barry:在 Mathematica 中玩代码高尔夫确实是一款不错的游戏... :) - user414706
2
@barrycarter 我们可以做得更好:interpcut[r_]:=Interpolation[r][#~Clip~SortBy[dat,First][[{1,-1},1]]]& - Mr.Wizard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接