Product Tips & Techniques

Tips and Tricks on how to get the most about Maple and MapleSim
A poster on comp.soft-sys.math.maple recently asked how to set the default zoom for worksheets to a non-standard value; the jump from 100% to 150% being rather large. Standard GUI This can be readily accomplished by modifying the proper Maple initialization file.
Linux
the file is ~/.maple10rc
Mac OS X
the file is Maple 10 Preferences in Library/Preferences under your user directory (thanks to Tim Lahey).
Windows
the file is Maple10.ini (not maple.ini). The maple help pages do not mention this file and I do not have Windows, so cannot check. I have received reports that it is located in the users subdirectory under the Maple installation directory, but also reports that it is in c:\Documents and Settings\JoeUser, where JoeUser is your user name. My advice, until this is cleared up, is to search for all instances of this file and use the newest one. Maple writes to this file whenever the gui exits, so the newest one should be the right one. You might send me a note on what you've found (along with which version of Maple you are using); I'll update this accordingly.
When I upgraded my Mac G5 from OS 10.3 to OS 10.4, the OS X versions of Maple (Maple 9.5 and Maple 10) continued to work. But the classic versions of Maple (Maple 7 and Maple Vr5) quit working. It turns out that the classic versions will run in OS 10.4 if the following files (perhaps from an old "System Folder") are moved into the "Extensions" folder of the active classic OS 9 "System Folder":
I've been completely unsatisfied with the Maple LaTeX output. So, with the help of Joe Riel on comp.soft-sys.math.maple, I've created a procedure to use instead of a call to the latex command called simpleLaTeX. I've attached to this entry a Maple 9.5 worksheet that contains the procedure and a sample of its use. I'd appreciate any feedback people might have or further suggestions. Please send me any modifications you might make to the procedure. It seems to work quite well for all the test expressions I've sent to it.

A while ago, I was trying to determine the fastest way, using Maple, to compute a list of a particular sequence of integers defined by a recurrence relation. This isn't a new idea of course, but I think the exercise is a useful introduction into the various ways of coding algorithms in Maple, and why some may be better than others.

My original example was a bit esoteric, so for simplicity I've redone it using the standard example of a recurrence relation, the Fibonacci sequence. We'll fix N, the number of Fibonacci numbers to compute, at 40000.

> N := 40000:

Below, we'll try to find the fastest way, in Maple, to compute a list of these numbers from scratch. Note that the speed comparisons might be specific to this machine, OS, or Maple version, and even though the runtime of most of these implementations is about the same, the fastest method at N=40000 might not be the fastest one for larger N.

The first idea is the completely naive approach. We'll store the Fibonacci numbers in a Maple list L, step through a loop counting up the sequence, and in each loop iteration add to the list with L := [op(L), new_element].

f1 := proc(N)
    local i, L;
    L := [1, 1];
    for i from 2 to N do
        L := [op(L), L[-2] + L[-1]];
    end do;
    L
end proc:

The problem with this approach is that Maple lists are not intended to be grown in this way, and each redefinition of the list L costs O(N) time, making the whole procedure O(N).

> time(f1(N));
31.440

From now on we'll use only implementations that take O(N) time, and see how they compare.

The next implementation uses a Maple table stored as a local variable of a module. We compute the sequence and assign it to table entries, and at the end generate a Maple list from these table entries. The use of tables is advantageous because tables can be dynamically grown more efficiently than lists can, but this approach has the disdvantage that the table must be completely re-traversed in the last step to generate the list.

f2 := module()
    local ModuleApply, T;

    T := table([0=1, 1=1]);

    ModuleApply := proc(N)
        local i;
        for i from 2 to N do
            T[i] := T[i-2] + T[i-1];
        end do:
        [seq(T[i], i=0..N)]
    end proc:
end module:

You'll see that since this code avoids list-appending, it's quite a bit faster:

> time(f2(N));
1.110

The next idea is to do essentially what we did above, but using remember tables rather than built-in Maple tables. We'll pre-populate the remember table for the utility procedure p with entries for the base cases, F0 and F1, and then build our list through recursive calls.

f3 := module()
    local p, ModuleApply;

    p := proc(n) option remember;
        procname(n-2) + procname(n-1)
    end proc:

    p(0) := 1;
    p(1) := 1;
 
    ModuleApply := proc(N)
        [1, 1, seq(p(i), i=2..N)]
    end proc:
end module:

As we might expect, the computed result is pretty close (but a bit higher than) our last number.

> time(f3(N));
1.229

One disadvantage of the last two approaches is that they both rely on creating an intermediate data structure of size O(N) (the table or remember table), which is promptly discarded, since what we're interested in is a list. Instead we can use a 'cache', which is a new feature of Maple 9.5, and is essentially a remember table of bounded size.

f4 := module()
    local p, ModuleApply;

    p := proc(n) option cache;
        procname(n-2) + procname(n-1)
    end proc:

    p(0) := 1;
    p(1) := 1;

    ModuleApply := proc(N)
        [1, 1, seq(p(), i=2..N)]
    end proc:
end module:

It works out to be slightly slower than f3; this may be because of the time taken in garbage-collecting the information from the cache.

> time(f4(N));
1.459

Next, I've tried to implement something like a cache, without actually using one. Here we have a utility procedure with two counters, which represent the last and second-last Fibonacci number respectively. The procedure updates the values and returns the appropriate one. We'll build the list with recursive calls to this procedure. Like the cache, the intermediate data structures used here are of bounded size, since there are just two of them.

f5 := module()
    local p, n1, n2, ModuleApply;

    n1 := 1;
    n2 := 1;

    p := proc(n)
        (n1, n2) := (n2, n1+n2);
        n2;
    end proc:

    ModuleApply := proc(N)
        [1, 1, seq(p(), i=2..N)]
    end proc:
end module:

It's about the same speed as using the cache, which is impressive since it involves a lot more procedure calls into the procedure body than the cache example, which mostly consisted of calls into the cache.

> time(f5(N));
1.439

Finally, mostly for completeness, we try to see we get by pre-allocating an Array and adding to that. Arrays can be modified inplace in O(1) time, but cannot be dynamically grown. Here we make an array of the appropriate size, fill it, then convert it to a list.

f6 := proc(N)
    local A, i;
    A := Array(0..N, {0=1,1=1});
    for i from 2 to N do
        A[i] := A[i-2] + A[i-1];
    end do:
    convert(A, 'list')
end proc:

It's about as fast as the previous two examples, and has the advantage of simplicity of design. However, building the array and converting that to a list is another instance of using large intermediate data structures, which we avoided with the previous two examples.

> time(f6(N));
1.469

So it looks like f2 is the winner in this very specialized contest. This probably has more to do with the quirks of this example than any difference in efficiency of the code concerned. And if minimizing intermediate memory use is the goal, then f4 or f5 would be preferable.

There are two ways of directly entering math into MaplePrimes. The first is the <maple> tag. Any text between <maple></maple> tags will be interpreted as Maple syntax and be replaced with a 2D GIF image of that syntax.

There has been active threads on easy ways to post Maple or math specific content - e.g. code snippets, good looking math, plots etc. This Web site will definitely be less effective if people are forced into cumbersome processes to put what most of us would consider to be "fundamental" information into their postings.

Theory has it that Maple is good at producing HTML code. For the original application that it was intended - i.e. creating self-contained Web pages, it works pretty well. Can this theory be extended to cover our MaplePrimes beta application. How easy is it to use Maple as the authoring environment to express some math and to do a plot and general HTML code that is useful for MaplePrimes? 

In some applications it is necessary to map an angle to a range of 0 to 360 degrees. Adding 360 degrees to an angle, or subtracting 360 from an angle does not change actually change the angle. One way to do this would be to add (or subtract) enough multiples of 360 degrees until the angle falls between 0 and 360. For example, given an angle of 400 you would subtract 360 to get an angle of 40 degrees. In Maple, this is easily accomplished by the following function.

Frem := (x,y) -> x - y*floor(x/y);

Maple's syntax is very intuitive and not complicated. The best way to learn how to use Maple is to take The New User's Tour . The New User's Tour presents the fundamental Maple commands that every user should be aware of. The tour covers many areas of Maple, including: The Maple Worksheet Environment, Numerical Calculations, Algebraic Computations, Graphics, Calculus, Differential Equations, Linear Algebra, Finance and Statistics, Programming, and Online Help. The tour is easy to proceed through, and it can take up to two hours if all topics are examined. In order to start The New User's Tour you should go to Help --> New User's Tour .
First 55 56 57 Page 57 of 57