Wolfram mathematica 使用Fold计算依赖于多个先前值的线性递归结果

Wolfram mathematica 使用Fold计算依赖于多个先前值的线性递归结果,wolfram-mathematica,Wolfram Mathematica,我有一个线性递归问题,其中下一个元素不仅仅依赖于先验值,例如斐波那契序列。计算第n个元素的一种方法是通过函数调用来定义它,例如 Fibonacci[0] = 0; Fibonacci[1] = 1; Fibonacci[n_Integer?Positive] := Fibonacci[n] + Fibonacci[n - 1] 对于我正在处理的序列,这正是我所做的。(定义在模块中因此我不会污染全局`)但是,我将使用210-213分,因此我担心在我只需要最后一个术语而不需要任何之前的元素时会产生

我有一个线性递归问题,其中下一个元素不仅仅依赖于先验值,例如斐波那契序列。计算第n个元素的一种方法是通过函数调用来定义它,例如

Fibonacci[0] = 0; Fibonacci[1] = 1;
Fibonacci[n_Integer?Positive] := Fibonacci[n] + Fibonacci[n - 1]
对于我正在处理的序列,这正是我所做的。(定义在
模块中
因此我不会污染
全局`
)但是,我将使用210-213分,因此我担心在我只需要最后一个术语而不需要任何之前的元素时会产生额外的开销。我想使用
Fold
来实现这一点,但是
Fold
只传递前一个结果,这意味着它对于一般线性递归问题没有直接的用处

我想要一对函数来替换
Fold
FoldList
,它们将指定数量的优先顺序元素传递给函数,即

In[1] := MultiFoldList[f, {1,2}, {3,4,5}] (* for lack of a better name *)
Out[1]:= {1, 2, f[3,2,1], f[4,f[3,2,1],2], f[5,f[4,f[3,2,1],2],f[3,2,1]]}
我有一些东西可以做到这一点,但在保存之前我关闭了笔记本。所以,如果我自己重写它,我会发布它

编辑:至于我为什么不使用
RSolve
MatrixPower
来解决这个问题。我的具体问题是,我正在执行一个函数,以解析方式继续一个函数,我只知道在虚轴{zi}上的一组点上。创建近似的一部分是生成一组系数ai,这是另一个递归关系,然后将其输入到最终关系中

A[n+1]== A[n] + (z - z[[n]]) a[[n+1]] A[n-1]
至少在我看来,
RSolve
MatrixPower
都不能满足您的要求。

可以为您执行此任务吗

根据前面的两个值,查找递归中的第1000个项:

In[1]:= RecurrenceTable[{a[n] == a[n - 1] + a[n - 2], 
  a[1] == a[2] == 1}, a, 
   {n, {1000}}]

Out[1]= {4346655768693745643568852767504062580256466051737178040248172\
9089536555417949051890403879840079255169295922593080322634775209689623\
2398733224711616429964409065331879382989696499285160037044761377951668\
49228875}
编辑:如果您的重复周期是由函数
f[m,n]
定义的,该函数不希望对非数字m和n进行计算,那么您可以使用:

f
表示的定期表:

In[3]:= RecurrenceTable[{a[n] == f[a[n - 1], a[n - 2]], 
  a[1] == a[2] == 1}, a, {n, {1000}}]

Out[3]= {4346655768693745643568852767504062580256466051737178040248172\
9089536555417949051890403879840079255169295922593080322634775209689623\
2398733224711616429964409065331879382989696499285160037044761377951668\
49228875}

多重折页列表可能很有用,但它不是一种有效的方法,无法获得针对大输入的线性重现值。有两种选择是使用RSolve或矩阵幂乘以初始值向量

下面是应用于示例的这些方法,如果第n项等于n-1项加上两倍的n-2项

f[n_] =  f[n] /. RSolve[{f[n] == f[n - 1] + 2*f[n - 2], f[1] == 1, f[2] == 1},
  f[n], n][[1]]
Out[67]=1/3(-1)^n+2^n)

Out[79]={683683}

丹尼尔·利奇布劳
Wolfram Research(Wolfram Research)

几乎是一个令人费解的笑话,但你可以使用NestWhileList的副作用

fibo[n_] := 
  Module[{i = 1, s = 1}, 
   NestWhileList[ s &, 1, (s = Total[{##}]; ++i < n) &, 2]];  

通过将最后一个
2
更改为任意整数,可以将最后的k个结果传递给函数(在本例中为Total[])

LinearRecurrence
RecurrenceTable
非常有用

对于小内核,Daniel给出的
MatrixPower
方法是最快的

对于某些问题,这些可能不适用,您可能需要自己解决

我将使用Nest,因为我相信它适用于这个问题,但是类似的构造也可以用于Fold

一个具体的例子,斐波那契序列。这可能不是最干净的,但我相信你会看到我继续实用程序

fib[n_] :=
  First@Nest[{##2, # + #2} & @@ # &, {1, 1}, n - 1]

fib[15]

Fibonacci[15]
这里我使用
Apply
@
),这样我就可以用
#2
等来处理元素,而不是
[[1]]
等。我使用
SlotSequence
从旧列表中删除第一个元素,同时将其按
顺序放入新列表

如果要同时对整个列表进行操作,那么简单的
追加[Rest@#,…
可能会更好。这两种方法都很容易推广。例如,可以使用简单的线性递归实现

 lr[a_, b_, n_Integer] := First@Nest[Append[Rest@#, a.#] &, b, n - 1]

 lr[{1,1}, {1,1}, 15]

(内核与内置的
线性电流的顺序相反)

+1,我需要更熟悉“最近的”对标准函数的添加。它正是我所需要的。我必须将它包装在
Quiet
中,因为递归引用外部列表和
Part
只是不喜欢将未定义的变量传递给它…有趣的条件用法。我从来没有想过要这样使用它。仅在编辑时,我希望我可以添加另一个+1。(+1)只是一个小注释,即检查
Head
s比模式匹配快,因此
f[m_Integer,n_Integer]
将比
f[m,n_]/;IntegerQ[m]&IntegerQ[n]快
+1,建议两种合理的方法,如果我的具体情况允许的话,我会使用。相信我,我真的很想!内置函数在你想要的情况下不好吗?问题是我的函数是数值函数,也就是说,我只在某些点知道它,而内置函数近似于已知函数。因此,我不能给它一个列表,也不能给它一个它还给了我一个函数。另外,其他内置插值函数也不起作用,因为它们不做有理插值,我的函数很可能有极点。因此,有理插值是必要的。+1,这看起来很像我为
Fold
直接提出的方法。
附加[Rest@#
方法非常好。
In[153]:= First@Timing@fibo[10000]
Out[153]= 0.235  
fib[n_] :=
  First@Nest[{##2, # + #2} & @@ # &, {1, 1}, n - 1]

fib[15]

Fibonacci[15]
 lr[a_, b_, n_Integer] := First@Nest[Append[Rest@#, a.#] &, b, n - 1]

 lr[{1,1}, {1,1}, 15]