Maple Programming Guide[001-200]
Maple Programming Guide[001-200]
L. Bernardin
P. Chin
P. DeMarco
K. O. Geddes
D. E. G. Hare
K. M. Heal
G. Labahn
J. P. May
J. McCarron
M. B. Monagan
D. Ohashi
S. M. Vorkoetter
Adobe and Acrobat are either registered trademarks or trademarks of Adobe Systems Incorporated in the United
States and/or other countries.
ISBN 978-1-926902-46-3
Contents
Preface ..................................................................................................... xxiii
1 Introduction to Programming in Maple .............................................................. 1
1.1 In This Chapter ...................................................................................... 1
1.2 The Maple Software ................................................................................ 1
The User Interface .................................................................................. 1
The Computation Engine .......................................................................... 1
1.3 Maple Statements ................................................................................... 2
Getting Help .......................................................................................... 2
Displaying a Text String ........................................................................... 2
Performing an Arithmetic Operation ........................................................... 3
Assigning to a Name ............................................................................... 3
Using Maple Library Commands .............................................................. 3
1.4 Procedures ............................................................................................ 4
Defining a Simple Procedure ..................................................................... 4
Entering a Procedure Definition ................................................................. 4
Adding Comments to a Procedure .............................................................. 7
Calling a Procedure ................................................................................. 8
Maple Library Commands, Built-In Commands, and User-Defined Proced-
ures ....................................................................................................... 8
Full Evaluation and Last Name Evaluation .................................................. 9
Viewing Procedure Definitions and Maple Library Code ............................... 10
1.5 Interrupting Computations and Clearing the Internal Memory ........................ 11
Interrupting a Maple Computation ............................................................ 11
Clearing the Maple Internal Memory ........................................................ 11
1.6 Avoiding Common Problems ................................................................... 12
Unexpected End of Statement .................................................................. 12
Missing Operator .................................................................................. 12
Invalid, Wrong Number or Type of Arguments ........................................... 12
Unbalanced Parentheses ......................................................................... 13
Assignment Versus Equality .................................................................... 13
1.7 Exercises ............................................................................................. 14
2 Maple Language Elements ............................................................................ 15
2.1 In This Chapter ..................................................................................... 15
2.2 Character Set ....................................................................................... 15
2.3 Tokens ................................................................................................ 16
Reserved Words .................................................................................... 16
Programming-Language Operators ........................................................... 17
Names ................................................................................................ 20
2.4 Natural Integers .................................................................................... 21
2.5 Strings ................................................................................................ 22
Length of a String ................................................................................. 22
iii
iv • Contents
Substrings ............................................................................................ 22
Searching a String ................................................................................. 23
String Concatenation ............................................................................. 23
Mutability of Strings .............................................................................. 24
Special Characters in Strings ................................................................... 24
Parsing Strings ..................................................................................... 25
Converting Expressions to Strings ............................................................ 26
2.6 Using Special Characters ........................................................................ 26
Token Separators .................................................................................. 26
Blank Spaces, New Lines, Comments, and Continuation ............................... 27
Punctuation Marks ................................................................................ 28
Escape Characters ................................................................................. 31
2.7 Types and Operands .............................................................................. 31
DAGs ................................................................................................. 31
Maple Types ........................................................................................ 32
Operands and op ................................................................................... 34
2.8 Avoiding Common Problems ................................................................... 37
Attempting to Assign to a Protected Name ................................................. 37
Invalid Left-Hand Assignment ................................................................. 38
Incorrect Syntax in Parse ........................................................................ 38
White Space Characters within a Token ..................................................... 38
Incorrect Use of Double and Single Quotes ................................................ 38
Avoid Using Maple Keywords as Names ................................................... 39
2.9 Exercises ............................................................................................. 40
3 Maple Expressions ....................................................................................... 41
3.1 In This Chapter ..................................................................................... 41
3.2 Introduction ......................................................................................... 41
Expressions and Statements .................................................................... 41
Automatic Simplification and Evaluation ................................................... 41
Syntax and Constructors ........................................................................ 41
3.3 Names ................................................................................................ 42
Creating Names: Lexical Conventions ....................................................... 43
3.4 Unevaluated Expressions ........................................................................ 46
Protecting Names and Options ................................................................. 47
Generic Expressions .............................................................................. 48
Pass by Reference ................................................................................. 48
Displaying the Original Command ............................................................ 49
Unassigning Names ............................................................................... 49
Evaluation and Automatic Simplification ................................................... 49
Example: Defining a Procedure That Is Returned Unevaluated ....................... 51
3.5 Numbers ............................................................................................. 53
Integers ............................................................................................... 53
Fractions ............................................................................................. 53
Contents • v
Floats .................................................................................................. 54
Complex Numbers ................................................................................ 58
3.6 Indexed Expressions .............................................................................. 62
3.7 Member Selection ................................................................................. 67
3.8 Functions ............................................................................................ 68
Calls to Procedures ................................................................................ 69
3.9 Arithmetic Expressions .......................................................................... 70
Arithmetic Operators ............................................................................. 70
Noncommutative Multiplication ............................................................... 82
Factorials ............................................................................................. 84
Forming Sums and Products .................................................................... 85
3.10 Boolean and Relational Expressions ........................................................ 86
Boolean Constants ................................................................................. 86
Boolean Operators ................................................................................. 86
Relational Operators .............................................................................. 90
Efficient Boolean Iteration ...................................................................... 93
3.11 Expressions for Data Structures .............................................................. 94
Sequences ............................................................................................ 94
Lists ................................................................................................... 96
Sets .................................................................................................... 98
Tables ................................................................................................. 99
Rectangular Tables .............................................................................. 100
3.12 Set-Theoretic Expressions ................................................................... 101
Membership ....................................................................................... 101
Set Inclusion ....................................................................................... 102
Other Binary Operators for Sets ............................................................. 103
3.13 Other Expressions .............................................................................. 105
Functional Operators ............................................................................ 105
Composition ....................................................................................... 105
Neutral Operators ................................................................................ 107
Ranges .............................................................................................. 107
The Concatenation Operator .................................................................. 110
The Double Colon Operator ................................................................... 111
Series ................................................................................................ 112
3.14 Attributes ......................................................................................... 115
3.15 Using Expressions ............................................................................. 116
Evaluating and Simplifying Expressions .................................................. 116
Substituting Subexpressions .................................................................. 117
Structured Types ................................................................................. 120
3.16 Exercises ......................................................................................... 124
4 Basic Data Structures ................................................................................. 127
4.1 In This Chapter ................................................................................... 127
4.2 Introduction ....................................................................................... 127
vi • Contents
xix
xx • List of Figures
List of Tables
Table 2.1: Special Characters ............................................................................ 15
Table 2.2: Reserved Keywords ......................................................................... 16
Table 2.3: Binary Operators ............................................................................. 17
Table 2.4: Unary Operators .............................................................................. 18
Table 2.5: Element-wise Operators .................................................................... 19
Table 2.6: Token Separators ............................................................................. 28
Table 2.7: Subtype ......................................................................................... 33
Table 3.1: Initially Known Names ..................................................................... 44
Table 5.1: Operators That Can Be Rebound ....................................................... 194
Table 6.1: Procedure Operands ........................................................................ 265
Table 7.1: Floating-Point Contagion Rules ........................................................ 283
Table 11.1: RandomnessTests ......................................................................... 393
Table 14.1: Basic Data Types .......................................................................... 488
Table 14.2: Compound Data Types .................................................................. 489
Table 14.3: Printer Commands ........................................................................ 506
Table 16.1: sieveTest.mpl ............................................................................... 596
Table 16.2: sieveTest2.mpl ............................................................................. 597
Table 16.3: Modified sieveTest2.mpl ................................................................ 598
Table A.1: Maple Structures ........................................................................... 601
xxi
xxii • List of Tables
Preface
Technical computation forms the heart of problem solving in mathematics, engineering,
and science. To help you, Maple™ offers a vast repository of mathematical algorithms
covering a wide range of applications.
At the core of Maple, the symbolic computation engine is second to none in terms of
scalability and performance. Indeed, symbolics was the core focus when Maple was first
conceived at the University of Waterloo in 1980 and to this day Maple continues to be the
benchmark software for symbolic computing.
The Maple user interface allows you to harness all this computational power by using context-
sensitive menus, task templates, and interactive assistants. The first steps are intuitively
easy to use and quickly lead you into the captivating, creative, and dynamic world of Maple.
As you get more proficient, you will want to explore more deeply and directly access all of
the computational power available to you. You can accomplish this through the Maple
programming language. Combining elements from procedural languages (such as Pascal),
functional languages (such as Lisp) and object-oriented languages (such as Java™ ), Maple
provides you with an exceptionally simple yet powerful language to write your own programs.
High-level constructs such as map allow you to express in a single statement what would
take ten lines of code in a language like C.
Maple allows you to quickly focus and reliably solve problems with easy access to over
5000 algorithms and functions developed over 30 years of cutting-edge research and devel-
opment.
Maple's user community is now over two million people. Together we have built large col-
lections of Maple worksheets and Maple programs, much of which is freely available on
the web for you to reuse or learn from. The majority of the mathematical algorithms you
find in Maple today are written in the Maple Programming Language. As a Maple user, you
write programs using the same basic tools that the Maple developers themselves use.
Moreover you can easily view most of the code in the Maple library and you can even extend
the Maple system, tying your programs in with existing functionality.
xxiii
xxiv • Preface
This guide will lead you from your first steps in Maple programming to writing sophisticated
routines and packages, allowing you to tackle problems in mathematics, engineering, and
science effectively and efficiently. You will quickly progress towards proficiency in Maple
programming, allowing you to harness the full power of Maple.
Have fun!
Audience
This guide provides information for users who are new to Maple programming, as well as
experienced Maple programmers. Before reading this guide, you should be familiar with
the following.
• The Maple help system
• How to use Maple interactively
• The Maple User Manual
To display the standard interface, double-click your Maple desktop icon (Windows® and
Macintosh®) or run the xmaple command (UNIX®).
used with a variety of languages including C, C++, Java, Fortran, Visual Basic®, and
C#. For more information about OpenMaple, see OpenMaple (page 472).
• The Maple command-line interface is a console-based application that can be used for
batch processing Maple command files. For more information, see The Maple
Command-line Interface (page 483).
• Maplet™ applications are custom interfaces that are created using the Maple programming
language. For more information, see Programming Interactive Elements (page 453).
For more information about the Maple user interfaces, refer to the Maple User Manual or
the versions help page.
You can also include your code in an external text file to be read by a worksheet or document,
or batch processed. For more information, refer to the file help page.
In document mode, you enter mathematical expressions within document blocks; no Maple
input prompt (>) or execution group boundaries are displayed in the document. You can
use this mode to create professional reports that combine text and typeset math with plots,
images, and other interactive components.
In worksheet mode, you enter mathematical expressions at input prompts, which are displayed
at the start of each input line in a Maple document. When you type an expression and press
Enter, the expression is evaluated and a new input prompt is displayed in the next line. In
both modes, the default format for entering mathematical text is 2-D math notation.
Both modes are equally suitable for creating and running programs in Maple. Select the
mode that suits your preferences and tasks. For more information about both modes, refer
to the worksheet,help,documentsvsworksheets help page.
xxvi • Preface
In 1-D math notation (or Maple input), mathematical text is displayed in a red fixed-width
font that is not typeset.
> int(sin(x),x):
1-D math notation can be used in external text files to write Maple code that can be read
by a worksheet or batch processed. You can enter individual statements in 1-D math notation
or configure Maple to display mathematical input in 1-D math by default in all future Maple
sessions.
Note: While 2-D math is the recommended format for mathematical text and equations
and can be used for short command sequences and procedures, it is generally not recom-
mended for long programs and package definitions.
Most input in this guide is shown in 1-D math notation. To clearly distinguish commands
and input, this guide uses a leading prompt character (>) and all input is entered in worksheet
mode.
For more information on starting Maple, toggling between 1-D and 2-D math notation, and
managing your files, refer to the Maple User Manual or enter ?managing at the Maple
prompt.
Web Resources
• Maplesoft Application Center: The Application Center provides thousands of complete
applications that you can download and use in Maple. For more information, visit
http://www.maplesoft.com/applications.
• MaplePrimes™: MaplePrimes is an online forum where you can search for tips and
techniques, read blogs, and discuss your work in Maple with an active community. For
more information, visit http://www.mapleprimes.com.
• Maplesoft Online Help: Documentation included with Maple is also posted online. The
web version offers the latest updates, Google™-based searching, and an easy way to
provide feedback on help documentation. For more information, visit,
http://www.maplesoft.com/support/help.
Preface • xxvii
• Teacher Resource Center: The Teacher Resource Center provides course content, lecture
notes, demonstrations, and other resources to help teachers incorporate Maple in their
classrooms. For more information, visit http://www.maplesoft.com/TeacherResource.
• Student Resource Center: The Student Resource Center provides online forums, training
videos, and other resources to help students with their work in Maple. For more inform-
ation, visit http://www.maplesoft.com/studentcenter.
Conventions
This guide uses the following typographical conventions.
• bold font - Maple command, package name, option name, dialog box, menu, or text field
• italics - new or important concept
• Note - additional information that is relevant to a concept or 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, contact [email protected].
xxviii • Preface
1 Introduction to Programming in Maple
Maple provides an interactive problem-solving environment, complete with procedures for
performing symbolic, numeric, and graphical computations. At the core of the Maple com-
puter algebra system is a powerful programming language, on which the Maple libraries of
mathematical commands are built.
For more information about the Maple user interface, refer to the Maple User Manual.
The kernel is the core of the Maple computation engine. It contains the essential facilities
required to run and interpret Maple programs, and manage data structures. In this guide,
the kernel commands are referred to as built-in commands.
The Maple kernel also consists of kernel extensions, which are collections of external
compiled libraries that are included in Maple to provide low-level programming functionality.
These libraries include Basic Linear Algebra Subprograms (BLAS), GNU Multiple Precision
(GMP), the NAG® C Library, and the C Linear Algebra PACKage (CLAPACK).
The math library contains most of the Maple commands. It includes functionality for nu-
merous mathematical domains, including calculus, linear algebra, number theory, and
combinatorics. Also, it contains commands for numerous other tasks, including importing
1
2 • 1 Introduction to Programming in Maple
data into Maple, XML processing, graphics, and translating Maple code to other programming
languages.
All library commands are implemented in the high-level Maple programming language, so
they can be viewed and modified by users. By learning the Maple programming language,
you can create custom programs and packages, and extend the Maple library.
Statements in 1-D notation require a trailing semicolon (;) or colon (:). If you enter a state-
ment with a trailing semicolon, for most statements, the result is displayed. If you enter a
statement with a trailing colon, the result is computed but not displayed.
> 2 + 3;
(1.1)
> 2 + 3:
For more information about statements in Maple, see Maple Statements (page 171).
Getting Help
To view a help page for a particular topic, enter a question mark (?) followed by the corres-
ponding topic name. For example, ?procedure displays a help page that describes how to
write a Maple procedure.
For more information about getting help in Maple, refer to the help and HelpGuide help
pages.
This type of Maple statement does not have a trailing colon or semicolon.
Normally, you would create a string as part of another statement, such as an assignment or
an argument for a procedure.
1.3 Maple Statements • 3
For more information about strings in Maple, see Maple Language Elements (page 15).
(1.3)
Assigning to a Name
By naming a calculated result or complicated expression, you can reference it. To assign
to a name, use the assignment operator, :=.
> a := 103993/33102;
(1.4)
> 2 * a;
(1.5)
For more information about names and assignment, see Maple Language Elements (page 15).
You can use the Maple library of commands, introduced in The Computation
Engine (page 1), for many purposes. For example, you can find the derivative of an ex-
pression by using the diff command.
4 • 1 Introduction to Programming in Maple
(1.7)
Note the difference between the names used in these two examples. In the first example, a
is a variable with an assigned value. In the second example, x is a symbol with no assigned
value. Maple can represent and compute with symbolic expressions.
For more information about the Maple library commands, refer to the Maple User Manual
or the help system.
1.4 Procedures
This section introduces the concept of procedures in Maple. For more information about
procedures, see Procedures (page 197).
You can also enter a procedure or any Maple statement on multiple lines. To move the
cursor to the next line as you are entering a multiline statement, hold the Shift key and press
Enter at the end of each line.
Note: This is necessary in the interactive worksheet environment only. If you enter code in
a code edit region, you can simply type the text and press Enter to move the cursor to next
line. For more information on code edit regions, refer to the CodeEditRegion help page.
For more information about using Shift+Enter, see Unexpected End of Statement (page 12).
You can indent lines in a procedure by using the spacebar. After you enter the last line, end
proc;, press Enter.
1.4 Procedures • 5
(1.9)
To run this procedure, enter its name followed by a set of parentheses and a semicolon:
> hello();
(1.10)
(1.11)
This procedure requires one input, x. The procedure computes the approximation of the
value of x divided by 2. When a return statement is not specified, a Maple procedure returns
the result of the last statement that was run. Since evalf(x/2) is the last calculation performed
in the procedure half (in fact, it is the only calculation), the result of that calculation is re-
turned.
The procedure is named half by using the := notation in the same way that you would assign
any other object to a name. After you have named a procedure, you can use it as a command
in the current Maple session. The syntax to run your procedure is the same syntax used to
run a Maple library command: enter the procedure name followed by the input to the pro-
cedure enclosed in parentheses.
> half(2/3);
(1.12)
proc( P )
...
end proc
The letter P indicates the parameters. The body of the procedure is between the proc and
end proc keywords.
Consider the following two statements, which calculate the angle in a right triangle given
the lengths of two sides.
> theta := arcsin(opposite/hypotenuse);
(1.15)
> evalf(180/Pi*theta);
(1.16)
The following example shows a procedure that corresponds to these statements. The proced-
ure definition contains two input parameters for the length of two sides of a right triangle.
> GetAngle := proc( opposite, hypotenuse )
local theta;
theta := arcsin(opposite/hypotenuse);
evalf(180/Pi*theta);
end proc;
(1.17)
When you run the procedure definition, the output shown is the Maple interpretation of this
procedure definition. Examine it carefully and note the following characteristics.
• The name of this procedure (program) is GetAngle. Note that Maple is case-sensitive,
so GetAngle is distinct from getangle.
• The procedure definition starts with proc( opposite, hypotenuse ). The two names in
parentheses indicate the parameters, or inputs, of the procedure.
• Semicolons or colons separate the individual commands of the procedure.
• The local theta; statement declares theta as a local variable. A local variable has meaning
in the procedure definition only. Therefore, if you were to declare another variable called
1.4 Procedures • 7
theta outside of the procedure, that variable would be different from the local variable
theta declared in the procedure and you could use theta as a variable name outside of
the procedure GetAngle without conflict.
For more information about local variables, see Variables in Procedures (page 219).
• Pi is a predefined variable in Maple. Two predefined functions, evalf and arcsin, are used
in the calculation.
• The end proc keywords and a colon or semicolon indicate the end of the procedure.
• As you enter the procedure, the commands of the procedure do not display output. The
procedure definition is displayed as output only after you complete it with end proc and
a semicolon.
• There is no explicit return statement, so the result of calling the procedure is the result
of the last calculation.
• The procedure definition that displays in the output is equivalent to, but not identical to,
the procedure definition you enter. When Maple parses the statement, the commands of
the procedure may be simplified.
To hide the output resulting from a complicated procedure definition, use a colon instead
of a semicolon at the end of the definition.
You can include single line comments anywhere in the procedure. They begin with a pound
character (#). You can also enter multiline comments between (* and *) symbols as shown
in the example above.
Calling a Procedure
Running a procedure is referred to as an invocation or a procedure call. When you invoke
a procedure, Maple runs the statements that form the procedure body one at a time. The
result of the last computed statement within the procedure is returned as the value of the
procedure call.
For example, to run the procedure GetAngle--that is, to cause the statements that form the
procedure to be run in sequence--enter its name followed by parentheses enclosing the inputs,
in this case, two numbers delimited (separated) by commas (,). End the statement with a
semicolon.
> GetAngle(4,5);
(1.18)
Only the result of the last calculation performed within the procedure GetAngle is returned-
-the result of evalf(180/Pi*theta). The assignment theta:=arcsin(opposite/hypotenuse);
is performed, but the statement result is not displayed.
Maple commands are implemented in one of two formats: those written and compiled in
an external language such as C and those written in the Maple programming language.
The commands that are compiled as part of the Maple kernel are referred to as built-in
commands. These are widely used in computations, and are fundamental for implementing
other Maple commands.
For more information about built-in kernel commands, see The Computation
Engine (page 1) and The builtin Option (page 213).
1.4 Procedures • 9
The commands in the Maple library are written in the Maple programming language. These
commands exist as individual commands or as packages of commands. They are accessed
and interpreted by the Maple system as required. The code for the library commands and
the definitions of user-defined procedures can be viewed and modified. However, before
exploring library commands, it is important that you learn about evaluation rules to under-
stand the code.
> e;
(1.20)
This is called full evaluation--each name in the expression is fully evaluated to the last as-
signed expression in any chain of assignments. The following statements further illustrate
how full evaluation works.
> c := b;
(1.21)
> b := a;
(1.22)
> a := 1;
(1.23)
> c;
(1.24)
If you try this approach with a procedure, Maple displays only the name of the procedure
instead of its value (the procedure definition). For example, in the previous section, GetAngle
is defined as a procedure. If you try to view the body of procedure GetAngle by referring
to it by name, the procedure definition is not displayed.
10 • 1 Introduction to Programming in Maple
> GetAngle;
(1.25)
This model of evaluation is called last name evaluation and it hides the procedure details.
There are several reasons for this approach relating to advanced evaluation topics. The most
important concept to understand is that you will only see the name of a procedure when you
reference it by itself or when it is returned unevaluated; you will not see the full procedure
definition. To obtain the value of the name GetAngle, use the eval command, which forces
full evaluation.
Last name evaluation applies to procedures, tables, and modules in Maple. For more inform-
ation, refer to the last_name_eval help page.
> eval(GetAngle);
(1.26)
For example, to view the procedure definition for the Maple least common multiple command,
lcm, enter the following statements.
For more information about interface variables, refer to the interface help page.
> interface(verboseproc = 2):
> print(lcm);
(1.27)
Because the built-in kernel commands are compiled in machine code, and not written in the
Maple language, you cannot view their definitions. If you print the definition of a built-in
procedure, you will see that the procedure has only an option builtin statement and no
visible body.
> print(add);
(1.28)
1.5 Interrupting Computations and Clearing the Internal Memory • 11
Note: Maple may not always respond immediately to an interrupt request if it is performing
a complex computation. You may need to wait a few seconds before the computation stops.
• Click the interrupt icon in the toolbar (in worksheet versions). See Figure 1.1.
Note: For more information on the toolbar icons, refer to the worksheet/reference/Work-
sheetToolbar help page.
• Hold the Ctrl key and press the C key (in UNIX and Windows command-line versions).
• Hold the Command key and press the period key (.) (in Macintosh command-line and
worksheet versions).
To perform a hard interrupt, which stops the computation and exits the Maple session, in
the Windows command-line interface, hold the Ctrl key and press the Break key.
For more information on clearing the Maple internal memory and the restart command,
refer to the restart help page. For more information on the toolbar icons, refer to the work-
sheet/reference/WorksheetToolbar help page.
Maple tracks the use of permanent and temporary objects. Its internal garbage collection
facility places memory that is no longer in use on free lists so it can be used again efficiently
as needed. For more information on garbage collection and the gc command, see Garbage
Collection (page 594).
12 • 1 Introduction to Programming in Maple
Tip: You can use the parse command to find errors in statements, and the Maple debugger
to find errors in programs. For more information on the debugger, see The Maple Debugger:
A Tutorial Example (page 549) or refer to the parse and debugger help pages.
If you press Enter to move the cursor to a new line when you are entering a procedure
definition on multiple lines, the following error is displayed.
> p:=proc()
To prevent this error message from displaying as you enter a procedure definition, hold the
Shift key and press Enter at the end of each line, instead of pressing only Enter.
> p := proc()
"Hello World";
end proc;
(1.29)
Missing Operator
The most common error of this type is omitting the multiplication operator.
> 2 a + b;
You can avoid this error by entering an asterisk (*) to indicate multiplication.
> 2*a + b;
(1.30)
Implicit multiplication, which can be used in 2-D math input, is not valid syntax in 1-D
math input.
> evalf();
Error, invalid input: evalf expects 1 or 2 arguments, but received 0
If such an error occurs, check the appropriate help page for the correct syntax. Enter ?top-
ic_name at the Maple prompt.
The same type of error message is displayed if you call a user-defined procedure, such as
GetAngle, with the wrong number of the arguments.
Unbalanced Parentheses
In complicated expressions or nested commands, it is easy to omit a closing parenthesis.
> {[1,0], [0,1};
The equal sign, =, is used in equality tests or to create equations. Creating an equation is a
valid Maple statement.
> x = y^2+3;
(1.32)
> solve(%,y);
> x;
(1.33)
In the example above, % is a special name that stores the value of the last statement. The
solve command is used to isolate y in the equation defined in the first statement. The first
statement is not an assignment; x remains a symbol with no assigned value.
14 • 1 Introduction to Programming in Maple
You can use the assignment operator, :=, to assign x the value y^2+3. The assignment op-
erator assigns the value of the right-hand side to the left-hand side. After an assignment is
made, the left-hand side can be used in place of the value of the right-hand side. The left-
hand side cannot be a number; it must be a name, indexed name, function call, or sequence
of these values.
> x := y^2+3;
(1.34)
> solve(x,y);
(1.35)
> x;
(1.36)
For more information about equations and Boolean testing, see Boolean and Relational
Expressions (page 86) or refer to the evalb help page. For more information about names
and assignment, see Names (page 42) and Assignments (page 172).
1.7 Exercises
1. Assign the integers 12321, 23432, and 34543 to the names a, b, and c. Use these names
to find the sum and difference of each pair of numbers.
2. Write two procedures. The first requires two inputs and finds their sum. The second re-
quires two inputs and finds their product. Use these procedures to add and multiply pairs
of numbers. How could you use these procedures to add and multiply three numbers?
3. Display your procedure definitions. Are they identical to the code you entered to write
them?
2 Maple Language Elements
Before programming in Maple, it is important to learn the properties and roles of the basic
elements of the Maple language. This chapter introduces some of the main concepts, which
will be described in more detail later in this guide.
There are also 33 special characters, which are listed in Table 2.1. These characters, or
combinations of these characters, have special meanings in the Maple language.
15
16 • 2 Maple Language Elements
These are the only characters used in the Maple language. However, all character types can
be used in names and strings, including international characters. For more information on
how to create names using international characters, see Names (page 20).
Note: When you manipulate a string or determine the length of a string, non-ASCII and
international characters may be counted as more than one byte.
2.3 Tokens
The Maple language combines characters into tokens. The set of tokens consists of reserved
words (also called keywords), programming-language operators, names, strings, and natural
integers.
Reserved Words
Maple keywords are reserved words that have special meanings. Therefore, you cannot
change them or use them as variables in procedures. The keywords are listed in Table 2.2.
You can find information about specific keywords in later chapters of this guide or the help
system.
For more information about reserved words in Maple, refer to the keyword help page.
Keywords Purpose
break, next loop control
if, then, elif, else if statement
for, from, in, by, to, while, do for and while loops
2.3 Tokens • 17
Keywords Purpose
proc, local, global, option, error, return, options, procedures
description
export, module, use modules
end ends structures
assuming assume facility
try, catch, finally exception handling
read, save read and save statements
quit, done, stop ending Maple
union, minus, intersect, subset set operators
and, or, not, xor Boolean operators
implies implication operator
mod modulus operator
Programming-Language Operators
There are two main types of Maple language operators: unary and binary. Simply put, a
unary operator acts on one operand, as in -a, where the operator - is applied to a. A binary
operator acts on two operands, as in a+b, where + is the operator and the operands are a
and b.
The Maple binary and unary operators, and their meanings, are listed in Table 2.3 and Table
2.4. For more information about these operators, refer to the operators,binary and operat-
ors,unary help topics.
Operator Meaning
+ unary plus (prefix)
- unary minus (prefix)
! factorial (postfix)
$ sequence operator (prefix)
not logical not (prefix)
&string neutral operator (prefix)
. decimal point (prefix or postfix)
Most of the unary and binary operators can also be used in element-wise form with objects
that have multiple elements. To perform an element-wise operation, add a trailing tilde (~)
after an operator that has an element-wise form. An element-wise operation allows you to
apply an operation to the elements of a list, set, table, Array, Matrix, or Vector. For example,
compare Matrix multiplication with element-wise multiplication of paired entries in a
Matrix.
> <1,2;3,4> . <2,2;2,2>;
(2.3)
(2.4)
The Maple element-wise operators are listed in Table 2.5. For more information about these
operators, refer to the operators,elementwise help page.
2.3 Tokens • 19
Also, three special nullary operators (also called ditto operators) can be used in interactive
sessions. These are special Maple names that can be used to refer to previously computed
non-NULL expressions.
% last expression
%% second-last expression
%%% third-last expression
While they can be used for simple computations, the ditto operators should be avoided when
writing programs. For results that need to be used in subsequent expressions, assign values
to variables instead.
Note: In a worksheet, the ditto operators do not necessarily reference the results of the
lines located above the execution groups in which they are used. They reference the results
of the most recently performed computations in the Maple session, regardless of the exe-
cution group or document in which they are located. Also, in terms of evaluation, the
ditto operators are treated differently than local variables in a procedure. They are fully
evaluated, which may require more processing than one-level evaluation of local variables.
For more information about local variables, see Local Variables (page 220).
20 • 2 Maple Language Elements
For more information about the ditto operators, refer to the ditto help page.
Names
A name in Maple is a sequence of one or more characters that uniquely identifies a command,
file, variable, or other entity.
The simplest instance of a name consists of a letter followed by a sequence of letters, digits,
and underscores.
> My_Name_1;
(2.5)
If you need to create a name that includes blank spaces or international characters, use left
single quotes (`).
> `A quoted name`;
(2.6)
In general any name that can be formed without left single quotes is identical to the same
name with quotes. For example, x and `x` refer to the same name x. Left single quotes are
similar to double quotes in that double quotes are used to build strings while left single
quotes are used to build names.
Note that the reverse is not true, some names can be formed with left single quotes that are
not identical to expressions typed in without quotes. One example is the name `2`. By putting
quotes around the 2 here, a name is formed instead of a number. Another example is a
quoted keyword, like `module`. To test if an expression is of type module, check type(ex-
pr,`module`). Without the quotes, the Maple parser determines that this is the start of a
module definition and the parser will flag a syntax error.
Characters in Maple are case-sensitive. Therefore, for example, the name Apple is different
from the name apple.
> Apple := 4;
(2.8)
> apple := 5;
(2.9)
2.4 Natural Integers • 21
For example, in the first statement below, y is a name that does not have a value. In the
second statement, the variable x has the value 3.
> 2*y - 1;
(2.11)
> x := 3; x^2 + 1;
(2.12)
You can create an empty name, which has no characters in its spelling.
> type( ``, 'name' );
(2.13)
Early versions of Maple did not have separate types for names and strings. As a result, many
commands for string processing will also accept names and process their characters the
same way. It is generally better to use strings for such processing as strings can never have
assigned values.
For more more information about names, see Names (page 42).
For more information about integers, see Integers (page 53) and Numeric Types in
Maple (page 269).
22 • 2 Maple Language Elements
2.5 Strings
A string is a sequence of characters that evaluates to itself. To create a string, enclose any
sequence of characters in double quotes.
> "This is a string";
(2.15)
In the following sections, strings and string operations are described. For information on
the StringTools package, refer to the StringTools help page.
Length of a String
Use the length command to determine the number of bytes in a string.
> length("What is the length of this string?");
(2.16)
All of the characters between, but excluding, the double quotes are counted. Each blank
space is counted as one character. Non-ASCII characters may be counted as more than one
byte.
The maximum string length is system-dependent and ranges from about 268 million bytes
on 32-bit systems to more than 34 billion bytes on 64-bit systems.
Substrings
You can extract a substring of a string by using a subscripted integer range (also called a
selection operation).
> S := "This is a string";
(2.17)
> S[6];
(2.18)
> S[6..9];
(2.19)
2.5 Strings • 23
Negative numbers in the range count backwards from the end of the string. -2 is the second
last character in the string. Either range endpoint can also be left off to indicate from the
beginning, or to the end.
> S[-6..-1];
(2.20)
> S[11..];
(2.21)
Searching a String
To perform case-sensitive and case-insensitive string searching, use the SearchText and
searchtext commands, respectively.
SearchText( pattern, exprString, range );
searchtext( pattern, exprString, range );
The SearchText command searches for exact matches of pattern in exprString. The
searchtext command performs the same search, but it is case-insensitive. If pattern is found,
Maple returns an integer indicating the position of the first character in pattern in ex-
prString. If the pattern is not found in exprString, 0 is returned.
> SearchText("my s", "This is my string.");
(2.22)
The optional range restricts the search to the specified range. It is equivalent to performing
a search on a substring, and it is useful when the pattern occurs more than once in the string.
> SearchText("is", "This is my string.", 4..-1);
(2.24)
String Concatenation
Strings can be formed through concatenation by using the cat command.
cat( sequence )
Here, the sequence parameter can contain any number of expressions that are separated by
commas.
24 • 2 Maple Language Elements
The cat command is commonly used to concatenate strings with names and integers, and
the result returned has the type (name or string) of the first argument to cat.
> i := 5;
(2.25)
(2.27)
Mutability of Strings
Strings are not mutable objects in Maple. This means that appending text to a string is not
done in-place, but involves allocating new storage for the result and copying the original
text, plus the appended text, into that new space. This is typically not an issue unless you
are incrementally processing large amounts of text. In the latter case, the StringBuffer
command may be useful.
> with(StringTools):
> s := StringBuffer();
(2.28)
(2.29)
> "a\"b";
(2.30)
Similarly, to display a backslash character as one of the characters in a string, enter two
consecutive backslash characters, \\. You must escape the backslash in this manner because
backslash is itself a special character. For more information, see Blank Spaces, New Lines,
Comments, and Continuation (page 27).
> "a\\b";
(2.31)
The special backslash character mentioned above counts as only one character, as demon-
strated by using the length command.
> length((2.31));
(2.32)
Doubling up backslashes is most notable when entering full path names in Maple. For this
situation it is easier to use forward slash instead. Forward slash is recognized as a directory
separator on all platforms including Windows.
Parsing Strings
The parse command accepts any Maple string and parses the string into a Maple expression
as if it had been entered or read from a file.
parse( exprString, option );
The parse command is especially useful when you want to interpret commands typed into
text components inside your Maple document. For more information, see Using the
GetProperty Command to Retrieve Properties (page 457).
Without specifying extra options, the string should contain exactly one Maple expression.
The expression is parsed and returned unevaluated.
> parse("a+b");
(2.33)
> parse("a+b;");
(2.34)
If the string is syntactically incorrect, the parse command displays an error message of the
form incorrect syntax in parse: ... (number).
26 • 2 Maple Language Elements
The number indicates the offset in characters, counted from the beginning of the string, at
which the syntax error was detected.
> parse("a++b");
Error, incorrect syntax in parse: `+` unexpected (near 3rd character
of parsed string)
If the option statement is specified, the string is parsed and evaluated, and then the result
is returned.
> parse("sin(Pi)");
(2.35)
Maple can convert a variety of expressions. For more information about expressions, see
Maple Expressions (page 41). For more information about conversions in Maple, refer to
the convert help page.
> convert(a, 'string');
(2.37)
The white space characters separate tokens, but are not themselves tokens. White space
characters cannot normally be used within a token.
> a: = b;
White space characters can be part of a token in a name or string formed by enclosing a
sequence of characters in left single quotes or double quotes respectively. For more inform-
ation, see White Space Characters within a Token (page 38).
Except in a string, all characters that follow a pound sign "#" on a line are part of a comment.
For information about adding comments in Maple procedures, see Adding Comments to a
Procedure (page 7).
> a := 1 + x + x^2; #This is a comment
(2.41)
Since white space and new line characters are functionally identical, you can continue
statements from line to line, as described in Entering a Procedure Definition (page 4).
> a:= 1 + x +
x^2;
(2.42)
Note: Press Shift+Enter to continue typing on the next line without evaluating the ex-
pression.
To enter a long number or string on multiple lines, use the backslash character (\) as a line
continuation character.
Line continuation functions as follows: if a backslash \ immediately precedes a new line
character, the Maple parser ignores both the backslash and the new line. If a backslash is
in the middle of a line, Maple usually ignores it. For more information about the backslash
character and exceptions to this rule, refer to the backslash help page.
28 • 2 Maple Language Elements
You can use the backslash character to break up a long sequence of digits into groups of
smaller sequences to enhance readability.
> "The input should be either a list of \
variables or a set of variables";
> G:= 0.57721566490153286060\
6512090082402\43104215933593992;
(2.43)
You can also enter long strings by using a continuation character. Maple automatically
concatenates string constants that are on separate lines, so another way to enter a long string
is to close one set of double quotes at the end of a line and enter a new double quote at the
beginning of the next line.
> S:= "This is the start of a long string "
"and this is part of the same string with no line in between";
(2.44)
Punctuation Marks
The punctuation marks that act as token separators are listed in Table 2.6.
> f:=x->x^2;
(2.45)
Basic names do not need to be enclosed in left single quotes. For information on when left
single quotes are necessary, see Names (page 20).
Parentheses
The left and right parentheses group terms in an expression, arguments in a function call,
and parameters in a procedure definition.
> (a+b)*c; cos(Pi);
proc( x, y, z )
x+y+z;
end proc:
(2.50)
30 • 2 Maple Language Elements
The left and right parentheses are also used to select components from certain data structures
(programmer indexing).
Square Brackets
Use the left and right square brackets to form indexed (subscripted) names and to select
components from data structures such as Arrays, tables, and lists. For more information on
selection, see Indexed Expressions (page 62). For more information on mathematical index-
ing and programmer indexing, see Basic Data Access (page 147).
> a[1]; L:=[2,3,5,7]; L[3];
(2.51)
(2.52)
Angle Brackets
The left and right angle brackets (<>) in conjunction with the the comma, semicolon, and/or
vertical bar (|) can be used to create Matrices and Vectors. For more information, refer to
the Matrix and MVshortcut help pages.
> <1,2,3; 4,5,6>;
(2.53)
(2.54)
2.7 Types and Operands • 31
Comma
Use the comma to form an expression sequence. Expression sequences are used to specify
the arguments of a function call or the elements of a list or set.
> sin(Pi), 0, limit(cos(xi)/xi, xi=infinity);
(2.55)
Escape Characters
An escape character indicates that the character that follows the escape character must be
handled in a special manner. The escape characters in Maple are ?, !, #, and \.
? - The question mark character, if it appears as the first non-blank character on a line,
opens the Maple help system. The words following ? on the same line determine the
terms used to display a help page. Use either "," or "/" to separate the words that follow
the question mark character. For more information, refer to the help help page.
! - The exclamation mark character, if it appears as the first non-blank character on a line,
passes the remainder of the line as a command to the host operating system. For more
information, refer to the system and escape help pages.
# and (*, *) - The pound sign character indicates that the characters that follow it on the
line are a comment. The multiline comment characters, (*, and *) indicate the beginning
and end of a comment. For more information, see Adding Comments to a
Procedure (page 7) or refer to the comment help page.
\ - The backslash character is used to continue lines, to group characters in a token, and
introduce control characters. For more information, refer to the backslash help page.
DAGs
All data in Maple is stored as a directed acyclic graph (DAG). An identifying tag for each
DAG indicates what type of data it stores and how it is stored. Names, strings, lists, and
positive and negative integers are examples of some DAG types. For a list of DAG types
and how they are stored in memory, see Internal Representation (page 601). The op command
(short for operand) can often be used to determine the DAG type of the underlying data by
returning the zeroth operand. This only applies to certain data structures where op(0,e),
32 • 2 Maple Language Elements
where e is an expression, is defined as a special case. For more information, see the partic-
ular data structure help page.
> op(0, [1,2,3]);
(2.56)
However, the correspondence is not exact. A notable exception to this is function calls
where the zeroth operand is the function name.
> op(0, f(x));
(2.60)
When names are assigned to data, they act as pointers in other languages. However, for
most purposes, the Maple evaluation rules are such that you can think of them as variables.
If you want to manipulate an assigned name rather than the data assigned to it, you can use
right single quotes (also called unevaluation quotes), which are described in more detail
in Unevaluated Expressions (page 46).
Assigned names that are pointers do not require type declarations as in low-level program-
ming languages. This means that a name a may be assigned an integer and then later assigned
a list without discretion. This system of weak typing means that, when writing robust code,
you must verify types since variables may be assigned any value.
Maple Types
The type facility in Maple is accessed by using the type command. It is a mathematical type
facility; however, some basic types such as integer or list map directly to the type of DAG.
Some types, such as numeric, encapsulate a group of many different kinds of structures
and structured types, such as name^integer, can match a very specific value.
Type checking is important in Maple to decide whether an expression is valid input for
procedure calls and Maple commands. You can use the the type command or the :: operator
2.7 Types and Operands • 33
for type checking. The operator form is primarily used to declare the type of a procedure
parameter. For more information on :: see The Double Colon Operator (page 111). For in-
formation on declaring the type of a procedure parameter, see Procedures (page 197). The
type command has the following syntax.
type( expression, typeName );
If the expression is of type typeName, the type command returns a value of true. Otherwise,
a value of false is returned.
> type([1,2,3], 'list');
(2.62)
The type of any integer is integer. The type command can also interpret many subtypes of
integers, some of which are listed in Table 2.7.
Subtype Meaning
integer[8] 64-bit sized integer
integer[4] 32-bit sized integer
negint negative integer
posint positive integer
nonnegint non-negative integer
nonposint non-positive integer
even even integer
odd odd integer
prime prime number
For more information, refer to the type help page, which also contains a complete list of
types in Maple.
The type facility can also interpret compound or structured types such as list(integer) for a
list of integers or list({negint,prime}) for a list of negative or prime integers.
34 • 2 Maple Language Elements
Operands and op
In addition to providing information about the underlying type, the op command can provide
information about the other operands or parts of a data structure. Most data structures in
Maple can be divided into components. For example, an equation of the form x=y+x can
be divided as follows.
• the operator, =
• the left-hand side, x
• the right-hand side, y+x
To determine the operands and the number of operands in an expression, use the op and
nops commands respectively. These commands have the following basic syntax.
op( i, expression );
nops( expression );
If the optional first argument i to the op command is a positive integer, the ith operand of
expression is returned.
> eq := x=y+x:
> nops(eq);
(2.68)
The op command can also determine the operands of an expression at various levels of a
structure with the following syntax.
op( [i1, i2, ...], expression );
This syntax is equivalent to and more efficient than a nested call to the op command.
> op([2,0], eq);
(2.73)
This hierarchical structure of expressions explains the name DAG. The internal representation
of looks like an infix expression tree. See Figure 2.1
For efficiency, Maple does not store multiple copies of identical objects, so the two x nodes
in the tree can be represented in a picture like the one in Figure 2.2. In Figure 2.1 you see
36 • 2 Maple Language Elements
two "x" nodes in the tree, implying a copy of each "x". Figure 2.2 shows that the same in-
stance of "x" is referred to in both places.
The term directed acyclic graph simply refers to this variation of a tree where nodes may
have multiple parents.
The tree form of an expression can be displayed using the dismantle command.
> dismantle(eq);
EQUATION(3)
NAME(4): x
SUM(5)
NAME(4): y
INTPOS(2): 1
NAME(4): x
INTPOS(2): 1
This model is not exactly what is used in practice but the principle of uniqueness, with respect
to nodes, still applies. Maple uses a more sophisticated internal representation for sums as
described in Internal Representation (page 601). The real structure of the DAG shown in
Figure 2.3.
2.8 Avoiding Common Problems • 37
The next three chapters introduce many of the other types in Maple and describe how to
create and use them in programs.
For more information about protected names, see Protected Names (page 45) or refer to
the protect help page.
> int := 10;
Error, attempting to assign to `int` which is protected. Try declaring
`local int`; see ?protect for details.
38 • 2 Maple Language Elements
For more information about strings, see Strings (page 22) or refer to the string help page.
> "my string" := 10;
The error message indicates the character number (counted from the left double quote)
where the error was detected. In this case, the 6th character (the second minus sign) caused
the error.
The less-than-or-equal operator <= is a token in Maple. Therefore, it cannot contain a space.
> evalb(2 <= 3);
(2.75)
For more information about using quotes, see Punctuation Marks (page 28) or refer to the
quotes help page.
> type((2.76),'string');
(2.77)
To form a name, enclose the expression in left single quotes. Unlike a string, which is dis-
played with double quotes around it, names are usually printed without quotes. The name
in this example only looks like an expression.
> `2 + 3`;
(2.78)
> type((2.78),'name');
(2.79)
> eval(f);
(2.81)
To resolve this issue, select a variable name that is not a Maple keyword.
Note: It is possible to use a Maple keyword as a name by enclosing it in left single quotes.
For example,
> `end` := 2;
(2.82)
> 1 + `end`;
(2.83)
40 • 2 Maple Language Elements
However, this approach is not recommended, since it makes it very likely that errors will
be introduced if, for example, you forget to place back-ticks around keywords. When pos-
sible, avoid using keywords as names.
2.9 Exercises
1. Using Maple operators, do the following:
a Compute the sum of 5434 and 6342.
b Compute the product of 92 and 310.
c Compute the quotient of the result from a) divided by the result from b).
d Create a list containing the numbers from a), b), and c).
e Square each element of the list from d).
2. Create variables named "my quotient" and "my remainder". Use these variables and the
irem command to find the integer quotient and remainder of 12345 divided by 234. Tip:
Because the irem command stores extra results by assigning to the third argument you
will need to make sure the name is passed and not its assigned value. Do this by using
uneval quotes (').
3. Compute 3^(3^98) modulo 7.
4. Concatenate the three strings "int", "(x^2,", and "x)". Parse the resulting string. Evaluate
the parsed string.
5. Determine a random integer between 40 and 100 using the command rand(40..100).
Concatenate this number with the string, "The student's grade is ". Extract the student's
grade from the resulting string.
6. Assign the expressions x^2 and x*x to the names a and b. Find the three operands of a
and b. Compare the results with those returned by using the dismantle command, that
is, dismantle(a) and dismantle(b). The dismantle command displays the internal data
structure used.
3 Maple Expressions
This chapter introduces Maple expressions associated with scalar data structures.
3.2 Introduction
Expressions and Statements
Maple language elements can be classified as either expressions or statements. An expression
is a first-class data element in the Maple language. In other words, expressions can be stored
in data structures, passed as arguments to procedures, and manipulated in various ways;
they are often used to represent mathematical objects. Statements, on the other hand, are
not first-class data elements; they generally describe non-mathematical programming con-
structs and are used to affect the state of Maple.
This chapter describes expressions associated with scalar data structures. For information
about non-scalar data structures, see Basic Data Structures (page 127).
For more information about Maple statements, see Maple Statements (page 171).
41
42 • 3 Maple Expressions
For example, a sum that would normally be entered using the syntax for addition
> a + b + c + d;
(3.1)
With some exceptions (for example, series, lists, sets, and procedures), the name of the
constructor for an expression can be displayed by using the op command with its first argu-
ment equal to 0.
> op( 0, a + b + c + d );
(3.3)
The example above shows that the constructor for the expression a + b + c + d is the com-
mand assigned to the name `+`.
3.3 Names
Names have several purposes in Maple. They can be used to reference algebraic indeterm-
inates, symbols, and variables in your code.
Names (page 20) provided a basic introduction to Maple names. The following section
describes concepts related to names in more detail.
A Maple name can be either global or local, depending on its scope. In this chapter, only
global names are used. A global name is created either by referring to it at the top level of
your program or by declaring it to be global in either a procedure or module definition. For
more information about scope, see Variables in Procedures (page 219).
Two names are the same if they have the same spelling and scope. Maple keeps only one
copy of any name in memory, so in a large expression that includes an indeterminate x,
only one copy of the name x is kept in memory. Each occurrence of x in the expression
refers to the same name x.
The polynomial
> x^3 - 3*x^2 + 3*x - 1;
(3.4)
3.3 Names • 43
contains three occurrences of the name x, but all three point to the same location in memory.
Maple is unique in that names can represent themselves. As a result, you can use names as
algebraic indeterminates, for example, to construct polynomials or other algebraic expres-
sions.
Names can also be used to represent variables in your code. When a name is assigned a
value, that name is associated with another expression and evaluating the name results in
its assigned value being returned. When a name is unassigned, evaluating the name results
in the name itself.
Before using a name on the left side of an assignment, the name has no assigned value.
> b;
(3.6)
When a value is assigned to a name, subsequent evaluation of the name results in its assigned
value.
> a;
(3.7)
For more information about assigning values, see Assignments (page 172).
Environment Variables
Names beginning with an underscore character (_) are reserved for use by the Maple library.
You should not create names that begin with an underscore.
As a special case, any name beginning with the four character sequence "_Env" is treated
as an environment variable.
Environment variables are a special kind of variable in that an assignment to one within a
procedure is automatically unassigned when the procedure has finished running. Therefore,
environment variables only affect subprocedures called from that procedure, unless they
are superseded locally.
44 • 3 Maple Expressions
The following predefined environment variables do not begin with _Env: Testzero, Use-
HardwareFloats, Rounding, %, %%, %%%, Digits, _ans, index/newtable, mod, Order,
printlevel, Normalizer, NumericEventHandlers.
For more information about environment variables, refer to the envvar help page. For more
information about procedures, see Procedures (page 197) or refer to the procedure help
page.
Constants
In addition to keywords, as described in Reserved Words (page 16), Maple has several
predefined constants.
You can display a sequence of all the names that represent symbolic constants in Maple by
using the global variable constants.
> constants;
(3.8)
(3.9)
Maple also has several other special constants. Table 3.1 lists some of them. For more in-
formation, refer to the initialconstants help page.
For more information about constants in Maple, refer to the constant help page.
Protected Names
A protected name has a predefined meaning; you cannot directly assign a value to a protected
name. For example, the names of built-in commands such as sin; utility operations such as
degree; commands such as diff; and type names such as integer and list, are protected
names. An error occurs if you attempt to assign a value to any of these names.
> list := [1,2];
Error, attempting to assign to `list` which is protected. Try
declaring `local list`; see ?protect for details.
The Maple system prevents these names from re-assignment. However, even though it is
not recommended, it is possible to reassign values to these names by first unprotecting them
as illustrated by the following statements.
Note: You can unassign values to Maple system names by entering a restart command or
by ending your Maple session. In general, using the unprotect command to modify Maple
system names is not recommended.
> unprotect(sin);
> sin := "a sin indeed";
(3.10)
As a result, Maple components that rely on the sine function may not work as expected.
> plot( sin, 0..2*Pi, coords=polar );
To prevent values from being assigned to a name, use the protect command.
> mysqr := x -> x^2;
(3.13)
46 • 3 Maple Expressions
where expr is an arbitrary expression. All of the expressions contained within the right
single quotes are not evaluated.
For example, the sin command normally performs the following computations.
> sin( 0.5 );
(3.15)
> sin( Pi / 2 );
(3.16)
To prevent the evaluation of these computations, you can enclose the expressions in right
single quotes (also called unevaluation quotes) as follows.
> 'sin( 0.5 )';
(3.17)
(3.18)
(3.19)
3.4 Unevaluated Expressions • 47
Also, you can enclose subexpressions in unevaluation quotes to prevent certain parts of an
expression from evaluating.
> 'sin( 0.5 )'^2 + cos( 0.5 )^2;
(3.20)
The sections below describe cases in which you may want to delay evaluation.
(3.21)
> a;
(3.22)
> 'a';
(3.23)
This is important when you want to use a variable as a name, regardless of whether it has
an assigned value.
Also, unevaluation quotes can be used to protect options. Names are often used as options
to control the behavior of a command. If the name of that option has been used as a variable,
the command that has been called uses the value of the variable and not the option name as
expected. Unevaluation quotes can be used around option names to protect against this.
> symbolic := 4;
(3.24)
(3.25)
In the next example, an exception is raised because the name of a command option is not
enclosed in unevaluation quotes.
> output := 2:
> CodeGeneration:-C( x^2, output = string );
Error, (in Translate) options [2 = string] not recognized
48 • 3 Maple Expressions
In this example, the best way to use the output option is to quote the name, thus preventing
its evaluation in case the name output has an assigned value.
> CodeGeneration:-C( x^2, 'output' = 'string' );
(3.26)
Tip: It is also recommended that you also use unevaluation quotes for the names of types
and conversions. For more information, see Structured Types (page 120).
For more information on types and conversions, refer to the type and convert help pages.
Generic Expressions
Expressions sometimes describe the operation to take place in a generic sense. For example,
B[i] can be used in certain contexts with unevaluation quotes to denote a generic index into
B. If unevaluation quotes are not used, Maple will try to look up the specific ith element of
B.
> B := <1,2,3,4>;
(3.27)
Pass by Reference
Some commands accept a name as an argument, with the intent that it will be used to store
a result. Unevaluation quotes ensure that the variable name (and not the value assigned to
the variable) is used in the procedure.
> remainder := irem(45,3,'quotient'); quotient;
(3.29)
3.4 Unevaluated Expressions • 49
(3.30)
If quotient is not enclosed in unevaluation quotes, the second call in the above example
raises an exception because 15, the value of quotient, is not a valid third argument to the
irem command.
(3.31)
> v;
(3.32)
Unassigning Names
To reset the value of a name, assign the unevaluated name (its initial value) to the name.
For example,
> x := 2+3;
(3.33)
> x := 'x';
(3.34)
In this example, Maple first simplifies the unevaluated sum '2 + 3' to the expression '5'.
During the evaluation process, Maple "removes" the right single quotes and produces the
numeric result 5.
All unevaluated expressions are of the type uneval. You can use the type command to check
whether an expression is an unevaluated expression.
> type( ''x'', 'uneval' );
(3.36)
In the example above, the first argument to the call to the type command is the name x,
which is enclosed in two sets of unevaluation quotes. The result of evaluating the first argu-
ment is the unevaluated expression 'x' because the evaluation process removes one set of
unevaluation quotes. The resulting expression is therefore of type uneval.
On the other hand, if you enclose the first argument to type in only one set of unevaluation
quotes, the evaluation process removes the only set of unevaluation quotes, leaving the
result as the name x, which is not an unevaluated expression.
> type( 'x', 'uneval' );
(3.37)
In other words, the type command accesses the name x, rather than the unevaluated expres-
sion 'x', since the type command accesses the result of its arguments that have been evaluated.
In the example above quotes were also used around the type name uneval. This provides a
measure of protection just in case the variable name, uneval has an assigned value (which
is unlikely because uneval is protected). During normal function evaluation, each argument,
x and uneval is evaluated. With quotes, 'x' becomes x, and 'uneval' becomes uneval as
seen by the type procedure. Without quotes, x would become the value of x (which may be
the symbol x itself), and uneval would become the value of uneval, which is usually the
symbol uneval itself. Unevaluation quotes make the displayed call robust against cases
where the variable you are using unexpectedly has a value. It is rarely necessary to use this
level of caution in interactive use, but when you write programs, it is a good practice to in-
clude unevaluation quotes to make your code as robust as possible.
Suppose f is not assigned to anything. Since evaluating f does not call a procedure, Maple
returns the unevaluated function call f(a).
3.4 Unevaluated Expressions • 51
> f(a);
(3.38)
Similarly, using uneval quotes around a function evaluation will cause Maple to behave as
if the named function had no value.
> ''sin''(Pi);
(3.39)
> (3.39);
(3.40)
> (3.40);
(3.41)
You will find this facility useful when writing procedures that need to act on the whole
original expression, not the evaluated result.
For more examples and information on unevaluated expressions, refer to the uneval help
page.
The correct calling sequence would be either plot( 'f'(x), x=-10..10), which puts uneval
quotes around f, or plot( f, -10..10), which avoids computing f(x) by omitting the variable
altogether. Remember that arguments in a function call are evaluated first before the called
procedure sees them.
Here, the precursor evaluation of f(x) tries to apply f to the unassigned symbol, x.
> f( x );
Error, (in f) cannot determine if this expression is true or false:
2 < x
The procedure could be rewritten so that it returns unevaluated whenever it encounters ar-
guments that cannot be processed. This trick causes f(x) to evaluate to itself when non-nu-
meric input is passed in.
> f := proc( x )
if type( x, 'numeric' ) then
if x > 0 then
x
else
2
end if
else
'procname( _passed )'
end if
end proc:
The unevaluated expression 'procname( _passed )' returns the full calling sequence unevalu-
ated.
> f( x );
(3.42)
3.5 Numbers
Maple supports computation with exact numerical quantities, as well as approximate com-
putation to arbitrarily high accuracy with floating-point numbers.
Integers
A natural integer is any sequence of one or more decimal digits.
> 12345;
(3.43)
> +42;
(3.46)
You can use the length command to determine the number of digits in an integer.
> 2^42;
(3.47)
Fractions
A rational number (fraction) is the quotient of two integers, where the denominator is always
positive.
For example,
> 2 / 3;
(3.49)
You can enter a fraction in which the numerator and denominator have a common (integer)
factor, but Maple automatically simplifies this to the lowest terms.
> 4 / 6;
(3.50)
(3.51)
You can use the numer and denom commands to extract the numerator and denominator,
respectively, of a fraction.
> numer( 2/3 );
(3.53)
Fractions can also be created by using the Fraction constructor with the numerator and
denominator as arguments.
> Fraction( 2, 3 );
(3.55)
Floats
Maple supports computation with floating-point numbers to arbitrary precision.
3.5 Numbers • 55
> 2.;
(3.57)
> .7;
(3.58)
> -.567;
(3.59)
Or, using exponent form using a suffix containing the letter "e" or "E" followed by an integer
with no spaces between.
> 4e3;
(3.60)
> 2.3e6;
(3.61)
> .2E3;
(3.62)
Observe that spaces are significant. The first example is a difference rather than a float in
exponent form.
> .2e -3;
(3.63)
> .2e-3;
(3.64)
Floats represent numbers of the form s*10^e, where the number s is called the significand
or mantissa of the float, and the number e is called the exponent. The significand is a Maple
integer. Therefore, it is restricted to values that have, at most, the number of digits indicated
by the kernelopts( 'maxdigits') command.
56 • 3 Maple Expressions
The maximum value of the exponent is a platform-dependent quantity whose value may be
queried by using the Maple_floats command.
> Maple_floats( 'MAX_EXP' );
(3.66)
returned by the Maple_floats command. For more information, refer to the Maple_floats
help page.
You can also create software floats by using the constructor SFloat. This constructor accepts
the significand and exponent as arguments, and has the general form
SFloat( m, e )
To extract the significand and exponent of a software float, use the SFloatMantissa and
SFloatExponent commands.
> SFloatMantissa( 2.3 );
(3.69)
The significand and exponent are also the operands of a software float.
> op( 2.3 );
(3.71)
Two software floats are equal if they represent the same number. However, equal floats by
themselves do not need to be the same object in memory.
> evalb( 2.3 = 2.30 );
(3.72)
3.5 Numbers • 57
(3.73)
Observe that the significands (and therefore, also, the exponents) differ in this example.
> SFloatMantissa( 2.3 );
(3.74)
Note that equal floats with different significands inside of two otherwise identical objects
will require something stronger than evalb for comparison. evalb is the implicit comparison
used when evaluating conditionals in if statements.
> evalb( 2.3 + x = 2.30 + x );
(3.76)
Testing the difference of the two expressions, or calling a command to do a deeper compar-
ison may be necessary.
> evalb( (2.3 + x) - (2.30 + x) = 0 );
(3.78)
The names of the constructor SFloat and accessors SFloatMantissa and SFloatExponent
all begin with the letter S. The S stands for "software" because these floating-point numbers
are implemented in software. Maple also supports the floating-point numbers supported by
the underlying hardware, called hardware floats or hfloats. You can create a hardware float
by using the hardware float constructor HFloat.
> HFloat( 24375, -3 );
(3.80)
58 • 3 Maple Expressions
> op( h );
(3.82)
Note, however, that hfloats are binary floating-point numbers, rather than decimal floating-
point numbers. That means that unlike the example above, there is often round-off error
when decimal numbers are converted into hfloats. For more information, see Hardware
Floating-Point Numbers (page 274).
> op( HFloat(2.3) );
(3.83)
The SFloatMantissa and SFloatExponent commands also accept hardware floats as input.
> SFloatMantissa( h );
(3.84)
> SFloatExponent( h );
(3.85)
For more information on floating-point numbers, see Floating-Point Numbers (page 272).
Complex Numbers
where re and im are the real and imaginary parts of the complex number, respectively. If
the expressions re and im are of type extended_numeric; the resulting complex number
will be of type complex( extended_numeric ). (It is not necessary that re and im are reals;
they may be arbitrary algebraic expressions. However, in this case, the result of the syntax
above will generally be an algebraic expression that will not be a complex numeric constant.)
3.5 Numbers • 59
You can also create complex numbers using the Complex constructor. It can be called using
either one or two arguments. The single-argument form has the following syntax.
Complex( expr )
If the argument expr is of type complex, the Complex constructor returns the value of expr.
Otherwise, if expr is of type extended_numeric, the Complex constructor returns expr *
I.
> Complex( 2 ), Complex( 0 ), Complex( 0.0 );
(3.87)
The first argument is interpreted as the real part and the second argument is interpreted as
the imaginary part, of the complex number constructed.
> Complex( 2, 3 ), Complex( 2.1, 3 ), Complex( 0, 0 );
(3.89)
Note that if either of the arguments is a float, the real and imaginary parts of the complex
number created are both of type float.
A complex zero with floating-point real and imaginary components can have four sign
combinations.
> z1 := 0.0 + 0.0*I; z2 := 0.0 - 0.0*I;
z3 := -0.0 - 0.0*I; z4 := -0.0 + 0.0*I;
(3.90)
Similar to 0.0 = -0.0, numerically, these four complex zeros are numerically equivalent.
> evalb( z1 = z2 and z2 = z3 and z3 = z4 );
(3.91)
60 • 3 Maple Expressions
If the arguments re and im are not of type extended_numeric, the Complex constructor is
returned unevaluated.
> Complex( u, v );
(3.92)
It is important to understand that there is a single complex infinity, which is a point on the
Riemann sphere. It can be denoted in different ways:
> inf1 := infinity + infinity * I; inf2 := infinity - infinity * I;
inf3 := -infinity - infinity * I; inf4 := -infinity + infinity *
I;
(3.93)
They are all treated as distinct from the positive and negative real infinities.
To select the real or imaginary part of a complex number, use the Re and Im commands,
respectively.
> Re( 2.3 + sqrt(2)*I );
(3.95)
(3.96)
Note that, for a symbolic expression of the form a + b*I, it is not assumed that a is the real
part and b is the imaginary part. Therefore, the Re and Im commands are not unevaluated
on such input.
3.5 Numbers • 61
However, the evalc command uses special rules for processing complex expressions, in
which any unknown symbol is assumed to be real. Therefore, when the evalc is used, these
expressions are returned as follows.
> evalc( Re( a + b*I ) );
(3.99)
You can change the default name used to input and display the imaginary unit by using the
interface command.
> interface( 'imaginaryunit' = i );
(3.101)
(The previous value is returned.) After calling the command above, the name i is used to
represent the imaginary unit.
> Complex( 2, 3 );
(3.102)
When this command is used, the name i can no longer be used as a program variable. As
an example, the following statements display error messages.
> i := 2;
Error, illegal use of an object as a name
where expr is an arbitrary expression and index represents a sequence of expressions. The
following are examples of indexed expressions.
> 2[ 3, 4 ];
(3.104)
> a[];
(3.105)
> a[ 1 ];
(3.106)
> a[ b ];
(3.107)
> a[ b, c ];
(3.108)
> map[ 2 ];
(3.109)
> [ 1, 2, 3 ][ 2 ..3 ][ 1 ];
(3.110)
Note that the last example above contains a nested (or iterated) indexed expression.
(3.111)
Note that the indices must be enclosed with square brackets in a list.
All or some of the elements of an index sequence can be extracted by using the op command.
The nops command will tell you how many elements are in the index sequence.
3.6 Indexed Expressions • 63
> nops( a[ b, c, d ] );
(3.112)
> op( a[ b, c, d] );
(3.113)
> op( 2, a[ b, c, d ] );
(3.114)
Indexed expressions are often used to perform selection operations. The behavior of a selec-
tion operation depends on the type of expression, expr, and the index sequence given.
If expr is itself a sequence of expressions, the index sequence must evaluate to a positive
integer, an integral range, or the empty sequence. The following are all examples of valid
ways to index a sequence.
> expr := (1,2,3,4);
(3.116)
> expr[ 3 ];
(3.117)
> expr[ 1 .. 3 ];
(3.118)
> expr[];
(3.119)
> expr[ 2 .. 1 ];
The result of evaluating an indexed sequence is a selection of the components of the sequence.
The indexing sequence must represent a valid index or range of indices. Attempting to select
an entry beyond the length of the sequence and will raise an error.
> expr[ 88 ];
Error, invalid subscript selector
Similarly, components of lists, sets, arrays, matrices, and vectors can be selected
64 • 3 Maple Expressions
> L := [1,2,3,4];
(3.120)
> L[ 3 ];
(3.121)
> L[ 1 .. 3 ];
(3.122)
> L[];
(3.123)
> M := <1,2,3;4,5,6>;
(3.124)
> M[2,3];
(3.125)
> M[1..2,1..2];
(3.126)
> S[ 3 ];
(3.128)
Note that, because sets are sorted data structures, the order at construction time may not
match the order stored internally. It is not predictable what color will be returned by the
index used to specify the third entry above. (It may not be green.)
A negative number may be used as an index, which selects elements starting from the end
of the list. Positive and negative indices mixed in a range return an empty selection.
> L[ -1 ];
(3.129)
3.6 Indexed Expressions • 65
> L[ -3 .. -2 ];
(3.130)
> L[ -3 .. 1 ];
(3.131)
Lists can be used as an index to pick out specific entries, such as the first and third entries
of a list, or the four corners of a matrix.
> L[ [1,3] ];
(3.132)
> M[[1,2],[1,3]];
(3.133)
Indexing on arrays, matrices and vectors is very flexible. In the case of these data structures,
round-brackets can also be used to index in a way that is useful to programming. For example,
where M[1] will return the first row of the matrix, M(1) will return the first entry (regardless
of the number of dimensions).
> M[1];
(3.134)
> M(1);
(3.135)
This class of data structures are known as rectangular tables, or "rtables" for short. For more
information on what ways they can be indexed, refer to the rtable_indexing help page.
If expr is a name with no assigned value, the result of evaluating the indexed expression is
an indexed name. In this case, the index can be any sequence of expressions, and if desired,
it is up to your program to define the meaning of the expression.
> aName[ x^2 - 3*x, "a string", anotherName[ 2, b ] ];
(3.136)
A string may be indexed by a positive integer, a positive integral range, or a general sequence.
The indexed string expression evaluates to itself, unless the indexing sequence is an integer
or integral range, in which case, the result is a substring of the indexed string.
66 • 3 Maple Expressions
> "abcde"[ 3 ];
(3.137)
> "abcde"[ 2 .. 4 ];
(3.138)
(3.139)
> "abcde"[];
(3.140)
If expr evaluates to a table, and if the index given is found in the table the expression eval-
uates to the corresponding entry. Otherwise, the indexed expression evaluates to itself.
> t := table( [ a = 1, b = 2, (c,d) = 3 ] );
(3.141)
> t[ a ];
(3.142)
> t[ c, d ];
(3.143)
> t[ u, v ];
(3.144)
If expr evaluates to a module, the index must evaluate to the name of an export of the
module, and then the entire indexed expression evaluates to the value of expr:-index.
> m := module() export e, f := 2; end module:
> m[ e ];
(3.145)
> evalb( e = m[ e ] );
(3.146)
> m[ f ];
(3.147)
3.7 Member Selection • 67
For more information about modules, see Programming with Modules (page 309).
> m:-f;
(3.150)
The first operand, modexpr, must evaluate to a module. The second operand, expname, must
be a literal name; it is not evaluated. If expname is not a name, or is not the name of an export
of the module modexpr, an exception is raised. The syntax m:-e is similar to m[e], in that
they both evaluate module m's export e. The difference is that the index selection form will
evaluate e before resolving the export.
In the second form, the operand name must be a literal name. The expression :-name then
evaluates to the global instance of the name name.
The following example defines, and then immediately calls, a procedure which declares a
local variable t. Since this local variable is never assigned, it evaluates to itself. The call to
the evalb command then compares, on the left-hand side of the equation, the local name t
to the global name t resulting from applying the member selection operator to t. The result
is false because the global name t and the name t local to the procedure are different expres-
sions.
> proc() local t; evalb( t = :-t ) end proc();
(3.151)
For more information on modules and member selection, see Programming with
Modules (page 309).
68 • 3 Maple Expressions
3.8 Functions
A function expression is a Maple expression of the form
expr( sequence )
that contains zero or more expressions in the sequence within the parentheses. It represents
a function call.
> F();
(3.152)
> F( x );
(3.153)
> F( x, y );
(3.154)
> sin( x + y );
(3.155)
(3.160)
can be formed. Note that Maple applies such "operator expressions" to the arguments. @
is the composition operator. For more information on composition of functions, see
Composition (page 105).
It is important to know that Maple computes numeric quantities as applicable operators with
constant values. Therefore, for example, the expression
> 2( x );
(3.161)
(in which unevaluation quotes are used to delay the evaluation process) appears to be a
product. However, this expression is, in fact, a function expression. When permitted to
evaluate fully, the result is the constant value of the operator.
> 2( 3 );
(3.164)
Calls to Procedures
The most important kind of function expression to understand is the case in which the zeroth
operands is a procedure or, more commonly, an expression (typically, as a name) that
evaluates to a procedure.
p( arg1, arg2, ..., argN )
For example, the name sin evaluates to a procedure that computes the mathematical sin
function. A function expression of the form
sin( expr )
computes the sin of its argument expr. This is performed as follows: Maple evaluates the
name sin and finds that it is assigned a procedure. The argument expr is evaluated to produce
a result. That result is then passed to the procedure assigned to the name sin and the result
computed by that procedure for the specific input is returned as the overall value of the
function call sin( expr ).
For information on defining functions and procedures, see Functional Operators (page 105)
and Procedures (page 197).
(3.165)
> u - v;
(3.167)
> +7;
(3.168)
> -42;
(3.169)
A sum resulting from the evaluation of either an addition or subtraction operation is an ex-
pression of type `+`.
3.9 Arithmetic Expressions • 71
The expression u-v has the operands u and -v; that is, it is a sum of the summands u and -
v.
> op( u - v );
(3.171)
Although sums are formed by using the binary operator `+`, they are actually expressions
of arbitrarily large arity (greater than unity). Since addition is associative, Maple "flattens"
all sums of more than two summands during the automatic simplification process. Therefore,
an expression of type `+` can have many operands.
> nops( a + b + c + d + e );
(3.174)
Since Maple performs automatic simplification, the number of operands of a sum may not
be apparent from the input.
> nops( a + 2 + b + 3 + c + 4 );
(3.176)
To see that this occurs during the automatic simplification process, enclose the input in
unevaluation quotes to delay evaluation.
> 'a + 2 + b + 3 + c + 4';
(3.178)
In a sum such as
> '2 + 3';
(3.179)
the addition is performed, as indicated, during the automatic simplification process. The
same sum can be computed in another way:
> u := 3:
> '2 + u';
(3.180)
In this example, the arithmetic is not performed because the value of the variable u does
not replace the name u during the automatic simplification process. If the unevaluation
quotes are removed to allow the full evaluation of the expression, numeric addition is per-
formed.
> 2 + u;
(3.181)
Since addition is commutative, the order of summands in an expression of type `+` is arbit-
rary. It is fixed within a Maple session, but may vary from one session to another. Therefore,
you must not rely on the operands of a sum occurring in any specific order.
(3.182)
Since procedures are not called during the automatic simplification process, the example
above does not fully simplify to the result
> 2/3 + sin( 5*Pi/6 - 2*Pi/3 );
(3.183)
3.9 Arithmetic Expressions • 73
during the automatic simplification process. However, the argument to the sin command is
computed to the simpler form , just as it would if it had been entered by itself.
(3.184)
If any numeric literal in a sum is a float, all the numeric operands are converted to floats
and their sum is computed as a float. For more information, see Floating-Point
Contagion (page 281).
> 'a + 2 + b + 3.7 + c + Pi';
(3.185)
Arithmetic computed during the automatic simplification process includes arithmetic with
values of infinity, undefined values, and signed (floating-point) zeroes.
> '2.3 + undefined';
(3.186)
Sums of non-algebraic summands can be formed. A sum of lists of the same length returns
the corresponding list of sums. This occurs during the automatic simplification process.
> '[ a, b, c ] + [ x, y, z ]';
(3.191)
Sums of arrays, matrices, and vectors occur during the regular evaluation process.
74 • 3 Maple Expressions
(3.192)
Since the addition of sets (which are not ordered) is not well-defined, a sum formed with a
set is returned unevaluated.
> { 1, 2 } + { 3, 4 };
{ 1, 2 } + [ 3, 4 ];
(3.193)
(3.194)
You can use the dismantle command to print a representation of the internal structure of
any Maple expression.
> dismantle( a / b );
PROD(5)
NAME(4): a
INTPOS(2): 1
NAME(4): b
INTNEG(2): -1
3.9 Arithmetic Expressions • 75
The output shows that the quotient is actually stored as a product of two factors: one con-
sisting of the expression a with a power of and the other consisting of the expression b
with a power of : .
Similar to sums, products are commutative and associative. Also, products are flattened due
to associativity, even though the `*` operator is binary. Automatic simplification is applied
to products, so as with sums, numeric factors are automatically combined.
> '2 * 3 * x * y';
(3.195)
Also like sums, the order of factors in an expression of type `*` is arbitrary, and may vary
between Maple sessions.
> 'y * x * 3 * 2';
(3.196)
The number of operands reflects the number of factors remaining after automatic simplific-
ation has taken place.
> nops( 2 * 3 * x * y );
(3.197)
> op( 2 * 3 * x * y );
(3.198)
If any numeric constant in a product is a float, the result of gathering all of the constants
into a single factor is a float.
> '3.1 * a / 2 / b * 4';
(3.200)
(3.201)
(3.202)
You can multiply a list by a number and the product is applied to all of the list elements
during the automatic simplification process.
> '2 * [ 2, 3 ]';
(3.203)
Matrix multiplication is done with the `.` operator rather than `*`. Division is not defined
for matrices.
> <1,2;3,4> . <5,6;7,8>;
(3.204)
(3.205)
Multiplying or dividing two arrays of the same size will perform paired element-wise oper-
ations on the individual entries. The element-wise operators *~ and /~ can be used on both
arrays and matrices to achieve the same result.
> Array([[1,2],[3,4]]) * Array([[5,6],[7,8]]);
(3.206)
(3.207)
3.9 Arithmetic Expressions • 77
(3.208)
(3.209)
Exponentiation
Powers are formed by using the `^` operator.
> a^b;
(3.210)
(3.211)
> a^(b^c);
(3.212)
Rational number powers are used to represent roots. Exact roots are left uncomputed, while
floating-point roots are computed during the automatic simplification process.
> 4^(1/2);
(3.213)
> '(2.1)^(1/3)';
(3.214)
78 • 3 Maple Expressions
Expressions to a power of 0 are reduced to unity during the automatic simplification process.
The type of the resulting 1 depends on the type of the zero power, unless the base of the
expression is a float, in which case the result is a float.
> 'a ^ 0';
(3.215)
There are some exceptions when infinity and undefined values are raised to a float zero
power.
> 'Float( undefined ) ^ 0.0';
(3.218)
Note the distinction between Float( -infinity ) ^ (-0.0) and -Float( infinity ) ^ (-0.0): the
latter is first automatically simplified to - Float(undefined) and then to Float(undefined).
> 0.0 ^ 0;
(3.222)
> 0 ^ 0.0;
(3.223)
Although a complex floating-point zero does not automatically simplify to a real zero, ex-
pressions raised to a complex zero are simplified automatically to an exact or floating-point
unity.
3.9 Arithmetic Expressions • 79
Powering of matrices is done in the mathematical sense achieving repeated matrix products.
Powering of arrays is done element-wise.
> <1,2;3,4> ^3;
(3.225)
(3.226)
Rational Expressions
Using sums and products, more complicated expressions can be formed.
> expr := ( a + a*b ) / ( a*b - b );
(3.227)
(3.229)
(3.230)
(3.231)
3.9 Arithmetic Expressions • 81
Maple does not automatically simplify the following expression. To perform such simplific-
ations, use the normal command.
> expr := (x - 1)/(x^2 - 1);
(3.232)
(3.233)
The normal command only performs normalization of rational expressions with rational
coefficients.
> expr := ( (sin(t)^2 + cos(t)^2)*(x - 1)/(x^2 - 1));
(3.234)
(3.235)
Use the expand command (or the normal command, with the expanded option) to perform
such expansions.
> expr := (a + b) * (c + d);
(3.237)
Similarly, you must use the normal command to simplify the following rational expression.
82 • 3 Maple Expressions
(3.240)
Noncommutative Multiplication
Noncommutative multiplication is represented by the dot operator (.), which is used mainly
in linear algebra computations for multiplication of matrices and vectors. It may also be
used to represent the noncommutative product of other types of mathematical expressions.
A . B;
If A and B are of type constant, then A . B = A * B during the evaluation process (but not
during the automatic simplification process). However, if one of A and B is a Matrix or a
Vector, and the other is a Matrix, Vector, or constant, the product is interpreted as a matrix
or vector product. If A or B is an Array (and the other is not a Matrix or Vector), then A .
B is interpreted as element-wise multiplication. For arguments that are not of type Matrix,
Vector, or constant, A . B remains unevaluated, but more importantly, it is not automatically
simplified to or interpreted as being equal to B . A.
> 7 . 6;
(3.242)
> M:=<<1,0,2>|<0,1,2>|<0,0,2>>;
(3.245)
3.9 Arithmetic Expressions • 83
> V:=<10,0,0>;
(3.246)
> M . V;
(3.247)
> lambda . M . V;
(3.248)
> A := Array([[1,2],[3,4]]);
(3.249)
> B := Array([[a,b,c],[d,e,f]]);
(3.250)
> A . B;
(3.251)
> 3 . B;
(3.252)
> 2. 3;
Factorials
The unary, postfix factorial operator ! is used to represent the mathematical factorial opera-
tion.
> 5!;
(3.254)
The argument of the ! operator is subject to automatic simplification, but factorials are not
computed during the automatic simplification process.
> '(2+3)!';
(3.257)
If the argument of the ! operator is a float, the expression is computed using the GAMMA
function.
> 2.3! = GAMMA( 3.3 );
(3.258)
If the argument is a non-negative integer, Maple computes the factorial. If the argument is
a negative integer, a numeric event is triggered.
3.9 Arithmetic Expressions • 85
> (-3)!;
Error, numeric exception: division by zero
However, if the argument is a negative integer float, the complex number Float(-infinity) -
Float(infinity)*I is returned.
> (-3.0)!;
(3.259)
For other arguments, the factorial operator is returned unevaluated after first evaluating its
argument.
> sin( Pi / 6 )!;
(3.260)
where i is a name, m and n are numeric values, and expression is an expression that depends
on i.
The add command is more efficient since it does not build each of the many intermediate
sums. The semantics of mul are similar with the exception that if , the result is 1,
rather than 0.
86 • 3 Maple Expressions
For more information on the add and mul commands, refer to the add help page. For more
information on the concatenation operator, ||, see The Concatenation Operator (page 110).
Note: The add and mul commands differ from sum and product in that the former are
straightforward construction commands while the latter are commands for computing closed
forms for symbolic sums and products.
When you call the Boolean evaluator evalb, the expression passed as its argument is inter-
preted as a Boolean-valued expression if possible, and evaluated as such.
FAIL is used to mean an unknown or undetermined value. For more information on the
constant FAIL, refer to the FAIL help page.
Boolean Operators
Maple supports several operators for the Boolean combination of expressions: not, and,
or, xor, and implies.
For example,
> not true;
(3.264)
If both operands evaluate to a truth value, the entire expression is evaluated according to
the following truth table.
expr1 expr2 expr1 and
expr2
true true true
true false false
true FAIL FAIL
false true false
false false false
false FAIL false
FAIL true FAIL
FAIL false false
FAIL FAIL FAIL
The or Operator
The or operator represents logical disjunction. It is a binary operator of the form
expr1 or expr2
If both operands evaluate to a truth value, the entire expression is evaluated according to
the following truth table.
expr1 expr2 expr1 or
expr2
true true true
true false true
true FAIL true
false true true
false false false
false FAIL FAIL
FAIL true true
FAIL false FAIL
FAIL FAIL FAIL
If both of its operands evaluate to truth values, the entire expression is evaluated according
to the following truth table.
3.10 Boolean and Relational Expressions • 89
If both of its operands evaluate to truth values, the entire expression is evaluated according
to the following truth table.
expr1 expr2 expr1 implies
expr2
true true true
true false false
true FAIL FAIL
false true true
false false true
false FAIL true
FAIL true true
FAIL false FAIL
FAIL FAIL FAIL
Relational Operators
Relational operators are used to form comparisons to be evaluated in a Boolean context.
The relational operators in Maple are =, <>, <, <=, and in. Each is a binary operator that
accepts two operands. When evaluated in a Boolean context, each of these operators determ-
ines whether its two operands have a certain relationship.
It represents an equation with expr1 as the left-hand side and expr2 as the right-hand side.
When evaluated in a Boolean context, it returns a value of true if its operands are equal,
and returns a value of false otherwise.
> evalb( 1 = 2 );
(3.275)
> evalb( 2 = 2 );
(3.276)
The names x and y are distinct and unequal names in Maple and, when they are unassigned,
they are considered different expressions in a Boolean comparison. If the names x and y
have assigned values, those values are first substituted into the comparison, and the equality
computation is performed on the assigned values, rather than the names themselves.
In general, expressions are compared for equality according to their memory address. That
is, two expressions are considered equal in a Boolean context if they have the same address
in memory. However, for certain expressions, a more mathematical test for equality is used.
For example, the floating-point numbers 2.0000 and 2.0 are considered numerically equal,
even though they are distinct objects in memory.
3.10 Boolean and Relational Expressions • 91
In fact, when the floating-point number 2.0 is compared to the integer 2, they are considered
equal.
> evalb( 2.0 = 2 );
(3.281)
An inequation can be formed by using the <> operator. The general form is
expr1 <> expr2
This expression represents non-equality and returns a value of true if its operands are un-
equal, and false if its operands are equal.
> x <> y;
(3.283)
Testing for inequality is performed similarly to testing for equality. Comparing two distinct
unassigned names using the <> operator computes the equality of the names. The expression
92 • 3 Maple Expressions
returns a value of true because the names x and y are distinct as names.
A strict inequality is created by using the < operator. This has the general form
expr1 < expr2
For example,
> x < y;
(3.287)
Maple automatically converts this to the same expression as results from the first form.
When evaluated in a Boolean context, Maple performs the indicated mathematical compar-
ison, or returns the inequality as unevaluated if the operands do not evaluate to comparable
expressions. If the operands are comparable, the inequality evaluates to the value true if
the first operand is less than, but not equal to, the second operand, and evaluates to false
otherwise. If the operands are not comparable, the inequality evaluates to itself.
A non-strict inequality is formed using the <= operator. This has the general form
expr1 <= expr2
For example,
> x <= y;
(3.289)
When evaluated in a Boolean context, and when the operands are comparable, it returns a
value of either true or false according to whether the first operand is less than, or equal to,
the second operand.
3.10 Boolean and Relational Expressions • 93
When evaluated in a Boolean context, it evaluates to the value true if its first operand expr1
is a member of its second operand expr2. If expr1 does not belong to expr2, the expression
evaluates to false. Maple can determine a truth value if the second operand expr2 is a con-
tainer object; that is, either a set or list, or an unevaluated function call of the form SetOf(
T ), where T is a Maple type. An expression of the form
expr in SetOf( T )
> evalb( 5 in { 1, 2, 3 } );
(3.291)
> evalb( x in X );
(3.292)
Note the simplification applied to the statement with the evalb command in the following
example.
> x in A union B;
(3.295)
If the second operand is not an explicit container object, the expression remains an unevalu-
ated in expression. However, some automatic simplifications may be applied.
ormap commands, which are similar to the map command described in Maple
Statements (page 171).
andmap( procedure, expression, ... )
ormap( procedure, expression, ... )
The following example considers type(element,name) for each element of the list. ormap
determines whether this statement is true for at least one element of the list. andmap de-
termines whether this statement is true for all the elements of the list.
> ormap(type, [1, "a", `a`, a()], name);
(3.297)
The main difference between these commands and map is that andmap and ormap have
short-circuit ("McCarthy") semantics, which means that an answer is returned as soon as it
can be determined.
> andmap(proc(x) print(x); x<2 end proc, [1,2,3,4]);
(3.299)
Sequences
The most basic aggregate expression type in Maple is the sequence. Sequences are formed
by using the `,` (comma) operator.
> a, 2/3, sin( x ), 5.1;
(3.300)
A sequence consists of zero or more other expressions, called elements or members. A se-
quence with exactly one member is automatically simplified to its unique member. The
empty sequence, containing zero members, is the value of the name NULL, and may be
written as ().
3.11 Expressions for Data Structures • 95
Sequences occur in many other data structures as a (principal) component, within which
they acquire additional semantics. Some examples include lists, sets, and function calls.
Automatic simplification of sequences is affected by recursively simplifying the component
expressions.
> '2 + 3, 1 - 7, 0^0, sin( Pi / 6 )';
(3.302)
Nested sequences are also flattened during the automatic simplification process.
> '( 1, 2 ), 3, ( 4, 5 )';
(3.303)
Because sequences are used to pass multiple arguments to procedures, it is not normally
possible to operate on a sequence as such (the list type described below is designed for ex-
actly for that reason). For example, you cannot pass a (nontrivial) sequence to the type
command to check its type. Therefore, there is no Maple type for sequences. However, the
whattype command returns the name exprseq when it is passed either zero or more than
one argument.
> whattype();
(3.304)
> whattype( 1, 2 );
(3.305)
Note that the name exprseq is not the name of any valid type in Maple.
Similarly, you cannot query the zeroth operand of a sequence. For example, the following
results in an error.
> op( 0, ( 1, 2, 3 ) );
Error, invalid input: op expects 1 or 2 arguments, but received 4
There is no constructor for sequences, but there is a built-in command for creating sequences,
called seq. The basic syntax of seq is below. It accepts many other types of arguments as
well.
seq(expression, i = integer1..integer2)
> seq( 2 .. 14 );
(3.307)
For more information on the seq command, refer to the seq help page.
Another way to create sequences is to use the dollar sign ($) operator.
expression $ i = integer1 .. integer2
> i^2 $ i = 1 .. 5;
(3.309)
The dollar sign operator is a binary operator that performs a similar function to the seq
command, but behaves slightly differently: the $ operator evaluates the expression argument
once before any substitutions, while the command does not evaluate until after each substi-
tution of i.
> cat(a,x) $ x= 1..2;
(3.310)
In general, it is recommended that you use the seq command instead of the dollar sign op-
erator.
Lists
Lists are created by enclosing a sequence of expressions between square brackets. Lists are
essentially sequences, which are designated as a single unit for other operations.
[ sequence ]
3.11 Expressions for Data Structures • 97
> [ 1, 2, 3 ];
(3.312)
Use the numelems command to determine the number of members in the enclosed sequence.
Note that lists can contain sublists. These are still counted as a single entry.
> numelems( [ 1, 2, 3 ] );
(3.314)
> numelems( [ 1, 2, [ 3, 4 ] ] );
(3.315)
To access the -th operand of a list, use an index to the list expression.
> L := [ a, b, c, d ];
(3.316)
> L[ 3 ];
(3.317)
To access the sequence of all elements in a list, use the op command. Converting back and
forth between lists and sequences can be a common operation, and is very efficient.
> Lseq := op(L);
(3.318)
It is common to create a list by using the seq command to create the enclosed sequence.
> [ seq( i^2, i = 1 .. 5 ) ];
(3.320)
Lists are ordered; two lists with the same members in a different order are distinct.
> evalb( [ 1, 2, 3 ] = [ 2, 1, 3 ] );
(3.321)
98 • 3 Maple Expressions
Lists are immutable; you cannot change the elements of a list once it has been created. You
can, however, create a new list using members of an existing list or lists.
> L2 := [ L[ 1 ], d, L[ 3 ] ];
(3.323)
You can also use the subsop command for this purpose.
> L3 := subsop( 2 = d, L );
(3.324)
> evalb( L2 = L3 );
(3.325)
The example above creates a new list using the original list L by substituting its second
operand for the expression d. If you need to change elements frequently it is usually better
to use an array. Arrays can be changed in-place avoiding the need for a copy. For more in-
formation on the subsop command, refer to the subsop help page.
Sets
Sets, similar to lists, are created from a sequence of expressions. However, sets use braces
({}) to enclose the sequence.
{ sequence }
In addition to the syntactical differences, sets differ from lists in that they are unordered
and do not have duplicate entries. These two properties are enforced during the automatic
simplification process.
> '{3, -1, 0}';
(3.327)
3.11 Expressions for Data Structures • 99
Note that the sets' ordering in the output may not match the input sets' ordering.
In Maple 11 and earlier, the ordering of sets was unpredictable as it was based on the posi-
tions of the elements in memory. In Maple 12 and later, set ordering is deterministic, session
independent, and based on properties of the contents. This just means that the same set will
now appear in the same order even after restarting Maple. For more information on the or-
dering of sets, refer to the set help page.
For more information on how to use sets in programming, see Sets (page 134). More inform-
ation on Maple expressions related to sets will be described later in this chapter.
Tables
Tables are mutable data structures that associate an index with an entry. Both the index and
entry can be arbitrary expressions. The underlying structure is sparse (a hash table), and
expands as more entries are inserted.
> T := table();
(3.329)
(3.330)
> T[color];
(3.331)
(3.332)
Assigning values to indexed names is further described in Indexed Expressions (page 62).
Tables can be initially populated by providing a list of equations as an argument to the table
constructor.
> T := table([a=1, b=2, c=3, d=4]);
(3.333)
For names with tables assigned to them, last name evaluation rules apply. Last name evalu-
ation is explained in more detail in Evaluation Rules for Tables (page 143). The most visible
effect of last name evaluation is that the name of the table is displayed by default rather
than all of its entries.
> T;
(3.335)
> eval(T);
(3.336)
Rectangular Tables
Rectangular tables, or rtables, are mutable data structures that associate a numeric index
sequence with an arbitrary entry. The bounds of the index are predefined and directly cor-
respond to the amount of memory reserved to hold entries.
The same rtable data structure is used to implement arrays, matrices, and vectors.
> A := Array(0..5,i->2*i);
(3.337)
> A[0];
(3.338)
> A[5];
(3.339)
> V := Vector([1,2,3]);
(3.340)
> V[1];
(3.341)
3.12 Set-Theoretic Expressions • 101
> M := Matrix(3,3,shape=identity);
(3.342)
> M[2,2];
(3.343)
Rectangular tables are very flexible and offer a rich set of features. For a more in-depth
discussion of them, see Arrays (page 146).
Membership
In Maple, the set membership relation is expressed by using the in operator. It has the fol-
lowing syntax.
a in b
> 1 in { 1, 2, 3 };
(3.345)
However, when evaluated in a Boolean context, one of the values true and false is returned
if the expression b evaluates to a set or list and Maple can determine whether the expression
a belongs to the expression b. For more information on Boolean evaluation of membership
expressions, see Boolean and Relational Expressions (page 86).
Use the rhs and lhs commands to extract the right or left hand side of the an in operator.
> lhs( a in b );
(3.346)
102 • 3 Maple Expressions
> rhs( a in b );
(3.347)
Set Inclusion
Set inclusion (the subset relation) is represented in Maple by the binary subset operator. It
has the following syntax.
a subset b
> {} subset T;
(3.350)
If Maple can determine whether the expressed relation is true or false, the expression eval-
uates to true or false. Otherwise, the expression is returned unevaluated.
The individual operands can be accessed by using the lhs and rhs commands.
> lhs( a subset b );
(3.354)
The union of two sets is created by using the union operator, which has the following syntax.
a union b
> { 1, 2 } union { 2, 3, 4 };
(3.357)
> { 1, 2 } union T;
(3.358)
The following expression displays an error message, since the second operand cannot
evaluate to a set.
> { a, b, c } union "a string";
Error, invalid input: `union` received a string, which is not valid
for its 2nd argument
A union expression may be returned unevaluated, and the operands of an unevaluated union
expression a union b are the expressions a and b.
> nops( a union b );
(3.359)
> b union a;
(3.362)
The union operation is also associative. A union of three or more operands returns an une-
valuated function call.
104 • 3 Maple Expressions
> {} union a;
(3.365)
Intersections of sets are represented using the intersect operator, which has the general
syntax.
a intersect b
> { 1, 2, 3 } intersect { 3, 4, 5 };
(3.367)
> {} intersect T;
(3.368)
Note that although union and intersection are mutually distributive, neither distributes
automatically over the other in a symbolic expression. However, the expand command can
distribute intersections over unions.
> expand( a intersect (b union c) );
(3.369)
The following two procedures are identical except in how they are displayed:
> x -> x^2;
(3.371)
(3.373)
For more information on the arrow operator, refer to the operators/functional help page.
For more information on procedures, see Procedures (page 197).
Composition
Use the operators @ and @@ to represent the composition (of functions). The operator @
denotes the composition of functions and takes the general form
f @ g
Note that @ has lower precedence than function application, so that the parentheses sur-
rounding f@g above are necessary:
> f@g(x);
(3.376)
The @ operator performs numerous simplifications and normalizations, and is (left) associ-
ative.
> (exp @ ln)( s );
(3.377)
> a @ b @ c @ d;
(3.378)
Repeated composition is represented by the operator @@. It has the general form
f @@ n
Note that the iterated composition is not automatically expanded in the example above. It
is necessary to apply the expand command.
> (f^2)( x );
(3.381)
The first example above denotes the -fold composition of with itself, while the second
denotes the arithmetic square of . In particular, although the inverses of the circular functions
are commonly denoted by a power-like notation in written mathematics, in Maple, for ex-
ample, sin^(-1) denotes the reciprocal of the function, while sin@@(-1) denotes the
arcsine (arcsin).
3.13 Other Expressions • 107
> sin@@(-1);
(3.382)
> (sin@arcsin)( x );
(3.383)
> sin^(-1);
(3.384)
> (sin^(-1))( x );
(3.385)
Neutral Operators
Neutral operators are constructions that are treated as operators by Maple, but that have no
predefined meaning so that they can be customized.
A neutral operator symbol is formed by the ampersand character (&) followed either by a
valid Maple name not containing ?, or by a sequence of one or more special characters. For
more information, refer to the neutral help page.
a &name b
A commonly used neutral operator is &* which is often used for representing a non-com-
mutative multiplication. Unlike dot (.), it does not automatically combine scalar constants.
> 1 &* 2;
(3.387)
> 1 . 2;
(3.388)
Ranges
The .. operator is used to construct ranges, and usually has the following syntax.
a .. b
A consecutive sequence of two or more dots (.) is parsed as a range operator. For example,
> 2 ......... 7;
(3.390)
If the left-hand endpoint of a range is a float ending with a decimal point, or if the right-
hand endpoint is a float beginning with a decimal point, it is therefore necessary to separate
the endpoint from the range operator with one or more space characters.
> 2....3;
(3.391)
> 2. .. .3;
(3.392)
Use the lhs and rhs commands to extract the individual operands of a range expression.
> lhs( a .. b );
(3.395)
> rhs( a .. b );
(3.396)
Ranges can be used to index complex data structures as well as strings and sequences.
> [ 1, 2, 3, 4, 5 ][ 2 .. 3 ];
(3.399)
> { 1, 2, 3, 4, 5 }[ 2 .. 3 ];
(3.400)
> "abcde"[ 2 .. 3 ];
(3.401)
> ( 1, 2, 3, 4, 5 )[ 2 .. 3 ];
(3.402)
There is a special form of input syntax for ranges in which one or both endpoints is missing.
> ..;
(3.403)
In the example above, each endpoint is the empty sequence () (or NULL). It is valid to omit
just one of the endpoints.
> a ..;
(3.404)
> .. b;
(3.405)
When used in this way to index a data structure, a missing endpoint denotes the end of the
valid range of indices.
> [ 1, 2, 3, 4, 5 ][ 3 .. ];
(3.406)
> [ 1, 2, 3, 4, 5 ][ .. 4 ];
(3.407)
110 • 3 Maple Expressions
> [ 1, 2, 3, 4, 5 ][ .. ];
(3.408)
Note the distinction between the third example above and the following example
> [ 1, 2, 3, 4, 5 ][];
(3.409)
in which the first operand a can be either a name or a string, and the second operand b can
be a name, a string, an integer, an integral range, a character range, or an expression sequence
of names, strings, and integers. If the second operand b is another kind of expression, an
unevaluated || expression is returned.
> "foo" || "bar";
(3.410)
> x || 1;
(3.414)
> x || (1..3);
(3.415)
> f( y ) || t;
(3.419)
The type of the result, if not an unevaluated || expression, is determined by the type of the
first operand. If the first operand a is a string, the type of the result (or results, in the case
of a sequence) is a string. If the first operand is a name, the type of the result, or results, is
a name.
The first operand of the || operator is not evaluated, but the second operand is.
> u := 2: v := 3:
> u || v;
(3.420)
The symbol `||`, which must be enclosed in left single quotes when not used as an infix op-
erator, is a type name.
> type( f( y ) || t, '`||`' );
(3.421)
> op( f( s ) || t );
(3.423)
For most applications, the cat command is more appropriate, as it evaluates all of its argu-
ments. For more information, refer to the cat help page.
expr :: t
In addition to its use as a general Boolean expression, it is used to introduce type annotations
on parameters and type assertions for local variables and procedure return types. For more
information, see Procedures (page 197).
Outside of a Boolean context, the :: operator is essentially inert, and returns an expression
of type :: with two operands.
> type( a :: b, '`::`' );
(3.426)
> nops( a :: b );
(3.427)
> op( a :: b );
(3.428)
You can use the lhs and rhs commands to access the operands of a :: expression.
> lhs( a :: b );
(3.429)
> rhs( a :: b );
(3.430)
Series
Maple supports generalized power series expansions using a series data structure. This is
a basic symbolic data structure that is used in many fundamental algorithms, such as the
computation of symbolic limits and symbolic integration. There is no syntax for the input
of series; a series structure is created by calling the series constructor, which has the general
forms
3.13 Other Expressions • 113
where name is a name and pt is the point of series expansion. The optional argument ord
specifies the order of truncation of the series. This is, by default, equal to the value of the
environment variable Order, whose default value is . If the second form using name is
used, the expansion point is taken to be .
> series( exp( x ), x );
(3.431)
(3.432)
(3.433)
(3.434)
In general, a truncated power series expansion to order ord of expr, about the point pt is
computed. If the expansion point pt is infinity, then an asymptotic expansion is computed.
In general, the series expansion is not exact, so there will be an order term of the form
O( pt^ord )
present as the last term in the series. This is not always present, however. For example, a
series expansion of a low-degree polynomial is exact.
114 • 3 Maple Expressions
(3.435)
(3.436)
(3.437)
A series data structure prints very much like a polynomial, but it is a distinct data structure.
In certain cases, a polynomial (sum of product) data structure is returned. This happens
when the generalized series expansion requires fractional exponents.
> s := series( sqrt( sin( x ) ), x );
(3.438)
(3.441)
Note that the series data structure is sparse in the sense that terms with coefficient are
not part of the data structure.
A series structure can be converted to a polynomial by using the convert command with
the name polynom as the second argument.
3.14 Attributes • 115
(3.442)
(3.444)
3.14 Attributes
In addition to their operands, certain types of expressions can have other information asso-
ciated with them in the form of attributes. As described earlier in this chapter, protected
names are a type of attribute. If an expression has attributes, they can be examined by using
the attributes command.
> attributes(sin);
(3.446)
Attributes can be assigned to expressions of the following types: name, string, list, set, Array,
Matrix, Vector, equation, procedure, unevaluated function call, or float using the setattribute
command.
setattribute(expression, attributes)
The setattribute command returns a copy of the expression with the attributes assigned. If
the expression is a symbol or string, it is modified in-place. For other data types, the original
expression is left unchanged.
> x := 1.0;
(3.447)
> attributes('x');
(3.449)
116 • 3 Maple Expressions
> attributes("Johanessphere");
(3.451)
> y := setattribute('f(z)',"common");
(3.452)
> attributes(y);
(3.453)
> attributes('f(z)');
You can check whether an expression has attributes by using the attributed type. For more
information, refer to the type,attributed help page.
> type(`just a name`, 'attributed');
(3.454)
Example 1
To understand how Maple evaluates and simplifies expressions, consider the following ex-
ample.
> x := Pi/6:
> sin(x) + 2*cos(x)^2*sin(x) + 3;
(3.456)
Maple first reads and parses the input. As the input is parsed, Maple builds an expression
tree to represent the value.
3.15 Using Expressions • 117
Maple simplifies the expression tree and then evaluates the result. The evaluation process
substitutes values for variables and invokes any commands or procedures. In this case, x
When the sin and cos commands are called, Maple obtains a new "expression tree,"
Example 2
Alternatively, consider the next example: evaluation occurs, but no simplification is possible.
> x := 1;
(3.457)
(3.458)
Substituting Subexpressions
The simplest method of substitution in Maple is to use the subsop command. This is an
operation on the expression tree. It creates a new expression by replacing an operand in the
original expression with the given value.
subsop( n=value, expr);
subsop( list=value, expr);
Note that most operations in Maple do not alter expressions in-place but, in fact, create new
expressions from old ones. For a list of exceptions, see Mutable Data Structures (page 139).
Also, note that the subsop command acts on the expression tree by changing an arrow in
the DAG, and not by changing the value of a node which would change all identical instances.
That is, in the following example only one instance of a is changed, not all. See Figure 3.2.
> expr := (a+a*b)/(a*b-b);
(3.461)
(3.462)
The subsop command is powerful, but generally useful only in very specific programming
applications. The most generally useful command for substitution is the two-argument
version of the eval command.
The eval command has the following syntax, where s is an equation, list, or set of equations.
eval( expr, s );
(3.463)
(3.464)
3.15 Using Expressions • 119
The eval command performs substitution on the expression considered as a DAG rather
than a tree, so it can be quite efficient for large expressions with many repeated subexpres-
sions.
An alternative to the eval command is the subs command, which performs syntactic substi-
tution. It computes the expression as a tree and replaces subexpressions in an expression
with a new value. The subexpressions must be operands, as identified by the op command.
Using the subs command is equivalent to performing a subsop operation for each occurrence
of the subexpressions to be replaced.
The subs command has the following syntax, where s is an equation, list, or set of equations.
subs( s, expr );
> f := x*y^2;
(3.467)
(3.468)
The other difference between the eval and subs commands is demonstrated in the following
example.
> subs( x=0, cos(x) + x^2 );
(3.469)
In the preceding subs command, Maple substitutes 0 (zero) for x and simplifies the result.
Maple simplifies cos(0) + 0^2 to cos(0). By using the eval command, Maple evaluates
cos(0) to 1 (one).
During the substitution process, operands are compared in the expression tree of expr with
the left-hand side of an equation.
120 • 3 Maple Expressions
The substitution does not result in d*c because the operands of the product a*b*c are a, b,
c. That is, the products a*b, b*c, and a*c do not appear specifically as operands in the ex-
pression a*b*c. The easiest way to make such substitutions is to solve the equation for one
unknown and substitute for that unknown.
> eval( a*b*c, a=d/b );
(3.472)
You cannot always use this method; for certain expressions, it may not produce the expected
results. The algsubs command provides a more powerful substitution facility.
> algsubs( a*b=d, a*b*c );
(3.473)
Two more useful substitution commands are subsindets and evalindets. These commands
perform substitution on all subexpressions of a given type; the former uses the subs func-
tionality and the latter uses the eval functionality.
subsindets( expr, atype, transformer, rest )
evalindets( expr, atype, transformer, rest )
(3.475)
Structured Types
A simple type check may not always provide sufficient information. For example, the
command
> type( x^2, `^` );
(3.476)
verifies that x^2 is an exponentiation, but does not indicate whether the exponent is, for
example, an integer. To do so, you must use structured types. Consider the following ex-
ample.
3.15 Using Expressions • 121
To learn more about structured types, study the following examples. The square root of x
does not have the structured type name^integer.
> type( x^(1/2), 'name^integer' );
(3.478)
The expression (x+1)^2 does not have type name^integer, because x+1 is not a name.
> type( (x+1)^2, 'name^integer' );
(3.479)
An expression matches a set of types if the expression matches one of the types in the set.
> type( 1, '{integer, name}' );
(3.481)
> exp(2);
(3.486)
Because is the typeset version of exp(2), it does not match the type anything^2.
> type( exp(2), 'exp'(integer) );
(3.488)
The next example illustrates why you should use unevaluation quotes (') to delay evaluation
when including Maple commands in type expressions.
> type( int(f(x), x), int(anything, anything) );
Error, testing against an invalid type
(3.489)
This is not a valid type. If you enclose the int command in unevaluation quotes, the type
checking works as intended.
> type( int(f(x), x), 'int'(anything, anything) );
(3.490)
The type specfunc(type, f) matches the function f with zero or more arguments of type
type.
> type( exp(x), 'specfunc(name, exp)' );
(3.491)
The type function(type) matches any function with zero or more arguments of type type.
> type( f(1,2,3), 'function(integer)' );
(3.493)
3.15 Using Expressions • 123
In addition to testing the type of arguments, you can test the number of arguments. The type
anyfunc(t1, ..., tn) matches any function with n arguments of the listed types in the correct
order.
> type( f(1,x), 'anyfunc(integer, name)' );
(3.495)
Another useful variation is to use the And, Or, and Not type constructors to create Boolean
combinations of types. Note that these are different from the and, or, and not logical oper-
ators.
> type(Pi, 'And( constant, numeric)');
(3.498)
For more information on structured types, refer to the type,structured help page. For more
information on how to define your own types, refer to the type,defn help page.
The indets command is useful for extracting a set of all the subexpressions of a given type.
indets( expr, atype)
(3.502)
(3.503)
Note that the indets command analyzes the entire expression so that the base of the exponent
is recognized as an integer. If you want to select only subexpressions from the top
level, use the command select described in The select, remove, and selectremove
Commands (page 186).
If you want to test whether that an expression has a subexpression of a given type, use the
hastype command rather than the indets command since it avoids building a potentially
large set of expressions.
> hastype([1,2,3.,5.,6.,7.], 'float');
(3.504)
3.16 Exercises
1. Find the numerator and denominator of the irreducible form of 4057114691 divided by
4404825097799.
2. Construct floating-point numbers using the floating-point number constructor. Construct
the number 917.3366 using a positive exponent, and then using a negative exponent.
Construct a floating-point approximation of 1/3.
3. Without using the Digits environmental variable, find the difference between estimated
to 20 digits and 10 digits.
4. Calculate the negative complex root of -1369, and then sum 3 and the root. Find the in-
verse of this complex sum. Find the inverse of (a*b)/c+((a-d)/(b*e))*I) in standard form,
where a, b, c, d, and e are real.
5. The Fibonacci numbers are a sequence of numbers. The first two numbers in the sequence
are zero (0) and one (1). For n greater than two, the th number in the sequence is the
sum of the two preceding numbers. Assign values to indexed names representing the
first, second, and general Fibonacci numbers.
6. Using the time command, determine the time required to multiply two ten-by-ten matrices.
7. Use Maple to verify de Morgan's laws.
3.16 Exercises • 125
8. Contrast the behavior of functions and expressions by performing the following com-
mands.
4.2 Introduction
Maple provides various data structures that you can use for programming and interacting
with Maple functions. This chapter focuses on the use of data structures in programming.
However, the sections Lists (page 128) and Sets (page 134) may be useful for users who want
to construct arguments for Maple functions.
Maple has many data structures that provide similar functionality, but certain data structures
are better suited for certain types of operations. Therefore, when choosing which data
structures to use, it is important to select a structure that performs well on the operations
used in your code.
Many aspects affect the performance of data structures. However, in Maple, the provided
data structures can be divided into two basic classes: mutable and immutable. The mutable
data structures can be modified, that is, the values they store can change. The immutable
data structures cannot be changed after they are created. Instead, copies of these structures
can be made with different contents. This difference in behavior can have significant impact
on the performance of code that uses these structures.
In Maple, there are two basic immutable data structures: lists and sets.
127
128 • 4 Basic Data Structures
Lists
A list stores an ordered sequence of expressions. The ordering of the elements in a list is
fixed when the list is created. Lists, in contrast to sets, will maintain duplicate elements.
Creating Lists
The easiest way to create a list is to enclose a sequence of expressions in square brackets
([]). A sequence of expressions is a series of comma-separated expressions.
[ sequence ]
This creates a list that contains the elements of sequence in the specified order. In the case
where sequence is empty, [] represents an empty list. Compare the results of these examples
to those in the Sets (page 134) section.
> [x, y, y];
(4.1)
(4.3)
In Maple, nested lists whose inner lists have the same number of elements have a special
name, listlist.
> M := [[a,b], [1,2], [3, 4]];
(4.5)
Many Maple functions return sequences. Thus, enclosing a call to one of those functions
in square brackets [] creates a list. For example, the seq command generates sequences.
> [ seq( x^j, j=1..3) ];
(4.9)
> op(L);
(4.11)
Thus op can be used to create new lists based on existing lists. For example, you can create
a new list with an additional element added to the start of the list.
> L2 := [ 0, op(L) ];
(4.12)
A list with another element added to the end of the list can be created in a similar way.
> L3 := [ op(L2), 4 ];
(4.13)
> L[1];
(4.16)
> L[2];
(4.17)
130 • 4 Basic Data Structures
> L[3];
(4.18)
You can also specify a range in the selection operation to extract a sublist containing the
elements that are indexed by that range.
> L := [ seq( i^2, i=1..10 ) ];
(4.19)
> L[3..6];
(4.20)
> L[5..8];
(4.21)
While it is possible to make an assignment to a list index, this operation can be inefficient
since it creates a new list. In fact, assignment to a large list is not permitted in Maple and
will produce an error. Assigning a list element is a common error, so if you find yourself
wanting to do this, consider using a mutable data structure instead. For more information,
see Mutable Data Structures (page 139).
> L := [1,2,3]:
> L[1] := 3;
(4.22)
> L;
(4.23)
L is now a new list with a different element at index 1. Thus, assigning to a single element
of a list causes the entire list to be copied in the same way as using the subsop command.
In fact, the previous example is equivalent to the following except in how the result is dis-
played.
> L := [1,2,3]:
> L := subsop(1=3, L);
(4.24)
If you attempt to assign to an index to a large list, an error will occur. Therefore, if you need
to make a copy of a list with one changed element, it is recommended that you use the
subsop command instead.
4.3 Immutable Data Structures • 131
(4.25)
This can be useful for many tasks, for example, using lists in a loop. For more information
on selectremove, see Filtering Data Structure Elements (page 155).
> L := [seq( i, i=2..100)]:
> divisor := 2:
> while ( numelems( L ) > 0 )
do
divisible, L := selectremove( i->(i mod divisor = 0), L ):
n := numelems( divisible );
if ( n > 0 ) then
printf( "%d integer%s whose smallest prime divisor is %d\n",
Sorting a List
The sort command can create a new list with sorted elements from any given list. By default,
sort arranges elements in ascending order.
> sort( [ 4,2,3 ] );
(4.33)
The sort command can also accept a second argument that specifies the ordering to use
when sorting the elements.
> sort( [4,2,3], `>` );
(4.34)
(4.35)
(4.36)
Maple provides other operations that can work with the members of a list, such as add and
mul.
> add( i, i in [ seq( j, j=1..100 ) ] );
(4.37)
Finally, a for loop can be combined with the in operator to loop over the contents of a list.
> for i in [1,2,3,4]
do
print( i^2 );
end do;
(4.39)
Sets
A set is an unordered sequence of unique expressions. When a set is created, Maple reorders
the expressions to remove duplicate values and to make certain operations faster.
Creating Sets
The easiest way to create a set is to enclose a sequence of expressions in braces ({}).
{ sequence }
4.3 Immutable Data Structures • 135
When Maple creates the set, it performs automatic simplification. This process creates a set
that contains the elements of sequence; however, during the automatic simplification process,
any duplicate elements are removed and the remaining elements are reordered.
Compare the results of these examples to those in the Lists (page 128) section.
> {x, y, y};
(4.40)
> {y[1],x,x[1],y[1]};
(4.42)
Similar to lists, sets can be created using functions such as seq that return sequences.
> { seq( i mod 3, i=1..10 ) };
(4.43)
Again, similar to lists, the op command can be used to extract the sequence of elements in
a set.
> S := {1,2,3};
(4.44)
> op(S);
(4.45)
However, unlike lists, Maple provides operations for set arithmetic, so for sets op is some-
what less important.
Set Arithmetic
Maple provides operators for mathematical set manipulations: union, minus, intersect, and
subset. These operators allow you to perform set arithmetic in Maple.
> s := {x,y,z};
(4.46)
> t := {y,z,w};
(4.47)
136 • 4 Basic Data Structures
> s union t;
(4.48)
> s minus t;
(4.49)
> s intersect t;
(4.50)
> s subset t;
(4.51)
> S[2];
(4.54)
> S[3];
(4.55)
Unlike lists, you cannot use the selection operation to create new sets.
> S[1] := 4;
Error, cannot reassign the entries in a set
You can specify a range in the selection operation to extract the elements indexed by the
range.
> S2 := { seq( i^2, i=1..10 ) };
(4.56)
4.3 Immutable Data Structures • 137
> S2[3..6];
(4.57)
> S2[5..8];
(4.58)
In this example, the features of sets are used to test Collatz's conjecture on the first million
integers. Collatz's conjecture states that given any integer, i, if the following function is
applied repeatedly, the result will eventually be 1.
> collatz := proc( i )
if ( i = 1 ) then
138 • 4 Basic Data Structures
1;
elif ( type( i, even ) ) then
i/2;
else
3*i+1;
end if;
end proc:
Begin with a set S that consists of the integers from 1 to 1 million. Under repeated application
of collatz, as numbers converge to 1, the set automatically removes duplicate values, until
eventually there is only 1 element left. For more information on the use of map, see Applying
a Function to the Contents of a Set (page 138).
> S := {seq( i, i=1..1000000)}:
> while ( numelems( S ) > 1 )
do
S := map( collatz, S ):
end do:
> S;
(4.66)
(4.67)
(4.68)
Notice that when applying a function to a set, the output is also a set, which means the ele-
ments are reordered and duplicate elements are removed.
Maple provides other operations that can work with the members of a list, such as add and
mul.
4.4 Mutable Data Structures • 139
Finally a for loop can be combined with the in operator to loop over the contents of a set.
Note that the set has been reordered.
> for i in {1,4,3,2}
do
print( i^2 );
end do;
(4.71)
The most flexible mutable data structure provided by Maple is the table.
Tables
A table stores a collection of index/entry pairs. For a given index, the table contains a par-
ticular value, called an entry. Index/entry pairs can be created or removed, or the value as-
sociated with an index can be modified.
Creating Tables
A new table can be created by calling the table function.
> t := table();
(4.72)
With no arguments, table creates a new empty table. To create a table that contains certain
index/entry pairs, specify the pairs as a list of equations. The left-hand side of an equation
is the index and the right-hand side is the entry.
140 • 4 Basic Data Structures
If the given list contains one or more expressions that are not equations, the list is treated
as a list of entries and the indices are the positions of the entries in the list (1, 2, 3, ...).
> t := table( [ a, b, c=d ] );
(4.74)
Tables are also created implicitly when you assign to an indexed name.
> t2[new] := 10;
(4.75)
> eval(t2);
(4.76)
> t[1];
(4.78)
> t[a];
(4.79)
> t[f(x)];
(4.80)
If the table does not contain a entry associated with the index, an unevaluated table reference
is returned.
> t[2];
(4.81)
The selection operation can also be used to add new index/entry pairs to the table.
4.4 Mutable Data Structures • 141
> t[2] := 3;
(4.82)
> t[c] := d;
(4.83)
> t[sin(x)] := 1;
(4.84)
> t[2];
(4.85)
> t[c];
(4.86)
> t[sin(x)];
(4.87)
Removing an Element
The best way to remove an element from a table is to call the unassign function.
> t[1] := x;
(4.88)
> t[sin(x)] := y;
(4.89)
(4.90)
(4.91)
The selection operation can also be used to remove an index/entry pair from a table. By
assigning the unevaluated table entry to its name, that element is removed from the table.
This can be done by using unevaluation quotes ( ' ) or the evaln command.
142 • 4 Basic Data Structures
> t[1] := x;
(4.92)
(4.93)
> t[1];
(4.94)
> t[sin(x)] := y;
(4.95)
(4.96)
> t[sin(x)];
(4.97)
> t;
(4.104)
To get the assigned value (the table), use the eval command.
> eval(t);
(4.105)
Extracting Data
Tables are often used as simple containers for data. Sometimes, it is useful to have a list of
the indices used in the table. Maple provides the indices function for this purpose.
> t := table( [a=1, b=2, c=3, d=4] );
(4.106)
> indices( t );
(4.107)
You may not expect to see that indices returns a sequence of lists, where each list contains
the index. This is because Maple allows sequences to be used as indices in tables.
> t2 := table( [ a=1, b=2, (a,b,c)=3 ] );
(4.108)
> indices( t2 );
(4.109)
If the indices were not wrapped in a list, it would be impossible to determine if an index is
a single expression or a sequence of expressions. Since using sequences as indices is uncom-
144 • 4 Basic Data Structures
mon, indices accepts a nolist option, for which indices returns a simple sequence and does
not wrap each index in a list.
> indices( t, 'nolist' );
(4.110)
Note that, with the nolist option, indices that are sequences are not returned properly.
> indices( t2, 'nolist' );
(4.111)
You can also use the entries function to get all the values stored in the table.
> entries( t );
(4.112)
To extract the index/entry pairs as a sequence of equations, use the pairs option to either
of the indices or entries commands.
> entries( t, 'pairs' );
(4.114)
Copying Tables
If you assign a table to multiple names, all the names reference the same table. Thus, changes
to the table using one name are visible from the other names.
> t := table( [a=1,b=2,c=3] );
(4.115)
> t1 := eval( t );
(4.116)
> t[d] := 4;
(4.117)
> eval( t );
(4.118)
4.4 Mutable Data Structures • 145
> eval( t1 );
(4.119)
If you want to create a copy of a table, use the copy function so that the tables can be mod-
ified independently.
> t1 := copy( t );
(4.120)
> t[e] := 5;
(4.121)
> eval( t );
(4.122)
> eval( t1 );
(4.123)
(4.124)
(4.125)
You can use the indices and entries functions to produce a list that can be mapped over or
used in a for-in loop. You can also use this technique to modify the original table.
> for i in entries(t,'pairs')
do
t[lhs(i)] := int( rhs(i), x );
end do;
(4.126)
146 • 4 Basic Data Structures
> eval(t);
(4.127)
Arrays
In Maple, an Array stores data as an n-dimensional rectangular block (rtable), that is, an
Array has 1 or more dimensions and each dimension has an range of integer indices. By
specifying one integer from each range, an element of the Array can be indexed.
Because Arrays are mutable, the values stored in an Array can change.
Creating Arrays
To create an Array in Maple, use the Array command and specify the ranges for the dimen-
sions. This creates a new Array with each entry initialized to 0. For Arrays, the ranges do
not need to start at 1.
> Array( 1..3 ); # 1 dimensional Array
(4.128)
(4.129)
(4.130)
When creating an Array, you can also specify a generator function to populate the Array
with data. The generator function takes an index as an argument and returns a value for the
corresponding entry.
4.4 Mutable Data Structures • 147
(4.131)
(4.132)
You can also provide the data for the Array by specifying the data as a list or nested lists.
> Array( [1,2,3] );
(4.133)
(4.134)
The basic indexing operator, [], provides mathematical indexing. Programmer indexing is
accessed by using round brackets, (). For Arrays whose dimension ranges all start at 1, the
two indices behave similarly.
> A := Array( 1..2, 1..3 ):
> A[1,1] := 1;
(4.135)
> A(2,1) := 2;
(4.136)
148 • 4 Basic Data Structures
> A(1,1);
(4.137)
> A[2,1];
(4.138)
You may notice that the assignment that uses programmer indexing is displayed differently
than the assignment that uses mathematical indexing. This is because the result of an assign-
ment to a programmer indexed Array is the entire array. This can be important when
working with large sub-Arrays.
When the ranges do not start at 1, mathematical and programmer indexing are different.
Mathematical indexing requires that the indices match the specified ranges, but programming
indexing always normalizes the ranges to start at 1.
> A := Array( 3..4, 5..6, (x,y)->x+y ):
> A[3,5];
(4.139)
> A(3,5);
Error, index out of bounds
> A(1,1);
(4.140)
This means that programmer indexing can always take advantage of negative indexing,
which normally only works when the ranges start at 1. Negative indexing counts backwards
from the end of the range.
> A[3,-1];
Error, Array index out of range
> A[3,6];
(4.141)
> A(1,-1);
(4.142)
Sub-Array Access
A sub-Array of an Array can be accessed by specifying a subrange in place of the indices.
4.4 Mutable Data Structures • 149
(4.143)
> A[1..2,1..3];
(4.144)
> A(2..4,2..3);
(4.145)
(4.146)
(4.147)
Note that the commands perform the same operation, but display the result differently. This
is the consequence of an important difference in how the modification is performed. This
150 • 4 Basic Data Structures
can be important when working with large sub-Arrays. Compare the time to perform the
assignment in the following examples:
> N := 4000:
> A := Array( 1..N, 1..N, (x,y)->rand() ):
> B := Array( 1..N, 1..N ):
> t := time():
> B[1001..4000,1001..4000]:=A[1..3000,1..3000]:
> time()-t;
(4.148)
> t := time():
> B(1001..4000,1001..4000):=A(1..3000,1..3000):
> time()-t;
(4.149)
The difference in running time of these copies is due to the difference in the result of an
assignment to an Array index. For mathematical indexing, a new 3000 by 3000 Array must
be created as the result. With programmer indexing, the result is the Array being assigned
to in its entirety - an object that already exists.
Automatic Resizing
One of the most important differences between mathematical and programmer indexing is
automatic resizing. When reading from or writing to an entry using mathematical indexing,
an index that is outside the bounds of the Array will raise an exception.
> A := Array( [[1,2,3],[4,5,6]] );
(4.150)
> A[1,4];
Error, Array index out of range
> A[1,4] := a;
Error, Array index out of range
However, programmer indexing allows you to write to an entry that is outside the bounds
of the current Array. Instead of raising an exception, the Array are automatically resized so
that the element can be stored. Reading from an out-of-bounds index will still raise an ex-
ception.
4.4 Mutable Data Structures • 151
> A(1,4) := a;
(4.151)
> A(3,5);
Error, index out of bounds
> A(3,5) := b;
(4.152)
As Array bounds may not start at , it is important that procedures that accept Arrays be
aware of this possibility. The upperbound and lowerbound functions can be used to get
the bounds on the ranges of an Array.
> printer := proc( A )
local lower, upper, i, j;
lower := lowerbound( A );
upper := upperbound( A );
for i from lower[1] to upper[1]
do
for j from lower[2] to upper[2]
do
printf( "%a ", A[i,j] );
152 • 4 Basic Data Structures
end do;
printf( "\n" );
end do;
end proc:
> printer( Array( [[1,2],[3,4]] ) ):
1 2
3 4
Copying an Array
As with tables, having multiple variables referencing the same Array does not create new
copies of the Array. You can use copy to copy the Array.
> A := Array( 1..2, 1..2 ):
> B := A;
(4.155)
> A[1,1] := 1:
> B;
(4.156)
> B := copy(A):
> A[1,2] := 2:
> A;
(4.157)
> B;
(4.158)
4.4 Mutable Data Structures • 153
(4.159)
> AC := copy(A);
(4.160)
> CompareArray(A,AC);
(4.161)
> AR := A;
(4.162)
> CompareArray(A,AR);
(4.163)
(4.164)
154 • 4 Basic Data Structures
> CompareArray(A,B);
(4.165)
There are some other advanced notions of equality such as whether or not arrays with un-
defined entries should be treated as having equal entries, and whether a Matrix and Array
with identical entries should be considered the same. The IsEqual command in the Ar-
rayTools package allows for different solutions for these two issues compared to
EqualEntries. The ArrayTools package contains a variety of functions for working with
Arrays. For more information, refer to the ArrayTools help page.
(4.166)
indices, entries, and the in operator work with Arrays, so you can use Arrays in add, mul,
and for loops. entries(A,pairs) can also be used to obtain a list of index/value pairs in the
same way that it does for tables.
> A := Array( [x,x^3,sin(x)] ):
> for entry in entries(A,'pairs')
do
A[lhs(entry)] := diff( rhs(entry), x ):
end do:
> A;
(4.167)
When assigning values into the Array, Maple will raise an exception if the given value does
not match the specified type.
> A := Array( [1,2,3,4], datatype=float[8] );
(4.168)
> A[1];
(4.169)
(4.170)
If you are working with numeric values that can be stored in these hardware types, it can
be much faster to use an Array with a hardware type. For more information on numerical
programming in Maple, see Numerical Programming in Maple (page 269).
Deprecated: array
The array data structure is an older implementation of Arrays. Its use has been deprecated;
use Array instead.
The parameter f must be a Boolean-valued function. This function is applied to each of the
elements of the data structure x. select returns the a data structure containing those elements
for which f returns true. remove returns a data structure containing those elements for which
f returns false. selectremove returns two structures, the first consisting of the elements for
which f returned true and the second consisting of the elements for which f returns false.
The type of the return value of these functions matches the type of the argument x.
156 • 4 Basic Data Structures
> x := [seq(i,i=1..10)];
(4.171)
Calling selectremove is more efficient than calling select and remove separately.
convert attempts to convert the expression x into the form t. In particular, Maple supports
conversions between the list, set, table, and Array types.
> x := [1,2,3,4];
(4.175)
(4.178)
4.6 Other Data Structures • 157
Create a Record
To create a new record, use the Record command. Record accepts a sequence of names as
parameters. Each name becomes a field in the returned record.
> r := Record( 'expression', 'variable' );
(4.179)
(4.180)
> r:-variable := x;
(4.181)
(4.182)
(4.183)
(4.184)
(4.185)
Note that you must call eval on r before passing it into Record. This is because records use
last name evaluation rules, similar to tables.
158 • 4 Basic Data Structures
Record Equality
As with Arrays, two references to Records are considered equal if they reference the same
structure. Two different structures that have the same fields and values are not considered
equal.
> r := Record( 'a'=1, 'b'=2, 'c'=3 ):
> rc := r:
> r2 := Record( 'a'=1, 'b'=2, 'c'=3 ):
> evalb( r = rc );
(4.186)
> evalb( r = r2 );
(4.187)
To compare two different records, you can use the verify command with the record argument.
verify/record returns true if the two records have the same set of fields with equal values
assigned to them.
> r3 := Record( 'a'=1, 'b'=2, 'c'=3, 'd'=4 ):
> r4 := Record( 'a'=1, 'b'=2, 'c'=4 ):
> verify( r, r2, 'record' );
(4.188)
Packed Records
The Record constructor function can also be called with the indexed name Record[packed],
to produce a packed record.
Unlike a regular record, a packed record does not create a unique instance of each field
name for each record instance. When working with thousands of similar records each with
many fields, this can save a significant amount of memory.
Fields of packed records do not exhibit last name evaluation. That is, the expression r:-a
always produces a value, even if that value is a procedure, table, Matrix, Vector, or another
record.
4.6 Other Data Structures • 159
Similarly, it is not possible for a packed record field to not have a value. The assigned
function will always return true, and unassigning a packed record field will set its value to
NULL instead.
Stacks
A stack is an abstract data type that provides two main operations: push and pop. A push
places a new value onto the top of the stack and pushes the existing elements down. A pop
removes the element from the top of the stack, moving the elements below up. This creates
a element access order referred to as last in first out (LIFO).
Stacks are useful for many operations. A typical use of a stack is to turn a recursive algorithm
into an iterative one. Instead of recursing on elements, those elements get pushed onto a
stack. When the current element has been handled, the element on top of the stack is removed
and handled next. By using a stack, the recently discovered elements are handled before
elements that were already in the stack, which is similar to how a recursive algorithm works.
Creating a Stack
In Maple, you can create a stack by calling stack:-new. If you do not specify any arguments,
stack:-new creates an empty stack. Maple stacks are implemented on top of tables.
> s := stack:-new():
> stack:-push( 1, s );
(4.191)
> stack:-push( 2, s );
(4.192)
> stack:-pop( s );
(4.193)
> stack:-pop( s );
(4.194)
You can also pass values into stack:-new that populate the stack. These elements are pushed
in the order specified.
> s := stack:-new(1,2,3,4,5):
> stack:-pop( s );
(4.195)
160 • 4 Basic Data Structures
> stack:-pop( s );
(4.196)
> stack:-push( 3, s ):
> stack:-pop( s );
(4.198)
> stack:-pop( s );
(4.199)
(4.200)
(4.201)
You can examine the element on the top of a stack, without removing it, by calling stack:-
top.
> s := stack:-new(x,x^2,sin(x)):
> stack:-depth(s);
(4.202)
> stack:-top(s);
(4.203)
> stack:-pop(s);
(4.204)
> stack:-depth(s);
(4.205)
> stack:-top(s);
(4.206)
> stack:-pop(s);
(4.207)
> stack:-depth(s);
(4.208)
> stack:-top(s);
(4.209)
Queues
The queue is an abstract data type similar to a stack; however, instead of the most recently
added element being returned first, the oldest element in the queue is returned first. Elements
in a queue are analogous to people waiting in a line. The main operations provided by a
queue are enqueue, which adds an element to the queue, and dequeue, which removes an
element from the queue. The access order used by a queue is called first in first out, or FIFO.
162 • 4 Basic Data Structures
A queue is used when you want to handle elements in the order that they are discovered. A
typical example of using a queue is a breadth-first search of a graph. You dequeue a node
and then enqueue any unvisited nodes that are neighbors of the current node. By using a
queue, the order in which the nodes are visited is breadth-first.
Create a Queue
To create a queue in Maple, use the queue:-new command.
> q := queue:-new():
> queue:-enqueue( q, 1 );
(4.210)
> queue:-enqueue( q, 2 );
(4.211)
> queue:-dequeue( q );
(4.212)
> queue:-dequeue( q );
(4.213)
You can also pass values into queue:-new to populate the new queue. The elements are en-
queued in the order they are specified.
> q := queue:-new( 1,2,3 ):
> queue:-dequeue( q );
(4.214)
> queue:-dequeue( q );
(4.215)
> queue:-dequeue( q );
(4.216)
> queue:-enqueue( q, 2 ):
> queue:-dequeue( q );
(4.217)
> queue:-enqueue( q, 3 ):
> queue:-dequeue( q );
(4.218)
> queue:-dequeue( q );
(4.219)
(4.220)
(4.221)
You can examine the front element of a queue, without removing it, by calling queue:-front.
> q := queue:-new(x,x^2,sin(x)):
164 • 4 Basic Data Structures
> queue:-length(q);
(4.222)
> queue:-front(q);
(4.223)
> queue:-dequeue(q);
(4.224)
> queue:-length(q);
(4.225)
> queue:-front(q);
(4.226)
> queue:-dequeue(q);
(4.227)
> queue:-length(q);
(4.228)
> queue:-front(q);
(4.229)
Maple provides two methods for enabling data coercion. For more information see The
coercion Modifiers (page 209).
Indexing
The time to perform an indexed look-up into a list, set, table, and Array are all constant
time operations. This means that the time needed to find the element does not vary based
on the number of elements stored in the structure. Time to perform a look-up into a list or
set is relatively similar and is faster than Arrays, which is faster than a table.
Similarly, writing into a table or Array is also a constant time operation, with Array look-
ups being slightly faster than table look-ups.
Membership
The member function determines if a particular element is stored in a structure. For lists,
this requires a linear search of the data in the list. Therefore, the time is proportional to the
total length of the list. A set is sorted, so searches of the list can be performed more quickly.
Searching within a set takes time proportional to the log[2] of the number of elements in
the set.
You can use a table for very fast membership testing. Use the table key as objects you want
to test for, and anything you want for the value. You can then call the assigned command
to test if the element exists in the table. A table index is a constant time operation, so this
membership test is also constant time.
> N := 2*10^5:
> memtest := proc( D, N )
local i;
for i from 1 to N
do
member( i, D ):
end do:
end proc:
> L := [seq( i, i=1..N )]:
> time(memtest(L,N));
(4.230)
(4.232)
Note that to benchmark the list and set membership functions, the call to member is within
a function. This is because of the Maple evaluation rules. If the call to the member command
is at the top level, the list or set is fully evaluated, which requires inspecting each element
of the list or set for each call to member. The overhead required for these full evaluations
would distort the results.
For more information on the Maple evaluation rules, see Unevaluated Expressions (page 46).
(4.233)
> t := table():
start:=time():
for i from 1 to N
do
t[i] := 1:
end do:
time()-start;
(4.234)
4.9 Avoiding Common Problems • 167
(4.235)
> op( 2, s );
Error, invalid input: op expects 1 or 2 arguments, but received 4
> L[0];
Error, invalid subscript selector
168 • 4 Basic Data Structures
> L[9];
Error, invalid subscript selector
Further, when specifying the endpoints of a range, make sure that the left-hand side of the
range specifies an element before the element specified by the right-hand side.
> L[6..3];
Error, invalid subscript selector
> L[6..-5];
Error, invalid subscript selector
The only exception to this is if the left-hand side of the range is n, then the right-hand side
can be n-1 and the result of this range is an empty structure (list or set).
> L[6..5];
(4.239)
(4.240)
> A[7];
Error, Array index out of range
> A[5..3];
Error, inverted range in Array index
Another type of index error occurs when sum is used instead of add to obtain explicit sums
over all the elements of a list, Array, Matrix, Vector, or similar data structures.
> V := Vector(5,{(1)=1,(2)=2,(3)=3,(4)=4,(5)=5}):
> sum(V(n),n=1..5);
Error, unsupported type of index, n
(4.241)
(4.242)
4.10 Exercises
1. Define a set with elements that are the powers of 13 modulo 100 for exponents ranging
from 1 to 1000. Is 5 a member of the set? Why is it beneficial to use a set instead of a
list?
Hint: You can determine the set by using one statement if you use the seq command.
2. Generate the sums of 4 and the first 100 multiples of 3. Determine the sums that are
square-free composite numbers.
Hint: The NumberTheory package has a function that you need to use.
3. Find floating-point approximations for the sum of the square root and cubic root of each
of the first 15 powers of 2.
4. Write a procedure that implements the sieve of Eratosthenes: Count the number of integers
(less than or equal to a given integer) that are prime.
5 Maple Statements
5.1 In This Chapter
• Introduction
• Expression Statements
• Assignments
• Flow Control
• The use Statement
• Other Statements
5.2 Introduction
A statement is a single complete piece of code that Maple can execute. There are many
types of statements in Maple, including expression statements, assignment statements, se-
lection statements (if ... then), repetition statements (loops), and program instructions (quit,
save, read).
A statement differs from an expression in that it is normally evaluated for effect, rather than
for its value. Most statements that do not consist of a single expression are formed so as to
have a side effect.
Statements can be run in Maple one at a time, or multiple statements can be run on one line.
If multiple statements are run on one line, the statements must be separated by a statement
separator, either a semicolon (;) or a colon (:).
At the top level, the output of a statement that ends with a colon is hidden.
> a:=2: a^2;
(5.1)
Note: In the standard interface, for input in 2-D math, the semicolon at the end of a
statement can be omitted.
171
172 • 5 Maple Statements
> sin( Pi - x );
(5.3)
5.5 Assignments
Assignment statements allow you to associate a value or expression with a name. The as-
signment statement has the general form
lhs := rhs
Evaluating the assignment associates the value on the right-hand side of the assignment
with the name on the left-hand side. After the assignment has taken effect, the result is the
associated value when the assigned name is evaluated.
The following assignment statement associates the value 2 / 3 with the name a.
> a := 2 / 3;
(5.6)
(5.7)
> a + 1 / 3;
(5.8)