通过 "for loop" 在 Maple 中定义递归关系

Defining recursive relation in Maple by "for loop"

我正在尝试通过 "for loop" 在 Maple 中建立递归关系。假设我们有两个序列 M[i](x)N[i](x),即 N[0](x)=x^2M[i](x)=N[i-1](x)+1 以及 N[i](x)=M[i](x)+2。所以我尝试了这段代码:

N[0] := proc (x) options operator, arrow; x^2 end proc;
for i to 3 do M[i] := proc (x) options operator, arrow; N[i-1](x)+1 end proc; N[i] := proc (x) options operator, arrow; M[i](x)+2 end proc end do;

但它没有给出正确答案(例如 N[1](x) 必须是 x^2+3)。顺便说一句,出于某些原因,我必须通过映射 x 来定义我的函数。有没有办法修改这段代码?

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 的特定计算中评估其中任何一个。您还可以根据这些结果创建过程,并分配它们。例如,

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 创建一个,它允许 ix 的两个参数?

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] 的索引值与其指定过程中的 i 之间没有 link,无论何时随后调用 N[2](x).

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

可以通过构造一个递归过程序列来修复您的原件。以下"works"。但它在 运行 时效率极低,因为每次调用任何 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 命令,我们可以解决一般公式的递归关系(根据 ix 关闭)。然后从那个封闭的公式我们可以利用 unapply 命令为 N 构造一个双参数过程,为 M.

构造一个双参数过程