【问题标题】:Defining recursive relation in Maple by "for loop"通过“for循环”在Maple中定义递归关系
【发布时间】:2018-10-25 12:56:42
【问题描述】:

我正在尝试通过 Maple 中的“for 循环”建立递归关系。假设我们有两个序列M[i](x)N[i](x),其中N[0](x)=x^2M[i](x)=N[i-1](x)+1N[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 来定义我的函数。有没有办法修改这段代码?

【问题讨论】:

    标签: recursion maple


    【解决方案1】:

    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
    

    创建所有这些运算符(程序分开)似乎效率低下。为什么不只为NM 创建一个,它承认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](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 命令,我们可以求解通用公式的递推关系(在ix 方面都是封闭的)。然后从这个封闭的公式中,我们可以利用unapply 命令为NM 构造一个2-参数过程。

    【讨论】:

      猜你喜欢
      • 2019-07-07
      • 1970-01-01
      • 1970-01-01
      • 2016-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多