rsolve 命令可以轻松处理此示例,只是它需要自变量 i 的函数。
而您所拥有的是涉及 x 函数的方程(不影响递归),i 仅作为索引出现。
您可以将方程重写为i 的函数,调用rsolve,然后重新代入原始函数。
只需手动输入即可构建下面的替换集S。但为了好玩,我以编程方式构建它。
restart;
R1 := N[0](x) = x^2;
2
R1 := N[0](x) = x
R2 := M[i](x) = N[i-1](x)+1;
R2 := M[i](x) = N[i - 1](x) + 1
R3 := N[i](x) = M[i](x)+2;
R3 := N[i](x) = M[i](x) + 2
S := map( u->u=op([0,0],u)(op([0,1],u)),
indets({R1,R2,R3},
specfunc(anything,{N,M})) );
S := {M[i](x) = M(i), N[0](x) = N(0), N[i](x) = N(i),
N[i - 1](x) = N(i - 1)}
newEqs := eval( {R1,R2,R3}, S );
2
newEqs := { M(i) = N(i - 1) + 1, N(0) = x , N(i) = M(i) + 2 }
newV := eval( {N[i](x),M[i](x)}, S );
newV := {M(i), N(i)}
tempans := rsolve( newEqs, newV );
2 2
tempans := { M(i) = x + 3 i - 2, N(i) = x + 3 i }
ans := eval( tempans, map(rhs=lhs,S) );
2 2
ans := { M[i](x) = x + 3 i - 2, N[i](x) = x + 3 i }
构造了M[i](x) 和N[i](x) 的一般形式的方程后,您可以在i 的特定cals 处评估其中的任何一个。您还可以根据这些结果创建过程并分配它们。例如,
for k from 1 to 3 do
N[k] := unapply(subs(i=k,eval(N[i](x),ans)), [x]);
end do:
N[3](11);
130
创建所有这些运算符(程序分开)似乎效率低下。为什么不只为N 和M 创建一个,它承认i 和x 的两个参数?
Nfunc := unapply(eval(N[i](x),ans), [i,x]);
2
Nfunc := (i, x) -> x + 3 i
Nfunc(3,x);
2
x + 9
Nfunc(3, 11);
130
[edited] 我应该告诉你为什么你最初的尝试失败了。
当您尝试最初的尝试时,出现在两个过程主体中的i 不会简化为循环索引i 的当前值。当您随后尝试运行任何构造过程时,它只会获取全局i 仍然具有的任何值。每当您随后调用N[2](x) 时,名称N[2] say 的索引值与其分配过程中的i 之间没有链接。
restart;
N[0] := x -> x^2:
for i to 2 do
M[i] := x -> N[i-1](x)+1;
N[i] := x -> M[i](x)+2;
end do;
M[1] := x -> N[i - 1](x) + 1
N[1] := x -> M[i](x) + 2
M[2] := x -> N[i - 1](x) + 1
N[2] := x -> M[i](x) + 2
N[2](11); # why this result, you might asK
M[3](11) + 2
i; # still the value coming out of that do-loop
3
unassign('i');
N[2](11); # no relation between the 2 and the `i`
M[i](11) + 2
您可以通过构建递归过程序列来修复您的原始文件。以下“作品”。但它在运行时的效率非常低,因为每次调用任何N[..] 或M[..] 过程都会递归调用链中的其他过程。每次调用时都会发生整个递归调用集。也就是说,这里的递归发生在每个过程的运行时。
restart;
N[0] := x -> x^2:
for i to 3 do
M[i] := subs(ii=i, x -> N[ii-1](x)+1);
N[i] := subs(ii=i,x -> M[ii](x)+2);
end do;
M[1] := x -> N[0](x) + 1
N[1] := x -> M[1](x) + 2
M[2] := x -> N[1](x) + 1
N[2] := x -> M[2](x) + 2
M[3] := x -> N[2](x) + 1
N[3] := x -> M[3](x) + 2
N[3](11);
130
运行这种方案的整体性能会很差。
最好使用unapply 命令,这样N[i] 和M[i](用于显式i 值)都是包含其显式公式的过程。当以下列方式使用unapply 时,我们将函数调用传递给它,该函数调用递归地评估相应的公式。这里的递归只发生在每个过程的构建时。
restart;
N[0] := x -> x^2:
for i to 3 do
M[i] := unapply( N[i-1](x)+1, x);
N[i] := unapply( M[i](x)+2, x);
end do;
2
M[1] := x -> x + 1
2
N[1] := x -> x + 3
2
M[2] := x -> x + 4
2
N[2] := x -> x + 6
2
M[3] := x -> x + 7
2
N[3] := x -> x + 9
N[3](11);
130
但正如我在上面的回答中所指出的,根本不需要构建所有这些程序。通过使用rsolve 命令,我们可以求解通用公式的递推关系(在i 和x 方面都是封闭的)。然后从这个封闭的公式中,我们可以利用unapply 命令为N 和M 构造一个2-参数过程。