Maple on Athena (AC-72)


About this document:


Introduction

Maple is an interactive program for symbolic computation. It has numerous built-in services and a programming language that enables you to extend its capabilities. You can use it not only to manipulate and calculate numeric values, but also to operate on a wide variety of mathematical and computational structures including:

  • equations and expressions

  • arrays

  • sets

  • groups

  • graph structures

  • sequences

  • tables

  • lists

  • strings

  • procedures

    By combining this powerful datatyping with the extensive libraries of Maple functions, you can solve problems from any field that requires:

  • solving systems of linear or non-linear equations

  • differentiation

  • definite and indefinite integration

  • taking limits

  • manipulating series

  • solving differential equations

  • traversing graph structures

  • analyzing groups

  • plotting 2-D or 3-D graphs

    Finally, whenever you use Maple there is one important caveat that you need to keep in mind. Maple is an excellent tool for performing or verifying tedious and error-prone computations, but it is not a substitute for mathematical knowledge and intuition. Like most programs it will try to do what you ask of it, but you must judge the mathematical relevance of both your question and Maple's answer.


    Conventions

    Every attempt has been made to include as examples actual dialogs between a user and Maple. Input from the user is shown to the right of Maple's default prompt >; responses from Maple are on the succeeding lines. For example:

    > commands-typed-here

    response-printed-here

    The only typographic licence taken with these dialogs is reduction of non-critical output like white space. Maple inserts blank lines liberally to make the results easier to read; it also inserts solid lines between completed statements that you enter.

    Example:

    > statement-one;

    response-to-statement-one

    -----------------------------------------------

    > statement-two;

    response-to-statement-two

    -----------------------------------------------

    >

    Most of these extra lines were removed to reduce size and improve overall readability of this document.

    Checkpoint. Look for notes like this located at various places in this document. They are designed to let you know that you are at a good place to stop and apply what you've learned about Maple, and what to do when you are ready to learn more.



    Starting a Session

    Since Maple V Release 2 is in a public locker, once you have located an appropriate workstation and logged in, you must attach the locker to your file system. You only need to do this one time during your login session. To attach the Maple V Release 2 locker, type the following command:

    athena% add maple

    (This is for all workstation types except VAXstations; for that type, you can only use Maple V, available in the maple.old locker rather than the maple locker). The add command attaches the maple locker to the directory /mit/maple and appropriately modifies your environment -- in particular, it adjusts both your program search path (PATH) and your manual-page search path (MANPATH) variables to let you run maple and access the Maple man pages.

    To run maple, just type the following command:

    athena% maple

    If you are running an X-windows session, then a few moments after you enter the command maple, a new window will appear with Maple running in it. (Note that Maple automatically "backgrounds" itself -- you do not need to use the command form maple & the way you might do for other windowed applications.)

    GIF_FILE

    If you are accessing Maple on a plain-text format (e.g., over dialup), you will just see its startup message and a prompt:

    |\^/| MAPLE V Release 2 (Massachusetts Institute of Technology)

    ._|\| |/|_. Copyright (c) 1981-1993 by the University of Waterloo.

    \ MAPLE / All rights reserved. Maple and Maple V are registered

    <____ ____> trademarks of Waterloo Maple Software.

    | Type ? for help.

    >



    Getting Help about Maple


    On-Line Help

    Maple has extensive built-in help information. This help system can provide detailed explanations of the Maple language and its extensive libraries of routines.

    There are two ways to invoke help on Maple. The simpler and recommended way is to preface a topic with a question mark. To get help on the help system itself, type either of these commands:

    > ?

    > ?help

    To get an index of topics, just type:

    > ?index

    To get a quick overview of maple, try:

    > ?intro

    The second way of getting help is to use the help function call. Your query must conform to Maple's statement syntax, which will be explained later in this document. As an example, to get the help on help you would use either of these commands:

    > help();

    > help(`help`);

    The backquotes and the semicolons are necessary, though in all other respects this method of getting help is the same as described previously.


    Hardcopy Documentation

    This document is only a brief overview of Maple. To learn more about it, you may want to read the vendor manuals for Maple. They will be published by Springer Verlag and consist of:

  • First Leaves: A Tutorial Introduction to Maple V

  • Maple V Language Reference Manual

  • Maple V Library Reference Manual

    These manuals are still in production, but the MIT Coop intends to stock them once they are available.

    If you have access to documentation for previous releases of Maple, you may notice references to the MRM. This stands for the Maple Reference Manual. Starting with Maple V, that document has been split into the separate language and library reference manuals listed above.


    Other Sources of Information

    If you have a specific question about some aspect of Maple, you can get help from the Athena Consultants in any of the following ways:

  • submit it to the On-Line Consultant (type olc at your athena% prompt and enter maple as your question topic)

  • ask your question by phone (call x3-4435)

  • visit the Consultants during office hours (in MIT Room 11-115)

    You can also browse the current collection of Answers to Commonly Asked Questions about Maple by typing olc_answers at your athena% prompt. Maple answers are under the category Other.

    A Maple user's group exists which corresponds by electronic mail. This group can be reached by sending mail to maple_group@daisy.waterloo.edu.

    If you have not used electronic mail before on Athena, you may want to read the document Electronic Mail on Athena. This document is available online in the Athena On-Line Help System (OLH). It is also available in hardcopy form at MIT Graphic Arts.

    There also exists a Usenet newsgroup devoted to symbolic algebra and various mathematical software packages. The newsgroup name is sci.math.symbolic.

    If you have not read netnews before, you may want to read the document Netnews on Athena. Like the mail document, this document is available both online on OLH and in hardcopy form from MIT Graphic Arts.



    Maple Basics


    Introduction

    The key format for your interaction with Maple is the statement. You type in statements for Maple; it evaluates them and gives you the results. To let you know that it is waiting for input, Maple prints a prompt:

    >

    For Maple to understand what you type, your commands must conform to Maple's expectations for statements. In particular, your statement must be terminated by a semicolon (;) or a colon (:) for Maple to realize that you have completed it. The semicolon tells Maple to print out the result of evaluating the statement, while the colon tells it not to print the result. The terminator does not need to be typed on the same line as the rest of the statement, so if you forget it on one line you can type it on the next line. For example:

    > 4+5:

    is a statement to add 4 and 5 but not to print the result. An equivalent statement is:

    > 4+5

    > :

    In this case, after the first line Maple will assume that you have not finished your statement. On seeing the colon on the next line, Maple will realize the statement is finished and evaluate 4+5.

    You can put more than one statement on a line, just as you can break a statement across multiple lines. The requirement is that statements be terminated, not that they fit on a line.

    There are two Maple statements that do not have to be terminated in this way:

  • The quit statement ends your Maple session. This statement does not require termination, so the following three command sequences all have the same result (they return the output from the addition statement and end the Maple session):

    > 4+5;

    > quit

    9

    > 4+5; quit

    9

    > 4+5; quit;

    9

  • The ? form of help request does not require termination. However, this statement form must be on a line by itself and must not be embedded within a statement. The two following examples show mistaken use of the form.

    The first example produces a syntax error; the second example actually works, but prints out the error message noted:

    > 4+5: ?help

    syntax error:

    4+5:?help

    ^

    >

    > 4+

    > ?help

    [a help window appears]

    Error, invalid types in sum

    >

    As shown above, when Maple detects a syntax error it echoes the statement and shows you how far it was along in reading it when it detected the error. It does this by placing a caret (^) below the point in question. The syntax error is generally somewhere in the statement prior to this point. The best way to recover from a syntax error is to type a terminator (:, ;) and Return to ensure that Maple will know that you are trying to enter in a new statement. Then type in a corrected version of the statement that gave you the syntax error.

    Maple has a number of pre-defined global variables. When you choose names for your own variables, you should avoid the predefined ones. They are there to help you control how Maple works. This is discussed further in the section Some Predefined Symbols.


    Comments and Echoing

    Any line or portion of a line beginning with a # is treated as a comment. Comments are ignored in processing. For example:

    > 4+5;#This is an example of a comment

    gives the output:

    9

    Since a comment is not a statement, it does not need to be terminated. It only causes the remaining input on the line to be ignored.

    It is possible to control how much information is echoed in Maple. The echo level can be set with the interface function. An echo level of four causes comments and statements to be echoed. For more information on how to control various user-interface settings, type:

    > ?interface


    Simple Arithmetic

    As you may have determined from some of the examples above, you can use Maple to evaluate arithmetic expressions in the intuitively obvious way:

  • + for addition

  • - for subtraction

  • * for multiplication

  • / for division

    Arithmetic expressions are evaluated according to typical precedence rules, so:

    > 4+2*3;

    10

    because 2*3 is evaluated before the addition. Other useful operators are:

  • ^ or ** for exponentiation (2^3 evaluates to 8)

  • abs(...) for absolute value (abs(-4) evaluates to 4)

  • ! for factorial (3! evaluates to 6)

    One useful aspect of Maple is that it distinguishes rational values from floating-point (pseudo-real) values. Compare these statements:

    > 2/3;

    2/3

    > 2.0/3.0;

    .6666666667

    This gives you the flexibility to choose between approximate or exact answers to many mathematical questions.


    Variables, Equations, and Expressions

    Maple variables are names that generally begin with a letter and are followed by up to 498 alphanumeric or underscore characters; case is significant (eg: x is different from X in Maple). Maple distinguishes between two kinds of variables. A Maple programming variable is a variable that you have assigned a result to, generally with an assignment statement:

    > x := 2 + 5;

    x := 7

    > x;

    7

    The programming variable x now is a label for the result of 2+5.

    The other kind of Maple variable is a mathematical variable or an unassigned variable. These exist in the sense of algebraic unknowns, as in the case of:

    > z := 2+y;

    z := 2 + y

    Here, y is a mathematical variable, and z is a programming variable because an expression has been assigned to it. If we now assign a value to y, y becomes a programming variable, and is no longer an algebraic unknown:

    > y := 5;

    y := 5

    > z;

    7

    An equation is different from an assignment statement. Consider the difference between:

    > a := 2;

    a := 2;

    > b = 2;

    b = 2

    In the first case we are assigning the value 2 to the variable a. In the second case, we are making the assertion that b is in fact already equal to 2. We can evaluate the boolean assertion using the evalb function:

    > # First, see what the value of b is:

    > b;

    b

    > # So b is a mathematical variable. Try the evaluation:

    > evalb(b=2);

    false

    > # Now assign the value 2 to b:

    > b := 2;

    b := 2

    > b;

    2

    > # So b is now a programming variable. Evaluate the assertion again:

    > evalb(b=2);

    true

    > # Now assign the assertion to a (which replaces the old contents of a):

    > a := b = 2;

    a := 2 = 2

    > evalb(a);

    true

    The last part of the example shows that you can assign an expression to a variable. Maple statements are built of zero or more expressions of various types connected in various ways. Thus b=2, and abs(4) are both expressions, while evalb(b=2) is a composite expression built from evalb(...) and b=2. Finally, evalb(b=2) and (c = 3); is a statement, because it is built from (boolean) expressions and is terminated.


    Quotes, Names, and Values

    There are three types of quotes used in Maple: double-quotes ("); backquotes (`); and apostrophes ('). Multiple double-quotes are used to refer to the results of previous statements, for example:

    > z1 := z2 + z3;

    z1 := z2 + z3;

    > a1 := a2 * a3;

    a1 := a2 * a3;

    > " + "";

    a2 a3 + z2 + z3

    Backquotes (left-quotes) are used to construct strings, as in:

    > a := `This is a string`;

    a := This is a string

    > a;

    This is a string

    In the previous section, a mathematical variable was also described as an unassigned variable. Unassigned variables have their own name as their value. This is the default condition for a variable until you assign it a value. To turn an assigned variable (i.e., a programming variable) back into an unassigned variable (i.e., a mathematical variable), you must assign it its own name. As an example:

    > # r hasn't been used, so its an unassigned variable:

    > r;

    r

    > # Now make r an assigned variable:

    > r := 2;

    r := 2

    > r;

    2

    > # Now try to give r its own name:

    > r := r;

    r := 2

    > # That didn't work, because the r on the right side of the assignment

    > # statement was evaluated prior to the assignment. Assign the name

    > # of the variable by delaying evaluation:

    > r := 'r';

    r := r

    > r;

    r

    > # r is now a mathematical variable once more.

    This shows the function of the apostrophe (right-quote). It delays evaluation of an expression.

    Maple generally performs what is called "full evaluation". You have seen an example of this already. Here it is again:

    > z := 2+y;

    z := 2 + y

    > y := 5;

    y := 5

    > z;

    7

    Once "y" had been assigned a value, you didn't have to do anything to tell Maple that "z" could be completely evaluated to a number instead of an algebraic expression. Every time Maple evaluates a statement, it checks to see if it knows any other expressions that could be re-evaluated in light of the new information. An exception to automatic full evaluation is in procedures, which is discussed later.


    Functions

    Maple has a large library of functions for you to use. Syntactically, functions are a type of expression. They have a name, a sequence of zero or more arguments, and they return a value as a result of calling the function. For example:

    > a := -2;

    a := -2

    > abs(a);

    2

    > a;

    -2

    The result of taking the absolute value of "a" is returned as the result of the function abs(...). The variable "a" itself is not modified as a side effect. If you wanted to change the value of the variable, you would use:

    > a := abs(a);

    a := 2

    Functions are a special case of procedures. Later in this document you will learn how to construct your own functions and procedures.


    Basic Types and Conversions

    Maple has a large number of object types. Typical types of numeric values are integer, float (floating-point or pseudo-real), fraction, rational, and boolean. Some of the more complex object types include string, polynom (polynomial expression), series, matrix, vector, set, list, and procedure.

    Integers are expressed as a string of one or more digits with an optional sign, like "-2" or "3870". Rational numbers are a signed ratio of unsigned integers, like "2/3" or "-8/30", and will be simplified by Maple:

    > -8/30;

    -4/15

    Floating point numbers contain an explicit decimal point, and any integer or rational expression that contains such a decimal point will be evaluated as floating point:

    > 2/3;

    2/3

    > 2.0/3.0;

    .6666666667

    Maple has a global variable named "Digits" that you use to control the accuracy of floating-point operations. The initial setting for Digits is 10 but you can change it by assigning it some other value:

    > Digits:=5;

    Digits := 5

    > 2.0/3.0;

    .66667

    > Digits:=10;

    Digits := 10

    > "";

    .66667

    > 2.0/3.0;

    .6666666667

    Notice that the value of Digits does not control the display of floating point values, it controls their calculation. If you calculate something with one value for Digits, then change Digits to a new value, then only future floating-point operations will reflect the change.

    You can perform conversions between various Maple datatypes. One way is to force evaluation of expressions in the type you want. For example to convert a rational expression to floating point, you could use the evalf function:

    > evalf(2/3);

    .6666666667

    > evalf(2/3, 5);

    .66667

    As you can see, evalf also provides a way to temporarily control the accuracy of floating-point calculations. See help('eval') for information on other Maple evaluation functions.

    The second, more general, way to convert between types is to use the convert function. See help('convert') for more information.


    Packages and Libraries

    A Maple "package" is a collection of related functions. An example of a package is linalg, the Maple linear algebra package. To use a package, you initially read it into memory using the with command:

    > with(linalg):

    Warning: new definition for norm

    Warning: new definition for trace

    When Maple loads a package, it checks to see whether any of the new function names will replace an existing function. If so, it gives you a warning. For instance, since linalg has a function to compute the trace of a matrix that is called "trace", which is the same name as the debugging command "trace", a warning was generated. The new function is available for use, but the previous function of the same name is no longer accessible.

    There is a way to avoid this problem if you want access to both functions. The technique will allow you to use a single function of a package without loading the entire package into memory. You use the "long form" to specify the function, libname[funcname](...) where funcname is the function you wish to use, libname is the package it is contained in, and (...) is the argument list.

    A Maple "library" is a collection of packages. The standard Maple library consists of some internally-defined functions, but most of them reside externally on the file system. When you use the readlib command, Maple reads in the definition for the specified function in much the same way that with works for packages. readlib is particularly useful in situations where you have redefined a standard library function.

    For example, when the linalg package was loaded in, the standard trace function became unavailable. To get it back, use:

    > readlib('trace');

    proc(fname) ... end


    Restoring, Saving and Ending Sessions

    During the course of a Maple session, you may have entered in a number of useful expressions and routines that you would like to re-use in future. To avoid retyping them the next time you use Maple, you can save that work in a file by using the save command.

    For example, the following command saves everything you created during the session in a file named "filename.m":

    > save `filename.m`;

    When you specify a filename with the extension ".m", Maple saves your work in "Maple internal format". This is the most useful format for Maple when you restore your work later on. You restore the information with the command:

    > read `filename.m`;

    To save only specific items, or to save and restore information in a human-readable format, read the sections in the First Leaves document entitled "Saving the state of your Maple session" and "Recording results in files in human-readable format".

    Once you have saved your work, you can terminate your Maple session with any of the commands quit, done, or stop.

    Checkpoint. You have now been given a general overview of the basic features and syntax of Maple. Experiment with what you have learned. When you want more information on what Maple can do, continue to read this document.



    Putting Maple to Work


    Simplification

    For the most part, Maple leaves expressions the way you entered them or the way they were created from some computation. However, there are some obvious simplifications that it automatically performs. An example of this would be turning 0 * x into the simpler 0. Other automatic simplifications are described in the document First Leaves, in the section "Automatic simplification".

    There are two reasons why only a limited number of automatic simplifications are performed:

  • Cost: some simplifications, such as the factoring of expressions, can be reasonably time-consuming to perform. The Maple solution to this is to automatically perform only certain low-cost simplifications, but to provide ways of forcing more involved methods.

  • Preference: different users will consider different styles of expression as being simpler. The Maple solution is to provide ways to specify specific simplification techniques.

    The simplify command provides typical expression simplifications. By using simplify(expr, variety) you can control what simplifications are performed:

    > (x^y)^z;

    y z

    (x )

    > simplify((x^y)^z,power);

    (y z)

    x

    See help('simplify') for the various simplification options.

    The expand command forces distribution of multiplication over addition. For instance:

    > f := (x + y) * (x - y);

    f := (x + y) (x - y)

    > expand(f);

    2 2

    x - y

    Since expand turns f into x^2 + y * x - x * y - y^2, the automatic simplifications turn the expression into x^2 - y^2.

    For more information on simplification, see help('simplify'), help('expand'), help('factor'), help('normal'), and the First Leaves section on "Simplification of expressions".


    Some Predefined Symbols

    There are four kinds of symbols that have some form of predefined meaning within Maple:

  • Syntactic parts of the Maple command and programming language. The meanings of these cannot be redefined. ("if" and "quit" are typical examples.)

  • System-supplied functions. These may be redefined, but you will lose the functionality of the system-supplied function. ("solve" and "trace" are typical examples.)

  • Predefined constants and names. Library functions assume that these symbols exist with no assigned value, so errors or incorrect results will usually result if they are redefined. ("I", the complex square root of 1, and "true" are typical examples.)

  • System programming variables. These are used to control computational effects, so they can (cautiously!) be assigned new values. ("Digits" and "printlevel" are typical examples.)

    The global variable "printlevel" is a particularly handy one to know. By setting "printlevel := 0;" you turn off the automatic printing of your commands; setting "printlevel := 1;" is the default behaviour. See help('printlevel') for the effect of other settings.


    Summation

    Maple allows you to specify both definite and indefinite symbolic summations using the sum command:

    > # Be sure that the index variable is a mathematical variable.

    > # If i had a value (say, 3), it would be meaningless to say

    > # something like "sum 3 squared for 3 from 1 to n" when you meant to

    > # say "sum i squared for i from 1 to n":

    > i;

    i

    > # This is an example of a sum over an indefinite (non-negative)

    > # index range:

    > x; # Just to be sure, we want to see if x is a mathematical variable.

    x

    > sum(x^i, i);

    i

    x

    -----

    x - 1

    > # These are examples of definite sums:

    > sum(i, i = -2 .. 5);

    12

    > sum(x**i, i = 0 .. 3);

    2 3

    1 + x + x + x


    Differentiation and Integration

    Differentiation is performed using the diff command:

    > # Take the first-order derivative of an expression w.r.t. x:

    > diff(3*x^2, x);

    6 x

    > # Take higher-order partial derivatives by specifying a sequence

    > # of variables. Derivatives are taken in the same order as the

    > # variable sequence:

    > diff(y * x^2 + y, x, y);

    2 x

    Definite and indefinite integration are performed using the int command, in the same way as described for the sum command:

    > # An example of indefinite integration:

    > int( cos(x), x );

    sin(x)

    > # An example of definite integration:

    > int( x^2, x=0..2 );

    8/3

    > # An example where Maple can't find the solution:

    > int(x^(-2), x=-1..1);

    1

    /

    | 1

    | ---- dx

    | 2

    / x

    -1

    When Maple is unable to find the solution to a problem, it returns a "prettyprinted" version of the original command expression. Sometimes this will be because Maple doesn't know how to solve the problem, but more often it will be because either no solution exists or the original command/query was not posed properly.


    Series

    Maple knows how to generate any finite number of terms of either a Taylor (Laurent) series or an asymptotic series expansion of some expression. The Maple functions are taylor and asympt respectively. You specify the number of terms by specifying the "order of truncation". If the terms up to the x^(n-1) do not make the complete expression, and order term of O(x^n) is added to the end. In the case of the Taylor series, you can specify the point of expansion for the series.

    > # Compute some terms of the Taylor series for cos(z) at z=0:

    > taylor(cos(z),z=0);

    2 4 6

    1 - 1/2 z + 1/24 z + O(z )

    > # The default number of terms in the expansion is controlled by the

    > # global variable Order, which is initially set to 6:

    > Order := 9;

    Order := 9

    > taylor(cos(z),z=0);

    2 4 6 8 9

    1 - 1/2 z + 1/24 z - 1/720 z + 1/40320 z + O(z )

    > # You can also specify the expansion order to taylor(..):

    > taylor(cos(z),z=0,4);

    2 4

    1 - 1/2 z + O(z )

    There is also a series function for a more general method of series expansion. See help('series'), help('taylor'), and help('asympt') for more information on series-expansion facilities.


    Limits

    Maple can compute limits of a limited (no pun intended) range of expressions. The expression in question must be an expression in one variable, and any other symbolic unknowns must be real and nonzero. As with integration, Maple may not be able to find the solution. In this case, the command expression is returned in the same fashion as what happens with integration. Maple will return "undefined" (if the limit doesn't exist) or a range (if the limit solution has a range of values).

    > limit(cos(x+Pi/2)/x,x=0);

    -1

    > limit(sin(1/y^2),y=0);

    -1 .. 1

    > limit(a*cos(x+Pi)/x,x=0);

    undefined


    Solving Equations

    There are many Maple functions for solving systems of different kinds of equations. The simplest and most commonly used of these is solve, which solves algebraic systems of equations:

    > # Solve a single equation with one unknown and one solution:

    > solve(exp(x) = 1);

    0

    > # Solve a single equation with a constant, an unknown, and two solutions:

    > solve(x^2 = a, x);

    1/2 1/2

    a , - a

    > # An expression like "x+y" is implicitely assumed to be equal to 0.

    > # Solve a system of equations simultaneously:

    > solve( {x+y, x*y=b}, {x,y} );

    1/2 1/2 1/2 1/2

    {y = - (- b) , x = (- b) }, {y = (- b) , x = - (- b) }

    The function for solving differential equations is dsolve. For full details on using it, see help('dsolve'). Here is a simple example:

    > deq := diff(y(x),x) + y = 0;

    / d \

    deq := |---- y(x)| + y = 0

    \ dx /

    > dsolve(deq, y(x));

    y(x) = exp(- x) _C1

    As the various solve functions need to specify solution constants, they generate names like "_C1", "_C2", etc.


    Assignment and Substitution

    The function assign is designed to take solution sets of the type produced by solve and actually perform the variable assignments. To show this applied to a previous example:

    > # x and y are mathematical variables:

    > x,y;

    x, y

    > solset := solve({x+y, x*y=b}, {x,y});

    solset :=

    1/2 1/2 1/2 1/2

    {y = - (- b) , x = (- b) }, {y = (- b) , x = - (- b) }

    > # Now assign the first solution to the independent variables:

    > assign(solset[1]); x,y;

    1/2 1/2

    (- b) , - (- b)

    When there is a choice of solutions to assign, and you haven't specified a particular choice by subscripting a particular solution in the set, assign will chose one solution to apply to the independent variables.

    You can make temporary assignments to mathematical variables using the function subs. This allows you to evaluate an expression for a given set of values, without turning the mathematical variables into programming variables. Given that Maple generally applies full evaluation, this is an important feature. By giving subs a sequence of variable bindings and an expression, you can "test" the expression with those values:

    > # z is a programming variable:

    > z;

    z

    > f := cos(z);

    f := cos(z)

    > # Now, to see what f(2) is:

    > subs(z=Pi, f);

    cos(Pi)

    > # Force evaluation to simplify the result:

    > eval(subs(z=Pi, f));

    -1

    > # Now check to see the value of z:

    > z;

    z


    Printing and Plotting Values

    When you give Maple a command, there is generally some form of expression that is the output, or value, of the command. The "prettyprinted" output that you see is created by the Maple function print. There are other forms of output that you can specify. These functions are:

  • lprint: print the expression in a linear format

  • fortran: print the expression according to Fortran 77 syntax

  • eqn: create an eqn version of the expression for the troff document processor

  • latex: generate a LaTeX description for the expression

    Here is an example to show the difference between print and lprint:

    > f := (a*b)/(c*d), c^d:

    > print(f);

    a b d

    ---, c

    c d

    > lprint(f);

    a*b/c/d c**d

    You can also plot expressions in Maple. Two-dimensional plots are generated using the plot command, which works both in tty- and X-sessions. To generate 3-D plots you use the plot3d command, which only works in X-sessions. To utilize the plotting features to the fullest, you may need to understand the basics of writing Maple procedures, but simple plots can be generated without this knowledge. The section "Plotting Functions" in the First Leaves document discusses 3-dimensional plotting of procedures; you can see help('plot') and help('plot3d') for more details.

    Checkpoint. You have now been given a general overview of some of the fundamental techniques of using Maple. Experiment with what you have learned. When you want more information on what Maple can do, continue to read this document.



    Maple Packages

    This is a brief summary of the capabilities of the various Maple packages included in the standard distribution. In each case, you can get more detailed information from within Maple by using ?package-name or help('package-name'); where package-name is the name of the package as it is shown below. You can always use ?packages or help('packages') to see the most up-to-date listing of Maple packages.

    Combinatorial Functions (combinat). This package contains functions to calculate or manipulate various combinatorial values and objects. This ranges from calculation of binomial or fibonacci numbers to generation of subsets and power sets.

    Differential Forms (difforms). The differential forms package is used to extend the basic differentiation and differential-equation-solving capabilities of Maple. Read the help sections on the differential operators "d" and "D" as well as the help on difforms for more information.

    Three-Dimensional Euclidean Geometry (geom3d). This package allows you to define and manipulate three-dimensional objects such as points, lines and line segments, planes, spheres, and tetrahedra. You can use the various functions to determine properties like volume, distance, collinearity, and area.

    Two-Dimensional Euclidean Geometry (geometry). This package is the two-dimensional equivalent of the geom3d package. It allows you to define and manipulate two-dimensional objects such as points, lines, circles, and triangles. There are functions in the package to determine properties like distance, circumferance, diameter, and similarity.

    Grobner Bases (grobner). This package gives you the ability to perform various grobner basis calculations for a given list of polynomial functions, with respect to a given list of variables.

    Permutation and Finitely-Presented Groups (group). This package implements and manipulates permutation groups and finite-presentation groups. Among other things, you can find the centralizer and normalizer for a group, test for group membership, and calculate the order of a group.

    Lie symmetries (liesymm). The Lie Symmetries package is an implementation of the Harrison-Estabrook procedure. This is another package for dealing with differential equations.

    Linear Algebra (linalg). The linear algebra package implements the numerous operations that you can perform on vectors and matrices, including determining eigenvalues and eigenvectors, column and row operations, basis finding, Gaussian elimination, and conversion to various normal/canonical forms. (There is a discussion of this package in the "Linear algebra in Maple; the with function; packages" section of the First Leaves document).

    Boolean logic (logic). The boolean logic package provides additional operations over boolean expressions, conversion to canonical forms, and expression simplification.

    Newman-Penrose Formalism (np). The Newman-Penrose formalism package is another package for dealing with differential operators.

    Number Theory (numtheory). The number theory package provides you with a wide assortment of algebraic operations and tests. In particular, you can generate mersenne primes, calculate modular roots, test primality, and perform integer factorizations.

    Orthogonal Polynomials (orthopoly). This package allows you to generate various kinds of orthogonal polynomials, including Gegenbauer, Hermite, Laguerre, Legendre, Jacobi, and Chebyshev types.

    Graphics Package (plots). The plots package implements a variety of plotting aids in addition to the commands plot and plot3d discussed in this document. For instance, sphereplot lets you plot a 3-dimensional surface in spherical coordinates.

    Formal Power Series (powseries). The formal power series package provides additional combinatorial facilities in Maple. Included are the ability to add, multiply, evaluate, and invert power series. This provides a very powerful combinatorial modelling capability when used in conjunction with standard library functions like op and coeff.

    Projective Geometry (projgeom). The projective geometry package provides additional geometric capabilities. You can find line meetings and intersections, tangents to conics in the complex plane, and test for or generate collinear points.

    Linear Optimization (simplex). The simplex package consists of implementations of routines for linear optimization. In addition to being able to find minimal or maximal solutions, you can also test for solution feasibility and generate the dual of a problem.

    Statistics (stats). The statistics package provides the standard collection of statistical calculations and tests, including linear and multiple regression, t and F tests, and random number generators for various distributions.

    Student Calculus (student). Typically, Maple packages are designed to (where possible) solve problems for you. You give the input or problem description, and Maple gives the output or solution. The student calculus package, on the other hand, is a collection of tools to solve problems in a step-by-step fashion. It is designed to be an instructional aid for a first-year calculus course.

    Total Orders on Names (totorder). The total ordering package helps you test for order between members of an ordered set. You give it the names of the members of a set, and some ordering relations between them, and it then lets you test for order between two arbitrarily-chosen members. For instance, if you tell it that "a<b" and "b<c" via the assume command, you could use the if function to test whether "a<c" with .

    Checkpoint. You have now been given a general overview of the various packages that come with Maple and what they can do. Experiment with ones that provide mathematical facilities that you are familar with. When you want more information on what Maple can do, continue to read this document.



    Advanced Maple


    Manipulating Expressions

    You can examine parts of expressions by using the standard Maple library functions designed to categorize them or to pull them apart: type, whattype, op, and nops are some of those functions.

    To look at the i-th part of an expression, you use op(i, expression), where i evaluates to a non-negative integer.

    Example:

    > e1 := op1 + op2 + op3:

    > e2 := op1 * op2 * sin(op3):

    > op(2, e1);

    op2

    > op(3, e2);

    sin(op3)

    As you can see, the operands of the expression are returned, not the operators that connect them. This is because Maple categorizes expressions into "types". For instance, "a+b+c" is of type "+" and has three operands; "a+b*c" is also of type "+" and has only two operands, one of which is of type "*" and itself has two operands. The whattype function tells you the type of an expression; type is a boolean test that allows you to check for a particular type of expression. For example:

    > whattype(e1);

    +

    > whattype(e2);

    *

    > type(e1+e2, `+`);

    true

    > type(expand(e1*e2),`+`);

    true

    To find out the number of operands in an expression, you use nops(expr).

    For example:

    > expand(e1*e2);

    2 2

    op1 op2 sin(op3) + op1 op2 sin(op3) + op1 op2 sin(op3) op3

    > nops(");

    3


    Sequences, Ranges, Sets, and Lists of Expressions

    A sequence is made from a finite number of expressions that are separated by commas. For instance, "x" is a sequence with one item, and "x, y" is a sequence of two items. The special symbol "NULL" is used to denote the empty sequence. A sequence is a valid type, "exprseq", so whattype and type can be used on it. The arguments that you pass to a function are an example of a sequence.

    Sets and lists are also Maple types. A set is just a sequence of items between "{" and "}" symbols; a list is a sequence of items between "[" and "]" symbols. Their Maple type names are "set" and "list".

    To access particular items of sequences, sets, and lists all you have to do is subscript them:

    > w0 := a1, a2, a3:

    > w0[1];

    a1

    > w1 := {a1, a2, a3};

    w1 := {a3, a2, a1}

    > w1[2];

    a2

    > w2 := [a1,a2,a3];

    w2 := [a1, a2, a3]

    > w2[1..2];

    a1, a2

    The last example uses a "range". A range is valid Maple type and is used to describe a range of values. Unlike sequences, sets, and lists, you can not subscript a range.

    There are a number of operations that work on sequences, sets, and lists. See the Maple help sections on their type names for more information.


    Tables and Arrays

    Maple uses the "table" type for collections of information in a tabular form. It is similar to records or structures found in other programming languages. Each entry has an index and a value; you use the table function to create a table and optionally initialize it. For example:

    > tab := table([key=100, name=joeuser, address=mit]);

    tab := table([

    key = 100

    name = joeuser

    address = mit

    ])

    > tab[name];

    joeuser

    > tab[phone] := `x0-0000`;

    tab[phone] := x0-0000

    > tab;

    tab

    > op(tab);

    table([

    phone = x0-0000

    key = 100

    name = joeuser

    address = mit

    ])

    The example shows that tables are one of Maple's exceptions to the use of full evaluation. Tables, arrays, and procedures use what is referred to as "last name evaluation". In essence, variables access these objects by reference, not by value. To directly access the value (to copy it, for instance), you need to use the op function described earlier.

    An array is much like a table, except that you specify an integer range of subscripts. For example:

    > arr := array(1..2, 1..2);

    arr := array(1 .. 2, 1 .. 2, [])

    > arr[1,1] := 1: arr[2,2] := 2:

    > print(arr);

    [ 1 arr[1, 2] ]

    [ ]

    [ arr[2, 1] 2 ]


    Maple Initialization

    When a Maple session begins, Maple looks for a file in your home directory called ~/.mapleinit and reads it in. This provides you with a convenient way to do things like automatically load in packages that you often use. All you need to do is use a text editor like emacs or ez to create the file ~/.mapleinit. Edit the file and place any Maple commands you want there in the same format that you would enter them interactively.

    Checkpoint. You have now been given a general overview of some of the more advanced non-programming features of Maple. Experiment with what you have learned. When you want more information on what Maple can do, continue to read this document.



    Programming in Maple

    Up until this point, discussion has been focused on only two statement types of the Maple programming language, the "expression statement" and the "assignment statement". We will now examine more complicated and useful forms of programming statements. In each case, we will give an outline of the syntax of the statement, a description of its meaning or effect, and an example of its use. Throughout you should remember that Maple is not a line-oriented language. Placing different parts of the statement on different lines is only done for clarity, not out of necessity.


    Control Structures

    There are four important types of non-procedural statements that affect the flow of control of a program:

  • the for-while loop

  • the if statement

  • the break statement

  • the next statement

    Each of these structures is explained here. There are some other statements that affect flow of control that have either already been introduced (done/quit/stop), or will be dealt with in the sections Procedures and Error Handling.

    For-While

    The two syntactic forms of the for-while statement are:

    for variable from start by change to finish while condition do

    statement-sequence

    od;

    and:

    for variable in expression while condition do

    statement-sequence

    od;

    The statement-sequence is repeated for each distinct value of "variable" while "condition" is true. The "for ...", "from ...", "by ...", "to ...", and "while ..." clauses are all optional. If "from start" or "by change" are not specified, they default to a value of 1.

    In the first case, "variable" is initially assigned the "start" value (so "variable" can be either a mathematical or programming variable prior to use in the loop). With each successive loop if "variable" is less than or equal to "finish" then "variable" is incremented by "change"; if the "while" condition is also true then the statement sequence is repeated. If either the "to" or "while" conditions are false, the loop terminates.

    In the second case, "variable" is successively assigned the component parts of the expression. This form of the for statement is just a more convenient way of expressing something like:

    for variable to nops(expression) while condition do

    statements that use op(variable, expression)

    od;

    Example:

    > printlevel := 0:

    > listsum := 0;

    > for i in [1,2,3,4,5] while i < 5 do

    > listsum := listsum + i;

    > od;

    > listsum;

    10

    > printlevel := 1:

    If

    The syntax of the if statement is:

    if condition then

    statement-sequence

    elif condition then

    statement-sequence

    ...

    elif condition then

    statement-sequence

    else

    statement-sequence

    fi;

    The elif and else portions are optional; there may be more than one elif clause in a row. The (boolean) condition in the if section is evaluated; the corresponding statement-sequence is evaluated if the condition is true. If the condition is false, control passes to the next elif or else clause. If no condition is true and there is no else clause, no action is taken.

    Example:

    > printlevel := 0:

    > for x by 3 to 20 do

    > if isprime(x) then

    > print(x, `is prime`);

    > elif type(x, odd) then

    > print(x, `is odd non-prime`);

    > else

    > print(x, `is even non-prime`);

    > fi;

    > od;

    1, is odd non-prime

    4, is even non-prime

    7, is prime

    10, is even non-prime

    13, is prime

    16, is even non-prime

    19, is prime

    > printlevel := 1:

    Break

    The syntax of the break statement is simply:

    break;

    The break statement is used in for and while loops to terminate iteration of the loop altogether. Flow of control resumes with the statement following the body of the loop.

    Example:

    > printlevel := 0:

    > listsum := 0;

    > for i in [1,2,3,4,5] do

    if i >= 5 then break fi;

    > listsum := listsum + i;

    > od;

    > listsum;

    10

    > printlevel := 1:

    Next

    The syntax of the next statement is simply:

    next;

    The next statement is used in for and while loops to terminate the current iteration of the loop. Flow of control resumes with evaluation of the loop condition.

    Example:

    > printlevel := 0:

    > listsum := 0;

    > for i in [1,2,3,4,5] do

    > if type(i, odd) then

    > next;

    > fi;

    > listsum := listsum + i;

    > od;

    > listsum;

    6

    > printlevel := 1:


    Procedures

    The syntax of the procedure statement is:

    proc (name-sequence)

    local name-sequence;

    options name-sequence;

    statement-sequence;

    end;

    The proc (name-sequence) is the procedure header, and the name-sequence is a formal parameter list. These are the internal variable names for values that you would pass during calls to the procedure. The local name-sequence is an optional clause listing the local variables, and options name-sequence is an optional clause of settings that influence the procedure's behaviour at runtime.

    Maple documentation variously refers to certain routines as being "functions" or "procedures". Syntactically, they are all the same kind of object, and are all implemented using proc. The only difference between functions and procedures is in side-effects. Functions use the values passed as parameters, but otherwise leave those arguments alone. Procedures may treat some of those arguments as variable names, and modify the value that the variable name refers to. This is the same distinction as you find in other programming languages that allow both "pass by value" and "pass by reference" parameters.

    Notice that there is no specification for the name of the procedure. Since procedures are objects that can be assigned to variables, the name of the variable you assign it to is used as the name of procedure. The value of the procedure is the value of the last expression evaluated (though see the section on the RETURN statement, later in this document).

    Example:

    > # Out of curiosity, see if "x" and "y" are mathematical variables:

    > x, y;

    x, y

    > f := proc(x)

    > x^2 + 1;

    > y := x;

    > end;

    f := proc(x) x^2+1 end

    > f(2);

    5

    > x, y;

    x, 2

    In this example, the global variable "x" is not affected by the formal parameter "x", which is local to function "f". The global variable "y" was affected, since it is not a parameter and was not declared as a local variable.

    Local Variables

    When you do not specify local variables in a procedure then all variable references are assumed to be to global variables, except for references to the formal parameters. Specified local variables are hidden from "the outside world", and themselves hide global variables of the same name from "the inside world" of the procedure. Local variables also have one other very important distinction: they are not subject to the default full evaluation. This is because local variables commonly do not require full evaluation, so performance is improved by this exception to the general evaluation scheme.

    Example:

    > # Set value of global "a":

    > a := 0;

    a := 0

    > g := proc(x)

    > local a, b;

    > a := b^2 + x;

    > print(a);

    > b := 2;

    > print(`a:`, a, ` eval a:`, eval(a), ` a:`, a);

    > end:

    > g(2);

    2

    b + 2

    2 2

    a:, b + 2, eval a:, 6, a:, b + 2

    > # So full evaluation doesn't happen to local variable "a", even

    > # if evaluation is called. You'd have to assign the result of

    > # "eval(a)" to "a" to update its value.

    > a;

    0

    > # Just to check, the global variable "a" is not affected by

    > # the local variable "a" in function "g".

    Options

    Options are used to control run-time behaviour of a procedure. The options defined for Maple V are builtin, remember, system, operator, and trace. remember is the one of greatest use to most users. When you use option remember, the values that correspond to particular parameter lists are stored for future use. This way they can be retrieved instead of recalculated, a feature particularly useful for recursive function implementations.

    You can force remember for particular argument values, whether or not option remember has been specified. You simply perform an assignment to the function with the appropriate parameter value. For example:

    > h(2) := 3;

    h(2) := 3

    > h(2);

    3

    This is why it is necessary to use proc to define functions. It is tempting to try syntactic definitions like m(x) := x^2, but what you are really doing is stating something like "the value of function m at the string `x` has the value `x`^2", assuming "x" was a mathematical variable when you entered in the assignment statement. When you try to plot this pseudo-function, you will find that some forms of plotting (like parameterized 3-D plotting) do not work.

    RETURN

    The syntax of the RETURN statement is simply:

    RETURN(value);

    The procedure terminates processing and returns the value specified. If an explicit RETURN(...) does not terminate the procedure, then the value of the procedure is result of the last expression evaluated before the procedure terminated normally.


    Error Handling

    There are three facilities for error handling in Maple: ERROR, lasterror, and traperror.

    ERROR

    The syntax of the ERROR statement is simply:

    ERROR(error-message-string);

    The "ERROR" must be in capital letters. When you use ERROR in procedures to indicate that something has gone wrong, you will see a message printed of the form:

    Error, (in functname) error-message-string

    As is the case with Maple-detected errors, the computation is then interrupted and aborted.

    lasterror and traperror

    The variable lasterror records the most recent kind of ERROR. The function traperror evaluates an expression sequence and returns the value if there were no errors, or lasterror if there was an error. You can use these two features in combination to control error handling yourself instead of just having Maple interrupt and abort processing.


    Plotting Functions You Created

    Now that you have learned how to write Maple functions you can effectively plot 3-dimensional graphs (assuming you are in an X-session). The command is plot3d. You specify a set of functions to plot and the ranges of the independent variables. The functions must satisfy the characteristics described in help('plot3d'), but with some thought you can plot almost any kind of surface in 3-space. You can also give plot options to configure various aspects of the final display. Here is a lengthy example of how to plot parametric functions using plot3d. You can enter it interactively or place the commands in a file and read it in.

    > x1 := proc(tau, theta)

    > (a + b*sin(tau))*cos(theta);

    > end:

    > y1 := proc(tau, theta)

    > (a + b*sin(tau))*sin(theta);

    > end:

    > z1 := proc(tau, theta)

    > b*cos(tau);

    > end:

    > torus1 := [x1,y1,z1]:

    > x2 := proc(tau, theta)

    > a + x1(tau, theta);

    > end:

    > y2 := proc(tau, theta)

    > z1(tau, theta);

    > end:

    > z2 := proc(tau, theta)

    > y1(tau, theta);

    > end:

    > torus2 := [x2, y2, z2]:

    > plotranges := 0..2*Pi, 0..2*Pi:

    > optionseq := scaling=CONSTRAINED, axes=NONE, numpoints=1600:

    > plotboth := 'plot3d({torus1, torus2}, plotranges, optionseq)':

    > a := 10: b := 3:

    > # Now just use "plotboth" to plot the two surfaces

    > plotboth;

    Maple will spend a few minutes calculating all the points for plot, then display the result in a separate window. If you find that the window does not display the graph when it opens, just try moving the window or iconizing and opening it again.

    To print the graph on a postscript printer, just click on the print button on the plotting window. It will open a pop-up dialog that gives you the default file name (plotoutfile) that it will write a postscript-format file to. Move the mouse pointer into this little window and change the filename if you so desire. Then click on the postscript button; after a few moments, Maple will have finished writing a description of your plot to the file.

    To print this file to a postscript printer, from the athena% prompt just use the command:

    athena% lpr -P printername filename

    where printername is the name of a postscript printer near you.


    Creating Packages and Libraries

    A package is just a table of procedures. To create a package, all you need to do is use the procedure name as the table index, and assign the corresponding procedure to that particular table entry. For example, the following command creates the function "successor" within the package "mypackage":

    > mypackage[successor] := proc(n) n+1 end:

    A library is a collection of Maple objects (typically packages) stored on disk. Though the implementation can vary across platforms, on Athena a Maple library is a directory that contains files of source and files in "Maple internal format", otherwise known as ".m" files.

    You need to tell Maple where your libraries will be. This is done with the global variable "_liblist". This variable contains a list of libraries (i.e., directory names) that you want to use in addition to the standard Maple library. Be sure you create the directories first from the athena% prompt before trying to use them in Maple. If you didn't create them before starting Maple, then enter an xterm and use a command like:

    athena% mkdir ~/mylibrary

    athena% mkdir ~/mylibrary/src

    to create the directories for your library and source off of your home directory.

    Example:

    > mylibrary := `/mit/joeuser/mylibrary/`:

    > _liblist := [ mylibrary ]:

    Now to place a package in a library, you need to save it as a ".m" file in one of the libraries (directories) in "_liblist". You should also place the source for package in the "src" subdirectory of the library. We are going to introduce the string concatenation operator to build the path names for the new library:

    Example:

    > save mypackage, `` . mylibrary . `mypackage.m`;

    > save mypackage, `` . mylibrary . `src/mypackage`;

    > # Now, lets see if we can load the package in:

    > with(mypackage);

    [successor]

    The concatenation operator "." takes expressions, evaluates them to strings if possible, then concatenates them together. The only operand that is not evaluated is the leftmost one. This is why the null string `` was used at the beginning of each pathname: we wanted "mylibrary" to be evaluated.


    Debugging

    Maple includes tools to help you debug the programs that you write. You can use the Mint utility to check a Maple source file for suspicious code that might be a source of trouble. To use mint from the athena% prompt, just type:

    mint filename

    Be sure that the file is a source file, not a .m file that is in Maple's own internal format.

    To help you debug programs while they are running, you use the Maple command trace and the global variable "printlevel". By setting "printlevel" to a high value, the values of statements nested in procedures and control structures is displayed, just as you see at the top level for statements you enter interactively. For example:

    > testproc := proc(x) if x > 2 then s := x-1; testproc(s) else x fi; end;

    testproc := proc(x) if 2 < x then s := x-1; testproc(s) else x fi end

    > printlevel := 17:

    > testproc(4);

    > testproc(4);

    --> enter testproc, args = 4

    s := 3

    --> enter testproc, args = 3

    s := 2

    --> enter testproc, args = 2

    <-- exit testproc = 2

    2

    <-- exit testproc = 2

    2

    <-- exit testproc = 2

    2

    > printlevel := 1:

    The trace command is used to selectively trace calls and exits of a particular procedure. You use trace(procname) to turn tracing on for the procedure procname; you use untrace(procname) to disable it. For example:

    > trace(testproc);

    testproc

    > testproc(4);

    --> enter testproc, args = 4

    --> enter testproc, args = 3

    --> enter testproc, args = 2

    2

    <-- exit testproc = 2

    2

    <-- exit testproc = 2

    2

    <-- exit testproc = 2

    2

    > untrace(testproc);

    testproc

    > testproc(4);

    2

    To learn more about debugging in Maple using trace and "printlevel", see help('trace'), help('printlevel'), and the section of the First Leaves document called "Creating and debugging Maple programs". To learn more about Mint you can read the man page (once you've added the maple locker) by typing the following command from the athena% prompt:

    athena% man mint

    Checkpoint. You have now been given a general overview of what Maple can do. Experiment with what you have learned. When you want more specific information on Maple, read the documentation produced by the vendor, including First Leaves and the Maple reference manual(s).