19487 Reputation

29 Badges

14 years, 314 days

Social Networks and Content at

MaplePrimes Activity

These are answers submitted by acer

See the Help page for Topic object,function_mechanism which discusses some special situations of invoking methods.

Your process example in particular (a collision with another module in the namespace) can also be handled via the function syntax.

This might also assist you with a releated case which you have not yet covered in your Questions, involving mapping the same name (of method functions) across multiple objects. (See examples in the page.) In that case you might specifically want to not refer to the name as the export of any particular one of the objects.


module car_class()
      option object;
      local name::string:="";

      export process::static := proc(o::car_class)
             print("process method");             
      end proc:   

      export set_name::static := proc(o::car_class,_name::string)
             print("inside set name");
             o:-name := _name:
      end proc:     
end module:

my_car:=Object(car_class):  #make object


"inside set name"


"process method"


"inside set name"



You could adjust the datatype to also include a specified default fill value.

Or you could specify a dummy instance of your object as a default fill value -- even if the fill value never gets used explicitly.

As an example of the former idea:

module solution_class()
      option object;
      local sol::anything;
end module:


A := Array(datatype={solution_class,identical(NULL)}, fill=NULL):

A(1) := sol;

Vector(1, {(1) = module solution_class () local sol::anything; option object; end module})



The former idea looks a little uglier when set up, and interferes a little as it relaxes the strictures that usually come for free from a proscriptive datatype. But the latter idea could be unsatisfactory if you really didn't want any instance to exist strictly outside of when instances were stored. (Such a circumstance could be contrived, albeit artificial.)

Also, the awkwardness is not specific to object types.

Error, unable to store '0' when datatype=prime

A:=Array(datatype=prime, fill=2):  # distasteful
A(3):=7;  # ugh
             A := [2, 2, 7]

A:=Array(datatype=prime, storage=sparse):
A(3):=7;  # sigh
Error, unable to store '0' when datatype=prime

A:=Array(datatype={prime,identical(0)}, storage=sparse):
             A := [0, 0, 7]

@nm You wrote,

   "It would be much more natural to do something like
     my_car[set_name]("toyota") or my_car:-set_name("toyota")

    And then my_car:-get_name() since in these, the object itself
    is upfront, instead of being passed as an argument."

You can do this:


module car_class()
      option object;
      local name::static;  #private
      export set_name::static:=proc(nname::string)
          name := nname;
      end proc;
      export get_name::static:=proc()
          return name;
      end proc;      
end module:

my_car:=Object(car_class); #make an object of class car

module car_class () option object; end module






Of the 8 root formulas (in v[c]) there are two that are real-valued for all real b[2].

You could plot them using the implicitplot command. Or you could plot the explicit formulations of just those two. Or you could plot the real and imaginarty parts of the explicit forumulations. You could investigate the discriminant, if you so wish.

What makes you think that you are missing out on some details? I see no evidence that you're missing out of some regions of b[2] for which there are additional nontrivial purely real solutions. Did I miss it?

note. I don't advise trying to think of matching up the explicit formulas (or their real and imaginary components) with particular connect curves, unless you want to wade into deeper water. (This relates to the blue vertical noice connecting curves in two of the plots.)

note. I have not tried to do anything along the lines of RootFinding:-Parametric, even with an approximation for Pi.




# I need to solve this polynomial and look at how the solutions behave over different values of b[2]



discrim(P, v); factor(%);



[RealRange(-infinity, Open(9+(1/18)*Pi)), RealRange(Open(9+(1/18)*Pi), Open(RootOf(240*_Z^4+(-2744*Pi-240)*_Z^3+28224*Pi*_Z^2-62370*Pi*_Z+21609*Pi^2+36450*Pi, index = 1))), RealRange(Open(RootOf(240*_Z^4+(-2744*Pi-240)*_Z^3+28224*Pi*_Z^2-62370*Pi*_Z+21609*Pi^2+36450*Pi, index = 1)), Open(RootOf(240*_Z^4+(-2744*Pi-240)*_Z^3+28224*Pi*_Z^2-62370*Pi*_Z+21609*Pi^2+36450*Pi, index = 2))), RealRange(Open(RootOf(240*_Z^4+(-2744*Pi-240)*_Z^3+28224*Pi*_Z^2-62370*Pi*_Z+21609*Pi^2+36450*Pi, index = 2)), infinity)]

[RealRange(-infinity, Open(9.174532925)), RealRange(Open(9.174532925), Open(13.54833498)), RealRange(Open(13.54833498), Open(21.09299752)), RealRange(Open(21.09299752), infinity)]

plots:-implicitplot(P, b[2]=-15..22, v=-10..10, gridrefine=3);

HHH := simplify([solve(P,v,explicit)]):


  seq(plot([Re,Im](HHH[i]), b[2]=-15..22), i=1..2)

  seq(plot([Re,Im](HHH[i]), b[2]=-15..22), i=1..8)

HH := [solve(P,v)]:

HH1 := [allvalues(HH[1])]:
HH2 := [allvalues(HH[2])]:

  plot(HH1[1], b[2]=-15..22),
  plot(HH2[1], b[2]=-15..22)

seq( print(evalf[20](eval(simplify(HH1[i]), b[2]=10))), i=1..4 );





  seq(plot([Re,Im](HH1[i]), b[2]=-15..22), i=1..4),
  seq(plot([Re,Im](HH2[i]), b[2]=-15..22), i=1..4)




with(plots); with(plottools)

interface(imaginaryunit = I)

L := `~`[[Re, Im]](sort([fsolve(x^8-1-I, x, complex)], key = argument))

display(pointplot(L, symbol = solidcircle, symbolsize = 20, color = red), polygon(L, style = line, thickness = 2, color = blue), gridlines)



There are other ways to accomplish this kind of thing.

I'm not sure which you would consider as best, in part because I know little details about your actual examples or requirements. (Are they all numeric, are float results ok, is it supposed to be highly efficient or just easy, etc.)


A,b := <<0,1>|<0,0>>, <0,0>;

A, b := Matrix(2, 2, {(1, 1) = 0, (1, 2) = 0, (2, 1) = 1, (2, 2) = 0}), Vector(2, {(1) = 0, (2) = 0})

S := LinearSolve(A, b);

Vector(2, {(1) = 0, (2) = _t10[2]})


Vector(2, {(1) = 0, (2) = 1})


Vector(2, {(1) = 0, (2) = 0})

LinearSolve(evalf(A), b, method=QR);

Vector(2, {(1) = 0., (2) = 0.})

LeastSquares(A, b, optimize);

Vector(2, {(1) = 0, (2) = 0})

LeastSquares(A, b, method=SVD);

Vector(2, {(1) = 0., (2) = 0.})



If your results have additional symbolic names in them (ie. that are present in the input, and are not just the introduced free parameters) then it is easy to adjust the evalindets 2nd argument (the type) to match only the introduced names. (With the base of the introduced parameter names under one's control there is no need to check also with a set intersection.)


A,b := <<0,u>|<0,v>>, <0,v>;

A, b := Matrix(2, 2, {(1, 1) = 0, (1, 2) = 0, (2, 1) = u, (2, 2) = v}), Vector(2, {(1) = 0, (2) = v})

S := LinearSolve(A, b, free=_t);

Vector(2, {(1) = -v*(_t[2]-1)/u, (2) = _t[2]})


Vector(2, {(1) = v/u, (2) = 0})


You can access data structures directly using OpenMaple. You could go via a C extension to python.

Using the cmaple interface is not the really the right interface for the kind of interprocess memeory interaction you're describing.

I am not sure how you got in that bind, but here are a few adjustments (still using Equation Labels, etc), but with eval and unapply.

I used Maple 2018.2, to match your major version.



Automatically loading the Units[Simple] subpackage






Fin := 2*Unit('gal')/Unit('min')



Cin := Unit('lb')/(2*Unit('gal'))



Qin := Fin*Cin



Fout := 2*Unit('gal')/Unit('min')



Cout := Q/(100*Unit('gal'))



Qout := Fout*Cout







theEq := diff(Q(t), t) = Qin-2*Q(t)*(1/100)

diff(Q(t), t) = (1/60)*Units:-Unit(lb/s)-(1/50)*Q(t)



Q(t) = (5/6)*Units:-Unit(lb/s)+exp(-(1/50)*t)*_C1


simplify(eval(Q(t) = (5/6)*Units[Unit](lb/s)+exp(-(1/50)*t)*_C1, _C1 = Unit(lb/min)))

Q(t) = (1/60)*(50+exp(-(1/50)*t))*Units:-Unit(lb/s)


q := unapply(rhs(Q(t) = (1/60)*(50+exp(-(1/50)*t))*Units[Unit](lb/s)), t)

proc (t) options operator, arrow; (1/60)*(50+exp(-(1/50)*t))*Units:-Unit(lb/s) end proc














Do either of the attempts in this attachment work in your Maple 13?

It's a little difficult for us, since the odeplot that seems problematic in your Maple 13 works in later versions (eg. Maple 16, Maple 2020).

I see that you've ignored my comment in your earlier duplicate of this topic, where you might consider another mechanism for the piecewise function than the unevaluated call to the unknown function(s).

Your procedure Basenwechsel itself uses the name Basenwechsel in two different ways.

Firstly, it assigns to the name Basenwechsel. as if to use it as a local variable. But secondly, it calls Basenwechsel in a function call (perhaps an attempt at a recursive call to itself).

Perhaps you can instead make Basenwechsel act recursively by using the procname syntax instead . See the attachment below.

Also, you have calls to with inside your procedures. That won't work properly. You could utilize the uses syntax within the procedures, or even more move them to the top level.

I suggest that you explicitly declare all the intended locals of your procedures, so that you know what they are doing. Don't rely on impliciat local declarations. And don't try and use the same name in two different ways.

Check whether this works as you hoped:

Did you mean that you wanted to shade the curve itself, or the area between y=0 and the curve, or something else?

If you just want to shade the curve with a single color then pass the color option, eg, color="Blue", etc.

  plot(x*ln(x), x=0..1, color="Blue");

If you want to shade the region between y=0 and y=x*ln(x) then pass the filled option.

If you want to shade the curve itself in a varying manner then you can pass an appropriate colorscheme option.

For example,

plot(x*ln(x), x=0..1, filled);

plot(x*ln(x), x=0..1,
     colorscheme=["ygradient", ["Blue", "Red"]]);

plot(x*ln(x), x=0..1,
     colorscheme=["xgradient", ["Blue", "Red"]]);



There are other variations of coloring, etc.

overload seems to be the cause, and I think that it's a bug.

LinearAlgebra:-MatrixInverse is defined with overload, and has the problem. But LinearAlgebra:-LUDecomposition is not, and doesn't.

An example:


M:=module() option package;
  export f,g;
  f := overload([
         proc(x::positive) option overload; x^2; end proc,
         proc(x::negative) option overload; x; end proc ]);
  g := proc(x::positive) x^2; end proc;
end module:


testf := proc()
           uses M;
         end proc:


testg := proc()
           uses M;
         end proc:


okf := proc()
         end proc:




There are several options that control the look and feel. But you might want to have the lower end-point of the x-range start a little above exact zero (to get some arrows near there). For example,


alpha := .75; omega[1] := .15; omega[2] := .20; N := .8; beta[1] := .65; beta[2] := .70; Mu[1] := .75; Mu[2] := .74; h[1] := 0.5e-2; h[2] := 0.4e-2; d := 0.5e-1; E := .35

sys := [(D(x))(t) = alpha*x(t)*(1-x(t)/N)-beta[1]*sqrt(x(t))*y1(t)/(1+h[1]*beta[1]*sqrt(x(t)))-beta[2]*sqrt(x(t))*y2(t)/(1+h[2]*beta[2]*sqrt(x(t)))-d*E*x(t), (D(y1))(t) = -omega[1]*y1(t)+Mu[1]*beta[1]*sqrt(x(t))*y1(t)*(1-y1(t)/(beta[1]*sqrt(x(t))))/(1+h[1]*beta[1]*sqrt(x(t))), (D(y2))(t) = -omega[2]*y2(t)+Mu[2]*beta[2]*sqrt(x(t))*y2(t)*(1-y2(t)/(beta[2]*sqrt(x(t))))/(1+h[2]*beta[2]*sqrt(x(t)))]; RHS := eval(map(rhs, sys), [x(t) = x, y1(t) = y1, y2(t) = y2])

[.75*x*(1-1.250000000*x)-.65*x^(1/2)*y1/(1+0.325e-2*x^(1/2))-.70*x^(1/2)*y2/(1+0.280e-2*x^(1/2))-0.175e-1*x, -.15*y1+.4875*x^(1/2)*y1*(1-1.538461538*y1/x^(1/2))/(1+0.325e-2*x^(1/2)), -.20*y2+.5180*x^(1/2)*y2*(1-1.428571429*y2/x^(1/2))/(1+0.280e-2*x^(1/2))]

plots:-fieldplot3d(RHS, x = 0.1e-6 .. 1, y1 = 0 .. 1, y2 = 0 .. 1, grid = [7, 7, 7], axes = boxed, fieldstrength = average)



You wrote that you want them to "extend infinitely". What do you mean by that, precisely?

Do you mean that you want the y-axis's end-points to appear be +-infinity, and if so then how would you be able to recognize the scaling?

Or would it suffice if the visible y-range matched amongst all three curves?


f := x -> (ln(4*x-4)/4)-(ln(4*x+4)/4)+(arctan(x)/2):

  plot([f(x), f(x)-2, f(x)+2], x=-10 .. -1-1e-8),
  plot([f(x), f(x)-2, f(x)+2], x=1+1e-8 .. 10),

plot([f(x), f(x)-2, f(x)+2], x=1..10, y=-infinity..infinity);



The plot command will evaluate your call to your RMP procedure up front, before tau gets any numeric value. That is Maple's usual evaluation model.

But your procedure RMP is not set up to accept tau as just a name. The problem is that when your procedure RMP gets called promaturely -- with tau being just the non-numeric unassigned name -- the conditional comparisons t1 < tau and tau <= t2 cannot be done.

You can also see the difficulty if you simply execute the very same call to RMP outside of the plotting command.

Your situation is called "premature evaluation". It is a common issue for beginners in Maple.

Your Question's attachment was last saved in Maple 13. In modern Maple versions the magenta error message provides a URL to this description.

There are several ways to deal with it. Here are a few of them. (I have adjusted the chosen values for t1, A1, and t2 only so that it shows a more interesting actual plot.)


RMP := proc (sl, t1, A1, t2, tau) local y; if t1 < tau and tau <= t2 then y := A1 end if; return y end proc:

RMP(2, 3, 3.7, 5, tau)

Error, (in RMP) cannot determine if this expression is true or false: 3 < tau and tau <= 5

('RMP')(2, 3, 3.7, 5, tau);

RMP(2, 3, 3.7, 5, tau)

plot(('RMP')(2, 3, 3.7, 5, tau), tau = 0 .. 6);

plot(proc (tau) options operator, arrow; RMP(2, 3, 3.7, 5, tau) end proc, 0 .. 6);

RMP2 := proc (sl, t1, A1, t2, tau) local y; if not type(tau, numeric) then return ('procname')(args) end if; if t1 < tau and tau <= t2 then y := A1 end if; return y end proc:

RMP2(2, 3, 3.7, 5, tau)

RMP2(2, 3, 3.7, 5, tau)

plot(RMP2(2, 3, 3.7, 5, tau), tau = 0 .. 6);



First 6 7 8 9 10 11 12 Last Page 8 of 222