nm

11453 Reputation

20 Badges

13 years, 75 days

MaplePrimes Activity


These are questions asked by nm

Other than saving few bytes of memory, why would one use ::static for methods of Object?

I found that if I use ::static, then I have to add prefix _self:- each time an object data member is referenced anywhere, making the code very hard to read.

Imagine having to write  _self:-x + 3* _self:-x^2 + 2* _self:-y^3 and so on all the time, instead of just x+3*x^2+2*y^3. (where it is assumed here that x,y happened to be object private data members and not local variables for a proc inside the module).

But then I found if I remove  ::static now _self:- no longer needed and can still get the benefit of using the object and the code works as before, but the code is now much more readable. 

I know that by not using static, then a copy of each method is made for each new object.

I am OK with that. As I do not use that many objects any way (few at a time before GC cleans the ones I used).

But the benefit of much more readable code far outweights the little extra memory needed, and memory is cheap these days anyway. I got lots of RAM. An extra few MB's is not a big deal.

What Am I missing here? Why does all the Maple help and documenation say that one should use static for object methods then? But do not mention that by not using static:: then the code will become more readable since _self:- is not needed to be appeneded to each variable or method name.

Here is an example below to compare. 

First example uses ::static methods, and the second does not.

One can see the difference The code is more clear in the second.   Is there something else I am overlooking by not using ::static . I am still learning OOP in Maple, and could be overlooking something else. I definitly do not want to code using _self:-variable_name all the time if I have to use OOP in Maple as it makes the code hard to read. 

Notice that in both examples, and for the exported methods, I used _self as first argument. This is OK. This is meant to allow client of the object to call it using object:-method() syntax which is what I prefer instead of method(object,....). syntax.

I am talking about the execssive use of _self internal to the module/object code when having to use ::static. methods.

restart;

person_class_STATIC:=module()
   option object;
   local age:=5;   

   export set_age::static:=proc(_self,age,$)      
     _self:-age:=age:
   end proc:      

   export update_age::static:=proc(_self,age,$)      
      do_the_update(_self)
   end proc:      

   local do_the_update::static:=proc(_self,$)
      _self:-age:=_self:-age+1;
      _self:-age:=sqrt(_self:-age^2+3);
   end proc;

   export get_age::static:=proc(_self,$)      
     return _self:-age;
   end proc:      

end module:

o:=Object(person_class_STATIC);
o:-set_age(100);
o:-get_age();
o:-update_age();

o2:=Object(person_class_STATIC);
o2:-get_age();

_m1982588380672

100

100

2*2551^(1/2)

_m1982698669216

5

person_class_NO_STATIC:=module()
   option object;
   local age:=5;   

   export set_age:=proc(_self,_age,$)      
     age:=_age:
   end proc:      

   export update_age:=proc(_self,$)      
      do_the_update()
   end proc:      

   local do_the_update:=proc()
      age:=age+1;
      age:=sqrt(age^2+3);
   end proc;

   export get_age:=proc(_self,$)      
     return age;
   end proc:      

end module:

o:=Object(person_class_NO_STATIC);
o:-set_age(100);
o:-get_age();
o:-update_age();

o2:=Object(person_class_NO_STATIC);
o2:-get_age();

_m1982698652256

100

100

2*2551^(1/2)

_m1982698629312

5

 

Download OOP.mw

Without trying it or looking down more, should these two code fragments give same output or not

# CASE 1

restart;
A   :=   2;
B   :=   x+2*y;
t^2 * ( A * B );


#CASE 2
restart;
t^2*( 2 * (x+2*y)  );

One would expect both to give same output, right? CASE 1 just uses variables and CASE 2 just uses the values of these variables. I mean the semantics of CASE 1 and 2 are the same, given that Maple replaces each variable with its value when evaluating.

But Maple does not give same result.

One way to force same result when using variables is to use t^2*(eval(A*B));

My question is why CASE 1 gives different result from CASE 2?  I would have expected same output.

Maple 2021.2 on windows 10. Worksheet.

interface(version);

`Standard Worksheet Interface, Maple 2021.2, Windows 10, November 23 2021 Build ID 1576349`

restart;

A:=2;
B:=x+2*y;
t^2*(A*B);

2

x+2*y

2*t^2*(x+2*y)

restart;

t^2*(2*(x+2*y));

t^2*(2*x+4*y)

restart;

A:=2;
B:=x+2*y;
t^2*(eval(A*B));

2

x+2*y

t^2*(2*x+4*y)

 

Download why_different.mw

Why would simplify(t^2*x^2+t^2*y^2)  give  (x^2 + y^2)*t^2 but with seemingly same input except changing `+` to `-` fails now to simplify it?  simplify(t^2*x^2-t^2*y^2) gives t^2*x^2-t^2*y^2

Just trying to understand the logic behind this behavior.

In Mathematica both do simplify as can be seen below, which is what one would expect.

Should Maple hangs when one quits a debugger in the middle of debugging session, and there is a call to the same function with a DEBUG break point in it next?

For example

restart;
foo:=proc()
  local x;
  DEBUG();
  x:=x+1
end proc;

And now in the next same execution group, I had

> foo(); #quitting debugger here makes Maple hangs/freeze

  foo();

 

When evaluating the above, the debugger comes up as expected when first call to foo() is made.

When quitting the debugger either by hitting Quit or by hitting the close red X at top right corner, Maple now hangs. I was expecting the debugger to come up again for the second call to foo().  

It seems closing the debugger window like this for some reason is not handled correctly. Even if the user is not supposed to do this, Maple should not just freeze like this.

Nothing I do causes it to unfreeze. Clicking on the ! button does nothing. Only way is to either kill Maple from task manager or close all of Maple if possible and sometimes this does not even work, ending possibly losing work done on other open worksheets.

Maple should be more robust that this. Does this happen on other platforms?

This problem does not happen if the calls were each in a separate execution group in the worksheet. Like this

> foo();

> foo();

Using Maple 2021.2 on windows 10.

I am looking for a robust way to factor an expression (if applicable) to become    x^n*(rest)  as we do it by hand.

edit The input will only be of type `+` and I am looking for a way extract a common factor to convert the input to term^n*(rest) where term is the common factor to pull out.

For example, given  x^2*Y+x and the symbol is given as x  the result will be x*(x*Y+1) and if the input is Y^2*x^3-x^3 then the output is x^3*(Y^2-1) and if there is no common factor x to pull out from all the terms, the output will be the same as the input.

I tried many commands and options, but can't find one method that works all the time for all cases.

For example for   x^2*Y+x  the command factor(x^2*Y+x) gives (Y - 1)*(Y + 1)*x^3 which is not what I want. There is no option to factor to give the name to factor on. And I did not know how to use the last argument of function to do that.

But here simplify(x^2*Y+x) happened to work on this and gives (Y^2 - 1)*x^3 but simplify does not work on first example. simplify(x^2*Y+x) returns the same expression back. So simplify is not reliable to use.

I tried collect, with options factor and simplify. Again, they work on one examples but not others. 

collect(x^2*Y+x,x); does not do it. But collect(Y^2*x^3-x^3,x); works and returns (Y^2 - 1)*x^3 which is what I want.

The problem is that I do not know what the expression looks like. I just know the name and want to find if there is a common to any power that can be pulled out to rewite the expression as x^n*(rest) where is an integer or rational number depending.

This seems like a simple problem. But can't find a Maple command for.   I could ofcourse program it by brute force. Go over each term in the expression, check if each term has a free to any power in it multiplied by something else, then collect all these x^n term in a list. At end find the which is raised to lowest power, and then divide the whole expression by it. 

Here is another way I can also try:  Use factor and also collect and also simplify. One at a time. Each time I check if the result is of type `*` but not a division! (check that denom is 1). If so, Then check if result has two operands only. If so, check if op(1,result) is for form x^anything. If so, then one of these cases worked.  Need to try this now to see if it will work on all cases I have. 

Is there a better way to do this in Maple? It has to work on all expresions f(x) without knowing what the expression looks like.

update

I've updated the test cases and included all algorithms given to compare. It is hard in Maple to make a nice table to present results and keep math formatting below.

restart;
makegrid := proc(M::Matrix)#https://www.mapleprimes.com/questions/202902-How-To-Create-Table-Like-Output-For
  uses DocumentTools:-Layout;
  local i,j,m,n,wks;
  m,n := op(1,M);
  wks := Worksheet(Table(alignment=center,width=20,
                         seq(Column(),j=1..n),
                         seq(Row(seq(Cell(Textfield(sprintf("%a",M[i,j]))),
                                     j=1..n)),i=1..m)));
  DocumentTools:-InsertContent(wks);
end proc:

acer_V1_common_factor := proc(x::algebraic, ee::algebraic)
  local p, d := gcd(ee, x^frontend(degree,[ee,x]),'p');
  d * p;
end proc:

acer_V2_common_factor := proc(x, ee) local d, t;
  if ee::`+` then
    t := max(map(proc(u) local r:=frontend(degree,[u,x]);
                         `if`(r::numeric,r,0); end proc,[op(ee)]));
    d := gcd(numer(ee),x^t);
    d*map(u->u/d,ee);
  else ee; end if;
end proc:

dharr_common_factor:=proc(x,z)
  local xn:=x^ldegree(collect(z,x),x);
  if rem(z,xn,x)=0 then xn*quo(z,xn,x) else z end if;
end proc:

me_common_factor:=proc(term,expr)
local tmp;
local T1;

local update_T1:=proc()
T1:= hastype(op(1,tmp),identical(term)^anything) or hastype(op(1,tmp),identical(term));
if not T1 then
   T1:= hastype(op(2,tmp),identical(term)^anything) or hastype(op(2,tmp),identical(term));
fi;
end proc;

if type(expr,`*`) or not has(expr,term) then 
   return expr;
fi;

tmp := collect(expr,term);       
if type(tmp,`*`) and evalb(denom(tmp)=1) and evalb(nops(tmp)=2) then
   update_T1();
   if T1 then
       return tmp;
   fi;
fi;

tmp :=factor(expr);
if type(tmp,`*`) and evalb(denom(tmp)=1) and evalb(nops(tmp)=2) then
    update_T1();
    if T1 then
      return tmp;
    fi;
fi;

tmp := simplify(expr);
if type(tmp,`*`) and evalb(denom(tmp)=1) and evalb(nops(tmp)=2) then
    update_T1();
    if T1 then              
      return tmp;
    fi;
fi;

return expr;
end proc:
############################

test_data:=[[x,x^2*Y+x],
[x,Y^2*x^3-x^3],
[x,x],
[x,x+2*x^2],
[x,x^4*diff(y(x),x)+x^7],
[x,x^4*diff(y(x),x)+x^7-sin(x)],
[y(x),y(x)^4*diff(y(x),x$2)^2*diff(y(x),x)+y(x)^2*diff(y(x),x)+y(x)],
[y(x),y(x)^4*diff(y(x),x$2)^2+y(x)^2*diff(y(x),x)+y(x)^9],
[x,x^4*y^2+x^2*y^2],
[y(x),y(x)^4*diff(y(x),x)^2+y(x)^2*diff(y(x),x)^2],
[diff(y(x),x),y(x)^4*diff(y(x),x)^2+y(x)^2*diff(y(x),x)^2],
[diff(y(x),x),y(x)*diff(y(x),x$2)^2*diff(y(x),x)*sin(x)+diff(y(x),x)^3],
[y(x),diff(y(x),x)-(1+x^(1/2))/(1+y(x)^(1/2))],
[y(x),diff(y(x),x) -(x-1)*y(x)^5/x^2/(-y(x)+2*y(x)^3)],
[y(x),3*y(x)+diff(y(x),x) - 2*x/exp(3*x)],
[x,3*x^2*y^3+7*x/y],
[y,A-(1+x)/(1+y^(1/2))]
]:
RESULT:=Matrix(nops(test_data),6);
for N,item in test_data do
    term:=item[1];
    expr:=item[2];
    RESULT[N,1]:=term; RESULT[N,2]:=expr;
    try
        result:=acer_V1_common_factor(term,expr);
        if type(result,`*`) and denom(result)<>1 then
           RESULT[N,3]:=expr;#bypass, not correct output
        else
           RESULT[N,3]:=result;#accept
        fi;  
    catch:
        RESULT[N,3]:=expr;#reject
    end try;      

    try
        result:=acer_V2_common_factor(term,expr);
        if type(result,`*`) and denom(result)<>1 then
           RESULT[N,4]:=expr;#bypass, not correct output
        else
           RESULT[N,4]:=result;#accept
        fi;  
    catch:
        RESULT[N,4]:=expr;#reject
    end try;      

    try
        result:=dharr_common_factor(term,expr);
        if type(result,`*`) and denom(result)<>1 then
           RESULT[N,5]:=expr;#bypass, not correct output
        else
           RESULT[N,5]:=result;#accept
        fi;  
    catch:
        RESULT[N,5]:=expr;#reject
    end try;      


    try
        result:=me_common_factor(term,expr);
        if type(result,`*`) and denom(result)<>1 then
           RESULT[N,6]:=expr;#bypass, not correct output
        else
           RESULT[N,6]:=result;#accept
        fi;  
    catch:
        RESULT[N,6]:=expr;#reject
    end try;      

od:

RESULT

how_to_do_special_factor.mw

Mapleprime will not let let insert content for some reason. Here is the output as screen shot but it is hard to read. But it is in the above worksheet.

First 79 80 81 82 83 84 85 Last Page 81 of 201