nm

11353 Reputation

20 Badges

13 years, 12 days

MaplePrimes Activity


These are replies submitted by nm

@ecterrab 

Thanks that worked,

Would you know how to turn that on and off from outside without me having to edit the file each time and comment the line option trace=0: For example if I do this

restart;

foo:=proc(n,m,k)   
   local r;
   option trace=0:

   r:=n:
   NULL;
 end proc:

foo(1,2,3)

{--> enter foo, args = 1, 2, 3
<-- exit foo (now at top level) = }

Which is what I wanted. But I have 1000's of proc's. I wanted to add option trace=0: to each proc in each module.

But I also want to be able to turn that on and off from outside before running the program.

Using global printlevel := 10: (instead of adding explicit option trace inside the proc) does not work for me, since it turns on tracing for everything including Maple's internal system calls and it also shows tracing of all assignments. 

I want to only trace enter/exit for my own code to help see where it hangs. Not including Maple's also.

But also want to be able to turn it on/off as needed without having to edit the code.

I thought of using global flag

restart;
DO_TRACE:=true;
foo:=proc(n,m,k)   
   local r;  
   if DO_TRACE then
      option trace=0:
   fi;

   r:=n:
   NULL;
 end proc:

but this gives Error, reserved word `option` or `options` unexpected

Would you know of a system level option to do this? i.e. I want to do trace only the enter/exit trace, just for my own code, but also be able to turn that on/off without having to edit the code. It will great if there is such an way to do this.

Maple 2022

@sursumCorda 

Thanks,. I'll accept this workaround as answer for now. May be this will be fixed in Maple 2024.

I am getting too many bugs in Maple 2023 when trying to solve for y(x) from an equation. Changing all of the code to solve for y instead (after replacing y(x) by y in the equation) solved all these problems. 

I can post collection of such problems if needed, but for now, this workaround works for me.

@acer 

Ok, I changed my code in the function to do this now at the start 

foo:=proc(ode,x::symbol,y::symbol)

local X,XX,XXX,XXX;

#keep fingers crossed that x,y is not X or XX or XXX or XXXX

DynamicSystems:-SystemOptions('statevariable'=X):
DynamicSystems:-SystemOptions('discretefreqvar'=XX):            
DynamicSystems:-SystemOptions('outputvariable'=XXX):
DynamicSystems:-SystemOptions('continuoustimevar'=XXXX):  
....

#y,x passed in can be any symbols. I have no control over 
#what they are

DynamicSystems:-SystemOptions('continuoustimevar'=y):  
etc...
end proc;


Before doing anything later on.

This is inside a function which takes in any possible symbols to use from the caller. It is not possible to predict which letters will be used by the caller. It seems DynamicSystems then has builtin default letters out of the box for these variables.

I do not think the caller will be using X or XX or XXXX for their variables in the ode.

There should really be a better way to do this all of this. I do not think it is a good idea to have the DynamicSystems with its own letters as default like this.

But for now, this works. No more accidental clash between letters. May be in the future I will change this to initilize it with random ly generated symbols to make it more robust.

 

 

@C_R 

Thanks for the suggestion. But how will this actually work?  I assume you mean to start one kernel server for each problem in the loop. With some CPUtime limit. When that is done, start the second problem. Right? So it is like this?

for N in 1 to 100 do
     #start server.exe to process problem number N with specific cputime limit
     #need somehow to wait here until the above is completed
od;

But since I never used this, the first question is, how would I pass arguments to the new server.exe being created? I need to pass it a number and name of .mpl file to run. The number will be the argument (problem number) that proc being invoked will process.

For obtaining the result back, is not that important, as I can have proc being runwrite to file or database its result.

So the main loop just needs to manage starting/terminating each server.exe, one for each problem. 

How will the LOOP know the server has completed? Is there a way to block until it completes? As I do not want to start 20,000 server.exe's. I want to start one to process one problem with some cputime limit, wait for it, and only when it is done start the next one.

Is this what you mean? Is there an example of how to do this in Maple? If this works, I will try it for sure. But now, I have no idea if this is what you mean or not.  Is there an example of how to do all of this in Maple?

reference https://www.maplesoft.com/support/help/maple/view.aspx?path=kernelopts

 

@Carl Love 

I see. But I use it to obtain estimate of size of expression as Maple does not have a leafCount function outside of this package.

How else would one then get this functionality in Maple?  Using length() on an expression does not really do the same thing as LeafCount

This is a basic function in computer algebra (measuring the size of an expression) that a CAS system as mature as Maple should provide.   Is there an alternative in Maple that I am overlooking?

@sursumCorda 

thanks for the examples. Help should have these.

Only thing I will change is to replace 

_EnvTry := hard;

with

_EnvTry := 'hard';

in case the the name hard was assigned some global value before the call is made. 

I think Maple should use strings for such options. Much safer.   So it should be

_EnvTry := "hard";

This applies to all other Maple functions (such as plot commands and others) which uses plain names as option values as these names could easily have been assigned to some global values before using them. But this is another subject.

 

plot( [W(x), W(-1,x)], x=-1..4, view=[-1..4, -3.5..1.5], colour=[red,blue], scaling=constrained, labels=[x,W(x)] );

produced a *better* plot near the branch point.

Do you know why there is larger gap near y=-1 ? Here is the code I used for Maple 2023 on windows and the corresponding Mathematica plot for the same function. You see Maple's has larger gap. Is there a way to reduce this in Maple's version? I am not too familiar with all of Maple's plotting options. May be it needs some tweeking of options to change this?

plot( [LambertW(x), LambertW(-1,x)], x=-1..4, view=[-1..4, -3.5..1.5], colour=[red,blue], scaling=constrained, labels=[x,LambertW(x)] );

Here is the Mathematica 13.2.1 version

Plot[{LambertW[x], LambertW[-1, x]}, {x, -1, 4}, ImageSize -> 400, 
 PlotStyle -> {Red, Blue}, PlotRange -> {Automatic, {-3.5, 1.5}}, 
 AspectRatio -> Automatic]

@Carl Love 

Thanks for the info, I read the help page you refer to. But after 1 hr trying, I given up. I can't get it to work.

i.e. I tried calling the parent's ModuleCopy from the child using the syntax parent:-ModuleCopy() but when later on I look at the fields, I see there are still not initialized. 

May be you can see what is the correct way to do this. Here is a small example I made. The parent is a bank_account and the child is saving_account.

I also found that the child ModuleCopy can not have ::static added to it, once kernelopts('assertlevel'=2): is added. Maple complain that type static does not exist.

So I removed ::static from the ModuleCopy on the child and kept ::static only on the parent ModuleCopy. This is new change from the example I gave originally, because I did not have kernelopts('assertlevel'=2): before.

I learn better by trying things and using examples. Maple help is not good at all for learning Maple as it lacks many examples. 

If one picture is worth 1,000 words, then one example is worth one million words. Maplesoft should improve its help system.
 

8632

restart;

8632

interface(version);

`Standard Worksheet Interface, Maple 2023.0, Windows 10, March 6 2023 Build ID 1689885`

interface(warnlevel=4);
kernelopts('assertlevel'=2):

3

module bank_account()
  option object;
  local account_id::integer:=0;
  local amount::float:=0.0;

  export ModuleCopy::static:=proc(_self, proto::bank_account, account_id::integer, amount::float,$)
         print("enter bank_account ModuleCopy");
         if nargs=2 then
            _self:-account_id := proto:-account_id;
            _self:-amount     := proto:-amount;
         else
             print("Not proto case. account_id=",account_id);
            _self:-account_id := account_id;
            _self:-amount     := amount;
         fi;
         NULL;
  end proc;

  export get_id::static:=proc(_self,$)
         print("enter bank_account::get_id, _self:-account_id=",_self:-account_id);
         RETURN(_self:-account_id);
  end proc;

  export get_amount::static:=proc(_self,$)
         RETURN(_self:-amount);
  end proc;

end module;

module bank_account () local account_id::integer, amount::float; option object; end module

module saving_account()
  option object(bank_account);
  local interest_rate::float:=0.0;

  #do not use export. do not use ::static either ! If using ::static then Maple
  #gives error when kernelopts('assertlevel'=2): may be a bug?

  ModuleCopy := proc(_self, proto::saving_account, account_id::integer, interest_rate::float, amount::float,$)
         print("enter saving_account ModuleCopy");
         if nargs=2 then
            _self:-account_id := proto:-account_id;
            _self:-amount     := proto:-amount;
            _self:-interest_rate := proto:-interest_rate;
         else
            #call parent constructor. Notice, must use _self as first argument ! else
            #will not work
            #but this is not working at all. It is not initializing the fields as expected.
            #bank_account:-ModuleCopy(account_id, amount);  does not work

            #call is made but fields are not initialized
            bank_account:-ModuleCopy(_self,account_id, amount);
  
            #finish child constructor
            _self:-interest_rate := interest_rate;
         fi;
         NULL;
  end proc;

  export get_interest_rate::static:=proc(_self,$)
         RETURN(_self:-interest_rate);
  end proc;
end module;

module saving_account () local account_id::integer, amount::float, interest_rate::float; option object(bank_account); end module

account_id := 903432; interest_rate:=5.4; initial_amount:=100.0;
my_bank_account:=Object(bank_account,account_id,initial_amount);
my_bank_account:-get_id();
my_bank_account:-get_amount();

903432

5.4

100.0

"enter bank_account ModuleCopy"

"Not proto case. account_id=", 903432

module bank_account () local account_id::integer, amount::float; option object; end module

"enter bank_account::get_id, _self:-account_id=", 903432

903432

100.0

my_saving_account:=Object(saving_account,account_id,interest_rate,initial_amount);
my_saving_account:-get_interest_rate();
my_saving_account:-get_id();  #this returns 0 which is wrong
my_saving_account:-get_amount(); #this returns 0 which is wrong

"enter saving_account ModuleCopy"

"enter bank_account ModuleCopy"

"Not proto case. account_id=", 903432

module saving_account () local account_id::integer, amount::float, interest_rate::float; option object(bank_account); end module

5.4

"enter bank_account::get_id, _self:-account_id=", 0

0

0.


 

Download calling_parent_constructor.mw

 

@Carl Love 

Thanks. So having "export" on ModuleCopy in the child was the problem. 

But I modified your solution as below.

I do not want to duplicate the work done in base constructor also in the child constructor. This was a very basic example. But imagine the base class doing lots of work in its constructor. Then the child constructor (since it overwrote the base class constuctor method) has now to duplicate all this work. right?

So I made a new method in base class called base_ode_class_constructor to do the actual initialization of the base class. This will be called from both the base class as well from the child class. 

So this way I can have ModuleCopy in both the base and the child, but not duplicate the code that does base class initialization.

I think now it is an OK setup. It would be better if Maple OOP allowed child class constructor to call base class constructor directly as in Java and C++ and all other OOP languages. But I think this workaround is OK for now.
 

restart;

30160

interface(version)

`Standard Worksheet Interface, Maple 2023.0, Windows 10, March 6 2023 Build ID 1689885`

module ode_class()
   option object;
   local ode::`=`;
   local x::symbol;
   local y::symbol;

   #constructor
   export ModuleCopy::static := proc( _self, proto::ode_class, ode, func, $ )           
       print("base class constructor");
       if nargs=2 then
          _self:-ode := proto:-ode;
          _self:-y   := proto:-y;
          _self:-x   := proto:-x;
       else
          _self:-base_ode_class_constructor(ode, func);
       fi   
   end proc;

   #this will be called by child class to initlize base
   local base_ode_class_constructor::static :=proc(_self,ode,func,$)
         print("base class constructor helper");
        _self:-ode := ode;
        _self:-y   := op(0,func);
        _self:-x   := op(1,func);
   end proc;

   export get_ode::static:=proc(_self,$)
     return _self:-ode;
   end proc;

   export get_x::static:=proc(_self,$)
     return _self:-x;
   end proc;

   export get_y::static:=proc(_self,$)
     return _self:-y;
   end proc;


end module;

module ode_class () local ode::`=`, x::symbol, y::symbol; option object; end module

module first_order_ode_class()
   option object(ode_class);
   local is_linear_ode::truefalse;

   #constructor
   ModuleCopy::static := proc( _self, proto::first_order_ode_class, ode, func, $ )
       if nargs=2 then
          _self:-ode := proto:-ode;
          _self:-y   := proto:-y;
          _self:-x   := proto:-x;
       else
          _self:-base_ode_class_constructor(ode, func);
       fi;

       #rest of child constructor here
       print("Finished base class constructor. Now doing child");
       _self:-is_linear_ode := false;
   end proc;

   export is_linear::static:=proc(_self,$)
          return _self:-is_linear_ode;
   end proc;
          
end module;

 

module first_order_ode_class () local ode::`=`, x::symbol, y::symbol, is_linear_ode::truefalse; option object(ode_class); end module

ode:=Object(first_order_ode_class,diff(y(x),x)=sin(x),y(x));
ode:-is_linear();
ode:-get_ode();

"base class constructor helper"

"Finished base class constructor. Now doing child"

module first_order_ode_class () local ode::`=`, x::symbol, y::symbol, is_linear_ode::truefalse; option object(ode_class); end module

false

diff(y(x), x) = sin(x)

 

 

Download OOP_with_base_class_call.mw

can't give you a definite answer as it can depend on many things, but with my limited experience with Maple is that if Maple does not solve an equation in few minutes, (assuming you have fast enough CPU and sufficient memory) then waiting many hours is not going to make any difference. 

But why not try and find out yourself? leave it running overnight on one of the problems you have which takes long time and find out?

Also you should really use timelimit() on all your calls to Maple functions. No need to wait and manually stop Maple yourself. timelimit() can also hang easily and not stop as asked, but at least it is better than nothing.

@acer 

Using Array is also fast

p1 := proc(N) local i;
  [seq(i^2, i=1..N)];
end proc:

p2 := proc(N) local i,T;
  T := table():
  for i from 1 to N do
    T[i] := i^2;
  end do:
  convert(T,list);
end proc:

p3 := proc(N) local i,R;
  R := []:
  for i from 1 to N do
    R := [op(R), i^2];
  end do:
  R;
end proc:
 
p4 := proc(N) 
    local T:=Array(0..1);
    local i;
    for i from 1 to N do
        T ,= i^2;
    od;
    convert(T,list);
end proc:
	
n := 10^5: 	
	
CodeTools:-Usage( p1(n) ):
CodeTools:-Usage( p2(n) ):
CodeTools:-Usage( p3(n) ):
CodeTools:-Usage( p4(n) ):

Gives on my PC

 

There is normally 2 updates per major version. So 2022.1 and 2022.2

This will be same for 2023. There will be 2023.1 and 2023.2

This is how maplesoft been doing for the last few years. I do not remember a time when there was more than two updates within one major version.

To get 2023 you can go to MapleStore and either do an upgrade or buy new version depending on what you qualify for. Upgrade is less expensive.

 

@Rouben Rostamian  

That is correct, the code does chop and not round, it comes from tihis line 

L[2]:=L[2][1..k];

It is easy to add code to make it do rounding instead. Will leave that to the OP as an exercise if they want to use it, but I suspect they will use your version as it is shorter and does rounding already.

 

 

have a look at  GraphTheory:-ShortestPath

@Ronan 

 This is a Maple specific problem

This is what I also think, since it is only the Maple application that this happens to. And only in Maple 2023. I have not seen this in Maple 2022.2. 

First 24 25 26 27 28 29 30 Last Page 26 of 91