如何使 DifferenceRoot 和 RecurrenceTable 对于非数值差分方程有用?
今天早上在回答物理论坛问题时,我遇到了 < code>DifferenceRoot 和 RecurrenceTable
与通过简单地采用指数生成函数的导数来计算表达式进行比较。少量的挖掘表明,DifferenceRoot
和 RecurrenceTable
并没有简化表达式。
例如,看看 RecurrenceTable
的以下输出,以及它如何通过仅扩展
结果来简化:
In[1]:= RecurrenceTable[f[n] == a f[n - 1] + (a - 1) f[n - 2] &&
f[0] == 0 && f[1] == 1,
f, {n, 6}]
% // Expand
Out[1]= {0, 1, a, -1+a+a^2, -a+a^2+a (-1+a+a^2), 1-a-a^2+a (-1+a+a^2)+a (-a+a^2+a (-1+a+a^2))}
Out[2]= {0, 1, a, -1+a+a^2, -2 a+2 a^2+a^3, 1-2 a-2 a^2+3 a^3+a^4}
这很快就会失控,因为第 20 次迭代的叶计数(使用 DifferenceRoot
计算)显示:
dr[k_] := DifferenceRoot[Function[{f, n},
{f[n] == a f[n - 1] + (a - 1) f[n - 2], f[0] == 0, f[1] == 1}]][k]
In[2]:= dr20 = dr[20]; // Timing
dr20Exp = Expand[dr20]; // Timing
Out[2]= {0.26, Null}
Out[3]= {2.39, Null}
In[4]:= {LeafCount[dr20], LeafCount[dr20Exp]}
Out[4]= {1188383, 92}
可以与memoized 进行比较执行
In[1]:= mem[n_] := a mem[n-1] + (a-1) mem[n-2] // Expand
mem[0] = 0; mem[1] = 1;
In[3]:= mem20 = mem[20];//Timing
LeafCount[mem20]
Out[3]= {0.48, Null}
Out[4]= 92
所以我的问题是: 是否有任何选项/技巧可以让 DifferenceRoot
和 RecurrenceTable
在它们运行时应用(简化)函数,从而使它们对非数字工作有用?
编辑: Sjoerd 在下面指出,我愚蠢地选择了一个具有 RSolve
able 封闭式解决方案的示例。在这个问题中,我主要关心 DifferenceRoot
和 RecurrenceTable
的行为。如果有帮助的话,想象一下 f[n-2]
项乘以 n
,这样就没有简单的封闭形式解决方案。
In answering a physics forum question this morning, I ran into really bad performance of DifferenceRoot
and RecurrenceTable
compared to calculating the expressions by naively taking derivatives of an exponential generating functional. A very small amount of digging showed that DifferenceRoot
and RecurrenceTable
do not simplify expressions as they go.
For example, look at the following output of RecurrenceTable
and how it simplifies by just Expand
ing the result:
In[1]:= RecurrenceTable[f[n] == a f[n - 1] + (a - 1) f[n - 2] &&
f[0] == 0 && f[1] == 1,
f, {n, 6}]
% // Expand
Out[1]= {0, 1, a, -1+a+a^2, -a+a^2+a (-1+a+a^2), 1-a-a^2+a (-1+a+a^2)+a (-a+a^2+a (-1+a+a^2))}
Out[2]= {0, 1, a, -1+a+a^2, -2 a+2 a^2+a^3, 1-2 a-2 a^2+3 a^3+a^4}
This quickly gets out of hand, as the leaf count of the 20th iteration (calculated using DifferenceRoot
) shows:
dr[k_] := DifferenceRoot[Function[{f, n},
{f[n] == a f[n - 1] + (a - 1) f[n - 2], f[0] == 0, f[1] == 1}]][k]
In[2]:= dr20 = dr[20]; // Timing
dr20Exp = Expand[dr20]; // Timing
Out[2]= {0.26, Null}
Out[3]= {2.39, Null}
In[4]:= {LeafCount[dr20], LeafCount[dr20Exp]}
Out[4]= {1188383, 92}
Which can be compared to the memoized implementation
In[1]:= mem[n_] := a mem[n-1] + (a-1) mem[n-2] // Expand
mem[0] = 0; mem[1] = 1;
In[3]:= mem20 = mem[20];//Timing
LeafCount[mem20]
Out[3]= {0.48, Null}
Out[4]= 92
So my question is:
Are there any options/tricks to get DifferenceRoot
and RecurrenceTable
to apply a (simplifying) function as they go and thus make them useful for non-numeric work?
Edit: A Sjoerd pointed out below, I foolishly chose an example with a RSolve
able closed form solution. In this question I'm primarily concerned with the behaviour of DifferenceRoot
and RecurrenceTable
. If it helps, imagine the the f[n-2]
term is multiplied by n
, so that there is no simple closed form solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我无法真正帮助您解决问题,因为到目前为止我还没有使用过这些功能,并且文档也没有提供任何线索。但为什么不在这里使用
RSolve
呢?它为表格的每个元素提供了一个封闭形式的解决方案:I can't really help with your question as I haven't used those functions until now, and the docs don't give a clue. But why don't you just use
RSolve
here? It gives a closed form solution for each of the table's elements: