Joe Riel

9660 Reputation

23 Badges

20 years, 3 days

MaplePrimes Activity


These are replies submitted by Joe Riel

Nice suggestion, Acer. I didn't know about the frandom option to rtable. It isn't clear from the rtable help page precisely what it does (no mention whether the numbers are uniformly generated). Also, its first argument is supposed to be a range, but giving it just a 0.0, as you did, seems to work. It is significantly faster (orders of magnitude) than the other approaches. I'll update the main blog entry with this and Jacques' suggestion.
Use the same approach, assign the procedure `print/a` in ModuleLoad. There is, alas, no equivalent PrintTools package. Instead of making `print/a` an export you need to declare it as a global. Here is a snippet
MyModule := module()
local ModuleLoad;
export FS;
option package;
   ModuleLoad := proc()
   global `print/a`;
     `print/a` := proc(t) ['a', op(1,t)] end proc;
     TypeTools[AddType]('FS', specfunc(anything,a));
   end proc:
   ModuleLoad();
end module:
Note that I used forward quotes, not backquotes, around a. The backquotes are never required. The forward quotes are useful to prevent a global assignment to a from spoiling the effect. Note the change to your type definition. Also, note that there is a probable flaw in your assignment to `print/a`, which I have not corrected. Try a().
Use the same approach, assign the procedure `print/a` in ModuleLoad. There is, alas, no equivalent PrintTools package. Instead of making `print/a` an export you need to declare it as a global. Here is a snippet
MyModule := module()
local ModuleLoad;
export FS;
option package;
   ModuleLoad := proc()
   global `print/a`;
     `print/a` := proc(t) ['a', op(1,t)] end proc;
     TypeTools[AddType]('FS', specfunc(anything,a));
   end proc:
   ModuleLoad();
end module:
Note that I used forward quotes, not backquotes, around a. The backquotes are never required. The forward quotes are useful to prevent a global assignment to a from spoiling the effect. Note the change to your type definition. Also, note that there is a probable flaw in your assignment to `print/a`, which I have not corrected. Try a().
Once separated, you can use the blank function (``) to keep them that way:
y := ``(2)*(p^2 + 2);
                                          2
                              y :=  (2) (p  + 2)
 expand(y);
                                      2
                                   2 p  + 4
This came up recently on comp.soft-sys.math.maple. I suggested the following crude procedure:
factorFrac := proc(p)
local d,n,dgcd,ngcd,poly;
    poly := factor(p);
    if not poly::`+` then return poly; end if;
    (n,d) := (numer,denom)(poly);
    ngcd := `if`(n::`+`,foldl(gcd, op(n)),n);
    dgcd := `if`(d::`+`,foldl(gcd, op(d)),d);
    (ngcd/dgcd)*``(n/d*dgcd/ngcd);
end proc:

factorFrac(2/3*p^2+4/9);
                                         2
                                2/9  (3 p  + 2)
expand(%);
                                     2
                                  2 p
                                  ---- + 4/9
                                   3
It can be improved.
Once separated, you can use the blank function (``) to keep them that way:
y := ``(2)*(p^2 + 2);
                                          2
                              y :=  (2) (p  + 2)
 expand(y);
                                      2
                                   2 p  + 4
This came up recently on comp.soft-sys.math.maple. I suggested the following crude procedure:
factorFrac := proc(p)
local d,n,dgcd,ngcd,poly;
    poly := factor(p);
    if not poly::`+` then return poly; end if;
    (n,d) := (numer,denom)(poly);
    ngcd := `if`(n::`+`,foldl(gcd, op(n)),n);
    dgcd := `if`(d::`+`,foldl(gcd, op(d)),d);
    (ngcd/dgcd)*``(n/d*dgcd/ngcd);
end proc:

factorFrac(2/3*p^2+4/9);
                                         2
                                2/9  (3 p  + 2)
expand(%);
                                     2
                                  2 p
                                  ---- + 4/9
                                   3
It can be improved.
As Jacques knows (and was careful to distinguish), but others may not realize, the result of
evalb(expr)
is not always identical to
if expr then true else false end if
For example,
evalb(I<4*I);
                                    FAIL
if I<4*I then true else false end if;
                                    false
As Jacques knows (and was careful to distinguish), but others may not realize, the result of
evalb(expr)
is not always identical to
if expr then true else false end if
For example,
evalb(I<4*I);
                                    FAIL
if I<4*I then true else false end if;
                                    false
I don't believe that will do the trick, that is, it will fail when the module is loaded from a repository because the type wasn't defined. The trick is to add the type in a procedure that is executed when module is loaded. By default, a local/export named ModuleLoad is executed when the module is loaded.
MyModule := module() 
option package;
export p, FS;
local ModuleLoad;
    ModuleLoad := proc()
        TypeTools[AddType](FS, identical('a'));
    end proc;
    p := proc(S::MyModule:-FS) local coeff, t;
        print(1);
    end proc;
    ModuleLoad(); # necessary if module is not saved/loaded.
end module:
Note that in the above I used identical('a') rather than the more cumbersome original procedure as the type definition.
I don't believe that will do the trick, that is, it will fail when the module is loaded from a repository because the type wasn't defined. The trick is to add the type in a procedure that is executed when module is loaded. By default, a local/export named ModuleLoad is executed when the module is loaded.
MyModule := module() 
option package;
export p, FS;
local ModuleLoad;
    ModuleLoad := proc()
        TypeTools[AddType](FS, identical('a'));
    end proc;
    p := proc(S::MyModule:-FS) local coeff, t;
        print(1);
    end proc;
    ModuleLoad(); # necessary if module is not saved/loaded.
end module:
Note that in the above I used identical('a') rather than the more cumbersome original procedure as the type definition.
While I don't know what is causing your specific problem, here are a few comments on your procedure. First, the statement T := 9/10T should probably be T := 9/10*T. Second, T should be declared as a global (if it isn't a global, this assignment will raise an error). Possibly the * is there but you are copying this from typeset output so it just didn't show up in the html. The assignments
meilleur := M;
travail := M;
should probably be
meilleur := copy(M);
travail:= copy(M);
otherwise changes to any affects the other, and M. As suggested previously, you might look into using Array rather than array as the data structure.
While I don't know what is causing your specific problem, here are a few comments on your procedure. First, the statement T := 9/10T should probably be T := 9/10*T. Second, T should be declared as a global (if it isn't a global, this assignment will raise an error). Possibly the * is there but you are copying this from typeset output so it just didn't show up in the html. The assignments
meilleur := M;
travail := M;
should probably be
meilleur := copy(M);
travail:= copy(M);
otherwise changes to any affects the other, and M. As suggested previously, you might look into using Array rather than array as the data structure.
Here is the code for the ListBuffer module that I presented on my blog a while ago. I made one tweak to remove a library call (table([ ... ] calls `index/FillInitVals`).
ListBuffer := proc()
local initial;
description "return a list buffer, analogous to StringTools:-StringBuffer";

    initial := args;

    module()
    local tbl, count, posindex;
    export append, value, clear, element, modify, remove, slice, length;
    description "a list buffer object";

        posindex := proc(i::integer)::posint;
        description "convert a negative index to a positive index";
            if abs(i) > count then
                error ("magnitude of index (%1) greater than number of elements (%2)"
                       ,i, count);
            end if;
            if i = 0 then
                error "index cannot be 0" end if;
            if i < 0 then
                return count+1+i;
            else
                return i;
            end if;
        end proc;

        clear := proc()
        local i;
        description "clear this list buffer"
            ,"optional arguments initialize the buffer";
            tbl := table();
            for i to nargs do tbl[i] := args[i] end do;
            count := nargs;
            NULL;
        end proc;

        value := proc()::list;
        local i;
        description "return the value of this list buffer";
            [seq](tbl[i], i = 1 .. count);
        end proc;

        append := proc()
        local e;
        description "append an element (or elements) to this list buffer";
            for e in args do
                count := 1 + count;
                tbl[count] := e
            end do;
            return NULL;
        end proc;

        element := proc(i::integer)
        description "return the i-th element of this list buffer";
            tbl[posindex(i)];
        end proc;

        modify := proc(i::integer,e)
        description "modify the i-th element of this list buffer"
            ,"return the new element";
            tbl[posindex(i)] := e;
        end proc;

        remove := proc(indx::{integer,range(integer)})
        local i,j,k;
        description "remove an element or range of elements from this list buffer"
            ,"return the removed element(s)";
            if indx::range then
                j,k := posindex(lhs(indx)), posindex(rhs(indx));
                return ([seq](tbl[i],i=j..k)
                        ,clear(seq(tbl[i],i=1..j-1)
                               ,seq(tbl[i],i=k+1..count)));
            else
                j := posindex(indx);
                return (tbl[j]
                        ,clear(seq(tbl[i],i=1..j-1)
                               ,seq(tbl[i],i=j+1..count)));
            end if
        end proc;

        slice := proc(r::range(integer))::list;
        local i,j,k;
        description "return a sublist of this list buffer";
            j,k := posindex(lhs(r)),posindex(rhs(r));
            [seq](tbl[i],i=j..k);
        end proc;

        length := proc()::nonnegint;
        description "return the length of this list buffer";
            count;
        end proc;

        # Clear the list buffer and initialize it
        # with the arguments passed to the constructor.

        clear(initial);

    end module;
end proc:

# Exercise it

Check := proc(eq)
    if not evalb(eq) then
        error "test failure: %1", eq;
    end if;
end proc:

lb := ListBuffer($1..10):
use lb in
    append($11..20);
    Check(length() = 20);
    Check(element(20) = 20);
    Check(slice(1..10) = [$1..10]);
    Check(value() = [$1..20]);
    Check(modify(1,100) = 100);
    Check(element(1)=100);
    Check(remove(1..10)=[100,$2..10]);
    Check(value() = [$11..20]);
end use;
Another possibility is to include the -c"libname:=NULL" option to maple, that prevents any library reads from occurring. Include -c"protect('libname')" for extra measure.
Better would be to use the -s option to suppress any startup scripts. Here's a shell script that returns the name of the file if it passes the test:
#!/bin/sh                                                                                                                                                      
maple -sq -L log $1 > /dev/null                                                 
if [ $( wc -l log | cut -d\  -f1 ) -eq 1 ] ; then echo $1 ; fi
Nice entry. I'd add preprocessor macros, though that's more a personal preference. I find the inclusion of maptype curious. It is, I believe, a relatively new command and one that I haven't used. In searching through the Maple repositories I see that it is not used at all in Maple10 or Maple11. It often takes a while for experienced programmers to add new commands (andmap, ormap, foldl, etc) to their repetoire. Could you suggest a definitive usage (the help page examples show function but ...)? If its name were MapTypeElseApply its function would be clear, but then it would be untypeable.
First 177 178 179 180 181 182 183 Last Page 179 of 195