Carl Love

Carl Love

26344 Reputation

25 Badges

11 years, 134 days
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity

These are answers submitted by Carl Love

I know that this Answer is not exactly what you're asking for, but you might find it useful anyway; and it's what I use personally. Any plot in Maple is simply a data structure that can be assigned to a variable. (In formal computer science, they would be called "first-class data structures".) The assigning can be done either before or after the plot is produced.

MyPlot:= plot(x^2, x= -2..2);

plot3d(x*y, x= -1..1, y= -1..1);

... plot output omitted ...

MyPlot2:= %:

This can be done with any command that produces a plot or plots as its formal output (i.e., return value); they needn't be from the specific plot or plot3d command. Like any first-class data structure, the assignment can be done can be done regardless of whether the plot appears on screen.

I've had a similar (although not identical) thing happen several times (although not with Maple 2023). In my case, some math symbols changed also: for example, + became C and - became K. 

In my case, the problem could be corrected by saving and closing the worksheet, then closing the entire Maple session, then restarting Maple and the worksheet.

The problem was only with the display of the worksheets, not their underlying content (which remained unchanged). Once it affected one of my open worksheets, it affected all of my open worksheets. And, I do tend to keep worksheets open for many days, sometimes weeks.

Let me know if opening and closing corrects the problem for you.

Here's a workaround that isn't perfect, but I think is a lot better than making s an export of A:


module A() option object;
    local s::string:= "";
end module:

module B() option object(A);
    local my_inner_proc::static:= proc(self::B)
        self:-s:= cat(self:-s, "somethig");
    end proc
   export foo::static:= proc(_self, $)
   end proc:
end module:

o:= Object(B);
                 o := Object<<B,1582203658720>>


There is a long-standing (well over 20 years), fairly well-known, formal mechanism for doing this. This can be done for any (unevaluated) function:

`print/pochhammer`:= (a,n)-> ``(a)[n];
pochhammer(1/2, n);

Unlike the proposed methods using subs or eval, the method above only affects the prettyprinted display of the function; it doesn't change the function itself or your ability to perform further computations with it.

I think that what's happening is that due to a design oversight, the overload wrapping obscures the special status of a parameter named _self in an object method. A workaround is to use a normal procedure as a wrapper of the overload. The normal procedure explicitly passes _self to the overload, and implicitly (via _rest) passes the user's other arguments.

module person() option object;
    Name::string:= "*", Age::numeric, #non-static object data

    set_info_inner::static:= overload([
        proc(self::person, name::string, $) option overload;
            self:-Name:= name;
        end proc,

        proc(self::person, name::string, age::integer, $) option overload;
            self:-Name:= name;  self:-Age:= age;
        end proc,

        proc() error "Wrong number or type of arguments", args[2..] end proc
    #wrapper that passes _self to overload:
    set_info::static:= _self-> set_info_inner(_self, _rest),

    Name?::static:= proc(_self, $) Name end proc,
    Age?::static:= proc(_self, $) Age end proc
end module
o:= Object(person);
o:-set_info("me", 20):

Name?(o), Age?(o);
              o := Object<<person,1582091427520>>

                            "me", 20

o:-set_info("me", "you", 20);
Error, (in person:-set_info_inner) Wrong number or type of arguments, me, you, 20

  By the way, I haven't seen you on MaplePrimes for a long time. I'm glad that you're back.

Try adding this option to whatever plot command you used to generate that plot:

axis[1]= [tickmarks= [["0 - 2", "3 - 5", "6 - 8", "9 - 11"], rotation= Pi/2]]

If that doesn't work, please post the actual plot command you used; I'm sure that some minor adjustment will work. The font for the tick labels can also be changed.

Replace sin(x) with sin(x[i]), and replace sin*t[j] with sin(t[j]).

Here are two more ways: If you know that you want the index of the maximum element, use


To get the index of any element, use

member(96, R, 'p'):  p;

where p is any variable.

Let be any type. Then

  • Type [T] matches lists with exactly 1 element, which must be type T;
  • Type list(T) matches lists with any number of elements (including 0), all of which are type T.

If you want to forbid the case of empty lists, you could make the declaration

m::And({Matrix, list(Matrix)}, Not([])) 


m::And({thistype, list}(Matrix), Not([])).

thistype is the identity function for types (not to be confused with the identical functional type).

Assuming that the 5 terms that you call Lr represent the beginning of an infinite power series in r, then that's a simple geometric series that converges iff abs(r) < 2/Pi, and its exact value is 

2*r/(1 + (2/Pi/r)^2),

or, equivalently,

2*r*(Pi*r)^2/((Pi*r)^2 + 4).

Since this exact value is easily obtained and is a degree-[3,2] rational function, it doesn't make sense to me to use a pade approximation.

Even if you truly only want to consider those 5 terms, they can be considered as the difference of two infinite geometric series to obtain

2*r*(1 + 1/R^5)/(1 + R), where R = (2/Pi/r)^2,

which is mathematically identical to your original 5 terms, not an approximation (with removable singularities for r in {-1, 0, 1}*2*I/Pi, but no inequality restriction on abs(r)).

I often need to filter a set/list of solution sets/lists to separate those that contain trivial equations. It can be done like this:

s:= [{f0(t, r) = 0, n(t) = n(t)}, {f0(t, r) = 0, n(t) = 0}, {f0(t, r) = 0, n(t) = 0}];
selectremove(t-> ormap(evalb, t), s);

     [{f0(t, r) = 0, n(t) = n(t)}],  [{f0(t, r) = 0, n(t) = 0}, {f0(t, r) = 0, n(t) = 0}]

This code would be identical regardless of whether the solutions are sets or lists. 

[This Answer was based on the original Question alone, before the OP posted any code. The Replies were written after the code was posted.]

I suspect that this is the correction for your problem: Let's suppose that you have a procedure that creates a table assigned to a variable T that is a local of P and you want that table to be the return value of P. Then due to the last name evaluation property of T, you should make the return value eval(T) rather than simply T. You should do this inside P. No second argument for the eval is necessary, but after you get this working with the simple eval(T), you might be able to make a slight efficiency improvement using an integer second argument for the eval depending on the what type of things are stored in T.

I suspect that this is the cause of your problem: Suppose that returns T without using eval. You make  your call P(...), and the displayed output makes it seem as if T has been returned. But that is still the T local to P. That's called an escaped local. (Although "escaped" might make them sound dangerous, they can be useful.) It is a distinct variable from the global T, which can use outside of P, such as in a worksheet. The two Ts have no connection whatsoever; they merely have names that are coincidentally spelled the same. I suspect that you've been trying to use something akin to T[k] from your worksheet level.

You can assign the returned table to any variable: If you use eval as I described in the first paragraph, and you make your call to P as T:= P(...), then you can index T at the worksheet level. But you can use any variable for this purpose; it needn't be T.

I am certain that these things have nothing to do with your problem: It makes absolutely no difference where the procedure P is defined (.mpl file, library archive, or directly in your worksheet). It makes no difference where you call P from (worksheet or from another procedure).


When I read @dharr 's proposed GAMMA workaround this morning, before @acer looked into it, I knew that it couldn't possibly work in the desired way (i.e., under evalhf) because GAMMA(401.) is still well above the maximum value of a hardware float. But replacing the three factorials with a single call to binomial does work under evalhf:

F:= (n,k,p)-> 100*binomial(n,k)*p^k*(1-p)^(n-k):
evalhf(F(400, 5.1, 1/100));


CodeTools:-Usage(plot(F(400, q, 1/100), q= 0..20, numpoints= 1000));
memory used=2.88MiB, alloc change=0 bytes, cpu time=31.00ms, real time=40.00ms, gc time=0ns

int(diff(y(x), x), x= 1..2, continuous)

If you use option tryhard, then it uses a completely different algorithm and that limitation doesn't apply.

4 5 6 7 8 9 10 Last Page 6 of 381