Maplesoft MAPLE Advanced Programming Guide

Maple
Advanced Programming
Guide
M. B. Monagan K. O. Geddes K. M. Heal
G. Labahn S. M. Vorkoetter J. McCarron
P. DeMarco
Maplesoft, a division of Waterloo Maple Inc. 1996-2010.
ii
Maplesoft, Maple, and Maplet are all trademarks of Waterloo Maple Inc.
© Maplesoft, a division of Waterloo Maple Inc. 1996-2010. All rights reserved.
Information in this document is subject to change without notice and does not represent a commitment on the part of the vendor. The software described in this document is furnished under a license agreement and may be used or copied only in accordance with the agreement. It is against the law to copy the software on any medium except as specifically allowed in the agreement.
Windows is a registered trademark of Microsoft Corporation. Java and all Java based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. Maplesoft is independent of Sun Microsystems, Inc. All other trademarks are the property of their respective owners.
This document was produced using a special version of Maple that reads and updates LaTeX files.
Printed in Canada
ISBN 978-1-897310-96-0
Contents
Preface 1
Audience . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Worksheet Graphical Interface . . . . . . . . . . . . . . . . . . 2
Manual Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Customer Feedback . . . . . . . . . . . . . . . . . . . . . . . . . 3
1 Procedures, Variables, and Extending Maple 5
Prerequisite Knowledge . . . . . . . . . . . . . . . . . . . 5
In This Chapter . . . . . . . . . . . . . . . . . . . . . . . 5
1.1 Nested Procedures . . . . . . . . . . . . . . . . . . . . . . 5
Scoping Rules . . . . . . . . . . . . . . . . . . . . . . . . . 6
Local Versus Global Variables . . . . . . . . . . . . . . . . 6
The Quick-Sort Algorithm . . . . . . . . . . . . . . . . . . 8
Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Creating a Uniform Random Number Generator . . . . . 11
1.2 Procedures That Return Procedures . . . . . . . . . . . . 14
Conveying Values . . . . . . . . . . . . . . . . . . . . . . . 14
Creating a Newton Iteration . . . . . . . . . . . . . . . . . 14
Example 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Example 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
A Shift Operator . . . . . . . . . . . . . . . . . . . . . . . 17
1.3 Local Variables and Invoking Procedures . . . . . . . . . . 19
Example 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Example 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Procedure as a Returned Object . . . . . . . . . . . . . . 22
Example 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Example 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.4 Interactive Input . . . . . . . . . . . . . . . . . . . . . . . 27
iii
iv Contents
Reading Strings from the Terminal . . . . . . . . . . . . . 27
Example 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Reading Expressions from the Terminal . . . . . . . . . . 28
Example 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Converting Strings to Expressions . . . . . . . . . . . . . 30
1.5 Extending Maple . . . . . . . . . . . . . . . . . . . . . . . 31
Defining New Types . . . . . . . . . . . . . . . . . . . . . 31
Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Neutral Operators . . . . . . . . . . . . . . . . . . . . . . 33
Example 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Extending Commands . . . . . . . . . . . . . . . . . . . . 39
1.6 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . 42
2 Programming with Modules 43
Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Module Versus Procedure . . . . . . . . . . . . . . . . . . 45
Accessing Module Exports . . . . . . . . . . . . . . . . . . 46
In This Chapter . . . . . . . . . . . . . . . . . . . . . . . 46
2.1 Syntax and Semantics . . . . . . . . . . . . . . . . . . . . 47
The Module Definition . . . . . . . . . . . . . . . . . . . . 47
The Module Body . . . . . . . . . . . . . . . . . . . . . . 48
Module Parameters . . . . . . . . . . . . . . . . . . . . . . 48
Named Modules . . . . . . . . . . . . . . . . . . . . . . . 48
Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Exported Local Variables . . . . . . . . . . . . . . . . . . 52
Module Options . . . . . . . . . . . . . . . . . . . . . . . . 57
Implicit Scoping Rules . . . . . . . . . . . . . . . . . . . . 58
Lexical Scoping Rules . . . . . . . . . . . . . . . . . . . . 58
Modules and Types . . . . . . . . . . . . . . . . . . . . . . 60
Example: A Symbolic Differentiator . . . . . . . . . . . . 61
2.2 Records . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
2.3 Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
What Is a Package . . . . . . . . . . . . . . . . . . . . . . 78
Writing Maple Packages by Using Modules . . . . . . . . 80
The LinkedList Package . . . . . . . . . . . . . . . . . . 80
Code Coverage Profiling Package . . . . . . . . . . . . . . 87
The Shapes Package . . . . . . . . . . . . . . . . . . . . . 95
2.4 The use Statement . . . . . . . . . . . . . . . . . . . . . . 103
Operator Rebinding . . . . . . . . . . . . . . . . . . . . . 106
Contents v
2.5 Modeling Objects . . . . . . . . . . . . . . . . . . . . . . . 108
Priority Queues . . . . . . . . . . . . . . . . . . . . . . . . 111
An Object-oriented Shapes Package . . . . . . . . . . . . 115
2.6 Interfaces and Implementations . . . . . . . . . . . . . . . 117
Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Generic Graph Algorithms . . . . . . . . . . . . . . . . . . 124
Quotient Fields . . . . . . . . . . . . . . . . . . . . . . . . 129
A Generic Group Implementation . . . . . . . . . . . . . . 138
2.7 Extended Example: A Search Engine . . . . . . . . . . . . 159
Introduction to Searching . . . . . . . . . . . . . . . . . . 159
Inverted Term Occurrence Indexing . . . . . . . . . . . . . 161
The Vector Space Model . . . . . . . . . . . . . . . . . . . 164
Term Weighting . . . . . . . . . . . . . . . . . . . . . . . . 167
Building a Search Engine Package . . . . . . . . . . . . . 168
Latent Semantic Analysis . . . . . . . . . . . . . . . . . . 172
The Search Engine Package . . . . . . . . . . . . . . . . . 173
Using the Package . . . . . . . . . . . . . . . . . . . . . . 180
2.8 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . 184
3 Input and Output 185
In This Chapter . . . . . . . . . . . . . . . . . . . . . . . 185
3.1 A Tutorial Example . . . . . . . . . . . . . . . . . . . . . 186
3.2 File Types and Modes . . . . . . . . . . . . . . . . . . . . 190
Buffered Files versus Unbuffered Files . . . . . . . . . . . 190
Text Files versus Binary Files . . . . . . . . . . . . . . . . 190
Read Mode versus Write Mode . . . . . . . . . . . . . . . 191
The default and terminal Files . . . . . . . . . . . . . . 191
3.3 File Descriptors versus File Names . . . . . . . . . . . . . 192
3.4 File Manipulation Commands . . . . . . . . . . . . . . . . 193
Opening and Closing Files . . . . . . . . . . . . . . . . . . 193
Position Determination and Adjustment . . . . . . . . . . 194
Detecting the End of a File . . . . . . . . . . . . . . . . . 195
Determining File Status . . . . . . . . . . . . . . . . . . . 195
Removing Files . . . . . . . . . . . . . . . . . . . . . . . . 196
3.5 Input Commands . . . . . . . . . . . . . . . . . . . . . . . 197
Reading Text Lines from a File . . . . . . . . . . . . . . . 197
Reading Arbitrary Bytes from a File . . . . . . . . . . . . 197
Formatted Input . . . . . . . . . . . . . . . . . . . . . . . 198
Reading Maple Statements . . . . . . . . . . . . . . . . . 204
Reading Tabular Data . . . . . . . . . . . . . . . . . . . . 204
3.6 Output Commands . . . . . . . . . . . . . . . . . . . . . . 206
vi Contents
Configuring Output Parameters Using the interface Com-
mand . . . . . . . . . . . . . . . . . . . . . . . . . 206
One-Dimensional Expression Output . . . . . . . . . . . . 206
Two-Dimensional Expression Output . . . . . . . . . . . . 207
Writing Maple Strings to a File . . . . . . . . . . . . . . . 210
Writing Bytes to a File . . . . . . . . . . . . . . . . . . . . 211
Formatted Output . . . . . . . . . . . . . . . . . . . . . . 211
Writing Tabular Data . . . . . . . . . . . . . . . . . . . . 215
Flushing a Buffered File . . . . . . . . . . . . . . . . . . . 217
Redirecting the default Output Stream . . . . . . . . . . 217
3.7 Conversion Commands . . . . . . . . . . . . . . . . . . . . 218
Conversion between Strings and Lists of Integers . . . . . 218
Parsing Maple Expressions and Statements . . . . . . . . 219
Formatted Conversion to and from Strings . . . . . . . . . 220
3.8 Notes to C Programmers . . . . . . . . . . . . . . . . . . . 221
3.9 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . 222
4 Numerical Programming in Maple 223
Floating-Point Calculations . . . . . . . . . . . . . . . . . 223
In This Chapter . . . . . . . . . . . . . . . . . . . . . . . 223
Why Use Numerical Computations . . . . . . . . . . . . . 223
4.1 The Basics of evalf . . . . . . . . . . . . . . . . . . . . . 224
4.2 Hardware Floating-Point Numbers . . . . . . . . . . . . . 227
Newton’s Method . . . . . . . . . . . . . . . . . . . . . . . 230
Computing with Arrays of Numbers . . . . . . . . . . . . 232
4.3 Floating-Point Models in Maple . . . . . . . . . . . . . . . 235
Software Floats . . . . . . . . . . . . . . . . . . . . . . . . 235
Roundoff Error . . . . . . . . . . . . . . . . . . . . . . . . 236
4.4 Extending the evalf Command . . . . . . . . . . . . . . . 238
Defining New Constants . . . . . . . . . . . . . . . . . . . 238
Defining New Functions . . . . . . . . . . . . . . . . . . . 240
4.5 Using the Matlab Package . . . . . . . . . . . . . . . . . . 243
4.6 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . 244
5 Programming with Maple Graphics 245
Maple Plots . . . . . . . . . . . . . . . . . . . . . . . . . . 245
Creating Plotting Procedures . . . . . . . . . . . . . . . . 245
In This Chapter . . . . . . . . . . . . . . . . . . . . . . . 245
5.1 Basic Plotting Procedures . . . . . . . . . . . . . . . . . . 246
Altering a Plot . . . . . . . . . . . . . . . . . . . . . . . . 248
5.2 Programming with Plotting Library Procedures . . . . . . 249
Contents vii
Plotting a Loop . . . . . . . . . . . . . . . . . . . . . . . . 249
Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
A Ribbon Plot Procedure . . . . . . . . . . . . . . . . . . 251
5.3 Maple Plot Data Structures . . . . . . . . . . . . . . . . . 254
The PLOT Data Structure . . . . . . . . . . . . . . . . . . 256
Arguments Inside a PLOT Structure . . . . . . . . . . . . . 257
A Sum Plot . . . . . . . . . . . . . . . . . . . . . . . . . . 259
The PLOT3D Data Structure . . . . . . . . . . . . . . . . . 262
Objects Inside a PLOT3D Data Structure . . . . . . . . . . 264
5.4 Programming with Plot Data Structures . . . . . . . . . . 266
Writing Graphic Primitives . . . . . . . . . . . . . . . . . 266
Plotting Gears . . . . . . . . . . . . . . . . . . . . . . . . 268
Polygon Meshes . . . . . . . . . . . . . . . . . . . . . . . . 272
5.5 Programming with the plottools Package . . . . . . . . 273
A Pie Chart . . . . . . . . . . . . . . . . . . . . . . . . . . 275
A Dropshadow Procedure . . . . . . . . . . . . . . . . . . 276
Creating a Tiling . . . . . . . . . . . . . . . . . . . . . . . 278
A Smith Chart . . . . . . . . . . . . . . . . . . . . . . . . 280
Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
Modifying Polygon Meshes . . . . . . . . . . . . . . . . . 281
5.6 Vector Field Plots . . . . . . . . . . . . . . . . . . . . . . 286
Drawing a Vector . . . . . . . . . . . . . . . . . . . . . . . 286
Generating a Vector Plot Field . . . . . . . . . . . . . . . 288
5.7 Generating Grids of Points . . . . . . . . . . . . . . . . . 296
5.8 Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
Animation in Static Form . . . . . . . . . . . . . . . . . . 302
Graphical Object as Input . . . . . . . . . . . . . . . . . . 302
Methods for Creating Animations . . . . . . . . . . . . . . 303
Two and Three Dimensions . . . . . . . . . . . . . . . . . 305
Demonstrating Physical Objects in Motion . . . . . . . . 306
5.9 Programming with Color . . . . . . . . . . . . . . . . . . . 308
Generating Color Tables . . . . . . . . . . . . . . . . . . . 309
Using Animation . . . . . . . . . . . . . . . . . . . . . . . 310
Adding Color Information to Plots . . . . . . . . . . . . . 312
Creating A Chess Board Plot . . . . . . . . . . . . . . . . 315
5.10 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . 316
6 Advanced Connectivity 319
In This Chapter . . . . . . . . . . . . . . . . . . . . . . . 319
Code Generation . . . . . . . . . . . . . . . . . . . . . . . 319
External Calling: Using Compiled Code in Maple . . . . . 319
viii Contents
OpenMaple: Using Maple in Compiled Code . . . . . . . . 319
6.1 Code Generation . . . . . . . . . . . . . . . . . . . . . . . 319
The CodeGeneration Package . . . . . . . . . . . . . . . . 319
Calling CodeGeneration Functions . . . . . . . . . . . . . 320
Translation Process . . . . . . . . . . . . . . . . . . . . . . 321
Extending the CodeGeneration Translation Facilities . . . 324
Defining a Custom Translator . . . . . . . . . . . . . . . . 325
6.2 External Calling: Using Compiled Code in Maple . . . . . 329
Method 1: Calling External Functions . . . . . . . . . . . 331
External Definition . . . . . . . . . . . . . . . . . . . . . . 333
Type Specification . . . . . . . . . . . . . . . . . . . . . . 334
Scalar Data Formats . . . . . . . . . . . . . . . . . . . . . 335
Structured Data Formats . . . . . . . . . . . . . . . . . . 335
Specifying Argument Passing Conventions . . . . . . . . . 337
Method 2: Generating Wrappers . . . . . . . . . . . . . . 337
Additional Types and Options . . . . . . . . . . . . . . . 338
Structured Data Formats . . . . . . . . . . . . . . . . . . 338
Enumerated Types . . . . . . . . . . . . . . . . . . . . . . 338
Procedure Call Formats . . . . . . . . . . . . . . . . . . . 339
Call by Reference . . . . . . . . . . . . . . . . . . . . . . . 339
Array Options . . . . . . . . . . . . . . . . . . . . . . . . 339
Non-passed Arguments . . . . . . . . . . . . . . . . . . . . 340
Argument Checking and Efficiency Considerations . . . . 341
Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Compiler Options . . . . . . . . . . . . . . . . . . . . . . . 343
Evaluation Rules . . . . . . . . . . . . . . . . . . . . . . . 347
Method 3: Customizing Wrappers . . . . . . . . . . . . . . 349
External Function Entry Point . . . . . . . . . . . . . . . 349
Inspecting Automatically Generated Wrappers . . . . . . 351
External API . . . . . . . . . . . . . . . . . . . . . . . . . 355
System Integrity . . . . . . . . . . . . . . . . . . . . . . . 373
6.3 OpenMaple: Using Maple in Compiled Code . . . . . . . . 373
Interface Overview . . . . . . . . . . . . . . . . . . . . . . 374
Call-back Functions . . . . . . . . . . . . . . . . . . . . . 379
Maple Online Help Database . . . . . . . . . . . . . . . . 385
Technical Issues . . . . . . . . . . . . . . . . . . . . . . . . 388
File Structure . . . . . . . . . . . . . . . . . . . . . . . . . 388
Building the Sample Program . . . . . . . . . . . . . . . . 389
6.4 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . 391
A Internal Representation and Manipulation 395
Contents ix
A.1 Internal Organization . . . . . . . . . . . . . . . . . . . . 395
Components . . . . . . . . . . . . . . . . . . . . . . . . . . 396
Internal Functions . . . . . . . . . . . . . . . . . . . . . . 396
Flow of Control . . . . . . . . . . . . . . . . . . . . . . . . 397
A.2 Internal Representations of Data Types . . . . . . . . . . 398
Logical AND . . . . . . . . . . . . . . . . . . . . . . . . . 399
Assignment Statement . . . . . . . . . . . . . . . . . . . . 399
Binary Object . . . . . . . . . . . . . . . . . . . . . . . . . 399
Break Statement . . . . . . . . . . . . . . . . . . . . . . . 399
Name Concatenation . . . . . . . . . . . . . . . . . . . . . 400
Complex Value . . . . . . . . . . . . . . . . . . . . . . . . 400
Communications Control Structure . . . . . . . . . . . . . 400
Type Specification or Test . . . . . . . . . . . . . . . . . . 401
Debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401
Equation or Test for Equality . . . . . . . . . . . . . . . . 401
Error Statement . . . . . . . . . . . . . . . . . . . . . . . 401
Expression Sequence . . . . . . . . . . . . . . . . . . . . . 402
Floating-Point Number . . . . . . . . . . . . . . . . . . . . 402
For/While Loop Statement . . . . . . . . . . . . . . . . . 402
Foreign Data . . . . . . . . . . . . . . . . . . . . . . . . . 403
Function Call . . . . . . . . . . . . . . . . . . . . . . . . . 404
Garbage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Hardware Float . . . . . . . . . . . . . . . . . . . . . . . . 404
If Statement . . . . . . . . . . . . . . . . . . . . . . . . . . 405
Logical IMPLIES . . . . . . . . . . . . . . . . . . . . . . . 405
Not Equal or Test for Inequality . . . . . . . . . . . . . . 405
Negative Integer . . . . . . . . . . . . . . . . . . . . . . . 405
Positive Integer . . . . . . . . . . . . . . . . . . . . . . . . 406
Less Than or Equal . . . . . . . . . . . . . . . . . . . . . . 406
Less Than . . . . . . . . . . . . . . . . . . . . . . . . . . . 407
Lexically Scoped Variable within an Expression . . . . . . 407
List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407
Local Variable within an Expression . . . . . . . . . . . . 408
Member . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
Module Definition . . . . . . . . . . . . . . . . . . . . . . 408
Module Instance . . . . . . . . . . . . . . . . . . . . . . . 410
Identifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
Next Statement . . . . . . . . . . . . . . . . . . . . . . . . 411
Logical NOT . . . . . . . . . . . . . . . . . . . . . . . . . 411
Logical OR . . . . . . . . . . . . . . . . . . . . . . . . . . 411
Procedure Parameter within an Expression . . . . . . . . 411
x Contents
Power . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
Procedure Definition . . . . . . . . . . . . . . . . . . . . . 412
Product, Quotient, Power . . . . . . . . . . . . . . . . . . 414
Range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
Rational . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
Read Statement . . . . . . . . . . . . . . . . . . . . . . . . 415
Return Statement . . . . . . . . . . . . . . . . . . . . . . 415
Rectangular Table . . . . . . . . . . . . . . . . . . . . . . 415
Save Statement . . . . . . . . . . . . . . . . . . . . . . . . 417
Series . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417
Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417
Statement Sequence . . . . . . . . . . . . . . . . . . . . . 417
Stop Maple . . . . . . . . . . . . . . . . . . . . . . . . . . 418
String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
Sum, Difference . . . . . . . . . . . . . . . . . . . . . . . . 418
Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
Table Reference . . . . . . . . . . . . . . . . . . . . . . . . 419
Try Statement . . . . . . . . . . . . . . . . . . . . . . . . 419
Unevaluated Expression . . . . . . . . . . . . . . . . . . . 420
Use Statement . . . . . . . . . . . . . . . . . . . . . . . . 420
Logical XOR . . . . . . . . . . . . . . . . . . . . . . . . . 421
Polynomials with Integer Coefficients modulo n . . . . . . 421
A.3 The Use of Hashing in Maple . . . . . . . . . . . . . . . . 422
Basic Hash Tables . . . . . . . . . . . . . . . . . . . . . . 422
Dynamic Hash Tables . . . . . . . . . . . . . . . . . . . . 423
The Simplification Table . . . . . . . . . . . . . . . . . . . 423
The Name Table . . . . . . . . . . . . . . . . . . . . . . . 424
Remember Tables . . . . . . . . . . . . . . . . . . . . . . . 425
Maple Language Arrays and Tables . . . . . . . . . . . . . 426
Maple Language Rectangular Tables . . . . . . . . . . . . 426
A.4 Portability . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
Index 429
Preface
This manual describes advanced MapleTMprogramming concepts, includ­ing:
Variable scope, procedures, modules, and packages
Advanced input and output
Numerical programming
Programming with Maple plots
Connectivity: translating Maple code to other programming lan-
guages, calling external libraries from Maple, and calling Maple code from external libraries
Internal representation and manipulation
Audience
This manual provides information for experienced Maple programmers. You should be familiar with the following.
Maple Online Help Introduction
Example worksheets
How to use Maple interactively
The
Introductory Programming Guide
1
2 Preface
Worksheet Graphical Interface
You can access the power of the Maple computation engine through a vari­ety of user interfaces: the standard worksheet, the command-line1version,
r
the classic worksheet (not available on Macintosh
), and custom-built
MapletTMapplications. The full Maple system is available through all of these interfaces. In this manual, any references to the graphical Maple interface refer to the standard worksheet interface. For more information on the various interface options, refer to the ?versions help page.
Manual Set
There are three other manuals available for Maple users, the
Maple Get-
ting Started Guide, the Maple User Manual, and the Maple Introduc­tory Programming Guide.
2
The Maple Getting Started Guide provides extensive information for new users on using Maple, and the resources available in the soft­ware and on the Maplesoft Web site (http://www.maplesoft.com).
The
Maple User Manual provides an overview of the Maple software including Document and Worksheet modes, performing computations, creating plots and animations, creating and using Maplets, creating mathematical documents, expressions, basic programming informa­tion, and basic input and output information.
The Maple Introductory Programming Guide introduces the basic Maple programming concepts, such as expressions, data structures, looping and decision mechanisms, procedures, input and output, de­bugging, and the Maplet User Interface Customization System.
The Maple software also has an online help system. The Maple help sys­tem allows you to search in many ways and is always available. There are also examples that you can copy, paste, and execute immediately.
1
The command-line version provides optimum performance. However, the worksheet interface is easier to use and renders typeset, editable math output and higher quality plots.
2
The Student Edition does not include the Maple Introductory Programming Guide and the Maple Advanced Programming Guide. These programming guides can be pur- chased from school and specialty bookstores or directly from Maplesoft.
Conventions 3
Conventions
This manual uses the following typographical conventions.
courier font - Maple command, package name, and option name
bold roman font - dialog, menu, and text field
italics - new or important concept, option name in a list, and manual
titles
Note - additional information relevant to the section
Important - information that must be read and followed
Customer Feedback
Maplesoft welcomes your feedback. For suggestions and comments related to this and other manuals, email doc@maplesoft.com
.
4 Preface
1 Procedures, Variables,
and Extending Maple
Prerequisite Knowledge
Before reading this chapter, you must have an understanding of Maple evaluation rules for variables and parameters as described in chapter 6 of
Introductory Programming Guide.
the
In This Chapter
Nested Procedures You can define a Maple procedure within another
Maple procedure.
Procedures That Return Procedures You can create procedures that return procedures by using Maple evaluation rules.
Local Variables Local variables can exist after the procedure which cre­ated them has exited. This feature allows a procedure to return a proce­dure. The new procedure requires a unique place to store information.
Interactive Input You can write interactive procedures, querying the user for missing information or creating an interactive tutorial or a test.
Extending Maple The Maple software includes useful mechanisms for extending Maple functionality, which reduce the need to write special­purpose procedures. Several Maple commands can be extended.
1.1 Nested Procedures
You can define a Maple procedure inside another Maple procedure. Some Maple commands are very useful inside a procedure. In the worksheet
5
6 Chapter 1: Procedures, Variables, and Extending Maple
environment, the map command is used to apply an operation to the elements of a structure. For example, you can divide each element of a list by a number, such as 8.
>
lst := [8, 4, 2, 16]:
>
map( x->x/8, lst);
1
1
,
[1,
, 2]
2
4
Consider a variation on the map command, which appears in the fol-
lowing procedure.
Example This new procedure divides each element of a list by the first element of that list.
>
nest := proc(x::list)
>
local v;
>
v := x[1];
>
map( y -> y/v, x );
>
end proc:
>
nest(lst);
1
1
,
[1,
, 2]
2
4
The procedure nest contains a second procedure, map, which in this case is the Maple command map. Maple applies its lexical scoping rules, which declare the v within the call to map as the same v as in the outer procedure, nest.
Scoping Rules
This section explains Maple scoping rules. You will learn how Maple de­termines which variables are local to a procedure and which are global. You must have a basic understanding of Maple evaluation rules for pa­rameters, and for local and global variables. For more information, refer to chapter 6 of the
Introductory Programming Guide.
Local Versus Global Variables
In general, when writing a procedure, you should explicitly declare which variables are global and which are local. Declaring the scope of the vari­ables makes your procedure easier to read and debug. However, sometimes declaring the variables is not the best method. In the previous nest pro­cedure, the variable in the map command is defined by the surrounding
1.1 Nested Procedures 7
procedure. What happens if you define this variable, v, as local to the invocation of the procedure within map?
>
nest2 := proc(x::list)
>
local v;
>
v := x[1];
>
map( proc(y) local v; y/v; end, x );
>
end proc:
>
nest2(lst);
4
2
8
,
[
v
16
,
,
v
]
v
v
The nest2 procedure produces different results. When the variables are declared in the inner procedure, the proper values from the enclosing procedure are not used. Either a variable is local to a procedure and certain procedures that are completely within it, or it is global to the entire Maple session.
Rule Maple determines whether a variable is local or global, from the inside procedure to the outside procedure. The name of the variable is searched for among:
1. Parameters of the inner procedure
2. Local declarations and global declarations of the inner procedure
3. Parameters of the outside procedure
4. Local and global declarations of the outside procedure
5. Implicitly declared local variables of any surrounding procedure(s)
If found, that specifies the binding of the variable.
If, using the above rule, Maple cannot determine whether a variable is global or local, the following default decisions are made.
If a variable appears on the
left side of an explicit assignment or as the controlling variable of a for loop, Maple regards the variable as local.
Otherwise, Maple regards the variable as global to the whole session. In particular, Maple assumes by default that the variables you pass as arguments to other procedures, which may set their values, are global.
8 Chapter 1: Procedures, Variables, and Extending Maple
The Quick-Sort Algorithm
Sorting a few numbers is quick using any method, but sorting large amounts of data can be very time consuming; thus, finding efficient meth­ods is important.
The following quick-sort algorithm is a classic algorithm. The key to
understanding this algorithm is to understand the operation of partition­ing. This involves choosing any one number from the array that you are about to sort. Then, you reposition the numbers in the array that are less than the number that you chose to one end of the array and reposition numbers that are greater to the other end. Lastly, you insert the chosen number between these two groups.
At the end of the partitioning, you have not yet entirely sorted the
array, because the numbers less than or greater than the one you chose may still be in their original order. This procedure divides the array into two smaller arrays which are easier to sort than the original larger one. The partitioning operation has thus made the work of sorting much eas­ier. You can bring the array one step closer in the sorting process by partitioning each of the two smaller arrays. This operation produces four smaller arrays. You sort the entire array by repeatedly partitioning the smaller arrays.
Example
The partition procedure uses an array to store the list because you can change the elements of an array directly. Thus, you can sort the array in place and not waste any space generating extra copies.
The quicksort procedure is easier to understand if you look at the
procedure partition in isolation first. This procedure accepts an array of numbers and two integers. The two integers are element numbers of the array, indicating the portion of the array to partition. While you could possibly choose any of the numbers in the array to partition around, this procedure chooses the last element of the section of the array for that purpose, namely A[n]. The intentional omission of global and local statements shows which variables Maple recognizes as local and which are global by default. It is recommended, however, that you not make this omission in your procedures.
>
partition := proc(A::array(1, numeric),
> > > > > >
i := m; j := n; x := A[j]; while i<j do
if A[i]>x then
m::posint, n::posint)
1.1 Nested Procedures 9
> > > > > > > > > >
Warning, ‘i‘ is implicitly declared local to procedure ‘partition‘ Warning, ‘j‘ is implicitly declared local to procedure ‘partition‘ Warning, ‘x‘ is implicitly declared local to procedure ‘partition‘
end do; A[j] := x; eval(A);
end proc:
A[j] := A[i]; j := j-1; A[i] := A[j];
else
i := i+1;
end if;
Maple declares i, j, and x local because the partition procedure con-
tains explicit assignments to those variables. The partition procedure also assigns explicitly to A, but A is a parameter, not a local variable. Because you do not assign to the name eval, Maple makes it the global name which refers to the eval command.
After partitioning the array a in the following, all the elements less
than 3 precede 3 but they are in no particular order; similarly, the elements larger than 3 come after 3.
>
a := array( [2,4,1,5,3] );
a := [2, 4, 1, 5, 3]
>
partition( a, 1, 5);
[2, 1, 3, 5, 4]
The partition procedure modifies its first argument, changing a.
>
eval(a);
[2, 1, 3, 5, 4]
The final step in assembling the quicksort procedure is to insert
the partition procedure within an outer procedure. The outer proce­dure first defines the partition subprocedure, then partitions the array. In general, avoid inserting one procedure in another. However, you will
10 Chapter 1: Procedures, Variables, and Extending Maple
encounter situations in following sections of this chapter in which it is nec­essary to nest procedures. Since the next step is to partition each of the two subarrays by calling quicksort recursively, partition must return the location of the element which divides the partition.
Example This example illustrates the role of nested procedures. The outer procedure, quicksort, contains the inner procedure, partition.
>
quicksort := proc(A::array(1, numeric),
> >
local partition, p;
> >
partition := proc(m,n)
> > > > > > > > > > > > > > > > > > > > > > > >
end proc:
i := m; j := n; x := A[j]; while i<j do
if A[i]>x then
A[j] := A[i]; j := j-1; A[i] := A[j];
else
i := i+1;
end if; end do; A[j] := x; p := j;
end proc:
if m<n then # if m>=n there is nothing to do
p:=partition(m, n); quicksort(A, m, p-1); quicksort(A, p+1, n);
end if;
eval(A);
m::integer, n::integer)
Warning, ‘i‘ is implicitly declared local to procedure ‘partition‘ Warning, ‘j‘ is implicitly declared local to procedure ‘partition‘ Warning, ‘x‘ is implicitly declared local to procedure ‘partition‘
>
a := array( [2,4,1,5,3] );
a := [2, 4, 1, 5, 3]
1.1 Nested Procedures 11
>
quicksort( a, 1, 5);
[1, 2, 3, 4, 5]
>
eval(a);
[1, 2, 3, 4, 5]
Maple determines that the A and p variables in the partition sub­procedure are defined by the parameter and local variable (respectively) from the outer quicksort procedure and everything works as planned. The variable A can be passed as a parameter to the partition subproce­dure (as in the stand-alone partition procedure). However, A does not need to be passed because, by using Maple scoping rules, it is available to the inner procedure.
Creating a Uniform Random Number Generator
If you want to use Maple to simulate physical experiments, you likely need a random number generator. The uniform distribution is particu­larly simple: any real number in a given range is equally likely. Thus, a uniform random number generator is a procedure that returns a ran­dom floating-p oint number within a certain range. This section develops the procedure, uniform, which creates uniform random number genera­tors.
The rand command generates a procedure which returns random
. For example, rand(4..7) generates a procedure that returns ran-
tegers
dom integers between 4 and 7, inclusive.
>
f := rand(4..7):
>
seq( f(), i=1..20 );
in-
4, 6, 6, 5, 4, 7, 5, 5, 6, 7, 7, 5, 4, 6, 7, 4, 7, 4, 5, 6
The uniform procedure is similar to rand but returns floating-point numbers rather than integers. You can use rand to generate random floating-point numbers between 4 and 7 by multiplying and dividing by 10^Digits.
>
f := rand( 4*10^Digits..7*10^Digits ) / 10^Digits:
>
f();
12 Chapter 1: Procedures, Variables, and Extending Maple
9482484381 2000000000
The procedure f returns fractions rather than floating-point numbers so you must compose it with evalf; that is, use evalf(f()). Alterna­tively, you can perform this operation by using the Maple composition operator, @.
>
(evalf @ f)();
5.709873593
The following uniform procedure uses evalf to evaluate the constants in the range specification, r, to floating-point numbers, the map command to multiply both endpoints of the range by 10^Digits, and round to round the results to integers.
>
uniform := proc( r::constant..constant )
>
local intrange, f;
>
intrange := map( x -> round(x*10^Digits), evalf(r) );
>
f := rand( intrange );
>
(evalf @ eval(f)) / 10^Digits;
>
end proc:
You can now generate random floating-point numbers between 4 and 7.
>
U := uniform(4..7):
>
seq( U(), i=1..20 );
4.906178722, 4.342783855, 5.845560096, 5.720041409,
4.477799871, 6.851756647, 4.806779819,
5.504811662, 6.060694649, 6.238504456,
6.440125341, 5.459747079, 5.177099028,
5.921894219, 6.758265656, 5.792661441,
4.988664160, 4.994950840, 4.374705325,
5.782030884
The uniform procedure has a serious flaw: uniform uses the current value of Digits to construct intrange; thus, U depends on the value of Digits when uniform creates it. On the other hand, the evalf command within U uses the value of Digits that is current when you invoke U. These two values are not always identical.
1.1 Nested Procedures 13
>
U := uniform( cos(2)..sin(1) ):
>
Digits := 15:
>
seq( U(), i=1..8 );
0.440299060400000, 0.366354657300000,
0.0671154810000000, 0.224056281100000,
0.131130435700000, 0.496918815000000,
0.464843910000000, 0.458498021000000
The proper design choice here is that U should depend only on the value of Digits when you invoke U. The following version of uniform accomplishes this by placing the entire computation inside the procedure that uniform returns.
>
uniform := proc( r::constant..constant )
> >
proc()
> > > > > > >
end proc:
local intrange, f; intrange := map( x -> round(x*10^Digits),
evalf(r) ); f := rand( intrange ); evalf( f()/10^Digits );
end proc;
The r within the inner proc is not declared as local or global, so it
becomes the same r as the parameter to the outer proc.
The procedure that uniform generates is now independent of the value
of Digits at the time you invoke uniform.
>
U := uniform( cos(2)..sin(1) ):
>
Digits := 15:
>
seq( U(), i=1..8 );
0.0785475551312100, 0.129118535641837,
0.153402552054527, 0.469410168730666,
0.0284411444410350, −0.136140726546643,
0.156491822876214, 0.0848249080831220
Note: The interface variable displayprecision controls the number of decimal places to be displayed. The default value is 1, representing full precision as determined by the Digits environment variable. This sim­plifies display without introducing round-off error. For more information, refer to ?interface.
14 Chapter 1: Procedures, Variables, and Extending Maple
Summary This section introduced:
Rules Maple uses to distinguish global and local variables
Principal implications of these rules
Tools available for writing nested procedures
1.2 Procedures That Return Procedures
Some of the standard Maple commands return procedures. For example, rand returns a procedure which in turn produces randomly chosen inte­gers from a specified range. The dsolve function with the type=numeric option returns a procedure which supplies a numeric estimate of the so­lution to a differential equation.
You can write procedures that return procedures. This section dis­cusses how values are passed from the outer procedure to the inner pro­cedure.
Conveying Values
The following example demonstrates how locating the roots of a function by using Newton’s method can be implemented in a procedure.
Creating a Newton Iteration
Use Newton’s method to find the roots of a function.
1. Choose a point on the x-axis that you think might be close to a root.
2. Find the slope of the curve at the point you chose.
3. Draw the tangent to the curve at that point and observe where the tangent intersects the x-axis. For most functions, this second point is closer to the real root than your initial guess. To find the root, use the new point as a new guess and keep drawing tangents and finding new points.
1.2 Pro cedures That Return Procedures 15
2
1.5
1
0.5
–0.5
0
–1
1 2 3 4
x1x0
5
x
7
6
8
To find a numerical solution to the equation f (x) = 0, guess an ap-
proximate solution, x0, and then generate a sequence of approximations using:
1. Newton’s method
2. The following formulation of the previous process
x
k+1
= xk−
f (xk)
f0(xk)
You can implement this algorithm on a computer in a number of ways.
Example 1
The following procedure takes a function and creates a new procedure, which takes an initial guess and, for that particular function, generates the next guess. The new procedure does not work for other functions. To find the roots of a new function, use MakeIteration to generate a new guess-generating procedure. The unapply command turns an expression into a procedure.
>
MakeIteration := proc( expr::algebraic, x::name )
>
local iteration;
>
iteration := x - expr/diff(expr, x);
>
unapply(iteration, x);
>
end proc:
The procedure returned by the MakeIteration procedure maps the
name x to the expression assigned to the iteration. Test the procedure on the expression x 2
>
expr := x - 2*sqrt(x);
x.
16 Chapter 1: Procedures, Variables, and Extending Maple
expr := x 2√x
>
Newton := MakeIteration( expr, x);
Newton := x x
x 2√x
1
1
x
Newton returns the solution, x = 4 after a few iterations.
>
x0 := 2.0;
x0 := 2.0
>
to 4 do x0 := Newton(x0); end do;
x0 := 4.828427124
x0 := 4.032533198
x0 := 4.000065353
x0 := 4.000000000
Example 2
The MakeIteration procedure requires its first argument to be an al­gebraic expression. You can also write a version of MakeIteration that works on functions. Since the following MakeIteration procedure recog­nizes the parameter f as a procedure, you must use the eval command to evaluate it fully.
>
MakeIteration := proc( f::procedure )
>
(x->x) - eval(f) / D(eval(f));
>
end proc:
>
g := x -> x - cos(x);
g := x x cos(x)
>
SirIsaac := MakeIteration( g );
SirIsaac := (x x)
x x cos(x)
x 1 + sin(x)
1.2 Pro cedures That Return Procedures 17
Note that SirIsaac is independent of the name g. Thus, you can
change g without breaking SirIsaac. You can find a go od approximate solution to x cos(x) = 0 in a few iterations.
>
x0 := 1.0;
x0 := 1.0
>
to 4 do x0 := SirIsaac(x0) end do;
x0 := 0.7503638679
x0 := 0.7391128909
x0 := 0.7390851334
x0 := 0.7390851332
A Shift Operator
Consider the problem of writing a procedure that takes a function, f , as input and returns a function, g, such that g(x) = f (x + 1). You can write such a procedure in the following manner.
>
shift := (f::procedure) -> ( x->f(x+1) ):
Try performing a shift on sin(x).
>
shift(sin);
x → sin(x + 1)
Maple lexical scoping rules declare the f within the inner procedure
to be the same f as the parameter within the outer procedure. Therefore, the shift command works as written.
The previous example of shift works with univariate functions but
it does not work with functions of two or more variables.
>
h := (x,y) -> x*y;
h := (x, y) x y
>
hh := shift(h);
18 Chapter 1: Procedures, Variables, and Extending Maple
hh := x h(x + 1)
>
hh(x,y);
Error, (in h) h uses a 2nd argument, y, which is missing
Multivariate Functions To modify shift to work with multivariate functions, rewrite it to accept the additional parameters.
In a procedure, args is the sequence of actual parameters, and
args[2..-1] is the sequence of actual parameters except the first one. For more information on the selection operation ([ ]), refer to chapter 4 of the
Introductory Programming Guide. It follows that the procedure x->f(x+1,args[2..-1]) passes all its arguments except the first directly to f .
>
shift := (f::procedure) -> ( x->f(x+1, args[2..-1]) ):
>
hh := shift(h);
>
hh(x,y);
hh := x h(x + 1, args
2..1
)
(x + 1) y
The function hh depends on h; if you change h, you implicitly change
hh;
>
h := (x,y,z) -> y*z^2/x;
2
y z
x
2
>
hh(x,y,z);
h := (x, y, z)
y z
x + 1
1.3 Lo cal Variables and Invoking Procedures 19
1.3 Local Variables and Invoking Procedures
Local variables are local to a procedure and to an invocation of that procedure. Calling a procedure creates and uses new local variables each time. If you invoke the same procedure twice, the local variables it uses the second time are distinct from those it used the first time.
Local variables do not necessarily disappear when the procedure exits. You can write procedures which return a local variable, either explicitly or implicitly, to the interactive session, where it can exist indefinitely. These variables are called escaped local variables. This concept can be confusing, particularly since they can have the same name as global variables, or local variables which another procedure or a different call to the same procedure created. You can create many distinct variables with the same name.
Example 1
The following procedure creates a new local variable, a, and then returns this new variable.
>
make_a := proc()
> > >
end proc;
local a; a;
make_a := proc() local a; a end proc
By using local variables, you can produce displays that Maple would otherwise simplify. For example, in Maple, a set contains
unique elements. The following demonstrates that each variable a that make_a returns is unique.
>
test := { a, a, a };
test := {a}
>
test := test union { make_a() };
test := {a, a}
>
test := test union { ’make_a’()$5 };
test := {a, a, a, a, a, a, a}
20 Chapter 1: Procedures, Variables, and Extending Maple
This demonstrates that Maple identities consist of more than names.
Important: Independent of the number of variables you create with the same name, when you type a name in an interactive session, Maple interprets that name to be a global variable . You can easily find the global a in the previous set test.
>
seq( evalb(i=a), i=test);
true, false , false, false , false, false , false
Example 2
You can display expressions that Maple would ordinarily simplify au­tomatically. For example, Maple automatically simplifies the expression a + a to 2a. It is difficult to display the equation a + a = 2a. To display such an equation, use the procedure make_a from Example 1.
>
a + make_a() = 2*a;
a + a = 2 a
When you type a name in an interactive session, the Maple program interprets it as the global variable. While this prevents you from using the assignment
statement to directly assign a value to an escaped local variable, it does not prevent you from using the assign command. You must write a Maple expression which extracts the variable. For example, in the previous equation, you can extract the local variable a by removing the global a from the left side of the equation.
>
eqn := %;
eqn := a + a = 2 a
>
another_a := remove( x->evalb(x=a), lhs(eqn) );
another_a := a
You can then assign the global name a to this extracted variable and
verify the equation.
Loading...
+ 422 hidden pages