Nested for loops for Maple 15

旧巷老猫 提交于 2019-12-12 03:32:17

问题


I need to run the inner most for loop for some particular coordinate points that are complex number valued. However, I do not know the particular coordinate points. I am suppose to guess and check to get an answer. However that is tediuos. Hence I wanted to come up with nested for loops to do the work for me of checking for different values. When I try to run the code below I get a unterminating loop. Is there an error in my code?

for i from -100.0 to 100.0 do  
for j from -100.0 to 100.0 do  
for m from -100.0 to 100.0 do  
for n from -100.0 to 100.0 do   
X__0:=[i+j*I, m+n*I]   
for K from 1 to 20 while evalf(abs(X[K-1][1]-X[K-2][1]),25)<>0 and evalf(abs(X[K-1][2]-X[K-2][2]),25)<>0  
do  
X[K]:=evalf(G(X[K-1][1], X[K-1][2]), 25)  
end do;

Also if it is possible, Can I add a condition to the loop to not print solutions of X[k] which matches [16.19615242270663188058234, -1.928203230275509174109785] or [5.803847577293368119417661, 11.92820323027550917410978]?


回答1:


Clearly this relates to your earlier question. So I'll try to address both here.

You may be get the idea that a "thorough" search grid does better at finding most (or sometimes all) roots, but that a random process can often be faster at finding a smaller subset. However as more and more roots are found by the random method then the chances grow are that each newly generated random starting point will converge to a root already found.

You mentioned Maple 15 in one of your questions, so I ran the code below in 64bit Maple 15.01 for Windows.

I wrapped your basic steps inside a proc, to make things easier to use and (hopefully) understand.

I did not change your iteration scheme (which may be homework), but notice that it requires an initial point. Note that X__0 displays similarly to X[0] as pretty-printed 2D Math output, but they are not the same. This was a problem for your code on the Question, and also for the transcribed code on one of the examples in your other Question. I suggest you use 1D Maple Notation for your input mode if that is not entirely clear to you.

There's no need to use linalg[jacobian] which is deprecated. I adjusted to use VectorCalculus:-Jacobian.

restart;

f := (x-7)^4+(y-2)^2-100:
g := (x-11)^2+(y-5)^2-75:

G := unapply(convert(Vector([x,y])
                 -1/VectorCalculus:-Jacobian([f, g],[x, y]).Vector([f,g]),
                 list),x,y):

p := proc(X0::[complex(numeric),complex(numeric)], G)
   local X, K;
   X[0]:=X0;
   for K to 30 while evalf[Digits+5](abs(X[K-1][1]-X[K-2][1])) <> 0
                     and evalf[Digits+5](abs(X[K-1][2]-X[K-2][2])) <> 0 do
     X[K] := evalf[Digits+5](G(X[K-1][1], X[K-1][2]));
   end do;
   if not type(X[K-1],[complex(numeric),complex(numeric)]) then
     error "nonnumeric results"; end if;
   if K<29 then map(simplify@fnormal, evalf(X[K-1]));
   else error "did not converge"; end if;
end proc:

p( [17, -2], G );

                     [9.879819419, -3.587502283]

p( [5, 11], G );

                     [5.127257522, 11.36481703]

p( [-1.0-11.*I, -2.0*I], G );

     [7.144643342 - 2.930435630 I, -3.398413328 + 1.345239163 I]

Digits := 20:
p( [-1.0-11.*I, -2.0*I], G );

        [7.1446433421702820770 - 2.9304356302329792484 I, 

           -3.3984133281207314618 + 1.3452391631560967251 I]

Equate([x,y],%);

        [x = 7.1446433421702820770 - 2.9304356302329792484 I, 

           y = -3.3984133281207314618 + 1.3452391631560967251 I]

eval( [f,g], % );

               [    -18       -18         -18       ]
               [1 10    + 2 10    I, -1 10    + 0. I]

Digits := 10:

NN:=2: # This attempts (NN+1)^4 iterates
incx,incy:=5.0,5.0:
Sols:={}:
count:=0:
st := time():
for a from -NN to NN do
  for b from -NN to NN do
    for c from -NN to NN do
      for d from -NN to NN do
         count:=count+1;
         try
           cand := p( [a*incx+b*incy*I, c*incx+d*incy*I], G );
           if not member(cand,{Sols}) then
             Sols := Sols union {cand}; end if;
         catch:
         end try;
      end do;
    end do;
  end do;
end do;
(time() - st)*'seconds', count*'attempts';

                    34.695 seconds, 625 attempts

nops( Sols );

                                  8

sort( Sols );

   {[3.867005122, 0.08874923598], [5.127257522, 11.36481703], 

     [5.721021477, 11.86530303], [9.879819419, -3.587502283], 

     [7.144643342 - 2.930435630 I, -3.398413328 + 1.345239163 I], 

     [7.144643342 + 2.930435630 I, -3.398413328 - 1.345239163 I], 

     [8.557804888 - 1.867139097 I, 13.53272982 - 0.5344031829 I], 

     [8.557804888 + 1.867139097 I, 13.53272982 + 0.5344031829 I]}


seq( eval( max(abs(f),abs(g)), Equate([x,y],xypoint) ), xypoint=Sols );

        -8      -7      -8      -8                -8                -8  
    3 10  , 1 10  , 9 10  , 4 10  , 3.162277660 10  , 3.162277660 10  , 

                    -7                -7
      1.019803903 10  , 1.019803903 10  

randomize():
fgen := proc(a::numeric,b::numeric,i::nonnegint:=1)
      seq(RandomTools:-Generate(float('range'=a..b,'digits'=5)),
          ii=1..i);
end proc:

fgen(-100.0, 100.0); # Usage example, a random point

                               -26.41

randSols := {}:
A,B := 15, 15:
numattempts:=100:
st := time():
for s from 1 to numattempts do
  try
    cand := p( [fgen(-A,A)+fgen(-B,B)*I, fgen(-A,A)+fgen(-B,B)*I], G );
    if not member(cand,{randSols}) then
             randSols := randSols union {cand}; end if;
  catch:
  end try;
end do;
(time() - st)*'seconds', numattempts*'attempts';

                     5.756 seconds, 100 attempts

nops(randSols);

                                  5

sort( randSols );

   {[3.867005122, 0.08874923598], 

     [7.144643342 - 2.930435630 I, -3.398413328 + 1.345239163 I], 

     [7.144643342 + 2.930435630 I, -3.398413328 - 1.345239163 I], 

     [8.557804888 - 1.867139097 I, 13.53272982 - 0.5344031829 I], 

     [8.557804888 + 1.867139097 I, 13.53272982 + 0.5344031829 I]}

seq( eval( max(abs(f),abs(g)), Equate([x,y],xypoint) ), xypoint=randSols );

        -8                -8                -8                -7                -7
    3 10  , 3.162277660 10  , 3.162277660 10  , 1.019803903 10  , 1.019803903 10  



回答2:


For each 'do' statement (i.e. loop) you need a corresponding 'end do', you only have one. Also you need to terminate statements (e.g. X__0:=[i+jI,m+nI]) with a colon or semicolon. E.g.,

for i from -100.0 to 100.0 do
  for j from -100.0 to 100.0 do
    for m from -100.0 to 100.0 do
      for n from -100.0 to 100.0 do
        X__0:=[i+j*I, m+n*I];
        for K from 1 to 20 while evalf(abs(X[K-1][1]-X[K-2][1]),25)<>0 and evalf(abs(X[K-1][2]-X[K-2][2]),25) <>0 do
          X[K]:=evalf(G(X[K-1][1], X[K-1][2]), 25);
        end do;
      end do;
    end do;
  end do;
end do;

end do;

Your code doesn't provide an initial definition of X[0] or define G, so it's hard otherwise to know what to suggest to improve things.



来源:https://stackoverflow.com/questions/35144017/nested-for-loops-for-maple-15

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!