Joe Riel

9660 Reputation

23 Badges

20 years, 21 days

MaplePrimes Activity


These are replies submitted by Joe Riel

Seems like some of that defense might have been applied to SaveSession.  It has a number of unprotected global variables:

> save SaveSession, "/tmp/SaveSession.mpl":
> !mint -q /tmp/SaveSession
Procedure SaveSession( archiveName::string ) on lines 1 to 23
  These names were used as global names but were not declared:  assertlevel, 
      cpulimit, datalimit, environment, errortable, imaginaryunit, latexwidth, 
      longdelim, stacklimit, traceproc, watchtable

In Maple13

map~(combine, H);

In Maple13

map~(combine, H);

The "surgical" solution (below) returns the two-argument form of arctan.

The "surgical" solution (below) returns the two-argument form of arctan.

Here's a way to partially answer that question (more accurately, its converse).  A week or so ago you asked for a procedure that returned the dependencies of a procedure.  I hacked together the following but haven't had time to extend it to work with module locals.

Dependencies := module()
export ModuleApply ;
local ProcDependencies, InertProcDependencies;
    ModuleApply := ProcDependencies;
    ProcDependencies := proc(f :: appliable, level :: posint )
    option cache;
    local F, opacity;
        F := f;
        try
            opacity := kernelopts('opaquemodules'=false);
            while F :: `module` do
                F := F:-ModuleApply;
            end do;
        finally
            kernelopts('opaquemodules'=opacity);
        end try;
        return InertProcDependencies(ToInert(op(F)), level);
    end proc;

    InertProcDependencies := proc(inert, level :: posint )
    option cache;
    local deps, nm, funcs, procs, p;
        procs := indets([op(inert)], 'specfunc(anything,_Inert_PROC)');
        inert := subs({seq(procs=NULL, procs in procs)}, [op(inert)]);
        funcs := map2(op, 1, indets(inert, 'specfunc(anything,_Inert_FUNCTION)'));
        deps := {seq(`if`(nm :: specfunc(anything, '{_Inert_NAME, _Inert_ASSIGNEDNAME, _InertMEMBER}')
                          , FromInert(nm)
                          , NULL
                         )
                     , nm in funcs
                    )};
        deps := select(type, deps, 'appliable');
        deps := `union`(NULL
                        #, lexs
                        , deps
                        , seq(procname(p, level), p in procs)
                       );
        if level = 1 then
            return deps;
        else
            return {seq(op(ProcDependencies(nm, level-1)), nm in deps)};
        end if;
    end proc;

end module:

From the help page for simplify we see that there are several extensions.  The following is crude, but it uses Dependencies to find any that calls "is",

simps := {NULL
          , `simplify/@`
          , `simplify/Ei`
          , `simplify/GAMMA`
          , `simplify/hypergeom`
          , `simplify/ln`
          , `simplify/polar`
          , `simplify/power`
          , `simplify/radical`
          , `simplify/RootOf`
          , `simplify/rtable`
          , `simplify/sqrt`
          , `simplify/trig`
         }:

select(proc(p)
       local deps := Dependencies(p,2);
           ormap(p -> has(eval(p), 'is')
                 , select(curry(StringTools:-IsPrefix, "simplify/"), deps)
                );
       end proc
       , simps
      );
               {`simplify/RootOf`, `simplify/power`, `simplify/trig`, `simplify/radical`}

I forgot you had mentioned the `tools/get_functions_called` procedure.  Using it is simpler than the Dependencies procedure above, but requires an extension to descend:

dependencies := proc(p,level::posint)
option cache;
local dep,deps;
    try 
        deps := map(convert, convert(`tools/get_functions_called`(p),set), name);
        if level > 1 then
            deps := `union`(deps
                            , seq(procname(dep, level-1)
                                  , dep in deps)
                           );
        end if;
        return deps
    catch:
        return {};
    end try;
end proc:

The try/catch is a crude workaround for a bug, it is suitable for our purpose.  Using dependencies instead of Dependencies gives

select(proc(p)
       local deps := dependencies(p,2);
           ormap(p -> has(eval(p), 'is')
                 , select(curry(StringTools:-IsPrefix, "simplify/"), deps)
                );
       end proc
       , simps
      );
       {`simplify/ln`, `simplify/RootOf`, `simplify/power`, `simplify/trig`, `simplify/radical`}

Here's a way to partially answer that question (more accurately, its converse).  A week or so ago you asked for a procedure that returned the dependencies of a procedure.  I hacked together the following but haven't had time to extend it to work with module locals.

Dependencies := module()
export ModuleApply ;
local ProcDependencies, InertProcDependencies;
    ModuleApply := ProcDependencies;
    ProcDependencies := proc(f :: appliable, level :: posint )
    option cache;
    local F, opacity;
        F := f;
        try
            opacity := kernelopts('opaquemodules'=false);
            while F :: `module` do
                F := F:-ModuleApply;
            end do;
        finally
            kernelopts('opaquemodules'=opacity);
        end try;
        return InertProcDependencies(ToInert(op(F)), level);
    end proc;

    InertProcDependencies := proc(inert, level :: posint )
    option cache;
    local deps, nm, funcs, procs, p;
        procs := indets([op(inert)], 'specfunc(anything,_Inert_PROC)');
        inert := subs({seq(procs=NULL, procs in procs)}, [op(inert)]);
        funcs := map2(op, 1, indets(inert, 'specfunc(anything,_Inert_FUNCTION)'));
        deps := {seq(`if`(nm :: specfunc(anything, '{_Inert_NAME, _Inert_ASSIGNEDNAME, _InertMEMBER}')
                          , FromInert(nm)
                          , NULL
                         )
                     , nm in funcs
                    )};
        deps := select(type, deps, 'appliable');
        deps := `union`(NULL
                        #, lexs
                        , deps
                        , seq(procname(p, level), p in procs)
                       );
        if level = 1 then
            return deps;
        else
            return {seq(op(ProcDependencies(nm, level-1)), nm in deps)};
        end if;
    end proc;

end module:

From the help page for simplify we see that there are several extensions.  The following is crude, but it uses Dependencies to find any that calls "is",

simps := {NULL
          , `simplify/@`
          , `simplify/Ei`
          , `simplify/GAMMA`
          , `simplify/hypergeom`
          , `simplify/ln`
          , `simplify/polar`
          , `simplify/power`
          , `simplify/radical`
          , `simplify/RootOf`
          , `simplify/rtable`
          , `simplify/sqrt`
          , `simplify/trig`
         }:

select(proc(p)
       local deps := Dependencies(p,2);
           ormap(p -> has(eval(p), 'is')
                 , select(curry(StringTools:-IsPrefix, "simplify/"), deps)
                );
       end proc
       , simps
      );
               {`simplify/RootOf`, `simplify/power`, `simplify/trig`, `simplify/radical`}

I forgot you had mentioned the `tools/get_functions_called` procedure.  Using it is simpler than the Dependencies procedure above, but requires an extension to descend:

dependencies := proc(p,level::posint)
option cache;
local dep,deps;
    try 
        deps := map(convert, convert(`tools/get_functions_called`(p),set), name);
        if level > 1 then
            deps := `union`(deps
                            , seq(procname(dep, level-1)
                                  , dep in deps)
                           );
        end if;
        return deps
    catch:
        return {};
    end try;
end proc:

The try/catch is a crude workaround for a bug, it is suitable for our purpose.  Using dependencies instead of Dependencies gives

select(proc(p)
       local deps := dependencies(p,2);
           ormap(p -> has(eval(p), 'is')
                 , select(curry(StringTools:-IsPrefix, "simplify/"), deps)
                );
       end proc
       , simps
      );
       {`simplify/ln`, `simplify/RootOf`, `simplify/power`, `simplify/trig`, `simplify/radical`}

I see. It is not in the blog post itself, but rather in the page that lists all of a person's blogs.

Is it?  Where does it show up?

If alphabetic order is desired, then sort after converting to a list of strings.

StringTools:-Join(sort(map(curry(sprintf,"%a=%f")@op, [sol[]])), ", ");
             "temp=234.900000, x1=0.000000, x2=0.239774, y1=1402.995860, y2=-47636.684970"

If alphabetic order is desired, then sort after converting to a list of strings.

StringTools:-Join(sort(map(curry(sprintf,"%a=%f")@op, [sol[]])), ", ");
             "temp=234.900000, x1=0.000000, x2=0.239774, y1=1402.995860, y2=-47636.684970"

That's probably what I'd do, but the user could have a reason for keeping the functional form.  A more realistic case might be

w := k*v(t)^2:
dw := diff(w,t);
                                          /d      \
                           dw := 2 k v(t) |-- v(t)|
                                          \dt     /

dv := diff(v(t),t):
pdiff(dw, dv);
                                   2 k v(t)

That's probably what I'd do, but the user could have a reason for keeping the functional form.  A more realistic case might be

w := k*v(t)^2:
dw := diff(w,t);
                                          /d      \
                           dw := 2 k v(t) |-- v(t)|
                                          \dt     /

dv := diff(v(t),t):
pdiff(dw, dv);
                                   2 k v(t)

Here's a simple procedure that works here, but has problems with higher-order derivatives

pdiff := proc(ex)
    frontend(diff, [_passed], [{Not(identical(_rest))},{}]);
end proc:

pdiff(a(t) + b(t)*sin(a(t)+b(t)), a(t));
                           1 + b(t) cos(a(t) + b(t))

pdiff(f(a(t),b(t)),a(t));
                              D[1](f)(a(t), b(t))

pdiff(f(a(t),b(t)),a(t),b(t));
                        diff(f(a(t), b(t)), a(t), b(t))

It isn't clear why diff did not use the D operator in that last example.  We can work-around that with

pdiff := proc(ex)
    frontend(proc()
             local df;
                 df := diff(_passed);
                 if has(df,diff) then
                     df := convert(df,'D');
                 end if;
                 return df;
             end proc
             , [_passed], [{Not(identical(_rest))},{}]);
end proc:

pdiff(a(t) + b(t)*sin(a(t)+b(t)), a(t));
                           1 + b(t) cos(a(t) + b(t))

pdiff(f(a,b),a);
                                 D[1](f)(a, b)

pdiff(f(a(t),b(t)),a(t),b(t),a(t));
                           D[1, 1, 2](f)(a(t), b(t))

Here's a simple procedure that works here, but has problems with higher-order derivatives

pdiff := proc(ex)
    frontend(diff, [_passed], [{Not(identical(_rest))},{}]);
end proc:

pdiff(a(t) + b(t)*sin(a(t)+b(t)), a(t));
                           1 + b(t) cos(a(t) + b(t))

pdiff(f(a(t),b(t)),a(t));
                              D[1](f)(a(t), b(t))

pdiff(f(a(t),b(t)),a(t),b(t));
                        diff(f(a(t), b(t)), a(t), b(t))

It isn't clear why diff did not use the D operator in that last example.  We can work-around that with

pdiff := proc(ex)
    frontend(proc()
             local df;
                 df := diff(_passed);
                 if has(df,diff) then
                     df := convert(df,'D');
                 end if;
                 return df;
             end proc
             , [_passed], [{Not(identical(_rest))},{}]);
end proc:

pdiff(a(t) + b(t)*sin(a(t)+b(t)), a(t));
                           1 + b(t) cos(a(t) + b(t))

pdiff(f(a,b),a);
                                 D[1](f)(a, b)

pdiff(f(a(t),b(t)),a(t),b(t),a(t));
                           D[1, 1, 2](f)(a(t), b(t))

First 114 115 116 117 118 119 120 Last Page 116 of 195