Information in this document is subject to change without notice and does not
represent a commitment on the part of the vendor. The software described in
this document is furnished under a license agreement and may be used or
copied only in accordance with the agreement. It is against the law to copy the
software on any medium except as specifically allowed in the agreement.
Windows is a registered trademark of Microsoft Corporation.
Java and all Java based marks are trademarks or registered trademarks of Sun
Microsystems, Inc. in the United States and other countries.
Maplesoft is independent of Sun Microsystems, Inc.
All other trademarks are the property of their respective owners.
This document was produced using a special version of Maple that reads and
updates LaTeX files.
This manual describes advanced MapleTMprogramming concepts, including:
• Variable scope, procedures, modules, and packages
• Advanced input and output
• Numerical programming
• Programming with Maple plots
• Connectivity: translating Maple code to other programming lan-
guages, calling external libraries from Maple, and calling Maple code
from external libraries
• Internal representation and manipulation
Audience
This manual provides information for experienced Maple programmers.
You should be familiar with the following.
• Maple Online Help Introduction
• Example worksheets
• How to use Maple interactively
• The
Introductory Programming Guide
1
2 • Preface
Worksheet Graphical Interface
You can access the power of the Maple computation engine through a variety of user interfaces: the standard worksheet, the command-line1version,
r
the classic worksheet (not available on Macintosh
), and custom-built
MapletTMapplications. The full Maple system is available through all of
these interfaces. In this manual, any references to the graphical Maple
interface refer to the standard worksheet interface. For more information
on the various interface options, refer to the ?versions help page.
Manual Set
There are three other manuals available for Maple users, the
Maple Get-
ting Started Guide, the Maple User Manual, and the Maple Introductory Programming Guide.
2
• The Maple Getting Started Guide provides extensive information
for new users on using Maple, and the resources available in the software and on the Maplesoft Web site (http://www.maplesoft.com).
• The
Maple User Manual provides an overview of the Maple software
including Document and Worksheet modes, performing computations,
creating plots and animations, creating and using Maplets, creating
mathematical documents, expressions, basic programming information, and basic input and output information.
• The Maple Introductory Programming Guide introduces the basic
Maple programming concepts, such as expressions, data structures,
looping and decision mechanisms, procedures, input and output, debugging, and the Maplet User Interface Customization System.
The Maple software also has an online help system. The Maple help system allows you to search in many ways and is always available. There are
also examples that you can copy, paste, and execute immediately.
1
The command-line version provides optimum performance. However, the worksheet
interface is easier to use and renders typeset, editable math output and higher quality
plots.
2
The Student Edition does not include the Maple Introductory Programming Guide
and the Maple Advanced Programming Guide. These programming guides can be pur-
chased from school and specialty bookstores or directly from Maplesoft.
Conventions •3
Conventions
This manual uses the following typographical conventions.
• courier font - Maple command, package name, and option name
• bold roman font - dialog, menu, and text field
italics - new or important concept, option name in a list, and manual
•
titles
• Note - additional information relevant to the section
• Important - information that must be read and followed
Customer Feedback
Maplesoft welcomes your feedback. For suggestions and comments related
to this and other manuals, email doc@maplesoft.com
.
4 • Preface
1Procedures, Variables,
and Extending Maple
Prerequisite Knowledge
Before reading this chapter, you must have an understanding of Maple
evaluation rules for variables and parameters as described in chapter 6 of
Introductory Programming Guide.
the
In This Chapter
Nested ProceduresYou can define a Maple procedure within another
Maple procedure.
Procedures That Return ProceduresYou can create procedures that
return procedures by using Maple evaluation rules.
Local VariablesLocal variables can exist after the procedure which created them has exited. This feature allows a procedure to return a procedure. The new procedure requires a unique place to store information.
Interactive InputYou can write interactive procedures, querying the
user for missing information or creating an interactive tutorial or a test.
Extending MapleThe Maple software includes useful mechanisms for
extending Maple functionality, which reduce the need to write specialpurpose procedures. Several Maple commands can be extended.
1.1Nested Procedures
You can define a Maple procedure inside another Maple procedure. Some
Maple commands are very useful inside a procedure. In the worksheet
5
6 • Chapter 1: Procedures, Variables, and Extending Maple
environment, the map command is used to apply an operation to the
elements of a structure. For example, you can divide each element of a
list by a number, such as 8.
>
lst := [8, 4, 2, 16]:
>
map( x->x/8, lst);
1
1
,
[1,
, 2]
2
4
Consider a variation on the map command, which appears in the fol-
lowing procedure.
ExampleThis new procedure divides each element of a list by the first
element of that list.
>
nest := proc(x::list)
>
local v;
>
v := x[1];
>
map( y -> y/v, x );
>
end proc:
>
nest(lst);
1
1
,
[1,
, 2]
2
4
The procedure nest contains a second procedure, map, which in this
case is the Maple command map. Maple applies its lexical scoping rules,
which declare the v within the call to map as the same v as in the outer
procedure, nest.
Scoping Rules
This section explains Maple scoping rules. You will learn how Maple determines which variables are local to a procedure and which are global.
You must have a basic understanding of Maple evaluation rules for parameters, and for local and global variables. For more information, refer
to chapter 6 of the
Introductory Programming Guide.
Local Versus Global Variables
In general, when writing a procedure, you should explicitly declare which
variables are global and which are local. Declaring the scope of the variables makes your procedure easier to read and debug. However, sometimes
declaring the variables is not the best method. In the previous nest procedure, the variable in the map command is defined by the surrounding
1.1 Nested Procedures• 7
procedure. What happens if you define this variable, v, as local to the
invocation of the procedure within map?
>
nest2 := proc(x::list)
>
local v;
>
v := x[1];
>
map( proc(y) local v; y/v; end, x );
>
end proc:
>
nest2(lst);
4
2
8
,
[
v
16
,
,
v
]
v
v
The nest2 procedure produces different results. When the variables
are declared in the inner procedure, the proper values from the enclosing
procedure are not used. Either a variable is local to a procedure and
certain procedures that are completely within it, or it is global to the
entire Maple session.
RuleMaple determines whether a variable is local or global, from the
inside procedure to the outside procedure. The name of the variable is
searched for among:
1. Parameters of the inner procedure
2. Local declarations and global declarations of the inner procedure
3. Parameters of the outside procedure
4. Local and global declarations of the outside procedure
5. Implicitly declared local variables of any surrounding procedure(s)
If found, that specifies the binding of the variable.
If, using the above rule, Maple cannot determine whether a variable
is global or local, the following default decisions are made.
• If a variable appears on the
left side of an explicit assignment or as
the controlling variable of a for loop, Maple regards the variable as
local.
• Otherwise, Maple regards the variable as global to the whole session.
In particular, Maple assumes by default that the variables you pass as
arguments to other procedures, which may set their values, are global.
8 • Chapter 1: Procedures, Variables, and Extending Maple
The Quick-Sort Algorithm
Sorting a few numbers is quick using any method, but sorting large
amounts of data can be very time consuming; thus, finding efficient methods is important.
The following quick-sort algorithm is a classic algorithm. The key to
understanding this algorithm is to understand the operation of partitioning. This involves choosing any one number from the array that you are
about to sort. Then, you reposition the numbers in the array that are less
than the number that you chose to one end of the array and reposition
numbers that are greater to the other end. Lastly, you insert the chosen
number between these two groups.
At the end of the partitioning, you have not yet entirely sorted the
array, because the numbers less than or greater than the one you chose
may still be in their original order. This procedure divides the array into
two smaller arrays which are easier to sort than the original larger one.
The partitioning operation has thus made the work of sorting much easier. You can bring the array one step closer in the sorting process by
partitioning each of the two smaller arrays. This operation produces four
smaller arrays. You sort the entire array by repeatedly partitioning the
smaller arrays.
Example
The partition procedure uses an array to store the list because you can
change the elements of an array directly. Thus, you can sort the array in
place and not waste any space generating extra copies.
The quicksort procedure is easier to understand if you look at the
procedure partition in isolation first. This procedure accepts an array
of numbers and two integers. The two integers are element numbers of the
array, indicating the portion of the array to partition. While you could
possibly choose any of the numbers in the array to partition around, this
procedure chooses the last element of the section of the array for that
purpose, namely A[n]. The intentional omission of global and local
statements shows which variables Maple recognizes as local and which
are global by default. It is recommended, however, that you not make
this omission in your procedures.
>
partition := proc(A::array(1, numeric),
>
>
>
>
>
>
i := m;
j := n;
x := A[j];
while i<j do
if A[i]>x then
m::posint, n::posint)
1.1 Nested Procedures• 9
>
>
>
>
>
>
>
>
>
>
Warning, ‘i‘ is implicitly declared local to procedure
‘partition‘
Warning, ‘j‘ is implicitly declared local to procedure
‘partition‘
Warning, ‘x‘ is implicitly declared local to procedure
‘partition‘
end do;
A[j] := x;
eval(A);
end proc:
A[j] := A[i];
j := j-1;
A[i] := A[j];
else
i := i+1;
end if;
Maple declares i, j, and x local because the partition procedure con-
tains explicit assignments to those variables. The partition procedure
also assigns explicitly to A, but A is a parameter, not a local variable.
Because you do not assign to the name eval, Maple makes it the global
name which refers to the eval command.
After partitioning the array a in the following, all the elements less
than 3 precede 3 but they are in no particular order; similarly, the elements
larger than 3 come after 3.
>
a := array( [2,4,1,5,3] );
a := [2, 4, 1, 5, 3]
>
partition( a, 1, 5);
[2, 1, 3, 5, 4]
The partition procedure modifies its first argument, changing a.
>
eval(a);
[2, 1, 3, 5, 4]
The final step in assembling the quicksort procedure is to insert
the partition procedure within an outer procedure. The outer procedure first defines the partition subprocedure, then partitions the array.
In general, avoid inserting one procedure in another. However, you will
10 •Chapter 1: Procedures, Variables, and Extending Maple
encounter situations in following sections of this chapter in which it is necessary to nest procedures. Since the next step is to partition each of the
two subarrays by calling quicksort recursively, partition must return
the location of the element which divides the partition.
ExampleThis example illustrates the role of nested procedures. The
outer procedure, quicksort, contains the inner procedure, partition.
>
quicksort := proc(A::array(1, numeric),
>
>
local partition, p;
>
>
partition := proc(m,n)
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
end proc:
i := m;
j := n;
x := A[j];
while i<j do
if A[i]>x then
A[j] := A[i];
j := j-1;
A[i] := A[j];
else
i := i+1;
end if;
end do;
A[j] := x;
p := j;
end proc:
if m<n then# if m>=n there is nothing to do
p:=partition(m, n);
quicksort(A, m, p-1);
quicksort(A, p+1, n);
end if;
eval(A);
m::integer, n::integer)
Warning, ‘i‘ is implicitly declared local to procedure
‘partition‘
Warning, ‘j‘ is implicitly declared local to procedure
‘partition‘
Warning, ‘x‘ is implicitly declared local to procedure
‘partition‘
>
a := array( [2,4,1,5,3] );
a := [2, 4, 1, 5, 3]
1.1 Nested Procedures• 11
>
quicksort( a, 1, 5);
[1, 2, 3, 4, 5]
>
eval(a);
[1, 2, 3, 4, 5]
Maple determines that the A and p variables in the partition subprocedure are defined by the parameter and local variable (respectively)
from the outer quicksort procedure and everything works as planned.
The variable A can be passed as a parameter to the partition subprocedure (as in the stand-alone partition procedure). However, A does not
need to be passed because, by using Maple scoping rules, it is available
to the inner procedure.
Creating a Uniform Random Number Generator
If you want to use Maple to simulate physical experiments, you likely
need a random number generator. The uniform distribution is particularly simple: any real number in a given range is equally likely. Thus, a
uniform random number generator is a procedure that returns a random floating-p oint number within a certain range. This section develops
the procedure, uniform, which creates uniform random number generators.
The rand command generates a procedure which returns random
. For example, rand(4..7) generates a procedure that returns ran-
The uniform procedure is similar to rand but returns floating-point
numbers rather than integers. You can use rand to generate random
floating-point numbers between 4 and 7 by multiplying and dividing by
10^Digits.
>
f := rand( 4*10^Digits..7*10^Digits ) / 10^Digits:
>
f();
12 •Chapter 1: Procedures, Variables, and Extending Maple
9482484381
2000000000
The procedure f returns fractions rather than floating-point numbers
so you must compose it with evalf; that is, use evalf(f()). Alternatively, you can perform this operation by using the Maple composition
operator, @.
>
(evalf @ f)();
5.709873593
The following uniform procedure uses evalf to evaluate the constants
in the range specification, r, to floating-point numbers, the map command
to multiply both endpoints of the range by 10^Digits, and round to
round the results to integers.
>
uniform := proc( r::constant..constant )
>
local intrange, f;
>
intrange := map( x -> round(x*10^Digits), evalf(r) );
>
f := rand( intrange );
>
(evalf @ eval(f)) / 10^Digits;
>
end proc:
You can now generate random floating-point numbers between 4
and 7.
The uniform procedure has a serious flaw: uniform uses the current
value of Digits to construct intrange; thus, U depends on the value of
Digits when uniform creates it. On the other hand, the evalf command
within U uses the value of Digits that is current when you invoke U. These
two values are not always identical.
1.1 Nested Procedures• 13
>
U := uniform( cos(2)..sin(1) ):
>
Digits := 15:
>
seq( U(), i=1..8 );
0.440299060400000, 0.366354657300000,
0.0671154810000000, 0.224056281100000,
−0.131130435700000, 0.496918815000000,
0.464843910000000, 0.458498021000000
The proper design choice here is that U should depend only on the
value of Digits when you invoke U. The following version of uniform
accomplishes this by placing the entire computation inside the procedure
that uniform returns.
>
uniform := proc( r::constant..constant )
>
>
proc()
>
>
>
>
>
>
>
end proc:
local intrange, f;
intrange := map( x -> round(x*10^Digits),
evalf(r) );
f := rand( intrange );
evalf( f()/10^Digits );
end proc;
The r within the inner proc is not declared as local or global, so it
becomes the same r as the parameter to the outer proc.
The procedure that uniform generates is now independent of the value
of Digits at the time you invoke uniform.
>
U := uniform( cos(2)..sin(1) ):
>
Digits := 15:
>
seq( U(), i=1..8 );
−0.0785475551312100, 0.129118535641837,
−0.153402552054527, 0.469410168730666,
0.0284411444410350, −0.136140726546643,
−0.156491822876214, 0.0848249080831220
Note:The interface variable displayprecision controls the number of
decimal places to be displayed. The default value is −1, representing full
precision as determined by the Digits environment variable. This simplifies display without introducing round-off error. For more information,
refer to ?interface.
14 •Chapter 1: Procedures, Variables, and Extending Maple
SummaryThis section introduced:
• Rules Maple uses to distinguish global and local variables
• Principal implications of these rules
• Tools available for writing nested procedures
1.2Procedures That Return Procedures
Some of the standard Maple commands return procedures. For example,
rand returns a procedure which in turn produces randomly chosen integers from a specified range. The dsolve function with the type=numeric
option returns a procedure which supplies a numeric estimate of the solution to a differential equation.
You can write procedures that return procedures. This section discusses how values are passed from the outer procedure to the inner procedure.
Conveying Values
The following example demonstrates how locating the roots of a function
by using Newton’s method can be implemented in a procedure.
Creating a Newton Iteration
Use Newton’s method to find the roots of a function.
1. Choose a point on the x-axis that you think might be close to a root.
2. Find the slope of the curve at the point you chose.
3. Draw the tangent to the curve at that point and observe where the
tangent intersects the x-axis. For most functions, this second point is
closer to the real root than your initial guess. To find the root, use
the new point as a new guess and keep drawing tangents and finding
new points.
1.2 Pro cedures That Return Procedures•15
2
1.5
1
0.5
–0.5
0
–1
1234
x1x0
5
x
7
6
8
To find a numerical solution to the equation f (x) = 0, guess an ap-
proximate solution, x0, and then generate a sequence of approximations
using:
1. Newton’s method
2. The following formulation of the previous process
x
k+1
= xk−
f (xk)
f0(xk)
You can implement this algorithm on a computer in a number of ways.
Example 1
The following procedure takes a function and creates a new procedure,
which takes an initial guess and, for that particular function, generates
the next guess. The new procedure does not work for other functions. To
find the roots of a new function, use MakeIteration to generate a new
guess-generating procedure. The unapply command turns an expression
into a procedure.
>
MakeIteration := proc( expr::algebraic, x::name )
>
local iteration;
>
iteration := x - expr/diff(expr, x);
>
unapply(iteration, x);
>
end proc:
The procedure returned by the MakeIteration procedure maps the
name x to the expression assigned to the iteration.
Test the procedure on the expression x − 2
>
expr := x - 2*sqrt(x);
√
x.
16 •Chapter 1: Procedures, Variables, and Extending Maple
expr := x − 2√x
>
Newton := MakeIteration( expr, x);
Newton := x → x −
x − 2√x
1
√
1 −
x
Newton returns the solution, x = 4 after a few iterations.
>
x0 := 2.0;
x0 := 2.0
>
to 4 do x0 := Newton(x0);end do;
x0 := 4.828427124
x0 := 4.032533198
x0 := 4.000065353
x0 := 4.000000000
Example 2
The MakeIteration procedure requires its first argument to be an algebraic expression. You can also write a version of MakeIteration that
works on functions. Since the following MakeIteration procedure recognizes the parameter f as a procedure, you must use the eval command
to evaluate it fully.
>
MakeIteration := proc( f::procedure )
>
(x->x) - eval(f) / D(eval(f));
>
end proc:
>
g := x -> x - cos(x);
g := x → x − cos(x)
>
SirIsaac := MakeIteration( g );
SirIsaac := (x → x) −
x → x − cos(x)
x → 1 + sin(x)
1.2 Pro cedures That Return Procedures•17
Note that SirIsaac is independent of the name g. Thus, you can
change g without breaking SirIsaac. You can find a go od approximate
solution to x − cos(x) = 0 in a few iterations.
>
x0 := 1.0;
x0 := 1.0
>
to 4 do x0 := SirIsaac(x0) end do;
x0 := 0.7503638679
x0 := 0.7391128909
x0 := 0.7390851334
x0 := 0.7390851332
A Shift Operator
Consider the problem of writing a procedure that takes a function, f , as
input and returns a function, g, such that g(x) = f (x + 1). You can write
such a procedure in the following manner.
>
shift := (f::procedure) -> ( x->f(x+1) ):
Try performing a shift on sin(x).
>
shift(sin);
x → sin(x + 1)
Maple lexical scoping rules declare the f within the inner procedure
to be the same f as the parameter within the outer procedure. Therefore,
the shift command works as written.
The previous example of shift works with univariate functions but
it does not work with functions of two or more variables.
>
h := (x,y) -> x*y;
h := (x, y) → x y
>
hh := shift(h);
18 •Chapter 1: Procedures, Variables, and Extending Maple
hh := x → h(x + 1)
>
hh(x,y);
Error, (in h) h uses a 2nd argument, y, which is
missing
Multivariate FunctionsTo modify shift to work with multivariate
functions, rewrite it to accept the additional parameters.
In a procedure, args is the sequence of actual parameters, and
args[2..-1] is the sequence of actual parameters except the first one.
For more information on the selection operation ([ ]), refer to chapter 4
of the
Introductory Programming Guide. It follows that the procedure
x->f(x+1,args[2..-1]) passes all its arguments except the first directly
to f .
The function hh depends on h; if you change h, you implicitly change
hh;
>
h := (x,y,z) -> y*z^2/x;
2
y z
x
2
>
hh(x,y,z);
h := (x, y, z) →
y z
x + 1
1.3 Lo cal Variables and Invoking Procedures •19
1.3Local Variables and Invoking Procedures
Local variables are local to a procedure and to an invocation of that
procedure. Calling a procedure creates and uses new local variables each
time. If you invoke the same procedure twice, the local variables it uses
the second time are distinct from those it used the first time.
Local variables do not necessarily disappear when the procedure exits.
You can write procedures which return a local variable, either explicitly or
implicitly, to the interactive session, where it can exist indefinitely. These
variables are called escaped local variables. This concept can be confusing,
particularly since they can have the same name as global variables, or local
variables which another procedure or a different call to the same procedure
created. You can create many distinct variables with the same name.
Example 1
The following procedure creates a new local variable, a, and then returns
this new variable.
>
make_a := proc()
>
>
>
end proc;
local a;
a;
make_a := proc() local a; a end proc
By using local variables, you can produce displays that Maple would
otherwise simplify. For example, in Maple, a set contains
unique elements.
The following demonstrates that each variable a that make_a returns is
unique.
>
test := { a, a, a };
test := {a}
>
test := test union { make_a() };
test := {a, a}
>
test := test union { ’make_a’()$5 };
test := {a, a, a, a, a, a, a}
20 •Chapter 1: Procedures, Variables, and Extending Maple
This demonstrates that Maple identities consist of more than names.
Important:Independent of the number of variables you create with
the same name, when you type a name in an interactive session, Maple
interprets that name to be a global variable . You can easily find the
global a in the previous set test.
>
seq( evalb(i=a), i=test);
true, false , false, false , false, false , false
Example 2
You can display expressions that Maple would ordinarily simplify automatically. For example, Maple automatically simplifies the expression
a + a to 2a. It is difficult to display the equation a + a = 2a. To display
such an equation, use the procedure make_a from Example 1.
>
a + make_a() = 2*a;
a + a = 2 a
When you type a name in an interactive session, the Maple program
interprets it as the global variable. While this prevents you from using
the assignment
statement to directly assign a value to an escaped local
variable, it does not prevent you from using the assign command. You
must write a Maple expression which extracts the variable. For example,
in the previous equation, you can extract the local variable a by removing
the global a from the left side of the equation.
>
eqn := %;
eqn := a + a = 2 a
>
another_a := remove( x->evalb(x=a), lhs(eqn) );
another_a := a
You can then assign the global name a to this extracted variable and
verify the equation.
Loading...
+ 422 hidden pages
You need points to download manuals.
1 point = 1 manual.
You can buy points or you can get point for every manual you upload.