Joe Riel

9660 Reputation

23 Badges

20 years, 9 days

MaplePrimes Activity


These are replies submitted by Joe Riel

@zhong chen Your model, from what I can see of it, looks okay.  The `msim/VAR#` is used internally to represent relations ( x < 1, etc).  The `msim/PIECEWISE` represents a piecewise expression (it is similar to the Maple ?piecewise function).

The ?gc command does not return allocated memory to the operating system.  Rather, it returns it to Maple's internal pool for reuse, thus reducing the need for additional memory allocation.  The ?restart command, in addition to unassigning variables, returns allocated memory to the operating system.

Concerning the poster's citation of some web site, it may be the case that the restart command in older versions of Maple does not return allocated memory to the O/S, but recent versions certainly do.

The restart command probably isn't going to help the problem he describes, where an initialization computation consumes a lot of memory. It could be done; the computed values could be saved to disk, a restart executed, then the values read back into the session.  That would reduce the remaining memory footprint on the O/S, however, it likely won't help the Maple computation, which could access the memory anyway, assuming the initialization was done in a way that unassigned the appropriate variables so they could be garbage collected.

The ?gc command does not return allocated memory to the operating system.  Rather, it returns it to Maple's internal pool for reuse, thus reducing the need for additional memory allocation.  The ?restart command, in addition to unassigning variables, returns allocated memory to the operating system.

Concerning the poster's citation of some web site, it may be the case that the restart command in older versions of Maple does not return allocated memory to the O/S, but recent versions certainly do.

The restart command probably isn't going to help the problem he describes, where an initialization computation consumes a lot of memory. It could be done; the computed values could be saved to disk, a restart executed, then the values read back into the session.  That would reduce the remaining memory footprint on the O/S, however, it likely won't help the Maple computation, which could access the memory anyway, assuming the initialization was done in a way that unassigned the appropriate variables so they could be garbage collected.

@Preben Alsholm A nice solution.  That the mixed form doesn't work seems reasonable.

A nice idea. Here is an extension.  Replace the `assuming` procedure so that the expression is evaluated with any assumptions of the form name=constant, then call the orginal `assuming` with the remaining.  Here is a proof of concept that merely does the first part:

unprotect(`assuming`):
`assuming` := proc(x::uneval,a)
    op(eval(x,ListTools:-Flatten(evalindets(a, set, [op]))));
end proc:

An advantage of this approach is that the assuming operator, which calls `assuming`, has the proper precedence, so

param := {a=2,b=7}:
plot(a*sin(x),x=0..b) assuming param;
plot(a*sin(x),x=0..b) assuming a=-2,b=7;
plot(a*sin(x),x=0..b) assuming [a=-2],{b=Pi};

all work as desired, no extra parentheses are needed.

@Alejandro Jakubi Try lprint(FromInert(f)). Using % doesn't work.  I'm not sure why, but suspect it is because % fully evaluates the expression.

@Alejandro Jakubi One way to accomplish that is

proc()
local p,P,f;
    p := proc(x) RealDomain:-sin(x) end proc;
    P := ToInert(eval(p));
    f := indets(P, 'specfunc(anything,_Inert_FUNCTION)')[1];
    f := op(0,FromInert(f));
    subs(f=g, eval(p));
end proc();
                          proc(x) g(x) end proc


The 'i' is not needed; seq(1..40,2) generates the odd integers.

The 'i' is not needed; seq(1..40,2) generates the odd integers.

@Dryan The expression andmap( l -> l[2] :: (identical(q) = anything), L) tests whether the second element in each of the sublists is an equation with the left side equal to the value of q.  The procedure ?andmap applies its first argument, which must be a predicate procedure (that is, a procedure that returns true or false) to each element in L, andmap returns true if all the predicates return true, otherwise it returns false.

I could have writtent this as andmap ( el -> type(el[2], equation) and lhs(el[2])=q, L); that probably is a bit clearer. The expression el[2] selects the second element in the list assigned to el, which will be each sublist in L. Instead I chose to use the :: operator to do a type match, with the type being identical(q) = anything.   The keyword 'identical' is a type that matches an expression that is identical to its argument.  More generally, if you give it a sequence of arguments it matches any of the expressions in the sequence.  For example,

type( a+1, identical(a+1));
                                                 true
type(a+1, identical(a+1,x));
                                                 true

 

What is piecewise(x < 1,q[O] = x, []) supposed to express?  That is, if x is greater than 1, it evalutes to an empty list, so you won't be able to pull out a common left side.

@Dryan The expression andmap( l -> l[2] :: (identical(q) = anything), L) tests whether the second element in each of the sublists is an equation with the left side equal to the value of q.  The procedure ?andmap applies its first argument, which must be a predicate procedure (that is, a procedure that returns true or false) to each element in L, andmap returns true if all the predicates return true, otherwise it returns false.

I could have writtent this as andmap ( el -> type(el[2], equation) and lhs(el[2])=q, L); that probably is a bit clearer. The expression el[2] selects the second element in the list assigned to el, which will be each sublist in L. Instead I chose to use the :: operator to do a type match, with the type being identical(q) = anything.   The keyword 'identical' is a type that matches an expression that is identical to its argument.  More generally, if you give it a sequence of arguments it matches any of the expressions in the sequence.  For example,

type( a+1, identical(a+1));
                                                 true
type(a+1, identical(a+1,x));
                                                 true

 

What is piecewise(x < 1,q[O] = x, []) supposed to express?  That is, if x is greater than 1, it evalutes to an empty list, so you won't be able to pull out a common left side.

@Dryan One way to get a better understanding of how a Maple procedure works is to trace.  So, after assigning SplitPW, do

(**) trace(SplitPW):
(**) SplitPW(pw);
# to make this a bit easier to follow, I've entered the corresponding lines of the procedure,
# proceeded by (**) before each output from the trace
{--> enter SplitPW, args = piecewise(x < 1,q[O] = x,q[O] = x^2)
(**)     L := PiecewiseTools:-ToList(pw);
                                                                  2
                          L := [[x < 1, q[O] = x], [true, q[O] = x ]]
(**)         q := op([1,2,1], L);
                                           q := q[O]
(**)             L := map(l -> [l[1],op([2,2],l)], L);
                                                           2
                                 L := [[x < 1, x], [true, x ]]
(**)             return q = piecewise(seq(op(l), l in L));
<-- exit SplitPW (now at top level) = q[O] = piecewise(x < 1,x,x^2)}
                                         { x           x < 1
                                  q[O] = {
                                         {  2
                                         { x         otherwise

 

The call to PiecewiseTools:-ToList converts the piecewise into a list of lists.  Each sublist consists of two elements, the condition and the action.

The next statement is a condition.  The expression op([1,2],L) refers to the action of the first sublist of L. The condition tests whether that action is an equation.  Here it is, so the then-clause of the conditional statement is executed.

The next statement is the assignment q := op([1,2,1], L); that assigns q the left side of the action of the first sublist. Here that is q[O].

The next conditional statement then checks whether all the actions are an equation with the left side equal to the value assigned to the local variable q. If so (and here it is so) the then clause is executed.

The map statement in the then-clause transforms all the actions in the sublists from equations to expressions; it does so by just grabbing the right side of each equation.

Finally, the return statement in the then-clause creates an equation with the left side equal to the common left side of each equation and the right side equal to a piecewise generated from the list of sublists.

@Dryan One way to get a better understanding of how a Maple procedure works is to trace.  So, after assigning SplitPW, do

(**) trace(SplitPW):
(**) SplitPW(pw);
# to make this a bit easier to follow, I've entered the corresponding lines of the procedure,
# proceeded by (**) before each output from the trace
{--> enter SplitPW, args = piecewise(x < 1,q[O] = x,q[O] = x^2)
(**)     L := PiecewiseTools:-ToList(pw);
                                                                  2
                          L := [[x < 1, q[O] = x], [true, q[O] = x ]]
(**)         q := op([1,2,1], L);
                                           q := q[O]
(**)             L := map(l -> [l[1],op([2,2],l)], L);
                                                           2
                                 L := [[x < 1, x], [true, x ]]
(**)             return q = piecewise(seq(op(l), l in L));
<-- exit SplitPW (now at top level) = q[O] = piecewise(x < 1,x,x^2)}
                                         { x           x < 1
                                  q[O] = {
                                         {  2
                                         { x         otherwise

 

The call to PiecewiseTools:-ToList converts the piecewise into a list of lists.  Each sublist consists of two elements, the condition and the action.

The next statement is a condition.  The expression op([1,2],L) refers to the action of the first sublist of L. The condition tests whether that action is an equation.  Here it is, so the then-clause of the conditional statement is executed.

The next statement is the assignment q := op([1,2,1], L); that assigns q the left side of the action of the first sublist. Here that is q[O].

The next conditional statement then checks whether all the actions are an equation with the left side equal to the value assigned to the local variable q. If so (and here it is so) the then clause is executed.

The map statement in the then-clause transforms all the actions in the sublists from equations to expressions; it does so by just grabbing the right side of each equation.

Finally, the return statement in the then-clause creates an equation with the left side equal to the common left side of each equation and the right side equal to a piecewise generated from the list of sublists.

@Dryan Try the following (it uses the undocumented PiecewiseTools:-ToList):

SplitPW := proc(pw)
local L,q,l;
    L := PiecewiseTools:-ToList(pw);
    if op([1,2],L)::equation then
# get lhs of first equation, then check whether all have the same form
        q := op([1,2,1], L);
        if andmap( l -> l[2] :: (identical(q) = anything), L) then
            L := map(l -> [l[1],op([2,2],l)], L);
            return q = piecewise(seq(op(l), l in L));
        end if;
    end if;
    return pw;
end proc:
pw := piecewise(x<1, q[O]=x, q[O]=x^2):
SplitPW(pw);
                                { x           x < 1
                         q[O] = {
                                {  2
                                { x         otherwise

assign(%);
q[O];
                             { x           x < 1
                             {
                             {  2
                             { x         otherwise


@Dryan Try the following (it uses the undocumented PiecewiseTools:-ToList):

SplitPW := proc(pw)
local L,q,l;
    L := PiecewiseTools:-ToList(pw);
    if op([1,2],L)::equation then
# get lhs of first equation, then check whether all have the same form
        q := op([1,2,1], L);
        if andmap( l -> l[2] :: (identical(q) = anything), L) then
            L := map(l -> [l[1],op([2,2],l)], L);
            return q = piecewise(seq(op(l), l in L));
        end if;
    end if;
    return pw;
end proc:
pw := piecewise(x<1, q[O]=x, q[O]=x^2):
SplitPW(pw);
                                { x           x < 1
                         q[O] = {
                                {  2
                                { x         otherwise

assign(%);
q[O];
                             { x           x < 1
                             {
                             {  2
                             { x         otherwise


First 83 84 85 86 87 88 89 Last Page 85 of 195