6

今天早上在回答一个物理论坛问题时,我遇到了非常糟糕的性能,DifferenceRoot并且RecurrenceTable与通过天真地取指数生成函数的导数来计算表达式相比。非常少量的挖掘表明了这一点,DifferenceRoot并且RecurrenceTable 不要简化表达式

例如,看看下面的输出,以及它是如何通过ing 结果来RecurrenceTable简化的:Expand

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}

这可以与记忆化的实现相比较

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

所以我的问题是: 是否有任何选项/技巧可以获取DifferenceRootRecurrenceTable应用(简化)函数,从而使它们对非数字工作有用?

编辑: Sjoerd 在下面指出,我愚蠢地选择了一个具有RSolve封闭形式解决方案的示例。在这个问题中,我主要关注DifferenceRootand的行为RecurrenceTable。如果有帮助,请想象该f[n-2]术语乘以n,因此没有简单的封闭形式解决方案。

4

1 回答 1

1

我对您的问题无能为力,因为直到现在我还没有使用过这些功能,而且文档也没有给出任何线索。但是你为什么不在RSolve这里使用呢?它为每个表格元素提供了一个封闭形式的解决方案:

sol = f /. RSolve[f[n] == a f[n - 1] + (a - 1) f[n - 2] && 
                  f[0] == 0 && f[1] == 1, f, n
           ][[1, 1]]

在此处输入图像描述

sol@Range[6] // Simplify

在此处输入图像描述

于 2011-08-14T21:35:23.663 回答