带有符号输入的RecurrenceTable出错

时间:2011-04-26 16:31:32

标签: wolfram-mathematica

我终于再次处理我的n-point Pade code,我正在遇到以前没有发生过的错误。问题的核心围绕着这段代码:

zi = {0.1, 0.2, 0.3}
ai = {0.904837, 1.05171, -0.499584}

Quiet[ RecurrenceTable[ {A[0] == 0, A[1] == ai[[1]],
          A[n+1]==A[n] + (z - zi[[n]]) ai[[n+1]] A[n-1]},
          A, {n, Length@ai -1 } ],
   {Part::pspec}]

(当Quiet纯粹具有象征意义时,Part抱怨zi[[n]]ai[[n+1]]时,必须使用n。)代码本身属于我希望得到符号结果的函数,因此zSymbol。但是,当我运行上面的代码时,我得到错误:

RecurrenceTable::nlnum1: 
  The function value {0.904837,0.904837+0. z} is not a list of numbers with 
  dimensions {2} when the arguments are {0,0.,0.904837}.

请注意{0.904837,0.904837+0. z}这一术语,其中0. z不会减少为零。我需要做些什么来强制它评估为零,因为它似乎是问题的根源?还有其他选择吗?

此外,作为对困扰stackoverflow的Wolfram Research人员的帮助系统的一般抱怨:在第7版RecurrenceTable::nlnum1中无法搜索!也不是,错误末尾的>>链接会将您带到错误定义,而是将您带到RecurrenceTable的定义,而不是交叉引用常见错误。

修改:在审核完我的代码后,我提出的解决方案是完全符号化地评估RecurrenceTable,包括初始条件。工作代码如下:

Clear[NPointPade, NPointPadeFcn]
NPointPade[pts : {{_, _} ..}] := NPointPade @@ Transpose[pts]

NPointPade[zi_List, fi_List] /; Length[zi] == Length[fi] :=
 Module[{ap, fcn, rec},
  ap = {fi[[1]]};
  fcn = Module[{gp = #, zp, res},
     zp =  zi[[-Length@gp ;;]];
     res = (gp[[1]] - #)/((#2 - zp[[1]]) #) &[Rest@gp, Rest@zp];
     AppendTo[ap, res[[1]]];
     res
  ] &;

  NestWhile[fcn, fi, (Length[#] > 1 &)];

 (*
  The recurrence relation is used twice, with different initial conditions, so
  pre-evaluate it to pass along to NPointPadeFcn
 *)
 rec[aif_, zif_, a_, b_][z_] := 
  Evaluate[RecurrenceTable[
     {A[n + 1] == A[n] + (z - zif[n])*aif[n + 1]*A[n - 1], 
      A[0] == a, A[1] == b}, 
     A, {n, {Length@ap - 1}}][[1]]];

  NPointPadeFcn[{zi, ap, rec }]
 ]

NPointPadeFcn[{zi_List, ai_List, rec_}][z_] /; Length[zi] == Length[ai] :=
 Module[{aif, zif},
  zif[n_Integer] /; 1 <= n <= Length[zi] := zi[[n]];
  aif[n_Integer] /; 1 <= n <= Length[zi] := ai[[n]];
  rec[aif, zif, 0, ai[[1]]][z]/rec[aif, zif, 1, 1][z]
 ]

Format[NPointPadeFcn[x_List]] := NPointPadeFcn[Shallow[x, 1]];

与内置插值函数一样,NPointPade执行一些预处理,并返回一个可以计算的函数NPointPadeFcnNPointPade完成的预处理除了预先估计递归关系之外,还会从ai生成zi s列表以及这些点处的函数值。当NPointPadeFcn提供z值时,它会通过向其提供适当的值来评估两个线性递归关系。

编辑:对于好奇的,这里的NPointPade正在运作

NPointPade in action

在第一个图中,很难区分这两个函数,但第二个图显示了绝对(蓝色)和相对(红色)错误。如上所述,创建一个20分的Pade需要很长时间,所以我需要加快速度。但是,就目前而言,它确实有效。

2 个答案:

答案 0 :(得分:6)

您可以隐藏功能背后的部件提取:

In[122]:= zi = {0.1, 0.2, 0.3};
ai = {0.904837, 1.05171, -0.499584};

In[124]:= zif[n_Integer] /; 1 <= n <= Length[zi] := zi[[n]]
aif[n_Integer] /; 1 <= n <= Length[ai] := ai[[n]]

In[127]:= RecurrenceTable[{A[0] == 0, A[1] == aif[1], 
  A[n + 1] == 
   A[n] + (z - zif[n]) aif[n + 1] A[n - 1]}, A, {n, (Length@ai) - 1}]

Out[127]= {0.904837, 0.904837, 
 0.904837 - 0.271451 aif[4] + 0.904837 z aif[4]}

<小时/> 的修改

以下是该问题的解决方法:

In[4]:= zi = {0.1, 0.2, 0.3};
ai = {0.904837, 1.05171, -0.499584};

In[6]:= zif[n_Integer] /; 1 <= n <= Length[zi] := zi[[n]]
aif[n_Integer] /; 1 <= n <= Length[ai] := ai[[n]]

In[8]:= Block[{aif, zif}, 
 RecurrenceTable[{A[0] == 0, A[1] == aif[1], 
   A[n + 1] == A[n] + (z - zif[n]) aif[n + 1] A[n - 1]}, 
  A, {n, 0, (Length@ai) - 1}]]

Out[8]= {0, 0.904837, 0.904837}

Block用于在执行aif时暂时删除zifRecurrenceTable的定义。然后,当Block退出时,将恢复值,并RecurrenceTable的输出进行评估。

答案 1 :(得分:3)

在我看来,仅Block Part zi = {0.1, 0.2, 0.3}; ai = {0.904837, 1.05171, -0.499584}; Block[{Part}, RecurrenceTable[{A[0] == 0, A[1] == ai[[1]], A[n + 1] == A[n] + (z - zi[[n]]) ai[[n + 1]] A[n - 1]}, A, {n, Length@ai - 1}] ] 可以模仿Sasha的方法。

With[{Part = $z}, 
  RecurrenceTable[{A[0] == 0, A[1] == ai[[1]], 
    A[n + 1] == A[n] + (z - zi[[n]]) ai[[n + 1]] A[n - 1]}, 
   A, {n, Length@ai - 1}]
] /. $z -> Part
   {0, 0.904837, 0.904837} 

解决Sasha的批评,以下是另外两种方法:

With[{Part = Hold[Part]}, 
  RecurrenceTable[{A[0] == 0, A[1] == ai[[1]], 
    A[n + 1] == A[n] + (z - zi[[n]]) ai[[n + 1]] A[n - 1]}, 
   A, {n, Length@ai - 1}]
] // ReleaseHold

-

{{1}}