About this document:
By combining this powerful datatyping with the extensive libraries of Maple functions, you can solve problems from any field that requires:
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.
> 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.
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.
>
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.
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.
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.
>
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:
> 4+5;
> quit
9
> 4+5; quit
9
> 4+5; quit;
9
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.
> 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
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:
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.
> 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.
> 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.
> 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.
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.
> 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
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.
There are two reasons why only a limited number of automatic simplifications are performed:
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".
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.
> # 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
> # 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.
> # 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.
> 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
> # 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.
> # 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
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.
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.
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
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.
> 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 ]
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.
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:
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 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
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.
> 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.
> 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.
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).