Maxima Workbook
Maxima Workbook
Roland Salz
Vers. 1.0.0
This work is published under the terms of the
GNU GPL-3.0 License.
Roland Salz
Braunsberger Str. 26
D-44809 Bochum
[email protected]
i
In some cases the objective is clear − and the results are surprising.
Richard J. Fateman
ii
Preface
iii
Contents
Preface iii
1 Historical evolution 2
1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 MAC, MACLisp and MACSyMa: The project at MIT . . . . . . . . . . . . . . 2
1.2.1 Initialization and basic design concepts . . . . . . . . . . . . . . . . 2
1.2.2 Major contributors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2.3 The users’ community . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Users’ conferences and first competition . . . . . . . . . . . . . . . . . . . 4
1.3.1 The beginning of Mathematica . . . . . . . . . . . . . . . . . . . . . . 4
1.3.2 Announcement of Maple . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 Commercial licensing of Macsyma . . . . . . . . . . . . . . . . . . . . . . . . 5
1.4.1 End of the development at MIT . . . . . . . . . . . . . . . . . . . . . . 5
1.4.2 Symbolics, Inc. and Macsyma, Inc. . . . . . . . . . . . . . . . . . . . 5
1.5 Academic and US government licensing . . . . . . . . . . . . . . . . . . . . 6
1.5.1 Berkeley Macsyma and DOE Macsyma . . . . . . . . . . . . . . . . . 6
1.5.2 William Schelter at the University of Texas . . . . . . . . . . . . . . 7
1.6 GNU public licensing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.6.1 Maxima, the open source project since 2001 . . . . . . . . . . . . . 7
1.7 Further reading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2 Documentation 9
2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2 Official documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.1 Manuals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.1.1 English current version . . . . . . . . . . . . . . . . . . . . . 10
2.2.1.2 German version from 2011 . . . . . . . . . . . . . . . . . . . 10
2.3 External documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3.1 Manuals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3.1.1 Paulo Ney de Souza: The Maxima Book, 2004 . . . . . . . 10
2.3.2 Tutorials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3.2.1 Michel Talon: Rules and Patterns in Maxima, 2019 . . . . 11
2.3.2.2 Jorge Alberto Calvo: Scientific Programming, 2018 . . . 11
2.3.2.3 Zachary Hannan: wxMaxima for Calculus I + II, 2015 . . 11
2.3.2.4 Wilhelm Haager: Computeralgebra mit Maxima: Grund-
lagen der Anwendung und Programmierung, 2014 . . . 11
iv
2.3.2.5 Wilhelm Haager: Grafiken mit Maxima, 2011 . . . . . . . 11
2.3.2.6 Roland Stewen: Maxima in Beispielen, 2013 . . . . . . . . 11
2.3.3 Mathematics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3.3.1 G. Jay Kerns: Multivariable Calculus with Maxima, 2009 12
2.3.4 Physics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3.4.1 Edwin L. (Ted) Woollett: "Maxima by Example", 2018,
and "Computational Physics with Maxima or R" . . . . . . 12
2.3.4.2 Timberlake and Mixon: Classical Mechanics with Max-
ima, 2016 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3.4.3 Viktor Toth: Tensor Manipulation in GPL Maxima . . . . . 12
2.3.5 Engineering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3.5.1 Andreas Baumgart: Toolbox Technische Mechanik, 2018 12
2.3.5.2 Wilhelm Haager: Control Engineering with Maxima, 2017 13
2.3.5.3 Tom Fredman: Computer Mathematics for the Engi-
neer, 2014 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.5.4 Gilberto Urroz: Maxima: Science and Engineering Ap-
plications, 2012 . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.6 Economics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.6.1 Hammock and Mixon: Microeconomic Theory and Com-
putation, 2013 . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.6.2 Leydold and Petry: Introduction to Maxima for Eco-
nomics, 2011 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.4 Articles and Papers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.4.1 Publications by Richard Fateman . . . . . . . . . . . . . . . . . . . . 13
2.5 Comparison with other CAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.5.1 Tom Fredman: Computer Mathematics for the Engineer, 2014 . 14
2.6 Internal and program documentation . . . . . . . . . . . . . . . . . . . . . . 14
2.7 Mailing list archives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
II Basic Operation 15
3 Basics 16
3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.1.1 REPL: The read-evaluate-print loop . . . . . . . . . . . . . . . . . . . 16
3.1.2 Command line oriented vs. graphical user interfaces . . . . . . . 17
3.2 Basic operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.2.1 Executing an input line or cell . . . . . . . . . . . . . . . . . . . . . . 18
3.3 Basic notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3.1 Output description and numbering conventions . . . . . . . . . . . 18
3.3.2 Syntax description operators . . . . . . . . . . . . . . . . . . . . . . . 18
3.3.3 Compound and separation operators . . . . . . . . . . . . . . . . . . 18
3.3.4 Assignment operators . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.3.4.1 Basic : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.3.4.2 Indirect :: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.3.5 Miscellaneous operators . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.3.5.1 Comment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
v
3.3.5.2 Documentation reference . . . . . . . . . . . . . . . . . . . . 21
3.4 Naming of identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.4.1 MaximaL naming specifications . . . . . . . . . . . . . . . . . . . . . 22
3.4.1.1 Case sensitivity . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.4.1.2 ASCII standard . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.4.1.3 Unicode support . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.4.1.3.1 Implementation notes . . . . . . . . . . . . . . . . . 23
3.4.2 MaximaL naming conventions . . . . . . . . . . . . . . . . . . . . . . 23
3.4.2.1 System functions and variables . . . . . . . . . . . . . . . . 23
3.4.2.2 System constants . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.4.3 Correpondence of MaximaL and Lisp identifiers . . . . . . . . . . . 24
vi
5.2.3.1 plot3d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5.2.3.1.1 Explicit plot . . . . . . . . . . . . . . . . . . . . . . . . 40
5.2.3.1.2 Parametric plot . . . . . . . . . . . . . . . . . . . . . 42
5.2.3.2 Coordinate transformations for 3D . . . . . . . . . . . . . . 42
5.2.3.2.1 Standard coordinate transformations . . . . . . . 43
5.2.3.2.2 User-defined coordinate transformations . . . . . 43
5.2.3.3 Options for 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.3 Draw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.3.2 General structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5.3.2.1 Using options . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5.3.2.1.1 General syntax . . . . . . . . . . . . . . . . . . . . . 45
5.3.2.1.2 Setting defaults for multiple scenes . . . . . . . . 45
5.3.2.1.3 Predefined personal sets of options . . . . . . . . 45
5.3.2.1.4 User_preamble . . . . . . . . . . . . . . . . . . . . . . 46
5.3.2.1.4.1 Predefined personal user_preambles . . . 46
5.3.3 2D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.3.3.1 Explicit plot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.3.3.1.1 Piecewise defined function . . . . . . . . . . . . . . 46
5.3.3.2 Implicit plot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.3.3.3 Polar plot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.3.4 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.3.4.1 Explicit plot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.3.4.2 Implicit plot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.3.5 List of available options . . . . . . . . . . . . . . . . . . . . . . . . . . 49
6 Batch Processing 50
vii
7.2.3.2 Big floating point numbers . . . . . . . . . . . . . . . . . . . 56
7.2.4 Complex numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
7.2.4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
7.2.4.1.1 Imaginary unit . . . . . . . . . . . . . . . . . . . . . . 56
7.2.4.1.2 Internal representation . . . . . . . . . . . . . . . . 57
7.2.4.1.3 Canonical order . . . . . . . . . . . . . . . . . . . . . 57
7.2.4.1.4 Simplification . . . . . . . . . . . . . . . . . . . . . . . 57
7.2.4.1.5 Properties . . . . . . . . . . . . . . . . . . . . . . . . . 58
7.2.4.1.6 Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
7.2.4.1.7 Generic complex data type . . . . . . . . . . . . . . 58
7.2.4.2 Standard (rectangular) and polar form . . . . . . . . . . . 58
7.2.4.2.1 Standard (rectangular) form . . . . . . . . . . . . . 58
7.2.4.2.2 Polar coordinate form . . . . . . . . . . . . . . . . . 59
7.2.4.3 Complex conjugate . . . . . . . . . . . . . . . . . . . . . . . . 59
7.2.4.3.1 Internal representation . . . . . . . . . . . . . . . . 60
7.2.4.4 Predicate function . . . . . . . . . . . . . . . . . . . . . . . . . 60
7.3 Boolean values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
7.4 Constant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
7.5 Sharing of data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
9 Expression 63
9.1 General definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
9.2 Forms of representation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
9.2.1 User visible form (UVF) . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
9.2.2 General internal form (GIF) . . . . . . . . . . . . . . . . . . . . . . . . 64
9.2.3 Canonical rational expression (CRE) . . . . . . . . . . . . . . . . . . 65
9.3 Canonical order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
9.4 Noun and verb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
9.5 Equation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
9.6 Reference to subexpression . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
9.6.1 Identify and pick out subexpression . . . . . . . . . . . . . . . . . . . 66
9.6.2 Substitute subexpression . . . . . . . . . . . . . . . . . . . . . . . . . 67
9.7 Manipulate expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
9.7.1 Substitute pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
9.7.1.1 subst: substitute explicite pattern . . . . . . . . . . . . . . 67
9.7.1.2 ratsubst: substitute implicit mathematical pattern . . . 69
9.7.2 Box and rembox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
10 Operators 71
10.1 Defining and using operators . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
10.1.1 Function notation of an operator . . . . . . . . . . . . . . . . . . . . . 71
viii
10.1.2 Miscellaneous . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
10.2 System defined operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
10.2.1 Identity operators and functions . . . . . . . . . . . . . . . . . . . . . 71
10.2.1.1 Equation operator . . . . . . . . . . . . . . . . . . . . . . . . . 71
10.2.1.2 Inequation operator . . . . . . . . . . . . . . . . . . . . . . . 72
10.2.1.3 equal, notequal . . . . . . . . . . . . . . . . . . . . . . . . . . 72
10.2.1.4 is, is(a=b), is(equal(a,b)) . . . . . . . . . . . . . . . . . . . . 74
10.2.2 Relational operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
10.2.3 Logical (Boolean) operators . . . . . . . . . . . . . . . . . . . . . . . . 75
11 Evaluation 76
11.1 Introduction to evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
11.1.1 Stavros’ warning note about ev and quote-quote . . . . . . . . . . 76
11.2 Function ev . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
11.3 Quote-quote operator 0 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
11.4 Substitution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
11.4.1 Substituting values for variables . . . . . . . . . . . . . . . . . . . . . 80
12 Simplification 81
12.1 Properties for simplification . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
12.2 General simplification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
12.2.1 Conversion between (complex) exponentials and circular/hy-
perbolic functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
12.3 Trigonometric simplification . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
12.4 Own simplification functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
12.4.1 Apply2Part . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
12.4.2 ChangeSign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
12.4.3 FactorTerms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
12.4.4 PullFactorOut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
ix
13.4 Assumptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
13.4.1 User interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
13.4.1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
13.4.1.2 Functions and system variables for assumptions . . . . . 96
13.4.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
17 Polynomials 120
17.1 Polynomial division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .120
17.2 Partial fraction decomposition . . . . . . . . . . . . . . . . . . . . . . . . . .120
x
18 Solving Equations 122
18.1 The different solvers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .122
18.1.1 Linsolve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .122
18.1.2 Algsys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .122
18.1.3 Solve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .122
18.1.4 To_poly_solve, %solve . . . . . . . . . . . . . . . . . . . . . . . . . . . .122
18.2 Special tasks and techniques . . . . . . . . . . . . . . . . . . . . . . . . . . .123
18.2.1 Eliminate variables from a system of equations . . . . . . . . . . .123
18.2.2 Solving trigonometric or hyperbolic expressions . . . . . . . . . .124
18.2.2.1 Exponentialize and solve or eliminate . . . . . . . . . . . .124
18.2.2.2 To_poly and to_poly_solve or elim(_allbut) . . . . . . . . .124
xi
19.4.4.4.1 Identity matrix . . . . . . . . . . . . . . . . . . . . . .138
19.4.4.4.2 Zero matrix . . . . . . . . . . . . . . . . . . . . . . . .138
19.4.4.4.3 Diagonal matrix . . . . . . . . . . . . . . . . . . . . .138
19.4.4.5 Genmatrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .138
19.4.5 Transform between representations . . . . . . . . . . . . . . . . . . .139
19.4.5.1 List of sublists -> matrix . . . . . . . . . . . . . . . . . . . . .139
19.4.5.2 Matrix -> list of column vectors . . . . . . . . . . . . . . . .139
19.4.5.3 List of column vectors -> list of sublists . . . . . . . . . . .140
19.4.6 Functions applied element by element . . . . . . . . . . . . . . . . .140
19.4.6.1 Arithmetic operations and other MaximaL functions ap-
plicable to matrices . . . . . . . . . . . . . . . . . . . . . . . .140
19.4.6.2 Mapping arbitrary functions and operators . . . . . . . . .140
19.4.7 Transposition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .141
19.4.8 Inversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .141
19.4.9 Product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .141
19.4.9.1 Non-commutative matrix product . . . . . . . . . . . . . . .141
19.4.10 Rank . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .142
19.4.11 Gram-Schmidt procedure . . . . . . . . . . . . . . . . . . . . . . . . .142
19.4.11.1 Orthogonalize . . . . . . . . . . . . . . . . . . . . . . . . . . .142
19.4.11.2 Orthonormalize . . . . . . . . . . . . . . . . . . . . . . . . . .142
19.4.12 Triangularize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .142
19.4.13 Eigenvalue, eigenvector, diagonalize . . . . . . . . . . . . . . . . . .143
19.5 Determinant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .144
19.5.1 Option variables for determinant . . . . . . . . . . . . . . . . . . . .144
20 Limits 145
xii
21.2.4.2 Multi-variable form . . . . . . . . . . . . . . . . . . . . . . . .152
21.2.4.3 Option ’asymp . . . . . . . . . . . . . . . . . . . . . . . . . . .152
21.2.4.4 Option variables . . . . . . . . . . . . . . . . . . . . . . . . . .153
22 Differentiation 154
22.1 Differentiation operator diff . . . . . . . . . . . . . . . . . . . . . . . . . . . .154
22.1.1 Single-variable form . . . . . . . . . . . . . . . . . . . . . . . . . . . . .154
22.1.1.1 Evaluating Dp ƒ at a point . . . . . . . . . . . . . . . . . . . .154
22.1.2 Multi-variable form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .155
22.1.2.1 Partial derivatives . . . . . . . . . . . . . . . . . . . . . . . . .155
22.1.2.1.1 Hessian . . . . . . . . . . . . . . . . . . . . . . . . . .155
22.1.2.2 Total derivative . . . . . . . . . . . . . . . . . . . . . . . . . . .155
22.1.2.2.1 Gradient . . . . . . . . . . . . . . . . . . . . . . . . . .156
22.1.2.2.2 Jacobian . . . . . . . . . . . . . . . . . . . . . . . . . .156
22.2 Evaluate expr at a point x with at . . . . . . . . . . . . . . . . . . . . . . . .156
22.3 Define value c of expr at a point x with atvalue . . . . . . . . . . . . . . .156
22.4 Evaluation flag diff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .157
22.5 Noun form differentiation and calculus . . . . . . . . . . . . . . . . . . . . .157
22.5.1 Two ways to represent mathematical functions . . . . . . . . . . .157
22.5.1.1 Variables and depends . . . . . . . . . . . . . . . . . . . . . .157
22.5.1.2 MaximaL functions . . . . . . . . . . . . . . . . . . . . . . . .157
22.5.2 Functional dependency with depends . . . . . . . . . . . . . . . . .158
22.5.3 Using MaximaL functions . . . . . . . . . . . . . . . . . . . . . . . . .159
22.5.3.1 Distinction between function and variable . . . . . . . . .159
22.5.3.2 Declared function . . . . . . . . . . . . . . . . . . . . . . . . .160
22.5.3.3 Undeclared function . . . . . . . . . . . . . . . . . . . . . . .160
22.5.3.4 Function call as the independent variable in diff . . . . .160
22.5.4 Using derivative noun forms in diff . . . . . . . . . . . . . . . . . . .161
22.5.4.1 Differentiating derivative noun forms . . . . . . . . . . . .161
22.5.4.2 Differentiation with respect to derivative noun form . . .161
22.5.5 Quoting and evaluating noun calculus forms . . . . . . . . . . . . .161
22.6 Defining (partial) derivatives with gradef . . . . . . . . . . . . . . . . . . .162
22.6.1 Show existing definitions . . . . . . . . . . . . . . . . . . . . . . . . . .164
22.6.2 Remove definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . .164
22.7 Gradient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .164
23 Integration 165
xiii
24.2.1.1.2 contrib_ode . . . . . . . . . . . . . . . . . . . . . . . .168
24.2.1.2 Solve initial value problem (IVP) . . . . . . . . . . . . . . . .168
24.2.1.2.1 1. order ODE: ic1 . . . . . . . . . . . . . . . . . . . .168
24.2.1.2.2 2. order ODE: ic2 . . . . . . . . . . . . . . . . . . . .168
24.2.1.3 Solve boundary value problem (BVP): bc2 . . . . . . . . .170
24.2.2 System of linear ODEs: desolve . . . . . . . . . . . . . . . . . . . . .170
24.3 Numerical solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .172
24.3.1 Runge-Kutta: rk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .172
24.4 Graphical estimate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .174
24.4.1 Direction field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .174
24.4.1.1 plotdf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .174
24.4.1.2 drawdf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .174
28 Tensors 185
28.1 Kronecker delta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .185
28.1.1 Generalized Kronecker delta . . . . . . . . . . . . . . . . . . . . . . .185
28.1.2 Levi-Civita symbol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .185
28.2 Elementary second order tensor decomposition . . . . . . . . . . . . . . .185
xiv
30 Strings and string processing 187
30.1 Data type string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .187
30.2 Transformation between expression and string . . . . . . . . . . . . . . . .187
30.2.1 Expression → string . . . . . . . . . . . . . . . . . . . . . . . . . . . . .188
30.2.2 String → expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . .188
30.3 Display of strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .188
30.4 Manipulating strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .188
30.5 Package stringproc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .189
xv
33.2.1 Sage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .203
33.2.2 Python, Jupyter, Java, etc. . . . . . . . . . . . . . . . . . . . . . . . . .203
xvi
X Developer’s environment 214
xvii
38.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .228
38.1.1 General intention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .228
38.1.2 Git and our local repository . . . . . . . . . . . . . . . . . . . . . . . .228
38.1.2.1 KDiff3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .229
38.1.3 GitHub and our public repository . . . . . . . . . . . . . . . . . . . .229
38.2 Installation and Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .229
38.2.1 Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .229
38.2.1.1 Installing Git . . . . . . . . . . . . . . . . . . . . . . . . . . . .229
38.2.1.2 Installing KDiff3 . . . . . . . . . . . . . . . . . . . . . . . . . .229
38.2.1.3 Configuring Git . . . . . . . . . . . . . . . . . . . . . . . . . . .230
38.2.1.4 Using Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .230
38.2.2 GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .230
38.2.2.1 Creating a GitHub account . . . . . . . . . . . . . . . . . . .230
38.3 Cloning the Maxima repository . . . . . . . . . . . . . . . . . . . . . . . . . .231
38.3.1 Creating a mirror on the local computer . . . . . . . . . . . . . . . .231
38.3.2 Creating a mirror on GitHub . . . . . . . . . . . . . . . . . . . . . . . .231
38.4 Updating our repository . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .232
38.4.1 Setting up the synchronization . . . . . . . . . . . . . . . . . . . . . .232
38.4.2 Pulling to the local computer from Sourceforge . . . . . . . . . . .232
38.4.3 Pushing to the public repository at GitHub . . . . . . . . . . . . . .233
38.5 Working with the Repository . . . . . . . . . . . . . . . . . . . . . . . . . . . .233
38.5.1 Preamble . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .233
38.5.2 Basic operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .234
38.5.3 Committing, merging and rebasing our changes . . . . . . . . . .234
XII Lisp program structure (model), control and data flow 240
A Glossary 243
xviii
A.1 MaximaL terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .243
A.2 Lisp terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .247
E blanco 252
Index 253
xix
Part I
Historical Evolution,
Documentation
1
Chapter 1
Historical evolution
1.1 Overview
The computer algebra system Maxima was developed, originally under the name
Macsyma, from 1968 until 1982 at Massachusetts Institute of Technology (MIT) as
part of project MAC. Together with Reduce it belongs to the first comprehensive
CAS systems and was based on the most modern computational algorithms of the
time. Macsyma was written in MacLisp, a pre-Common Lisp which had also been
developed by MIT.
In 1982 the project was split. An exclusive commercial license was given to a com-
pany named Symbolics, Inc., created by Macsyma users and former MIT developers,
while at the same time the United States Department of Energy (DOE) obtained a
license for the source code of Macsyma to be made available (for a considerable
fee) to academic and government institutions. This version is known as DOE Mac-
syma. When Symbolics got into financial problems, enhancement and support for
the commercial Macsyma license was separated to a company named Macsyma,
Inc., which continued development until 1999. Financial failure of this company has
left the enhanced source code unavailable ever since.
From 1982 until his death in 2001, William Schelter, professor of mathematics at
the University of Texas, maintained a copy of DOE Macsyma. He ported Macsyma
from MacLisp to Common Lisp. In 1999 he requested and received permission from
the Department of Energy to publish the source code on the Internet under a GNU
public license. In 2000 he initiated the open source software project at Sourceforge,
where it has remained until today. In order to avoid legal conflicts with the still
existing Macsyma trademark, the open source project was named Maxima. Since
then, Maxima has been continuously improved.
2
area of artificial intelligence and symbolic computation, and after having completed
their respective theses in 1967 (Joel Moses’ thesis is entitled Symbolic integration),
while staying at MIT they joined their efforts and initialized, together with Carl En-
gelman, the development of a computer algebra system called Macsyma, standing
for project MAC’s SYmbolic MAnipulator. It was meant to be a combination of all
their previous projects, an interactive system for solving symbolic mathematical
problems designed for engineers, scientists and mathematicians, with the capabil-
ity of two-dimensional display of formulas on the screen, an interpreter for step-by-
step processing, and using the latest and most sophisticated algorithms in symbolic
computation available at the time.
Since both liked Lisp for its short and elegant notation and the universal and flexible
list structure, and since they had used it in most of their previous projects, Lisp was
going to be the language in which Macsyma was to be written.
Another conceptual decision based on previous experiences was to use multiple
internal representations for mathematical expressions. Apart from the general rep-
resentation there would be a rational function representation for manipulating ra-
tios of polynomials in multiple variables, and another representation for power and
Taylor series. These different representations can still be found in today’s Maxima.
Bill Martin led the project. But Carl Engelman and his staff already left in 1969.
In 1971 the project was presented at a Symposium on Symbolic and Algebraic Ma- [MartFate]
nipulation by William Martin and Richard Fateman (born 1946), who had joined the
project right from the beginning. He was a graduate student in the Division of En-
gineering and Applied Physics of Harvard, (1966-71) but found an opportunity to
pursue research down the road in Cambridge, at MIT. He received his Ph.D. from
Harvard, but de facto he had contributed to the Macsyma project. His thesis from
1971 on Algebraic Simplification describes various components of Macsyma which [FatemThe]
he had implemented, in particular the simplifier and the pattern matcher. From
1971-1974 he taught at MIT (in Mathematics), before he left for University of Cal-
ifornia at Berkeley, in Computer Science. The Macsyma project now comprised a
considerable number of doctoral students and post-doc staff members. But soon
after this presentation William Martin left the project, too, which was then led by
Joel Moses.
3
Golden (simplifier, language, system), R. W. Gosper (definite summation, special
functions, simplification, number theory), Carl Hoffman (general simplifier, macros,
non-commutative simplifier, ports to Multics and LispM, system, visual equation ed-
itor), Charles Karney (plotting), John Kulp, Ed Lafferty (ODE solution, special func-
tions), Stavros Macrakis (real/imaginary parts, compiler, system), Richard Pavelle
(indicial tensor calculus, general relativity package, ordinary and partial differential
equations), David A. Spear (Gröbner), Barry Trager (algebraic integration, factoring,
Gröbner), Paul Wang (polynomial factorization and GCD, complex numbers, limits,
definite integration, Fortran and LaTeX code generation), David Y. Y. Yun (polynomial
GCDs), Gail Zacharias (Gröbner) and Rich Zippel (power series, polynomial factor-
ization, number theory, combinatorics).
4
system memory size, so that it could operate on smaller and cheaper hardware and
eventually on personal computers.
5
1.5 Academic and US government licensing
1.5.1 Berkeley Macsyma and DOE Macsyma
Richard Fateman had gone to Berkeley already in 1974. He continued to work on
computers at MIT via ARPANET, predecessor of the Internet. He was interested
in making Macsyma run on computers with larger virtual memory than the exist-
ing PDP-10, and when the VAX-11/780 was available he fought for Berkeley to get
one. This achieved, his idea was to write a Lisp compiler compatible with MacLisp
and which would run on Berkley UNIX. Franz Lisp was created, the name having
been invented spontaneously for its resemblance with Franz Liszt; it was still a
pre-Common Lisp. With these resources rapidly developed, Fateman had in mind
to share usage of Macsyma with other universities around. But MIT resisted these
efforts.
UC Berkeley finally reached an agreement with MIT to be allowed to distribute
copies of Macsyma running on VAX UNIX. But this agreement could be recalled
by MIT when a commercial license was to be sold by them, which eventually was
done to Symbolics. About 50 copies of Macsyma were running on VAX systems at
the time. But Fateman wanted to go on and ported Franz Lisp to Motorola 68000,
so that Macsyma could run on prototypes of workstations by Sun Microsystems.
Around 1981, when the discussion about commercial licensing of Macsyma became
more and more intense at MIT, Richard Fateman and a number of other Macsyma
users asked the United States Department of Energy (DOE), one of the main and
therefore influential sponsors of the Macsyma project, for help to make MIT allow
the software to become available for free to everyone. What he had in mind was a
kind of Berkeley BSD license, which does not, like a GNU general public license, pre-
vent commercial exploitation of the software. On the contrary, such a license, which
can be considered really free, would not only allow everyone to use and enhance
the software, but also to market their product. This license, for instance, allowed
Berkeley students to launch startups with software developed at their school.
Finally, in 1982, at the same time when the commercial license was sold to Sym-
bolics, DOE obtained a copy of the source code from MIT to be kept in their library.
It was not made available to the public, its use remained restricted to academic
and US government institutions. For a considerable fee these institutions could ob-
tain the source code for there own development and use, but without the right to
release it to others. This version of Macsyma is known as DOE Macsyma.
The version of the Macsyma source code given to DOE had been recently ported
from MacLisp to NIL, New Implementation of Lisp, another MIT development. Unfor-
tunately, this porting was not really complete, MIT never finalized it, and the DOE
version was substantially broken. All academic and government users fought with
these defects. Some revisions were exchanged or even passed back to DOE, but
basically everyone was left alone with having to find and fix the bugs.
6
1.5.2 William Schelter at the University of Texas
From 1982 until his sudden death in 2001 during a journey in Russia, William Schel-
ter, professor of mathematics at the University of Texas in Austin, maintained one
of these copies of DOE Macsyma. He ported Macsyma from MacLisp to Common
Lisp, the Lisp standard which had been established in the meantime. Schelter, who
was a very prolific programmer and a fine person, added major enhancements to
DOE Macsyma.
7
of Physics, California State University, Long Beach) has spent years writing a highly
sophisticated and free Maxima tutorial for applications in Physics, called Maxima by
example. Richard J. Fateman (Prof. of Computer Science, University of California at
Berkeley) and Dr. Stavros Macrakis (Cambridge, Ma.), who already were chief de-
signers and major contributors to the Macsyma software at MIT, are both still with
the Maxima project today, giving valuable advice to both developers and users on
Maxima’s principal communication channel, the mailing list at Sourceforge.
8
Chapter 2
Documentation
2.1 Introduction
It is our feeling that Maxima’s documentation can be improved. Both as a user
and even more as a developer one would like to have much more information at
hand than what the official Maxima manual, the other internal documentation that
comes with the Maxima installation, and the comments in Maxima’s program code
provide.
Especially in the beginning, the user will often not understand the information in
the manual easily. It contains a concise description of the Maxima language, here
abbreviated MaximaL, but primarily as a reference directed to the very experienced
user. It takes years to really understand and efficiently use a CAS. The beginner will
need further explanation of all the implications of the condensed information from
the official manual, more examples and a better understanding of the overall struc-
ture of the complex Maxima language (it comprises of thousands (!) of different
functions and option variables).
Numerous external tutorials, some of them generally covering Maxima’s mathemat-
ical capabilities, others restricted to applications of Maxima in the most important
fields, such as Physics, Engineering or Economics, have been written and are of
immense help for the beginner. Some of them are so comprehensive that they
come close to a reference manual. Our intention is not to write a tutorial, but a
manual, directed to a broader audience than the existing one, ranging from the still
unexperienced user to the Lisp developer.
A considerable number of user interfaces have been developed, and the user will
be quite lost about judging which one will best fit his needs.
Users and developers wanting to build Maxima themselves will find little documen-
tation of the build process, especially if they want to work under Windows.
Even for an experienced Lisp developer the structure of Maxima’s huge amount of
program code will not be easy to understand. There is almost no documentation
besides the program code, and this code itself is poorly documented, having been
revised by many hands over many years. There are inconsistencies, forgotten sec-
tions, relics of ancient Lisp dialects and lots of bugs. The complicated process of
Maxima’s dynamic scoping and the information flow within the running system are
9
hard to keep track of. Very few of Maxima’s few Lisp developers really overlook it
completely.
This obvious lack of documentation motivated us to start the Maxima Workbook
project. But before diving into it, let us get an overview about exactly what sources
and what extend of information we have available already. As a first reference, the
user should consult the bibliography contained in Maxima’s official documentation
page.
The official Maxima manual in English is updated with each new Maxima release. It [MaxiManE]
is included in HTML format, as PDF and as the online help in each Maxima installer
or tarball. It can also be built when building Maxima from source code. Our Maxima
Workbook is primarily based on this documentation.
A German version of the manual exists. It is also distributed with the Maxima in- [MaxiManD]
stallers and tarballs. Note, however, that it reflects the status of release 5.29, it is
currently not being updated. Compared to the English version, it contains numer-
ous introductins, additional comments and examples and a much more complete
index. It was translated/written by Dieter Kaiser in 2011. Many of his amendments
and improvements have been incorporated in the Maxima Workbook. The author
wishes to express his thanks to Dieter Kaiser for his pioneer work in improving the
Maxima documentation.
Paulo Ney de Souza has written, together with Richard Fateman, Joel Moses and Cliff [SouzaMaxB]
Yapp, one of the most comprehensive Maxima manuals. Unfortunately, the project
has not been finalized and is no longer updated, the last version dating from 2004.
In particular, the Maxima Book contains detailed information about different user
interfaces, including installation instructions.
2.3.2 Tutorials
The tutorials presented first are those not focused on a specific field of application.
The order is according to their date of publication.
10
2.3.2.1 Michel Talon: Rules and Patterns in Maxima, 2019
This tutorial of some 20 pages facilitates access to understanding how to use Max- [TalonRP]
ima’s pattern matching facilities, which remains difficult from reading the section
from Maxima’s manual alone. It is particularly useful for someone who furthermore
wants to understand how the pattern matcher works internally. Hints to example
applications from mathematics and physics are given at the end. Altogether, a very
substantial work written by someone deeply interested in Maxima.
Scientific Programming. Numeric, Symbolic, and Graphical Computing with Maxima [CalvoSP]
uses Maxima to illustrate some methods of numeric and symbolic computation for
application in mathematically oriented sciences, and at the same time the general
use of computer programming.
This tutorial by Zachary Hannan from Solano Community College, Vallejo, Ca., al- [HanMC1]
though having wxMaxima in its title, really covers the CAS Maxima, viewed through [HanMC2]
the wxMaxima user interface. Two volumes of about 160 pages each cover basic
methods of using Maxima to solve problems from Calculus. Volumes on other fields
of application are to follow.
Wilhelm Haager’s major work on the CAS Maxima was published 2014 in German [HaagCAM]
at Hanser Verlag. This tutorial has over 300 pages and comes close to a compre-
hensive manual of the Maxima language. For example, rule-based programming is
coverd in a separate chapter, data transfer to other programs and the implications
of Lisp are treated. A very valuable publications that one would like to see available
in English, too.
A tutorial in German on graphics with Maxima of about 35 pages, in the typical, [HaagGM]
well-edited Haager style.
Roland Stewen from Rahel Varnhagen Kolleg in Hagen, Germany, has written a [StewenMT]
Maxima tutorial in German of some 400 pages primarily addressed to highschool
students. It is available online in html format and can be downloaded as PDF. The
document is clearly written, well structured, contains a detailed table of content,
an index, a bibligraphy, and can be highly recommended for the intended purpose.
11
2.3.3 Mathematics
2.3.3.1 G. Jay Kerns: Multivariable Calculus with Maxima, 2009
Originating from material the author compiled for a university course in Calculus, [KernsMVC]
this document of some 50 pages grew up to become a real introduction to Maxima.
A concise and very illustrative work for the undergraduate level.
2.3.4 Physics
2.3.4.1 Edwin L. (Ted) Woollett: "Maxima by Example", 2018, and "Com-
putational Physics with Maxima or R"
This tutorial by Edwin L. (Ted) Woollett, Prof. Emeritus of Physics and Astronomy at [WoolMbE]
California State University (CSULB), is free online-material and certainly one of the
best and most inspiring tutorials around, and Ted’s work is still continuing! Here
we find valuable advice and many examples from the viewpoint of a computational
physicist, and some impressive, highly sophisticated worked-out applications.
In their series Undergraduate Lecture Notes in Physics, Springer in 2016 published [TimbCMM]
Classical Mechanics with Maxima, written by Todd Keene Timberlake, Prof. of Physics
and Astronomy, and J. Wilson Mixon, Jr., Prof. Emeritus of Economics, both at Berry
College, Mount Berry, Georgia. This elegantly written, professionally styled and
therefore well readable book contains on some 260 pages applications of Maxima
to problems from classical mechanics at the undergraduate level. After opening
the view to a wide range of problems for symbolical computation from the field of
Newtonian mechanics, the book focuses on the programming facilities inherent in
the Maxima language and on the methodology and techniques of how to transform
sophisticated algorithms for the symbolical or numerical solution of problems from
mathematical physics into Maxima. Graphical representations of the data obtained
are always in the center of interest, too, and throughout the book vividly illustrate
the results from computations.
Written by Viktor T. Toth, theoretical physicist, member of the Maxima team, and [TothTenM]
responsible for maintaining the tensor packages, this highly recommended paper
published in arxiv gives a comprehensive description of the present abilities of Max-
ima’s tensor packages for applications in physics, in particular general relativity.
2.3.5 Engineering
2.3.5.1 Andreas Baumgart: Toolbox Technische Mechanik, 2018
12
2.3.5.2 Wilhelm Haager: Control Engineering with Maxima, 2017
This well-illustrated tutorial of some 35 pages has been written by Wilhelm Haager [HaagCEM]
from HTL St. Pölten, Austria. It shows applications of Maxima in the field of Electrical
Engineering.
A free tutorial of 135 pages covering both Maxima and Octave has been written [FredmCME]
by Tom Fredman of Abo Akademi University, Finnland for applications in Engineer-
ing. Its bibliography contains a number of other sources for Maxima applied to
engineering.
The extensive tutorial by Gilberto Urroz used to be available online for free, but now [UrrozMSE]
comes as a self-published paperback for a very moderate price, considering its size
of 438 pages. It contains a large number of applications in engineering.
2.3.6 Economics
2.3.6.1 Hammock and Mixon: Microeconomic Theory and Computation,
2013
J. Wilson Mixon, Jr., Professor Emeritus of Economics at Berry College, Mount Berry, [HammMTC]
Georgia, published Microeconomic Theory and Computation. Applying the Maxima
Open-Source Computer Algebra System together with Michael R. Hammock in 2013
with Springer. This extensive work of about 385 pages shows how Maxima can be
applied to solve a wide variety of symbolical and numerical problems that arise in
the field of economics and finance, from exploring empirical relationships between
variables up to modeling and analyzing microeconomic systems. This is the most
comprehensive book written so far which demonstrates the usefulness of Maxima
in Economic Sciences.
A detailed Maxima tutorial of some 120 pages with applications to Economics has [LeydoldME]
been written by Josef Leydold and Martin Petry from Institute for Statistics and
Mathematics, WU Wien. It is based on version 5.25 and was last published in 2011.
It is available online as PDF.
13
lished a large number of articles and other papers on Macsyma/Maxima. Subjects
range from specific technical and algorithmic problems to reflections about the his-
tory of Macsyma’s development and its place in the evolution of CAS in general.
Most references can be found on his Berkeley homepage
http://people.eecs.berkeley.edu/ fateman/.
A considerable number of very interesting papers is available for free download at
https://people.eecs.berkeley.edu/ fateman/papers/.
14
Part II
Basic Operation
15
Chapter 3
Basics
3.1 Introduction
3.1.1 REPL: The read-evaluate-print loop
Maxima is written in the programming language Lisp. Originally, before this lan-
guage was standardized, MacLisp, a dialect developed at MIT, was used, later the
Maxima source code was translated to Common Lisp, the Lisp standard still valid
today. One of the key features of Lisp is the so-called REPL, the read-evaluate-
print loop. When launching Lisp, the user sees a prompt where he can enter a Lisp
form. The Lisp system reads the form, evaluates it and displays the result. After
having done this, Lisp outputs the prompt again, giving back the initiative to the
user to start a new cycle of operation by entering his next form. The Lisp system
primarily works as an interpreter. Nevertheless, functions and packages can also
be compiled.
The same basic principle of operation has been employed to the Maxima language,
which in this book we will abbreviate MaximaL. Maxima also works with a REPL, as
being the cycle of interpretation of some expression entered by the user. (Later we
will see that Maxima program code can be compiled, too.) This design principle for
the user interface was easy to implement and therefore the natural choice in the
early times. With one exception, all Maxima front ends still use this principle today.
It may seem simple and out of date, but it offers a number of significant advantages
which the user will quickly learn to appreciate. The successive loops, as they are
operated sequentially and recorded chronologically on the screen, provide a natural
log which the user can scroll back at any time to see what he has done and what
results he has obtained so far. By simply copying and pasting, the user can take
both input and output from previous loops and insert it again at the input prompt.
Previous commands can be modified and reentered, and intermediate results can
be used for further computation.
But the benefits of this way of working reach even further: when programming in
MaximaL, the user can test out every bit of code in the REPL first, before integrating
it into his program. Bottom up, step by step, he builds the program, from the
most detailed routines to the most abstract layers, always basing every new part
on the direct experience in the test environment of his Maxima REPL. This way of
programming had proved to be very efficient in Lisp, and with good reason the
16
same could be expected for Maxima.
This basic principle of operation has been adopted by almost all other computer
algebra systems as well. By the way: most CAS’ are implemented in Lisp or a
Lisp-like language.
Thus, with regard to this general procedure of the REPL, MaximaL and Lisp have a
certain similarity. The user who takes the effort to learn Lisp will soon find out that
similarities reach much further. However, there are also significant differences.
While Lisp is a strictly and visibly list based language working with a non-intuitive,
but highly efficient prefix notation, MaximaL is much closer to traditional languages
of the Algol-type, more intuitive, more natural to the human user, with a structure
and notation closer to the mathematical one.
17
3.2 Basic operation
3.2.1 Executing an input line or cell
In command line Maxima, sect. 33.1.1, use enter to execute an input line. In
wxMaxima, sect. 33.1.2, use shift+enter.
... [syntax description operator]
Optional elements, e.g. optional function parameters, are enclosed in angle brack-
ets. Example: see genmatrix.
... ... [syntax description operator]
Alternatives are separated by and enclosed
in . More than two alternatives
can be represented by repeating the operator inside of the green parentheses.
Exactly one of the alternative has to be selected. Example: see to_poly_solve.
(. . . , . . . , . . . ) [matchfix operator]
While in Lisp any kind of list is enclosed in parentheses, in Maxima these are re-
served for specific lists, e.g. the list of parameters of an ordinary function definition,
the list of arguments of a function call, or a list of statements in a simple sequential
compound statement. The elements are separated by commas.
18
[. . . , . . . , . . . ] [matchfix operator]
Square bracketes enclose data lists, e.g. the elements of a one-dimensional list, or
the the rows of a matrix. They also enclose the subscripts of a variable, array, hash
array, or array function. They are also used to enclose the local variable definitions
of a block. The elements are separated by commas.
(%i1) x: [a,b,c];
(%o1) [a,b,c]
(%i2) x[3];
(%o2) c
(%i3) array(y,fixnum,3);
(%o3) y
(%i4) y[2]: %pi;
(%o4) π
(%i5) y[2];
(%o5) π
(%i6) z[a]:b;
(%o6) b
(%i7) z[a];
(%o7) b
(%i8) g[k] := 1/(k^2+1);
1
(%o8)
k2 +1
(%i9) g[10];
1
(%o9)
101
{. . . , . . . , . . . } [matchfix operator]
Braces enclose sets. The elements are separated by commas. Note that the ele-
ments of a set, unlike a list, are not ordered.
, [infix operator]
Separator of elements of a list or set. Note that in Lisp, instead, the separation
character of a list is the blank.
: [infix operator]
This is the basic assignment operator. When the lhs (lhs) is a simple variable (not
subscripted), : evaluates its rhs (rhs), unless quoted, and associates that value with
the symbol on the lhs.
(%i1) a:3;
(%o1) 3
(%i2) b:a; /* The rhs is evaluated before assigning. */
(%o2) 3
(%i3) c:’a; /* The rhs is not evaluated. */
19
(%o3) a
(%i4) ev(c); /* Evaluation of c. */
(%o4) 3
Chain constructions are allowed; in this case all positions but the right-most one
are considered lhs.
(%i1) x : y : 3;
(%o1) 3
(%i2) x;
(%o2) 3
(%i3) y;
(%o3) 3
When the lhs is a subscripted element of a list, matrix, declared Maxima array, or
Lisp array, the rhs is assigned to that element. The subscript must name an existing
element; such objects cannot be extended by naming nonexistent elements.
When the lhs is a subscripted element of an undeclared Maxima array, the rhs is
assigned to that element, if it already exists, or a new element is allocated, if it
does not already exist.
When the lhs is a list of simple and/or subscripted variables, the rhs must evaluate
to a list, and the elements of the rhs are assigned to the elements of the lhs, ele-
ment by element, in parallel (not in serial; thus evaluation of an element may not
depend on the evaluation of a preceding one).
3.3.4.2 Indirect ::
:: [infix operator]
This is the indirect assignment operator. :: is the same as :, except that :: evaluates
its lhs as well as its rhs. Thus, the evaluated rhs is assigned not to the symbol on
the lhs, but to the value of the variable on the lhs, which itself has to be a symbol.
(%i1) x : ’y;
(%o1) y
20
(%i2) x :: 123;
(%o2) 123
(%i3) x;
(%o3) y
(%i4) y;
(%o4) 123
(%i5) x : ’[a, b, c];
(%o5) [a, b, c]
(%i6) x :: [1, 2, 3];
(%o6) [1, 2, 3]
(%i7) a;
(%o7) 1
(%i8) b;
(%o8) 2
(%i9) c;
(%o9) 3
A value (and other bindings) can be removed from a variable by functions kill
and remvalue. These unassignment functions are more important than they might
seem. Unbinding variables from values no longer needed should be made a habit by
the user, because forgetting about assigned values is a frequent cause of mistakes
in following computations which use the same variables in other contexts.
? [prefix operator]
? [prefix operator]
These are the documentation operators. ? placed before a system function name f
(and separated from it by a blank) is a synonym for describe (f). This will cause the
online documentation about system function f to be displayed on the screen.
?? placed before a system function name f (and separated from it by a blank) is a
synonym for describe (f, inexact). This will cause the online documentation about
function f and all other system functions having a name which starts with "f" to be
displayed on the screen.
21
3.4 Naming of identifiers
3.4.1 MaximaL naming specifications
3.4.1.1 Case sensitivity
Maxima identifiers may comprise alphabetic characters, the digits 0 through 9, the
underscore _, the percent sign %, and any special character preceded by the back-
slash character. A digit may be the first character of an identifier, if it is preceded
by a backslash. Digits which are the second or later characters need not be pre-
ceded by a backslash.
alphabetic [property]
Special characters may be declared alphabetic using the declare function. If so de-
clared, they need not be preceded by a backslash in an identifier. The special char-
acters declared alphabetic are initially %, and _. The list of all characters presently
declared alphabetic can be seen as the Lisp variable *alphabet*.
Since almost all special characters from the ASCII code set are in use for other
purposes in Maxima, often as operators for which the parser pays special attention,
it makes little sense to declare them alphabetic. Thus, we have taken an example
with non-ASCII characters (which does not make much more sense, as we will soon
see).
(%i1) declare("äöüÄÖÜß",alphabetic);
(%o1) done
(%i2) Größe : 123;
(%o2) 123
(%i3) :lisp *alphabet*
(_ % ä ö ü Ä Ö Ü ß)
(%i4) featurep("ä",alphabetic);
(%o4) true
All characters in the string passed to declare as the first argument are declared to
be alphabetic. Function featurep returns true, if all characters in the string passed
to it as the first argument have been declared alphabetic by the user or are the _
or % characters.
Recently, efforts have been made to include Unicode support in Maxima. It has to
be stated, however, that Unicode support is not a universal feature of Maxima, but
depends to some extend on the operating system, on the Lisp and on the front-end
used. Given that our actual system supports it, almost any Unicode character can
nowadays be used within a Maxima identifier, including in the first position. Thus,
22
we do not need to declare German Umlaute as alphabetic, we can just use them.
We can use Greek letters, too, or even Chinese.
Special attention has to be payed, though, when using non-ASCII characters. If
things work well on one system, this does not guarantee it will work without prob-
lems on another one. Besides, there might still be issues in some situations and
circumstances that have not been solved in a satisfactory way yet.
As a general statement we can say that Linux gives better and more consistent
Unicode support than Windows. Concerning the Lisp, we find that SBCL is always a
good choice, combining most efficient behavior with least problems. From the point
of view of the front-ends, wxMaxima takes most efforts to provide comprehensive
Unicode support.
In general, Maxima’s system functions and variables use lower-case letters only
and use the underscore character to separate words within a symbol, e.g. carte-
sian_product.
In order to clearly distinguish them from system functions, our own additional func-
tions and variables start with capital letters and use capital letters to separate
words within a symbol, e.g. ExtractEquations.
System constants like the imaginary unit i, the Euler’s number e, or the constants
π and γ are preceded by % in Maxima (i.e. %i, %e, %pi, %gamma) to make them
better distinguishable from ordinary letters or identifiers. One has to keep this in
mind in order not to be confused. Note in the following example that log denotes
the natural logarithm with base e. Maxima and its system functions return the input
expression, if they cannot evaluate it.
(%i1) %e^log(x);
(%o1) x
(%i2) e^log(x);
(%o2) elog()
(%i3) %pi;
(%o3) %pi
(%i4) float(%pi);
(%o4) 2.128231705849268
(%i5) float(pi);
23
(%o6) pi
MaximaL Lisp
var $VAR, $var, $Var → $VAR; |$VAR|
VAR |$var|
Var |$Var|
?var VAR, var, Var → VAR
MaximaL and Lisp symbols are distinguished by a naming convention. A Lisp symbol
which begins with a dollar sign $ corresponds to a MaximaL symbol without the
dollar sign. For example, the MaximaL symbol foo corresponds to the Lisp symbol
$FOO. Lisp functions and variables which are to be visible in Maxima as functions
and variables with ordinary names (no special punctuation) must have Lisp names
beginning with the dollar sign $.
On the other hand, a MaximaL symbol which begins with a question mark ? cor-
responds to a Lisp symbol without the question mark. For example, the MaximaL
symbol ?foo corresponds to the Lisp symbol FOO. Note that ?foo is written without
a space between ? and foo; otherwise it might be mistaken for the Maxima function
describe("foo") which can also be written as ? foo.
Hyphen -, asterisk *, or other special characters in Lisp symbols must be escaped
by backslash \ where they appear in MaximaL code. For example, the Lisp identifier
*foo-bar* is written ?\∗ ƒ oo\ − br\∗ in MaximaL.
While Maxima is case-sensitive, distinguishing between lowercase and uppercase
letters in identifiers, Lisp does not make this distinction. $foo, $FOO and $Foo are
all converted by the Lisp reader by default to the Lisp symbol $FOO.
This discrepancy requires some rules governing the translation of names between
Lisp and Maxima.
1. A Lisp identifier not enclosed in vertical bars || corresponds to a Maxima identifier
in lowercase. Whether a Lisp identifier is uppercase, lowercase, or mixed case, is
ignored, e.g., Lisp $foo, $FOO, and $Foo all correspond to Maxima foo. This is
because $foo, $FOO and $Foo are converted by the Lisp reader to the Lisp symbol
$FOO, since Lisp is not case-sensitive.
2. A Lisp identifier enclosed in vertical bars and
2.1. which is all uppercase or all lowercase corresponds to a Maxima identifier
with case reversed. That is, uppercase is changed to lowercase and lowercase
24
to uppercase. E.g., Lisp |$FOO| and |$foo| correspond to Maxima foo and FOO,
respectively.
2.2. which is mixed uppercase and lowercase corresponds to a Maxima identifier
with the same case. E.g., Lisp |$Foo| corresponds to Maxima Foo.
25
Chapter 4
(%i1)
(%i1) 2+3;
(%o1) 5
(%i2)
wxMaxima shows a slightly different behavior. The input tag appears only at eval-
uation time. Enter will only cause a line-feed, having no other effect on evaluation
than a blank, while shift-enter or ctrl-enter starts evaluation. When an input expres-
sion is an assignment, the corresponding output expression displays no numbered
output tag, but instead the symbol to the left of the assignment in parentheses. If
the input expression is only a symbol, the normal output tag is displayed.
(%i1) temp:-30.5;
(temp) -30.5
(%i2) temp;
(%o2) -30.5
linenum [variable]
Maxima keeps the current tag number in the global variable linenum. Entering
linenum:0 or kill(all) resets the input and output tag number to 1.
26
(%i17) linenum:0;
(%o0) 0
(%i1) a;
(%o1) a
The * (asterisk) operator for multiplication cannot be omitted in input; a blank does
not mean multiplication.
4.2 Input
4.2.0.1 One-dimensional form
Maxima and all of its front-ends allow input of mathematical expressions only in
one-dimensional form. Parentheses have to be used to group subexpressions, e.g.
the numerator and denominator of a fraction.
27
4.2.2 System variables for backward references
_ (underscore) [variable]
This system variable contains the most recently evaluated input expression, i.e.
the expression with input tag (%in), n ∈ N being the most recent cycle having
been evaluated. _ is assigned the input expression before the input is simplified
or evaluated. However, the value of _ is simplified (but not evaluated) when it is
displayed.
_ is recognized by batch and load. In a file processed by batch, _ has the same
meaning as at the interactive prompt. In a file processed by load, _ is bound to the
input expression most recently evaluated at the interactive prompt or in a batch
file. _ is not bound to the input expressions in the file being processed.
Note that a :lisp command is not associated with an input tag and cannot be refer-
enced by _.
(%i1) 13 + 29;
(%o1) 42
(%i2) :lisp $_
((MPLUS) 13 29)
(%i2) _;
(%o2) 42
(%i3) sin (%pi/2);
(%o3) 1
(%i4) :lisp $_
((%SIN) ((MQUOTIENT) $%PI 2))
(%i4) _;
(%o4) 1
(%i5) a: 13$
(%i6) a + a;
(%o6) 26
(%i7) :lisp $_
((MPLUS) $A $A)
(%i7) _;
(%o7) 2 a
(%i8) a + a;
(%o8) 26
(%i9) ev (_);
(%o9) 26
The above example not only illustrates the _ operator, but also nicely demonstrates
the difference between evaluation and simplification. Although in a broader sense
we often talk about "evaluation" when we want to indicate that Maxima processes
an input expression in order to compute an output, in the strict sense the meaning
of evaluation is limited to dereferencing. Everything else is simplification. In the
example above, only at %o6, %o8 and %o9 we see evaluation, as the symbol a is
dereferenced, i.e. replaced by its value. After this replacement, the addition of the
values constitutes another simplification.
%in [variable]
28
This system variable contains the input expression with input tag (%in), n ∈ N. Its
behavior corresponds exactly to _.
4.3 Output
4.3.0.1 One- and two-dimensional form
% [variable]
This system variable contains the output expression most recently computed by
Maxima, whether or not it was displayed, i.e. the expression with output tag (%on),
n ∈ N being the most recent cycle having been evaluated. When the output was
not displayed, this output tag is not visible on the screen either.
% is recognized by batch and load. In a file processed by batch, % has the same
meaning as at the interactive prompt. In a file processed by load, % is bound to the
output expression most recently computed at the interactive prompt or in a batch
file; % is not bound to output expressions in the file being processed.
Note that a :lisp command does not create an output tag and therefore cannot be
referenced by %.
%th(n) [function]
This system function returns the n-th previous output expression, n ∈ N. Its behavior
corresponds to %.
%on [variable]
This system variable contains the output expression with output tag (%on), n ∈ N.
Its behavior corresponds exactly to %.
%% [variable]
In compound statements, namely (s1 , . . . , sn ), block, or lambda, this system variable
contains the value of the previous statement. At the first statement in a compound
29
statement, or outside of a compound statement, %% is undefined. %% is recog-
nized by batch and load, and it has the same meaning as at the interactive prompt.
A compound statement may comprise other compound statements. Whether a
statement be simple or compound, %% contains the value of the previous state-
ment. Within a compound statement, the value of %% may be inspected at a break
prompt, which is opened by executing the break function.
)$
[function of rs_pretty_print]
expr$ Pr0( "text"
)$
[function of rs_pretty_print]
expr$ Pr00( "text" )$ [function of rs_pretty_print]
30
Function Pr is used in the following way. Terminate the input expression with $.
Then continue on the same line with the function call of Pr, also terminated with $.
If a parameter string "text" is supplied, Maxima’s output will be preceeded by "text"
as a comment to what follows, terminated with a colon. Then, if the return value
is different from the input, a noun form of the input will preceed Maxima’s return
value, separated by either = or <=>, depending on whether the expression is an
equation or not. In case of the input being an assignment, the variable assigned
to will preceed the assigned value (again split into a noun form and the evaluated
form, if different), separated by :=.
Mathematical expressions evaluated by Maxima can be included in the leading com-
ment. The comment can comprise a variable number of parameters (including
zero), separated by commas.
Pr0 is the same as Pr, but the noun form is not displayed. Pr0 is useful, when
a number of consecutive transformations of an expression is performed and the
leading comment is to replace the information given by the noun form of a step.
Pr00 is the same as Pr0, but the equal or equivalence sign is omitted as well.
Note that when using one of the pretty print functions, %th(2) has to be used in-
stead of % when refering to the last output expression. The next example shows
that we can even display the most challenging tensor notations.
31
Chapter 5
Graphical representation of
functions
5.1 Introduction
There are two different Maxima interfaces for plotting, both being based on GNU-
plot: plot and draw. Both interfaces are able to deliver 2D and 3D representations.
Although they cover the same kind of problems, the two interfaces are substantially
different with respect to the structure of their commands, so we treat them sepa-
rately. Plot is the older interface, offering less functionality, but being easier at the
same time, so we describe it first.
Both plot and draw come with additional special functions for use with wxMaxima
only. These functions start with the prefix wx (e.g. wxplot2d, wxplot3d). They are
the same as the ordinary functions plot2d and plot3d, with the only difference that
they do not open a separate window to display the plot, but instead integrate it into
the output of the .wxm file or into the .wxmx file.
5.2 Plot
5.2.1 General
5.2.1.1 Options, (user) standard options, and system standard options
The user can customize any of the plot functions by setting plot options. This can
be done individually for each function call. It is also possible to set (user) standard
options which then apply to any function call unless they are overwritten by it.
Certain individual options cannot be set as standard, see details in the description
of plot options.
Certain options are set standard by the system already, e.g. the order of colors in
a multiple plot, if no colors are specified by the user. They can be viewed with the
following function.
set_plot_option ( opton n )
1
, . . . , opton [function]
get_plot_option (nme , nde )
[function]
remove_plot_option (name) [function]
32
Setting (user) standard options is done with function set_plot_option. Each option is
a list in square brackets, as described below. set_plot_option returns a list not only
of the standard options currently set by the user, but also of all system standard
options. Giving an empty set of parentheses to this function will only return the
currently set (user and system) standard options without adding any to them.
get_plot_option returns as a list in square brackets the current standard setting of
the option name. If the second argument index is present, only the indexth element
of this list will be returned (the first element is the option name).
remove_plot_option removes from the list of standard options the option name.
Note that this function requires exactly one argument; multiple removals are not
possible.
All options (this also holds for the options specific to either 2D or 3D as described
in sections 5.2.2.4 and 5.2.3.3) consist of a list (in square brackets) starting with
one of the keywords in this section, followed by one or more values. (This layout is
comparable to a function name and its arguments.) The options that accept among
their possible values true or false, can also be set to true by simply writing their
names. For instance, typing logx as an option is equivalent to writing [logx, true].
[box, true false] default: true [plot option]
If set to true, a bounding box will be drawn around the plot; if set to false, no box
will be drawn.
33
Specifies the format for the plot. In Windows the default is gnuplot, in all other
systems it is gnuplot_pipes. The formats xmaxima or openmath will cause the plot
to be displayed in an xMaxima window.
[plot_realpart, true false] default: false [plot option]
If set to true, the functions to be plotted will be considered as complex functions
whose real part should be plotted; this is equivalent to plotting realpart(function).
If set to false, nothing will be plotted when the function does not give a purely real
value. For instance, when x is negative, log(x) gives a complex value, with the real
value equal to log(abs(x)); if plot_realpart were true, log(-5) would be plotted as
log(5), while nothing would be plotted if plot_realpart were false.
(%i1) plot2d(realpart(log(x)),[x,-2,2],[y,-4,2]);
(%i2) plot2d(log(x),[x,-2,2],[y,-4,2],plot_realpart);
[same_xy, true false] default: false [plot option]
If true, displays the graph with the same scale for both x and y axes. For a 2D plot,
see also yx_ratio.
34
These options cannot be used with set_plot_option.
5.2.2 2D
There are 5 basic types of 2D plot: explicit plot, parametric plot, discrete plot,
implicit plot, and contour plot. The first three are implemented in function plot2d,
the last two in separate functions.
5.2.2.1 plot2d
plot2d ( pot [pot1 , . . . , potn ] , _rnge , y_rnge , optons )
[function]
wxplot2d(...) [function]
These functions plot a two-dimensional graph of
- an expression giving the y-coordinate as a function of one variable being the x-
coordinate (explicit plot),
- two expressions, one for the x- and one for the y-coordinate, as being functions of
a single common parameter (parametric plot), or
- a number of discrete points in the xy-plane (discrete plot).
Each type can be used in single or multiple form, and different types can be com-
bined to one representation.
pot [ pot1 , . . . , potn ]
A single plot is given as the first argument to plot2d while a multiple plot is given
as a list (of plots) being the first argument. Each of the plots is either an expression
(for an explicit plot), a parametric plot, or a discrete plot.
35
y_range is of the form: [y, min, max].
This is optional and specifies the range of the codomain to be displayed on the
vertical axis. If this option is used, the plot will show this exact vertical range,
independently of the values reached by the plot. Everything outside of the given
range will be clipped off. If the vertical range is not specified, it will be set according
to the minimum and maximum values of the second coordinate reached by the plot.
For y_range the name is always y. So it is wise not to use y as the name of the
independent variable.
Options are described in sections 5.2.1.2 and 5.2.2.4. In case of a multiple plot,
different colors will be used automatically for the different expressions and a legend
will be created. Options present in case of a multiple plot apply to all plots; it is not
possible to set options individually.
Note that the separate plot window (not when integrated into the wxMaxima file
with wxplot2d) can be scrolled both horizontally and vertically to see beyond the
selected ranges. The plot can be exported, e.g. as a .png file, directly from the
separate plot window.
36
This creates a curve in in the two-dimensional space epr × epry in terms of the
parameter t ranging from min to max.
Neither x_range nor y_range have to be present. When they are, they will specify
the ranges to be displayed in the graph for the horizontal and the vertical axis.
When they are not present, ranges will be set according to the minimum and maxi-
mum values of the coordinates reached by the plot points.
37
Figure 5.4 – Multiple
discrete plot2d. The
x- and y-coordinates of
the points are gener-
ated by function make-
list.
(%i1) load(implicit_plot);
(%i1) implicit_plot([x^2+y^2=1, (x/2)^2+y^2=1/4], [x,-1,1], [y,-1,1],
_
same xy);
38
5.2.2.3 Contour plot
(%i1) contour_plot(x/y,[x,-2,2],[y,-2,2]);
39
Describes the style(s) of the plot(s). If there are more plots than styles present, the
styles will be repeated sequentially. Each style is either given by its name only, or
as a list with additional arguments. In the first case, standard values are assumed
for the style. In the second case, the first element of the list is the name of the
style, followed by the arguments.
Each style can be either lines for line segments, points for isolated points, lines-
points for segments and points, or dots for small isolated dots. Gnuplot accepts
also an impulses style. If enclosed in a list, lines accepts one or two arguments: the
width of the line and an integer that identifies a color. The default color codes are:
1: blue, 2: red, 3: magenta, 4: orange, 5: brown, 6: lime and 7: aqua. If Gnuplot
is used with a terminal different than X11, those colors might be different. points
accepts one to three arguments; the first one is the radius of the points, the second
one is an integer that selects the color, using the same code used for lines and the
third one is currently used only by Gnuplot and it corresponds to several objects
instead of points. The default types of objects are: 1: filled circles, 2: open circles,
3: plus signs, 4: x, 5: *, 6: filled squares, 7: open squares, 8: filled triangles, 9:
open triangles, 10: filled inverted triangles, 11: open inverted triangles, 12: filled
lozenges and 13: open lozenges. Note that point types can be specified with option
point_type, see above. linespoints accepts up to four arguments: line width, points
radius, color and type of object to replace the points.
5.2.3 3D
In 3D only two basic types of plot are possible: explicit plot and parametric plot.
They are both implemented in function plot3d. Implicit 3D plots are possible only
with draw3d.
5.2.3.1 plot3d
plot3d (plot , optons ) [function]
wxplot3d(...) [function]
These functions plot a three-dimensional graph of
- an expression giving the z-coordinate as a function of two variables being the x-
and the y-coordinates (explicit plot), - three expressions, one for each of the x-, y-,
and z-coordinates, as being functions of two common parameters (parametric plot).
Multiple explicit plots can be combined to one representation. In contrast to plot2d,
however, only single parametric plots can be displayed, and the combination of
explicit and parametric plots is not possible, either.
40
plot displays multiple such graphs. In this case, an explicit functional expression in
terms of the independent variables is given for each individual plot.
For a single plot, the explicit functional expression is given as the first argument to
plot3d. In this case, x_range and y_range have to be the second and third argument,
possibly followed by options. The complete syntax for a single plot is
plot3d (expr, x_range, y_range , optons ).
A multiple explicit plot can have two different forms, depending on whether the
individual plots share the same x_range and y_range or not. In both cases, and in
contrast to plot2d, x_range and y_range form part of the list of plots. The syntax
for a multiple explicit plot using the same x_range and y_range is
plot3d ([epr1 , . . . , eprn , _rnge, y_rnge] , optons ).
The syntax for a multiple plot using a different x_range and y_range for each indi-
vidual plot is
plot3d ([[epr1 , _rnge1 , y_rnge1 ],. . . ,[eprn , _rngen , y_rngen ]] , optons ).
41
Here is an example of a multiple explicit plot consisting of three individual plots,
each having different x- and y-ranges
(%i1) plot3d([[x^2+y^2,[x,-4,4],[y,-4,4]],[x^3+y^3,[x,-3,3],[y,-3,3]],[x
^4+y^4,[x,-2,2],[y,-2,2]]]);
(%i1) plot3d([t+u,t-u,t*u],[t,0,2],[u,0,2]);
42
Figure 5.8 – Single 3D
parametric plot.
43
Returns a function suitable to be used in the option transform_xy of plot3d.
cnme1 , cnme2 , cnme3 specify the names of the three new coordinates, and
epr , epry , eprz their functional expressions to build the cartesian x-, y- and
z-coordinates.
As an example, we shall define a coordinate transformation called cylindrical_to_xyz
which is in fact identical to the preconfigured one polar_to_xy
[same_xyz, true false] default: false [plot option]
If true, the scales of all three axes will be the same.
[transform_xy, false ct_name] default: false [plot option]
This is a 3D option only. It allows for coodinate transformations within plot3d.
ct_name is the name of either a predefined coordinate transformation (polar_to_xy
or spherical_to_xyz), or one defined by the user with make_transform. See section
5.2.3.2 for details.
5.3 Draw
5.3.1 Introduction
This package is a Maxima interface to GNUplot. It allows for significantly more
functionality compared to Maxima’s propriatory plot package, but at the price of a
far more complicated syntax.
44
This package was written and is being maintained by Mario Rodriguez Riotorto.
Ample examples can be found in ...
(%i1) draw3d(implicit(x^2+y^2=z^2,x,-1,1,y,-1,1,z,-1,1),
my_general_options,my_3d_options);
(%i1) apply(set_draw_defaults,my_general_options);
(%i2) draw3d(implicit(x^2+y^2=z^2,x,-1,1,y,-1,1,z,-1,1,my_3d_options));
(%i1) apply(set_draw_defaults,append(my_general_options,my_3d_options));
(%i2) draw3d(implicit(x^2+y^2=z^2,x,-1,1,y,-1,1,z,-1,1));
45
5.3.2.1.4 User_preamble
This option allows to specify certain gnuplot settings which cannot be incorporated
with the usual syntax for options.
user_preamble = "set opt1 ; . . . ; set optn "
Options are specified by using gnuplot’s set command followed by the option and
possible values. Options are separated by a semicolon.
(%i1) draw2d(explicit(x,x,0,1),user_preamble=my_user_preamble);
The user preamble of a specific scene can contain other options as well.
(%i1) draw2d(polar(1,theta,0,2*%pi),user_preamble=append(my_user_preamble
,["set raxis","set grid polar"]);
5.3.3 2D
gr2d ( opt1 , . . . , optm , grph_obj1 , . . . , grph_objn ) [scene constructur]
This is the constructor for a single 2D scene to be used as an argument to function
draw. Multiple graphical objects gobj1 , . . . , gobjn can be plotted within the scene
under global options opt1 , . . . , optm .
draw2d ( opt1 , . . . , optm , grph_obj1 , . . . , grph_objn ) [function]
wxdraw2d (...) [function]
These two functions,
(%i1) draw2d(explicit(0.5,x,0,1),explicit(1,x,1,2),explicit(1.5,x,2,3),
xrange=[0,3],yrange=[0,2]);
46
Figure 5.11 – Plotting a piecewise defined func-
tion with draw.
5.3.4 3D
gr3d ( opt1 , . . . , optm , grph_obj1 , . . . , grph_objn ) [scene constructur]
This is the constructor for a single 3D scene to be used as an argument to function
draw. Multiple graphical objects gobj1 , . . . , gobjn can be plotted within the scene
under global options opt1 , . . . , optm .
draw3d ( opt1 , . . . , optm , grph_obj1 , . . . , grph_objn ) [function]
wxdraw3d(...) [function]
47
Figure 5.12 – Plotting a function in
polar coordinates and with an under-
lying polar grid with draw.
48
A graphical object of this type plots function f, given in implicit form, with dependent
variable x in the range from x=min to x=max. Note that in combination with the
global option xrange it is possible to plot a piecewise defined function.
49
Chapter 6
Batch Processing
50
Part III
Concepts of Symbolic
Computation
51
Chapter 7
7.1 Introduction
For the data type string see section 30.1.
7.2 Numbers
7.2.1 Introduction
7.2.1.1 Types
Note. The argument to this and the following predicate functions described in this
section concerning numbers must really evaluate to a number in order for the func-
tion to be able to return true. A symbol that does not evaluate to a number, even
if it is declared to be of a numerical type, will always cause the function to return
false. The special predicate function featurep (symbol, feature) can be used to test
for such merely declared properties of a symbol.
(%i1) c;
(%o1) c
(%i2) declare(c, even);
(%o2) done
(%i3) featurep(c, integer);
(%o3) true
(%i4) integerp(c);
(%o4) false
(%i5) numberp(c);
52
(%o5) false
7.2.2.1.1 External
Integers are returned without a decimal point. Rational numbers are returned as a
fraction of integers. Arithmetic calculations with interger and rational numbers are
exact. In principal, integer and rational numbers can have an unlimited number of
digits.
(%i1) a:1;
(%o1) 1
(%i2) b:-2/3;
2
(%o2) −
3
(%i3) 100!;
(%o3) 933262154439441526816992388562667004907159682643816214685929\
638952175999932299156089414639761565182862536979208272237582\
51185210916864000000000000000000000000
7.2.2.1.2 Internal
(%i1) a:1/2;
1
(%o1)
2
(%i3) :lisp $a
((RAT SIMP) 1 2)
53
integerp (expr) [Predicate function]
If expr evaluates to an integer, true is returned. In all other cases false is returned.
7.2.2.3.1 Automatic
If any element of an expression that does not contain floating point numbers evalu-
ates to a rational number, then all integers in this expression are, when evaluated,
converted to rational numbers, too, and the value returned is a rational number.
7.2.2.3.2 Manual
rationalize (expr) [Function]
Converts all floating point numbers and bigfloats in expr to rational numbers. Max-
ima knows a lot of identities but applies them only to exactly equivalent expres-
sions. Floats are considered inexact so the identities aren’t applied. rationalize
replaces floats with exactly equivalent rationals, so the identities can be applied.
It might be surprising that rationalize (0.1) does not equal 1/10. This behavior is
because the number 1/10 has a repeating, not a terminating binary representation.
(%i1) rationalize(0.1);
3602879701896397
(%o1)
36028797018963968
Note. The exact value can be obtained with either function fullratsimp (expr) or, if
a CRE form is desired, with rat(expr).
(%i1) rat(0.1);
rat: replaced 0.1 by 1/10 = 0.1
1
(%o1) / R/
10
54
7.2.3 Floating point numbers
7.2.3.1 Ordinary floating point numbers
Maxima uses floating point numbers (floating points) with double presicion. Inter-
nally, all calculations are carried out in floating point.
Floating point numbers are returned with a decimal point, even when they denote
an integer. The decimal point thus indicates that the internal format of this number
is floating point and not integer.
(%i1) a:1;
(%o1) 1
(%i2) float(a);
(%o2) 1.0
Another feature of this file allows for all floating points to be returned in engineer-
ing format, that is with an exponent that is a multiple of three, with 1-3 non-zero
digits in front of the decimal point and the number of significant digits accord-
ing to the value of fpprintprec. If set, engineering_format_floats overrides scien-
tific_format_floats.
(%i1) engineering_format_floats:true$
(%i2) b:0.23
(%o2) 230.0e-3
If any element of an expression that does not contain bigfloats evaluates to a float-
ing point number, then all other numbers in this expression are, when evaluated,
transformed to floating point, and the numerical value returned is a floating point
number.
1 RS only. In standard Maxima the file engineering-format.lisp provides only the engineering format.
55
1
(%o1)
4
(%o1) 2340.0
(%i2) a+b+c;
(%o2) 2340.25 + c
In principal, big floating point numbers (bigfloats) can have an unlimited presicion.
Bigfloats are always represented in scientific notation, the exponent being sepa-
rated by "b".
If any element of an expression evaluates to a bigfloat number, then all other num-
bers in this expression, including ordinary floating point numbers, are, when evalu-
ated, converted to bigfloats, and the numerical value returned is a bigfloat.
bfloat(expr) [Function]
Converts all numbers in expr to bigfloats and returns a bigfloat. The number of
significant digits in the returned bigfloat is specified by the option variable fpprec.
%i [special variable]
In Maxima the imaginary unit with 2 = −1 is written as %i.
(%i1) sqrt(-1);
(%o1)
(%i2) %i^2;
(%o2) -1
56
7.2.4.1.2 Internal representation
There is no generic data type for complex numbers. Maxima represents a complex
number in standard form as a sum + b, realpart and imagpart each being of
one of the four generic types of numbers, see sect. 7.2.1.1. More complicated
expressions involving complex numbers are represented just as real valued ones,
with the only difference that the special variable %i appears in them. This variable
is treated as would be any other variable.
(%i1) r: 3+%i*5;
(%o1) 5i + 3
(%i2) :lisp $r
((MPLUS SIMP) 3 ((MTIMES SIMP) 5 $%I))
(%i3) p: polarform(r);
p 5
(%o1) 34 e rctn 3
(%i4) :lisp $p
((MTIMES SIMP) ((MEXPT SIMP) 34 ((RAT SIMP) 1 2))
((MEXPT SIMP) $%E ((MTIMES SIMP) $%I ((%ATAN SIMP) ((RAT SIMP) 5 3)))))
7.2.4.1.4 Simplification
Complex expressions are, in contrast to real ones, not always simplified as much as
possible automatically. Simplification of products, quotients, roots, and other func-
tions of complex expressions can usually be accomplished by applying rectform.
(%i1) (2+%i)*(3-%i);
(%o1) (3 − ) ( + 2)
(%i2) rectform(%);
(%o2) +7
(%i3) (2+%i)/(3-%i);
57
+2
(%o3)
3−
(%i4) rectform(%);
1
(%o4) +
2 2
7.2.4.1.5 Properties
A variable can be declared the property real, complex, or imaginary. These prop-
erties are recognized by the functions of section 7.2.4.2 and 7.2.4.3. Note that
these functions consider symbols, unless declared otherwise (complex, imaginary)
or evaluating to a complex expression, as real.
(%i1) declare(z,complex,r,real)$
7.2.4.1.6 Code
The code of functions and variables for complex numbers is contained in file conju-
gate.lisp.
(%i1) rectform(sqrt(2)*%e^(%i*%pi/4));
(%o1) i + 1
(%i2) expr: z+k*%i+b+a*%i+4+3*%i+2-%i;
58
(%o2) z + ik + b + ia + 2i + 6
(%i3) rectform(expr);
(%o3) z + i(k + a + 2) + b + 6
(%i5) declare(z,complex,b,real)$ rectform(expr);
(%o5) Re(z) + i(Im(z) + k + a + 2) + b + 6
(%i6) realpart(expr);
(%o6) z+b+6
(%i7) imagpart(expr);
(%o7) k+a+2
r e φ = r cos φ + sin φ
with r being the complex absolute value and φ the complex argument.
(%i1) polarform(3+4*%i);
4
(%o1) 5 e rctn 3
(%i2) polarform(a+b*%i);
Æ
atan2 (b,)
(%o2) 2 + b2 e
(%i3) cabs(a+b*%i);
Æ
(%o3) 2 + b2
(%i4) carg(a+b*%i);
(%o4) atan2 (b, )
59
(%i1) conjugate(a+b*%i);
(%o1) a-ib
(%i2) conjugate(c);
(%o2) c
(%i3) declare(d,imaginary)$ conjugate(d);
(%o4) -d
(%i5) polarform(1+2*%i);
p
(%o5) 5 e rctn 2
(%i6) conjugate(%);
p
(%o6) 5 e− rctn 2
(%i7) conjugate(a1*a2);
(%o7) a1 a2
(%i8) declare([z1,z2],complex)$ conjugate(z1*z2);
(%o9) z1 z2
(%i10) f:a+b*%i$ (f+conjugate(f))/2;
(%o10) a
(%i1) complexp(2/3);
(%o1) true
(%i2) complexp((2+3*%i)/(5+2*%i));
(%o2) true
(%i3) polarform(2+3*%i);
Æ 3
(%o3) (13) e rctn 2
(%i4) complexp(%);
(%o4) true
(%i5) complexp(3*cos(%pi/2)+7*%i*sin(0.5));
(%o5) true
(%i6) complexp(a+b*%i);
(%o6) false
60
7.3 Boolean values
7.4 Constant
(%i1) a:[1,2,3];
(%o1) [1,2,3]
(%i2) b:a;
(%o2) [1,2,3]
(%i3) a[2]:x$ a;
(%o4) [1,x,3]
(%i5) b;
(%o5) [1,x,3]
(%i6) b[3]:y$ b;
(%o7) [1,x,y]
(%i8) a;
(%o8) [1,x,y]
Note: Adding columns or rows to an existing matrix with addcol or addrow will
create a new data structure with respect to sharing.
In order to create a real copy of an existing list or matrix, the functions copylist and
copymatrix have to be used.
61
Chapter 8
8.1 List
8.1.1 makelist
makelist ( epr
, n )
[function]
makelist (epr, , 0 m , step )
makelist ( epr [epr1 , . . . , eprn ] , , st )
This is a very powerful function to create lists from expressions and/or other lists.
There are three general forms, each of them with some possible variations.
The first form ...
The second form ...
For an example see the example to the discrete plot of plot2d.
The third form returns a list whose elements are evaluations of expr or sublists
being evaluations of epr1 , . . . , eprn . These expressions are functions of vari-
able x, which takes its values running through list. makelist’s return value has
as many elements as list has, i.e. length(list) elements. For j running from 1
through length(list), the jth element of the list returned is given by ev(expr,x=list[j])
or ev([epr1 , . . . , eprn ],x=list[j]).
For an example see the second example to the function rk implementing the Runge-
Kutta method for numerically solving a first order ODE.
8.1.2 create_list
8.2 Matrix
8.3 Structure
62
Chapter 9
Expression
If, instead, it is entered in exponention form −1/ 2 , which is possible, it will still be
displayed as a fraction, not in exponential form.
Within the UVF we have different appearances of the expression, depending on the
63
user interface we work with (e.g. wxMaxima, iMaxima or the console), or depending
on whether display2d is set or not. However, in this chapter we are not concerned
about these differences in appearance, they belong into the chapter on input and
output or the chapter on different user interfaces. We don’t distinguish between
these appearances here, because the abstract UVF representation is the same for
all of them.
(%i1) 1/sqrt(x);
1
(%o1)
()
p
(%i2) x^(-1/2);
1
(%o2)
()
p
(%i3) display2d
(%o3) true
(%i4) display2d:false$
(%i5) 1/sqrt(x);
(%o5) 1/sqrt(x)
(%i4) :lisp $%
((MEXPT SIMP) $X ((RAT SIMP) -1 2))
(%i4) 1/sqrt(x);
1
(%o4)
()
p
(%i5) :lisp $%
((MEXPT SIMP) $X ((RAT SIMP) -1 2))
(%i5) -x/2;
64
−
(%o5)
2
(%i6) :lisp $%
((MTIMES SIMP) ((RAT SIMP) -1 2) $X)
What we see is that internally our top level fraction having a variable in the de-
nominator is always represented as an exponential form of the variable having a
negative exponent. Only if the denominator is a numerical value, a fraction will be
represented internally as such. This happens for example in the exponent of −1/ 2 .
The expression −/ 2 is internally represented as the product −1/ 2 ∗ , and − is
represented as the product −1 ∗ .
In these examples we have seen some of the major differences between the UVF
and the GIF representation. A more comprehensive explanation of Maxima’s inter-
nal representation of expressions can be found in [FatemMGS].
We also saw in the above examples, that the different levels of subexpressions,
that is: the tree structure of the overall expression, are nicely represented in Lisp
by nested lists.
(%i1) powerdisp:true$
(%i2) x+x^3+x^2;
(%o2) x+x^2+x^3;
(%i2) :lisp$%
((MPLUS SIMP) $X ((MEXPT SIMP) $X 2) ((MEXPT SIMP) $X 3))
Note, however, that the order in which an expression is displayed in UVF depends
on whether the flag powerdisp is set to true or false (default). If it is false, display
is in the reverse canonical order. GIF is not affected by powerdisp.
65
9.4 Noun and verb
9.5 Equation
66
b+2
(%o4) y +
(%i9) part(eq,1,0); part(eq,1,1); part(eq,1,2); part(eq,1,1,0); part(eq
,1,1,1);
(%o5) derivative
(%o6) 2y
(%o7) x
(%o8) *
(%o9) 2
(%i14) part(eq,2,0); part(eq,2,1); part(eq,2,2); part(eq,2,2,0); part(eq
,2,2,1);
(%o10) +
(%o11) ay
b+2
(%o12)
(%o13) /
(%o14) b+2
If the last index is a list of indices, then a subexpression is returned which is made
up of multiple operands (subexpressions or atoms) of the last operator, each index
in the list standing for one. These operands are combined by their operator in the
expression.
(%i1) part(2*(x+y+z),2,[1,3]);
(%o1) x+z
Function part can also be used to obtain an element of a list, a row of a matrix, etc.
and the new value of expr is returned. repl may be some operator to be substituted
for an operator of expr. In some cases repl needs to be enclosed in double-quotes
" (e.g. substpart ("+", a*b, 0) yields b + a).
67
old, expr). eq_i are equations of the form old=new indicating multiple substitutions
to be done in expr, carried out in serial. See example after sublis.
As usual, all arguments are evaluated and can be quoted or, if necessary to enforce
evaluation, even double quoted, see example. This function allows for substituting
values (numbers or symbolic expressions) for symbols or vice versa.
If old or new are to be single-character operators, they must be enclosed in double-
quotes. Note, however, that, due to the differences between UVF and GIF, replacing
operators in an expression often does not yield the expected result and should be
avoided.
In any case, if the result of subst is not what was expected, one should take a
look at the GIF of the expression in order to find an explanation. Although subst is
implemented on the basis of Maxima’s rules and patterns mechanism, which itself
works strictly on the basis of GIF, some concessions have been made to the UVF
in subst. In general, any subexpression which can be selected by part and which
is complete can be replaced. For instance, in 1/ () the subexpression () can
p p
be replaced, although in GIF this subexpression does not exist. See sect. 14.5.1
for an alternative to subst working directly with rules and patterns, and therefore
strictly on the basis of GIF. You will see that this alternative is more powerful than
subst. The most powerful tool for substituting mathematical patterns, however, is
ratsubst.
(%i1) expr:x*a+(x*b)/2;
b
(%o1) +
2
(%i2) e:c+d$
(%i3) x:’e$
(%i4) expr;
b
(%o4) +
2
(%i5) ev(expr);
be
(%o5) + e
2
(%i6) ev(expr,eval);
b (d + c)
(%o6) + (d + c)
2
(%i8) subst(’’x,’x,expr);
b (d + c)
(%o8) + (d + c)
2
(%i9) subst(x,’’x,%);
be
(%o9) + e
2
(%i7) subst(’x,x,%);
b
(%o7) +
2
68
This is the same as the corresponding form of subst, but the substitutions are done
in parallel. As opposed to subst, the left side of the equation must be an atom; a
complete subexpression of expr is not allowed. The form with a single equation as
the first argument is not allowed, either.
(%i1) radsubstflag:true$
(%i2) ratsubst(b,sqrt(x),x);
(%o2) b2
(%i3) ratsubst(b,sqrt(x),x^(-3/2));
1
(%o3)
b3
69
(%i1) a:2$ box(a);
(%o1) 2
(%i2) box(a)*3;
(%o2) 3(2)
(%i3) part(box(a),0);
(%o3) box
(%i4) part(box(a),1);
(%o4) 2
(%i5) %*3;
(%o5) 6
(%i6) rembox(a*box(a)*box(4));
(%o6) 16
70
Chapter 10
Operators
10.1.2 Miscellaneous
Any prefix operator can be used with or without parentheses: not a <=> not(a) -a
<=> -(a)
= [infix operator]
This is the equation operator. Chains like a = b = c are not allowed. See sect. 9.5
for the exceptional case where the equation operator can be omitted.
When Maxima encounters an equation, its arguments, which means the lhs and
the rhs, are evaluated and simplified separately. The operator = by itself does
nothing more. It does not compare the two sides at all and the two sides are not
simplified against each other. An expression like a = b represents an unevaluated
equation, which might or might not hold. Unevaluated equations may be passed as
arguments to solve, algsys or some other functions.
Only is(a = b) and some other functions, namely if, while, unless, and, or, and not,
will evaluate the equation a = b to true or false.
71
Assumptions of equality cannot be specified with the = operator, only with function
equal.
Any desired simplification across the = operator has to be carried out manually. For
example, functions rhs(eq) and lhs(eq) return the rhs and lhs, respectively, of an
equation or inequation. Using them, we can indirectly achieve some basic simpli-
fication of an unevaluated equation by subtracting one side from the other, thus,
bringing them both to one side. Of course, the user may write his own simplifica-
tion routines to handle specific situations, as for example to subtract equal terms
on both sides, to divide both sides by a common factor, etc.
# [infix operator]
The negation of = is represented by #, which is the inequation operator. Just like
for an equation, only the lhs and rhs will be evaluated separately, the returned
expression constitutes an unevaluated inequation.
Only is(a # b) and the other functions mentioned above will evaluate the inequation
a # b to true or false. Note that because of the rules for evaluation of predicate
expressions (in particular because not expr causes evaluation of expr), not a = b is
equivalent to is(a # b), and not to a # b.
Assumptions of inequality cannot be specified with the # operator, only with func-
tion notequal.
These functions by themselves, like = and #, do nothing more than evaluate both
arguments separately. Unlike a = b, however, equal(a,b) is not an unevaluated
72
equation which can be passed as an argument to solve, algsys or some other func-
tions. Instead, Functions equal and notequal can be used to specify assumptions
with assume.
Function is tries to evaluate equal(a,b) to a Boolean value. is(equal(a,b)) evalu-
ates equal(a,b) to true, if a and b are mathematically equivalent expressions. This
means, they are mathematically equal for all possible values of their arguments.
Comparison is carried out and equivalence established by checking the Maxima
database for user-postulated assumptions, and by checking whether ratsimp(a-b)
returns zero.
When is fails to reduce equal to true or false, the result is governed by the global
flag prederror. When prederror is true, is returns an error message. Otherwise
(default), it returns unknown.
notequal (a,b) represents the negation of equal(a,b). Because not expr causes
evaluation of expr, not equal(a,b) is equivalent to is(notequal(a,b)).
Assumptions are stored as Maxima properties of the variables concerned. Thus,
comparison can be carried out and equivalence established between variables which
are unbound, having no (numerical or symbolical) values assigned. But compari-
son can also be carried out and equivalence established by retrieving the variables’
values (process of evaluation, dereferencing) and subsequent simplification. Of
course, a combination of both methods is possible, too.
73
10.2.1.4 is, is(a=b), is(equal(a,b))
is (expr) [function]
Function is evaluates an (in)equation, a relation, or a function call of equal or
nonequal to a Boolean value. is(a = b) evaluates a = b to true if a and b, af-
ter each having been evaluated and simplified separately, which includes bringing
them into canonical form, are syntactically equal. This means, string(a) is identical
to string(b). This is the case if a and b are atoms which are identical, or they are
not atoms and their operators are all identical and their arguments are all identical.
Otherwise, is(a = b) evaluates to false; is never evaluates to unknown.
Note that in contrast to function equal, is(a=b) does not check assumptions in Max-
ima’s database. Thus, Maxima properties of a and b are not considered, only their
values. Assumptions of equality cannot be specified with the = operator, only with
function equal.
(%i1) assume(a=b);
Error!
(%i2) assume(equal(a,b))$
(%i3) is(a=b);
(%o3) false
(%i4) is(equal(a,b));
(%o4) true
These are the relational operators. They are binary operators. Chains like a<b<c
are not allowed. Just like = and #, relational operators do nothing more than evalu-
ate and simplify their arguments separately. An expression like < b is an uneval-
uated relational expression, which might or might not hold. Any desired simplifica-
tion across the relational operator has to be carried out manually. Function solve
does not accept relational expressions.
Relational operators can be used to specify assumptions with assume.
Function is tries to evaluate a relational expression like a<b to a Boolean value.
Comparison is carried out by checking Maxima’s database for user-postulated as-
sumptions, and by checking what ratsimp(a-b) returns. Thus, as for functions equal
and notequal, both Maxima properties of the variables concerned and their values
are considered.
74
+1
(%o3) −
(t + 1)2
When is fails to reduce a relational expression to true or false, the result is governed
by the global flag prederror. When prederror is true, is returns an error message.
Otherwise (default), it returns unknown.
In addition to function is, some other operators evaluate relational expressions to
true or false, namely if, while, unless, and, or, and not.
75
Chapter 11
Evaluation
Richard Fateman’s paper from 1996, which can also be found on his homepage in a
revised version from 1999.
Evaluation in Maxima means dereferencing. If a symbol is bound, i.e. if it has a
value, or as we say refers to a value, then evaluation of a symbol means retrieving
this value. Evaluation is not to be confused with simplification.
A symbol which is not bound evaluates to itself.
(%i1) a;
(%o1) a
(%i1) a:b;
(%o1) b
(%i2) b:c;
(%o2) c
(%i3) a;
(%o3) b
(%i4) ev(a);
(%o4) c
(%i5) a:ev(a);
(%o5) c
(%i6) a;
(%o6) c
76
Double-quote does not "force evaluation" − it substitutes a value at read time. It
is a handy shortcut in interactive use, but I urge you to avoid it in general. For one
thing, you can’t prototype a calculation interactively and then package it up as a
function if you use ’ ’(...).
ev is another convenience function with some surprising behavior. In particular,
e(..., = 1) is not equivalent to bock([ : 1], ...). For example, e(dƒ ƒ (,0 ), =
1) gives an error, while bock([ : 1], dƒ ƒ (,0 )) gives 0. Since it performs an
evaluation, it also risks free-variable capture in programs (again, a problem when
you package up an interactive prototype). I always urge people to avoid ev as much
as possible. It is always cleaner and clearer to use subst rather than ev.
Trying to get ev to do what you want by clever use of ’(...) or ’ ’(...) is a fool’s
errand: you may get it to work in one case, but you will quickly find cases where it
isn’t quite right.
To recap:
ev(...) and ’ ’(...) are handy hacks, but have peculiar semantics and are best to
avoid.
11.2 Function ev
ev (expr ,
rg1 , . . . , rgn ) [function]
expr, rg1 , rg2 , . . . , rgn
Function ev evaluates the expression expr in the environment specified by the argu-
ments rg1 , . . . , rgn . These arguments are switches (Boolean flags), assignments,
equations, and functions from the list given below. ev returns the result (another
expression) of the evaluation.
An alternate top level syntax has been provided for ev, whereby one may just type
in the expression and its arguments separated by commas. This is not permitted as
part of another expression, e.g., in functions, blocks, etc. For an example see sect.
24.2.1.2.2.
The evaluation is carried out in steps, as follows.
1. First the environment is set up by scanning the arguments which may be any or
all of the following.
simp causes expr to be simplified regardless of the setting of the switch simp
which inhibits simplification if false.
noeval suppresses the evaluation phase of ev (see step (4) below). This is use-
ful in conjunction with the other switches and in causing expr to be resimplified
without being reevaluated.
77
expand causes expansion.
expand (m, n) causes expansion, setting the values of maxposex and max-
negex to m and n respectively.
detout causes any matrix inverses computed in expr to have their determinant
kept outside of the inverse rather than dividing through each element.
risch causes integrals in expr to be evaluated using the Risch algorithm. The
standard integration routine is invoked when using the special symbol nouns.
eval causes an extra post-evaluation of expr to occur. (See step (5) below.)
eval may occur multiple times. For each instance of eval, the expression is
evaluated again.
Any other function names, e.g. sum, cause evaluation of occurrences of those
names in expr as though they were verbs.
78
or assignment, then the indicated binding or substitution is performed. If the
result is a list, then the elements of the list are treated as though they were
additional arguments given to ev. This permits a list of equations to be given
(e.g. [X=1, Y=A**2]), or a list of names of equations (e.g., [%t1, %t2] where
%t1 and %t2 are equations) such as returned by solve.
The arguments of ev may be given in any order with the exception of substitution
equations which are handled in sequence, left to right, and evaluation functions
which are composed, e.g., ev (expr, ratsimp, realpart) is handled as realpart (rat-
simp (expr)). The simp, numer, and float switches may also be set locally in a block,
or globally in Maxima so that they will remain in effect until being reset. If expr is
a canonical rational expression (CRE), then the expression returned by ev is also a
CRE, provided the numer and float switches are not both true.
2. During step (1), a list is made of the non-subscripted variables appearing on
the left side of equations in the arguments or in the value of some arguments if
the value is an equation. The variables (subscripted variables which do not have
associated array functions as well as non-subscripted variables) in the expression
expr are replaced by their global values, except for those appearing in this list.
Usually, expr is just a label or % (as in %i2 in the example below), so this step
simply retrieves the expression named by the label, so that ev may work on it.
3. If any substitutions are indicated by the arguments, they are carried out now.
4. The resulting expression is then re-evaluated (unless one of the arguments was
noeval) and simplified according to the arguments. Note that any function calls in
expr will be carried out after the variables in it are evaluated and that ev(F(x)) thus
may behave like F(ev(x)).
5. For each instance of eval in the arguments, steps (3) and (4) are repeated.
00
11.3 Quote-quote operator
0 0 expr [prefix operator]
The quote-quote operator 0 0 (two single quote marks) modifies evaluation in input
expressions. Applied to a general expression expr, quote-quote causes the value
of expr to be substituted for expr in the input expression. Applied to the operator
of an expression, quote-quote changes the operator from a noun to a verb (if it
is not already a verb). The quote-quote operator is applied by the input parser;
it is not stored as part of a parsed input expression. The quote-quote operator is
always applied as soon as it is parsed, and cannot be quoted. Thus quote-quote
causes evaluation when evaluation is otherwise suppressed, such as in function
definitions, lambda expressions, and expressions quoted by single quote ’.
Quote-quote is recognized by batch and load.
11.4 Substitution
Maxima has three different functions which carry out substitutions: ev, at, and
subst.
79
11.4.1 Substituting values for variables
at ( epr [epr1 , . . . , eprn ] , eqn [eqn1 , . . . , eqnn ] )
[function]
Evaluates expr or the expressions in the list with variables assuming values as
specified in eqn or the list of equations. at carries out multiple substitutions in
parallel. Depending on the first argument, at returns a single expression or a list of
expressions.
Note that values do not necessarily mean numerical values. Symbols and even ex-
pressions can also be substituted for symbols. (Substituting expressions for expres-
sions sometimes is possible, sometimes not. Anyway, this use of at is discouraged.)
In particular, at allows to indicate that the derivative of an unspecified function is
to be evaluated at a certain point.
(%i1) at(x^2,x=x0);
(%o1) 02
(%i2) at(f(x),x=x0);
(%o2) f(x0)
(%i3) at(diff(f(x),x),x=x0);
d
(%o3) f()
d =0
80
Chapter 12
Simplification
(%i1) exponentialize(2*cos(s)+sin(s/2));
%s %s
% %e 2 − %e− 2
(%o1) %e%s − + %e−%s
2
81
(%i2) demoivre(%);
s
(%o2) 2 cos (s) + sin
2
(%i3) exponentialize(tanh(s));
%es − %e−s
(%o3)
%es + %e−s
(%i4) demoivre(%);
%es − %e−s
(%o4)
%es + %e−s
. [function of rs_simplification]
Selectively applies function, which must be quoted1 and followed by parentheses
(either empty or with additional arguments to function2 ), to the part of expr, which
is specified by the following arguments in the way of the arguments of function
part. As in part, a list of selected terms can be specified as the last argument, or
the construction with allbut can be used. The complete expr with the substitution
accomplished is returned.
A lamba expression can be specified instead of a symbol for function. Again it
must be quoted and followed by parentheses (either empty or with additional argu-
ments).
Apply2Part can be used e.g. with functions factor, expand, ratexpand (which brings
terms to a common denominator), or trigsimp. Note that PullFactorOut has this
functionality already built in, so its combination with Apply2Part is unnecessary.
As an example, function being set to factor allows to selectively factor a part (or
even specific terms from a sum) anywhere in an expression. This constructs and
evaluates an expression of the form substpart(factor(part(expr, indices)),expr, in-
dices), where the last index can be a list of the terms of a sum to be factored. The
factor itself is specified only implicitely by this selection.
82
(%i1) expr: f(t)=a*x+b*y+c*x*y+d*y;
(%o1) f(t)=cxy+dy+by+ax
(%i2) Apply2Part(’factor(),expr,2,[1,2,3]);
(%o2) f(t)=(cx+d+b)y+ax
(%i3) Apply2Part(’factor(),expr,2,[1,4]);
(%o3) f(t)=x(cy+a)+dy+by
(%i4) Apply2Part(’factor(),%,2,[2,3]);
(%o4) f(t)=x(cy+a)+(d+b)y
(%i5) Apply2Part(’lambda([x],x^2)(),%,2,1,1);
(%o5) f(t)=x^2(cy+a)+(d+b)y
12.4.2 ChangeSign
ChangeSign (epr , 1 , . . . , n ) [function of rs_simplification]
Changes the sign of expr or the subexpression epr, 1 , . . . , n specified as in func-
tion part. By applying this function to an expression twice, the minus sign can be
switched between two places, e.g. two factors, between numerator and denomina-
tor of a fraction, or between a product as a whole and one of its factors. The inner
function call should be tested alone before being wrapped by the second call, be-
cause the canonical order may be changed by the inner call. Note that the operator
of the sum − b is "+", with the operator of −b being "−" (b can be a subexpression).
(%i1) expr:-((a-b)/(c-d));
−b
(%o1) −
c−d
(%i2) ChangeSign(ChangeSign(expr,1,1),1,2);
b−
(%o2) −
d−c
(%i3) expr:f=(’diff(a,x)+((a+b)/(c-d)))/(h+j+log(d));
b+ d
c−d
+ d
(%o3) ƒ=
j + h + log (d)
(%i4) ChangeSign(ChangeSign(expr,2,1,1,1),2,1,1);
d
d
− −b−
c−d
(%o4) ƒ=
j + h + log (d)
(%i5) expr:-s*(-a+b)*(-c+d);
(%o5) -(-a+b)*(-c+d)*s
(%i6) ChangeSign(ChangeSign(expr),2);
(%o6) (-a+b)*(c-d)*s
12.4.3 FactorTerms
83
one of the given factors. In this case, the result will equal the given subexpression,
which can be shown by expanding it again, but the desired factoring is impossible.
So in this case Apply2Part(factor) has to be used instead, which allows selecting
terms individually; here the specific factor to be factored out of the multi-factor
term is specified implicitely.
The complete expr with the substitution accomplished is returned.
12.4.4 PullFactorOut
PullFactorOut ( epr 0 prt (epr, 1 , . . . , n , [j1 , . . . , j ] bt(j1 , . . . , j ) ) , ƒ ctor )
.
[function of rs_simplification]
PullFactorOut2 (expr , ƒ ctor ) [function of rs_simplification]
Pulls factor out of expr and wraps it in a box which normally preceeds the remainder.
expr can be a product, fraction, sum, list, vector or matrix. If the remainder is a
fraction, a list or a matrix, it is placed in a second box in order for the first box not
to be pulled into the numerator or each element of the list or matrix. If no factor
is specified, the gcd is determined and pulled out. However, this does not make
sense and does not work for products or fractions.
If part of an expr is specified as in function part (note that this has to be quoted
here), only this part will be factored, but the whole expr will be returned. Thus,
combination of PullFactorOut with Apply2Part is not necessary. Giving the last pa-
rameter as a list of selected terms or using allbut to exclude selected terms as in
function part is also possible, see "‘Kugel rollte im Hohlkegel.wxm"’.
PullFactorOut2 is an experimental version with the same functionality, but not re-
quiring to put a box around the pulled out factor, unless -1 is pulled out of a matrix.
(%i1) v:r*CVect(cos(t),sin(t));
r cos(t)
(%o1)
r sin(t)
(%i2) PullFactorOut(v,r);
cos (t)
(%o2) (r)
sin (t)
(%i1) g1:-3*a*b/2;
3b
(%o1) −
2
(%i2) PullFactorOut(’part(g1,2),3/2);
3
(%o2) − b
2
(%i3) g2:Fn=p+(a-(3*a*b/(2*c*d)))/(d+g);
84
3b
− 2cd
(%o3) Fn = p +
g+d
(%i4) PullFactorOut(’part(g2,2,2,1,2),-3*a/2);
b
− 3
2 cd
+
(%o4) Fn = p +
g+d
85
Chapter 13
In Maxima, variables and user-defined functions can be associated not only with
values, but also with properties and with assumptions. Properties contain infor-
mation about the type of value the respective variable or function is supposed to
take, while assumptions limit the numerical range of their allowed values. Both
categories of information can be used by Maxima or by user-written functions for
computation and simplification of expressions comprising these variables.
Maxima’s mathematical knowledge database system was written by Michael Gene-
sereth while studying at MIT in the early 1970s . Today he is professor of computer
science at Stanford University.
Before looking closer at the information it contains, namely properties and assump-
tions, we will focus on general features of this database system. We describe its
user interface first, then some aspects of the implementation.
Properties and assumptions associated with a Maxima symbol are called facts.
There are certain facts already provided by the system, for instance about general
and predefined mathematical constants such as e, i or π. In addition, the user may
assign one or more of a number of system-defined properties to any of his variables
or user functions. He can also define his own new property types, called features,
and assign them to symbols just like the system-defined properties. Finally, using
assumptions, he can impose restrictions on the numerical range of values to be
taken by a symbol denoting a variable or function.
Some, but not all Maxima functions recognize facts. For example, solve does not
consider assumptions (it was written before the knowledge database was intro-
duced into Maxima), whereas to_poly_solve, a more recent and sometimes more
powerful solver, does. User-written functions, of course, may also take facts into
account.
If they need certain information about user variables in order to proceed operating
on them, some Maxima functions will ask the user interactively at the time they are
86
called. This is a useful procedure in order to reach computational results, since the
user may not be aware of any such necessity in advance. He can, however, declare
the corresponding properties or assumptions prior to calling the function in order to
avoid these questions.
Maxima’s mathematical knowledge database system organizes facts in a hierarchi-
cal structure of contexts. The context named global forms the root of this hierarchy,
the parent of all other contexts. It contains information for instance about prede-
fined constants, e.g. %e, %i or %pi, and their respective values. When a Maxima
session is started, the user sees a child context of global named initial. If he does
not specify any other context, all facts, that means all properties created by declare
and all assumptions created by assume, will be stored in this context. The context
which presently accomodates newly declared assumptions is called the current con-
text. Function facts may be used to list all facts contained in a certain context, or
all facts defined for a particular symbol and kept within the current context.
The user may create child contexts to any existing context, including global. The
facts that are visible and are used for deductions at any moment are those of the
current context plus all of its parent contexts. In addition, the user may activate
any other context freely at will with function activate. This context plus all of its
parent contexts will then also be visible in addition to the current context and its
parents. The user can deactivate any explicitely activated context with deactivate.
A list of all activated contexts is kept in activecontexts.
Function context can be used to show the current context or to change it. New
contexts are defined by either newcontext or supcontext. contexts gives a list of
all contexts presently defined.
The context mechanism makes it possible for the user to bind together and name a
collection of facts. Once this is done, he can activate or deactivate large numbers of
previously defined facts merely by activating or deactivating the respective context.
Facts contained in a context will be retained in storage until destroyed one by one
by calling forget, or as a whole by calling killcontext to destroy the context to which
they belong.
The terms "subcontext" and "sup(er)context" are used in Maxima, but they have
some inherent ambiguity. A child context is always bigger than its parent context
as a collection of facts, because the facts a child context contains are added to the
facts already active in the line of its parent contexts. (It is not possible to deacti-
vate parent contexts to the current context or any other explicitly active context).
The child context therefore is a superset of the parent context. Thus, function sup-
context creates a child context to the current context. Parent contexts are called
subcontexts. This terminology, however, contradicts the normal description of a
tree structure, where one would naturally tend to name a leave a sub-element to
its parent. There is another interpretation contradicting the terminology used in
Maxima. If a context is bigger because it contains more facts, on the other hand
it is smaller, because every additional fact narrows and constrains the possibilities
for the corresponding variable or function to take values. Due to this ambiguity we
stay with the parent-child terminology.
87
Facts and contexts are global in Maxima, even if the corresponding variables are
local. However, it is possible to make facts associated with a local variable local,
too, by declaring (inside of the local environment) the respective local variable or
function a with the system function local(a).
Killing a variable or function with kill(a) will not delete facts associated with .
Only kill(all) will delete everything, including the defined facts and contexts.
88
contexts exist, otherwise an error message.
Note that by activating a context, the facts of all its parent contexts also become
available for deductions, although these parent contexts are not added to the list
activecontexts.
13.1.2 Implementation
13.1.2.1 Internal data structure
89
13.3 MaximaL Properties
13.3.1 Introduction
In Maxima, variables and user-defined functions can be associated not only with
values, but also with properties. Properties contain information about the kind of
variable or function which the respective symbol is to represent, or the type of value
which the respective variable or function is supposed to take.
The concept of properties is inherent in Lisp. In order to distinguish both types, we
will henceforth use the terms Lisp property to refer to the properties on the Lisp
level, and MaximaL property (sometimes also called: mathematical property) to
refer to the properties on the MaximaL level.
There are three types of MaximaL properties:
User-defined properties can be defined by the user and then be declared for a
symbol or removed from it.
Unlike values, properties (except for the property value) are global in Maxima. Thus,
a property assigned to a local variable inside of a local environment (like a block or
a function) will remain associated with this symbol outside of the block or function
(after it has been called). This holds in particular for function definitions: a function
defined inside of a block will be global (once the block has been evaluated). In order
to prevent properties of a local variable to become global, the variable has to be
declared local (a) inside of the local environment.
kill (a) not only unbinds the symbol , but also removes all associated properties.
90
13.3.3 User-declared properties
These are pre-defined properties, which the user can assign to a variable or user-
defined function or remove from it. Properties are recognized by the simplifier
and other Maxima functions. There are general (featurep) and specific (e.g. con-
stantp) predicate functions which can test a certain symbol for having a specific
user-declared or user-defined property or not.
[function]
Assigns property (or list of properties) pj to symbol (or list of symbols) j , j =
1, . . . , n. Symbols may be variables, functions, operators, etc. Arguments are not
evaluated. declare always returns done. To test whether an atom has a specific
(user-declared or user-defined) property, see featurep. For the use of declare to
create user-defined properties, see declare (p , feature).
(%i1) declare(a,outative,b,additive)$
(%i2) declare([r,s,t],real)$
(%i3) declare(c,[constant,complex])$
integer [property]
noninteger [property]
Tells Maxima to recognize j as an integer or noninteger variable. Function askinte-
ger recognize this property, but integerp does not.
91
even [property]
odd [property]
Tells Maxima to recognize j as an even or odd integer variable. The properties even
and odd are recognized by function askinteger, but not by the predicate functions
evenp, oddp, and integerp.
rational [property]
irrational [property]
Tells Maxima to recognize j as a rational variable or an irrational real variable.
real [property]
complex [property]
imaginary [property]
Tells Maxima to recognize j as a real, complex or pure imaginary variable.
constant [property]
The declaration of j to be constant does not prevent the assignment of a non-
constant value to j . Such an assignment, on the other hand, does not remove the
property constant from j . The following predicate function constantp not only tests
for a variable declared constant, but for a constant expression in general.
scalar [property]
nonscalar [property]
Tells Maxima to recognize j as a scalar or nonscalar variable. The usual application
is to declare a variable as a symbolic vector or matrix. Makes j behave as does
a list or matrix with respect to the dot operator. The following predicate functions
scalarp and nonscalarp not only test variables declared scalar or nonscalar.
92
scalarp returns true, if expr is a number, a constant, or a variable declared scalar,
or composed entirely of numbers, constants, and such declared variables, but not
containing matrices or lists. nonscalar returns true if expr contains atoms declared
nonscalar, or lists, or matrices.
nonarray [property]
Tells Maxima to consider j not to be an array. This prevents multiple evaluation of
a subscripted variable.
integervalued [property]
Tells Maxima to recognize j as an integer-valued function.
increasing [property]
decreasing [property]
Tells Maxima to recognize j as an increasing or decreasing function.
posfun [property]
Tells Maxima to recognize j as a positive function.
evenfun [property]
A function with this property is recognized as an even function. ƒ (−) will be sim-
plified to ƒ ().
oddfun [property]
A function with this property is recognized as an odd function. ƒ (−) will be simpli-
fied to −ƒ ().
outative [property]
If a function has this property and it is applied to an argument forming a product,
constant factors are pulled out on simplification. Constants in this sense are num-
bers, standard Maxima constants such as %e, %i or %pi, and variables that have
been declared constant.
(%i1) declare(f,outative)$
(%i2) f((r-2+%e^%i)*x);
(%o2) ƒ ((r + e − 2) )
93
(%i3) declare(r,constant)$
(%i4) f((r-2+%e^%i)*x);
(%o4) (r + e − 2) ƒ ()
The standard functions sum, integrate and limit are by default outative. However,
this property can be removed from them by the user.
additive [property]
If a function has this property and it is applied to an argument forming a sum, the
function is distributed over this sum, i.e. f(y+x) will simplify to f(y)+f(x).
linear [property]
Equivalent to declaring j both outative and additive.
multiplicative [property]
If a function has this property and it is applied to an argument forming a product,
the function is distributed over this product, i.e. f(y*x) will simplify to f(y)*f(x).
commutative [property]
symmetric [property]
These two properties are synonyms. If assigned to a function ƒ (, z, y), it will be
simplified to ƒ (, y, z).
antisymmetric [property]
If assigned to a function ƒ (, y, z), it will be simplified to −ƒ (, y, z). That is, it will
give (−1)n times the result given by symmetric or commutative, where n is the
number of interchanges of wo arguments necessary to convert it to that form.
lassociative [property]
rassociative [property]
A function with this property is recognized as being left-associative or right-associa-
tive.
94
(%i1) declare(new_property, feature)$
(%i2) declare(a, new_property)%
(%i3) properties(a);
(%o3) [database info,kind(a,new_property)]
(%i4) featurep(a,new_property);
(%o4) true
(%i5) a:b;
(%o5) b
(%i6) featurep(a,new_property);
(%o6) false
(%i7) featurep(’a,new_property);
(%o7) true
(%i8) c:new_property;
(%o8) new_property
(%i9) featurep(a,c);
(%o9) true
13.3.5 Implementation
13.4 Assumptions
13.4.1 User interface
13.4.1.1 Introduction
95
13.4.1.2 Functions and system variables for assumptions
96
to those previously assumed (e.g., b*2>4 eliminates b>2, but 2*a<2*b does not
eliminate a<b).
forget does not complain if a predicate to be forgotten does not exist. In any case,
pred1 , pred2 , . . . , predn or L is returned.
is (expr) [function]
ev(expr, pred), which can be written expr, pred at the interactive prompt, is equiv-
alent to is(expr).
is attempts to determine whether the predicate expr is provable from the facts in
the database. If the predicate is provably true or false, is returns this respectively.
Otherwise, the return value is governed by the global flag prederror. If it is not set
(default), it returns unknown. Otherwise, is returns an error message.
Note that is can evaluate any other predicate, too,independently of the assump-
tions in the database. Special attention has to be paid for tests of equality. is(a=b)
tests a and b to be literally equal, that is identical. is(equal(a,b)) tests for equiva-
lence, which does not necessarily imply literal identity. Different symbolic expres-
sions, that can be simplified by Maxima to the same (canonical) expression, are
considered equivalent.
is attempts to derive predicates from the facts database. Note that assumptions
cannot be tested for literal equality or inequality.
If is can neither prove nor disprove a predicate by itself of from the facts database,
the global flag prederror governs the behavior of is.
97
(%i1) assume (a > b);
(%i1) [a > b]
(%i2) prederror: true$
(%i3) is (a > 0);
Maxima was unable to evaluate the predicate: a > 0
-- an error. Quitting. To debug this try debugmode(true);
(%i4) prederror: false$
(%i5) is (a > 0);
(%i1) unknown
13.4.2 Implementation
98
Chapter 14
14.1 Introduction
This chapter describes pattern matching and user-defined simplification rules. Max-
ima’s pattern matcher was written by Richard J. Fateman. His dissertation from
1971, entitled Algebraic Simplification, describes it together with other components [FatemThe]
of Macsyma which he had implemented. We recommend reading chapter 2, "The
User-Level Semantic Matching Capability In MACSYMA", of this thesis, because it
motivates why we want to use pattern matching in a CAS, and on what theoretical
background Maxima’s pattern matcher was designed. Repeatedly, when related
question arose on maxima-discuss in the past, Richard took the time to explain the
principles of Maxima’s pattern matcher. So the archives of maxima-discuss consti-
tute another valuable source of information in this respect.
The very concise chapter on rules and patterns of the Maxima manual was written
by Robert Dodier. Michel Talon recently contributed an introductory tutorial which [TalonRP]
focuses on special issues and potential problems in application and includes refer-
ences to how the pattern matcher works on the Lisp level.
There are two groups of functions which implement different pattern matching
schemes. The first group comprises defmatch, defrule, tellsimp, tellsimpafter,
apply1, applyb1, and apply2. To the second group belong let and letsimp. Both
schemes define patterns in terms of pattern variables declared by matchdeclare.
Pattern-matching rules defined by tellsimp and tellsimpafter are applied automati-
cally by the Maxima simplifier, while rules defined by defmatch, defrule, and let are
applied by an explicit function call.
There are additional mechanisms for rules applied to polynomials by tellrat, and for
commutative and noncommutative algebra in the affine package.
99
will, in case of a positive match, also replace the matching expression or subex-
pression with some replacement expression, that is, they will modify the original
expression.
In combination with functions which can decompose a given expression into all of
its subexpressions (apply1, applyb1, apply2), pattern matching functions can com-
pare a defined pattern with all subexpressions on all levels of a given expression.
The replacement can then be done to all subexpressions which match the pattern.
This constitutes a very powerful mechanism which allows to modify or simplify the
given expression according to certain rules. Such rules are nothing more than a
combination of a pattern and a corresponding replacement.
Pattern matching is done in several steps. First we have to define a pattern. This
is done with the help of pattern variables. So actually, defining the pattern vari-
ables is the very first step. This is done with matchdeclare. The definition of the
actual pattern is done in the next step, when we create a function which can test a
given expression for whether it matches the pattern (and how) or not. Creating this
function and defining the pattern is done with defmatch. defmatch not only uses
pattern variables, but also pattern parameters to define the pattern. Alternatively,
we can define a function which substitutes an expression matching the pattern with
a replacement expression. This is done with defrule. Thus, defrule not only defines
a pattern, but a complete rule consisting of a pattern and the corresponding re-
placement to be carried out in case of a positive match.
Both defmatch and defrule create a match function which can be called explicitely
by the user. Calling this function with an actual expression (an expression to be
tested for whether it matches the pattern or not) as an argument forms the third
step in pattern matching. If we want to apply our match function to all subexpres-
sions of the actual expression, we have to wrap it in apply1, applyb1, or apply2
before calling it. However, it is also possible to make the simplifier use our newly
defined rule automatically for any expression (and any of its subexpressions) which
is being simplified by the system. Depending on whether our new rule is to be used
before or after the system simplification rules, its definition is done with tellsimp or
tellsimpafter.
100
defined in the form of a predicate, a Boolean function returning either true or false.
More than one pattern variable can occur in a pattern, and a pattern variable can
occor more than once.
A pattern is an expression in which pattern variables occur together with pattern
parameters, other symbols introduced by the user, numbers, operators, or function
calls. If a pattern is to match an actual expression, all pattern variables occuring in
the pattern and all of their occurrences have to match a subexpression of the actual
expression; all pattern parameters, if any, have to match a symbol identical with
the pattern argument; and all other elements of the pattern have to literally match
a counterpart of the actual expression (with the exception of a possible evaluation
of any symbol introduced by the user). Only if all of this is fulfilled and nothing
of the actual expression is left over, the pattern matches as a whole. In this case,
every pattern variable will be bound (i.e. assigned as its value) to the corresponding
subexpression of the actual expression.
14.1.1.2 No backtracking
101
14.1.1.3 The matching strategy in detail
Maxima’s pattern matcher is more than just a literal matcher. It considers algebraic
properties of expressions, for instance the commutativity of addition and multipli-
cation.
The usual strategy of the matcher is to compare a given pattern variable, according
to its match predicate, with all subexpressions of the actual expression, one after
the other. The first subexpression it finds which satisfies the match predicate, it will
take. Then the matcher goes to the next pattern variable and repeats the process
with what is left from the actual expression. If at any point a pattern variable cannot
find a matching counterpart, the global match fails. This implies that the order in
which the pattern variables are compared against the subexpressions is important.
Pattern variables are tested against subexpressions in the inverse order in which
they appear in the pattern. If a subexpression of the actual expression satisfies the
match predicate of more than one pattern variable, it will be assigned to the first
pattern variable which finds it. If a pattern variable occurs more than once in a
pattern, then of course what it takes must be identical for all occurrences (this is an
extra condition in addition to the match predicate).
102
If a (part of a) pattern of the form ∗b+ c∗d with pattern variables , b, c, d, that is a
sum of subexpression being products, is to be compared with a subexpression ∗y+
∗ of the actual expression, , y, , possibly themselves being subexpressions,
and we expect say to match with , we will most likely not be able to set up a
correct matching scheme unless we employ the anchor principle.
In the above pattern, Maxima’s pattern matcher can correctly determine whether
matches only, if b and y are identical, or if at least the matcher can determine
what y is, possibly with the help of some pattern parameter. The matcher needs to
have an anchor for being able to match with , and this anchor is y. In fact, what
the matcher simply does in this case, is to use ratcoeff(x*y+u*w,y). This way it can
determine the coefficient of y, which is x. x might well be a complicated expression
consisting of multiple factors. But if the matcher does not know what y is, if y is
unknown in the same way that x is unknown, it cannot apply ratcoeff, because it
does not know what coefficient (the coefficient of what) to look for. In this case
most likely the matcher (e.g. function defmatch) will issue a warning, saying that it
cannot safely match the pattern specified by the user under the given conditions,
i.e. the specifiactions of the pattern variables it contains.
We will give an example of the anchor principle in sect. 14.3.1, when we discuss
defmatch and defrule.
14.2 Matchdeclare
matchdeclare ( r1 [r11 , . . . , r1k1 ] , pred1 , ..., rn , predn )
[function]
The arguments of matchdeclare are pairs = 1, . . . , n consisting of a pattern vari-
able r or a list [r1 , . . . , rk ] of pattern variables, and a match predicate
pred . matchdeclare associates r or the corresponding list of pattern variables
with pred . See the introduction for the meaning of pattern variable and match
predicate.
The functions defmatch, defrule, tellsimp, tellsimpafter, and let use pattern vari-
ables to construct patterns.
A match predicate is an unfinished function call or lambda call, in the sense that it
lacks its last argument, or has no argument at all, if the function or lambda expres-
sion requires only one. In the first case, the list of arguments given in parentheses
to the function call or lambda call lacks the last element. In the latter case, only
the name of the function or only the lambda expression itself is given, with no ar-
gument (and no empty parentheses). A match predicate, however, can also be true
or all. Here are some examples of valid match predicates.
103
The missing argument will be supplied later, when the match predicate is evalu-
ated. This will not be done before the match function, which will be defined by
e.g. defmatch or defrule, is called to test an actual expression against the defined
pattern containing the pattern variables we have just defined.
When a pattern containing a pattern variable is tested against an actual expres-
sion, the matcher will compare subexpressions of the actual expression with the
predicate of the pattern variable, in order to find out whether this subexpression
matches the pattern variable or not. If the predicate returns anything other than
false, this particular subexpression is said to match the pattern variable and will be
assigned to it as its value. If a replacement expression (e.g. in defrule) contains
this pattern variable, it will be evaluated to this subexpression bound to it. See the
introduction for how multiple pattern variables are matched and at what point the
pattern matches as a whole.
When a pattern containing a pattern variable is tested against an actual expression,
the subexpression to be tested against the particular pattern variable is appended
to the list of arguments of the function call or lambda call of its match predicate,
or, if it has no arguments yet, it is supplied as its sole argument. In any case, the
tested subexpression completes the required number of arguments of the match
predicate.
At this point it should be clear that a match predicate cannot simply be a relational
or Boolean expression. Instead, it has to be wrapped in a function or lambda ex-
pression waiting for the particular subexpression to be its (last) argument. It is not
necessary to call is to evaluate relational expressions within the match predicate.
This will be done automatically when the match is attempted.
Any subexpression matches a match predicates which is defined as true or all. If
the match predicate is a function, it need not be defined yet when matchdeclare is
called, since the predicate is not evaluated until a match is attempted. matchde-
clare quotes its arguments and always returns done.
If an subexpression satisfies a match predicate, the match variable is assigned this
subexpression and nothing more. However, addition and multiplication are treated
differently; other nary operators (both built-in and user-defined) are treated like or-
dinary functions. In the case of addition and multiplication, the match variable may
be assigned a single expression which satisfies the match predicate, or a sum or
product (respectively) of such expressions. Such multiple-term matching is greedy,
which means: predicates are evaluated in the order in which their associated vari-
ables appear in the pattern, and a term which satisfies more than one predicate
is taken by the first predicate which it satisfies. A pattern variable’s predicate is
tested against all operands of the sum or product before the next pattern variable’s
predicate is evaluated. Furthermore, if "0" or "1" (respectively) satisfy a match
predicate and there are no other terms which satisfy the predicate, "o" or "1" is
assigned to the match variable associated with the predicate.
The algorithm for processing addition and multiplication patterns makes some match
results (for example, a pattern in which a "match anything" variable appears) de-
pendent on the ordering of terms in the match pattern and in the expression to be
104
matched. However, if all match predicates are mutually exclusive, the match result
is insensitive to ordering, as one match predicate cannot accept terms matched by
another. See the introduction for more explications.
Calling matchdeclare with a variable var as an argument changes the matchdeclare
property of var, if one was already declared; only the most recent matchdeclare is
in effect when a rule for var is defined. Later changes to the matchdeclare property
of var (via matchdeclare or remove) do not affect already existing rules.
propvars (matchdeclare) returns the list of all variables for which there is a matchde-
clare property. printprops (var, matchdeclare) returns the predicate for variable var.
printprops (all, matchdeclare) returns the list of predicates for all match variables.
remove (var, matchdeclare) removes the matchdeclare property from var.
(%i1) matchdeclare (a, lambda ([k], k#0 and freeof(x, k)), b, freeof(x))$
(%i2) defmatch (linearp, a*x + b)$
(%i3) linearp (3*x + (y + 1)*x + y^2);
105
(%o3) [b = y 2 , = y + 4]
(%i4) linearp (3*z + (y + 1)*z + y^2);
(%o4) false
Note that both defmatch and linearp now have two arguments. We specifically ask
linearp for linearity in z. This is the case. The global pattern variables a and b
have been assigned the matching subexpressions, while the pattern parameter x
has not.
106
with the angular frequency ω depending on the particular ODE and the constants
C1 , C2 depending on the initial conditions. Note that the arguments of the sin and
the cos are identical. Any expression like this, representing the superposition of two
oscillations with the same frequency, but with different amplitudes and a phase shift
between them, can be brought into the form of a single oscillation
with the amplitude A and the phase constant α. The formulas are
r
A = C21 + C22 and α = tn2(C1 , C2 ). (14.3)
(%i1) matchdeclare([a,b,c],all)$
(%i2) defmatch(m1,a*sin(c)+b*cos(c));
defmatch: a*sin(c) will be matched uniquely since sub-parts would otherwise
be ambigious.
defmatch: cos(c)*b will be matched uniquely since sub-parts would otherwise
be ambigious.
(%o2) m1
(%i3) m1(sin(sqrt(g/l)*t)*sin(x)*cos(y)*s+cos(sqrt(g/l)*t)*cos(x));
v v
tg tg
(%o3) [b = cos t , = s sin t cos (y), c = ]
We got warnings from defmatch, which we ignored, because we did not understand
them yet. We chose to test our match function m1 with an expression, which con-
tains other sines and cosines as part of the factors we want to extract. But m1
p
messed it up: instead of selecting the sin and cos with the argument g/ t as the
anchors, m1 took the sin and cos whose arguments are x. We want to improve our
match predicates, knowing that our anchors must both contain in their arguments
the factor t, and that no other sin or cos occuring in the expression can contain t.
(%i1) matchdeclare([a,b],all,c,lambda([i],not(freeof(t,i))))$
(%i2) defmatch(m1,a*sin(c)+b*cos(c));
defmatch: a*sin(c) will be matched uniquely since sub-parts would otherwise
be ambigious.
defmatch: cos(c)*b will be matched uniquely since sub-parts would otherwise
be ambigious.
(%o2) m1
(%i2) m1(sin(sqrt(g/l)*t)*cos(x)*s+cos(sqrt(g/l)*t)*sin(x));
v
tg
(%o2) [b = sin (), = s cos (), c = t]
107
(%i3) m1(sin(sqrt(g/l)*t)*sin(x)*cos(y)*s+cos(sqrt(g/l)*t)*cos(x));
(%o2) false
The warnings are still there. But the first try of m1 with a slightly less complicated
expression than before looks promising: m1 has computed the factors properly.
However, the second try fails: m1 does not find any match with the expression
from above.
What went wrong? We have to read the introduction carefully again, in particular
the section about the anchor principle. Then we realize, that what we are trying to
do cannot succeed. It is impossible to match all three pattern variables in this one
step, because for a and b we have no unambiguous anchor available: sin(c) and
cos(c) cannot be identified in the actual expression by the matcher, because c also
is unknown. And vice versa: the matcher cannot identify the anchor for finding c
either, because a and b are unknown. In this situation the result from the matcher is
unpredictable: it might by coincidence return a correct match in one situation, and
it may just as well return an incorrect match in another one, but most likely it will
not find any match, returning false. We just shouldn’t have ignored the warnings.
So we have to start all over again and use an approach in two steps. First we
need to find the anchor, and then with its help we determine the factors. We give
the first step an intuitive try with a little function called anchor, which makes use of
function gatherargs of the opsubst package. We collect and test all arguments from
sin function calls appearing in the expression. If we do not find any one containing
t, we do the same with the cos function calls. anchor will return the complete
argument to what will be our sin and cos anchor, or 0 in case we did not find any,
meaning that our oszillation function is the zero function.
(%i1) load("opsubst")$
(%i2) anchor(expr):=block([erg,g:0], local(expr,erg,g),
erg: gatherargs(expr,sin),
for i:1 thru length(erg) do
if not(freeof(t,erg[i][1])) then g:erg[i][1],
if g=0 then (
erg: gatherargs(expr,cos),
for i:1 thru length(erg) do
if not(freeof(t,erg[i][1])) then g:erg[i][1]
),
g
)$
With the value returned from anchor we now go into the second step. Instead
of declaring the argument of sin and cos as a match variable, we make it a match
parameter. This way, defmatch issues no warning any more, and our match function
properly isolates the factors a and b, even for complicated expressions.
(%i3) matchdeclare([a,b],all)$
(%i4) defmatch(m1,a*sin(anc)+b*cos(anc),anc);
(%o4) m1
(%i5) expr:sqrt(l/g)*sin(sqrt(g/l)*t)+cos(sqrt(g/l)*t);
108
v v v
t tg tg
u
(%o5) sin t + cos t
g
(%i6) an:anchor(%);
v
tg
(%o6) t
(%i7) if an#0 then m1(expr,an) else (a:b:0,[’a=0,’b=0]);
v v
t tg
u
(%o7) [b = 1, = , nc = t]
g
Although we have solved the problem, we are not quite happy yet with the solution
of step 1. There is a vage feeling that our Pascal-like loops are not the most elegant
way of doing things in the Lisp world. Fortunately, Robert Dodier shows us how we
can program it in a Lisp-like fashion employing pattern matching once more, this
time with defrule.
(%i1) matchdeclare(a,lambda([i],i=t),f,lambda([i],freeof(t,i)))$
(%i2) defrule(r1,sin(a*f),(anc:a*f,sin(a*f)))$
(%i3) defrule(r2,cos(a*f),(anc:a*f,cos(a*f)))$
(%i4) anchor(expr):= block([anc:0],local(a,c,expr))),
apply1(expr,r1,r2),
anc
)$
(%i5) expr:sqrt(l/g)*sin(sqrt(g/l)*t)+cos(sqrt(g/l)*t);
v v v
t tg tg
u
(%o5) sin t + cos t
g
(%i6) an:anchor(%);
v
tg
(%o6) t
We do not really change anything when applying the rules r1, r2 to every subex-
pression of expr with apply1. We simply use a side-effect to make an assignment
to anc when we have found the right subexpression. It does not matter, which one
of the two rules does the assignment, it will be the first one (or the only one) find-
ing the argument containing t. If expr contains both terms, the second rule, when
having found the argument containing t, too, will overwrite anc; but this does not
matter, since the arguments are always identical for both sin and cos. Note, that in
the way we do the assignment ot anc we use dynamic scoping, not lexical scoping.
109
pattern is an expression comprising pattern variables, declared by matchdeclare,
as well as other atoms and operators, considered literals for the purpose of pat-
tern matching. replacement is substituted for an actual expression which matches
pattern. Pattern variables in replacement are assigned the values matched in the
actual expression.
pattern may be any nonatomic expression in which the main operator is not a pat-
tern variable nor "+" nor "*". The newly defined simplification rule is associated
with pattern’s main operator, as it is done for the built-in simplification rules.
tellsimp/tellsimpafter does not evaluate its arguments, and it returns the list of all
simplification rules for the main operator of pattern, including the newly established
rule. Thus, this function can also be used to see what are the built-in simplification
rules for a given main operator.
The names of functions (with one exception, described below), lists, and arrays may
appear in pattern as the main operator only as literals, but not pattern variables.
This excludes expressions like a(x) or b[y] as patterns, if a and b are pattern vari-
ables. Names of functions, lists, and arrays which are pattern variables may appear
as operators other than the main operator in pattern. There is one exception to
the above rule concerning names of functions. The name of a subscripted function
in an expression such as a[x](y) may be a pattern variable, because the main op-
erator is not a, but rather the Lisp atom mqapply. This is a consequence of the
representation of expressions involving subscripted functions.
The rule constructed by tellsimp/tellsimpafter is named after pattern’s main opera-
tor. Rules for built-in operators and user-defined operators defined by infix, prefix,
postfix, matchfix and nofix have names which are Lisp identifiers. Rules for other
functions have names which are MaximaL identifiers.
Rules defined with tellsimp/tellsimpafter are applied after evaluation of an expres-
sion (if not suppressed through quotation or the flag noeval). They are applied
in the order they were defined, and before/after any built-in rules. Rules are ap-
plied bottom-up, that is, applied first to subexpressions before applied to the whole
expression. It may be necessary to repeatedly simplify a result, e.g. via the quote-
quote operator ’ ’ or the flag infeval, to ensure that all rules are applied.
Pattern variables are treated as local variables in simplification rules. Once a rule is
defined, the value of a pattern variable does not affect the rule, and is not affected
by the rule. An assignment to a pattern variable which results from a successful
rule match does not affect the current assignment (or lack of it) of the pattern
variable. However, as with all atoms in Maxima, the properties of pattern variables
(as declared by put and related functions) are global.
The treatment of noun and verb forms is slightly confused. If a rule is defined for
a noun (or verb) form and a rule for the corresponding verb (or noun) form already
exists, the newly-defined rule applies to both forms (noun and verb). If a rule for
the corresponding verb (or noun) form does not exist, the newly-defined rule applies
only to the noun (or verb) form.
The rule constructed by tellsimpafter is an ordinary Lisp function. If the name of
the rule is $foorule1, the construct : sp(trce $ƒ oore1) traces the function, and
110
: sp(symbo − ƒ ncton 0 $ƒ oore1) displays its definition.
remrule (op, rulename all) [function]
Removes rules defined by tellsimp or tellsimpafter. remrule (op, rulename) removes
the rule rulename from the operator op. When op is a built-in or user-defined oper-
ator (as defined by infix, prefix, etc.), op and rulename must be enclosed in double
quotes. remrule (op, all) removes all rules from the operator op.
111
(%i1) halfintegerp(r):=is(integerp(2*r))$
(%i2) matchdeclare(half,halfintegerp)$
(%i3) defrule(r1,x^half,b^(2*half))$
(%i4) defrule(r2,x,b^2)$
(%i5) apply1(sqrt(x)^3+x+sqrt(x)+1/sqrt(x)+1/x+x^(-3/2),r1,r2);
1 1 1
(%o5) b3 + b2 + b + + +
b b2 b3
See, however, that the above example could have easily been done with ratsubst,
too.
clear_rules() [function]
Calls kill (rules) and then resets the next rule number to 1 for addition +, multipli-
cation *, and exponentiation ^.
112
Part IV
Basic Mathematical
Computation
113
Chapter 15
factorial(expr) [function]
expr ! [operator]
Represents the factorial function. Maxima treats x! the same as factorial(x).
For a complex number x, except for negative integers, x! is defined as ( + 1),
where is the gamma function.
For an integer x, x! simplifies to the product of the integers from 1 to x inclusive.
0! simplifies to 1. For a real or complex number x in float or bigfloat precision, x!
simplifies to the value of ( + 1). For x equal to n/2 where n is an odd integer, x!
p p
simplifies to a rational factor times π, since ( 12 ) is equal to π.
The factorial of an integer is simplified to an exact number unless the operand is
greater than factlim. The factorial for real and complex numbers is evaluated in
float or bigfloat precision.
double_factorial(expr) [function]
expr !! [operator]
114
Represents the double factorial function, generally defined for an argument z as
1 (1−cos(zπ)) z
2 4 z
22 +1 .
π 2
(%i1) double_factorial(x);
(%o1) double_factorial(x)
(%i1) _
diff(double factorial(x),x,1);
2
π log sin (π)
+ Ψ0 + 1 + log (2)
π
doble_fctoril() 2 2
(%o1)
2
genfact(x,y,z) [function]
Returns the generalized factorial, defined as ( − z)( − 2z)...( − (y − 1)z). Thus,
when x is an integer, genfact (, , 1) ≡ ! and genfact (, / 2, 2) ≡ !!.
15.2.1.2 Simplification
15.2.2 Binomials
binomial(x,y) [function]
The binomial coefficient is defined as
!
= .
y ( − y)!y!
It can be used for numerical or symbolic computation. If x and y are integers, then
the numerical value of the binomial coefficient is simplified to an integer. If x and y
are real or complex float numbers, the binomial coefficient is computed according to
the generalized factorial. If x is a symbol and y an integer, the binomial coefficient
is expressed as a polynomial.
115
Chapter 16
16.1 Roots
sqrt(expr) [function]
Returns the square root of expr.
16.1.2 Simplification
radexpand default: true [option variable]
domain default: real [option variable]
When radexpand is set to its default value true and domain to its default value real,
sqrt(xˆ 2) is simplified to abs(x).
When radexpand is all or assume(x>0) has been executed, nth roots of factors
which are powers of n are pulled outside of the root. E.g. sqrt(16 ∗ 2 ) is simplified
to 4, and sqrt(2 ) to x.
When radexpand is false or (radexpand is true and domain is set to complex),
sqrt(2 ) will not be simplified.
116
16.1.3 Roots of negative real or of complex numbers
Maxima allows negative real numbers, and more generally, complex numbers as
arguments of any n-th root. If a real root exists, it is returned, otherwise Maxima
computes the principal complex root. This, however, in certain cases will not be
accomplished by a single command. Maxima does not automatically simplify com-
plex numbers, so it may be that the expression is simplified only partially and will
be returned containing a noun form. Further simplification can be achieved with
rectform.
(%i1) (-8)^(1/3)
(%o1) -2
(%i2) sqrt(-4)
(%o2) 2i
(%i3) (-8)^(1/4); 1 1
(%o3) (−1) 4 8 4
(%i4) float(%); 1
(%o4) 1.681792830507429 (−1) 4
(%i5) (-1)^(1/4) 1
(%o5) (−1) 4
(%i6) rectform(%);
% 1
(%o6) p +p
2 2
(%i7) float(%);
(%o7) 0.7071067811865475 + 0.7071067811865475
In the preceeding section we saw that Maxima computes only the principal root
with the exponentiation operator to a rational exponent. If we want to compute all
n (pairwise different) complex roots, we can use function solve. The principal root
will usually be the last one in the list returned. As an example, we want to compute
all three cubic roots of 110 + 74.
(%i1) float(rectform(solve(z^3=110+74*%i,z)));
(%o1) [z=3.830127018922193i-3.366025403784439, z=-4.830127018922193i
-1.633974596215562, z=0.9999999999999999i+5.000000000000001]
(%i2) expand((5+%i)^3);
(%o2) 74i+110
(%i1) float(rectform((110+74*%i)^(1/3)));
(%o2) 0.9999999999999997i+5.0
we notice that the expressions for the principal root differ slightly, apparantly due
to the internal use of different algorithms.
117
16.2.1 Simplification
(%i2) (%e^x-1)/(1+%e^(x/2));
radcan(%);
e − 1
(%o1)
e 2 +1
(%o2) e 2 −1
e b − e− b e b + e− b
(%o3) e +
2 2
(%o4) e+ b
118
Ist die Optionsvariable %emode gesetzt, wird eine Exponentialform %e^(%i*%pi*x)
≡ e π vereinfacht
- falls x eine ganze Zahl, ein ganzzahliges Vielfaches von 1/2, 1/3, 1/4 oder 1/6 oder
eine Gleitkommazahl ist, die einer ganzen oder halbganzzahligen Zahl entspricht:
nach der Euler’schen Formel zu einer komplexen Zahl in der Standardform cos(%pi*x)+%i*sin(%
und dann wenn möglich weiter vereinfacht,
- für andere rationale x zu einer Exponentialform %e^(%i*%pi*y), mit y = − 2k für
ein k ∈ N, sodaß |y| < 1 ist.
Eine Exponentialform %e^(%i*%pi*(x+y)) ≡ e π (+y) wird zu e π e π y umgeformt
und dann der erste Faktor entsprechend vereinfacht, wenn y ein Polynom oder etwa
eine trigonometrische Funktion ist, nicht jedoch, wenn y eine rationale Funktion ist.
Wenn mit komplexen Zahlen in Polarkoordinatenform gerechnet werden soll, kann
es hilfreich sein, %emode auf den Wert false zu setzen.
119
Chapter 17
Polynomials
120
or more terms) of the sum returned by partfrac. In the second step, the rational
function rem/ q, with rem being the remainder polynomial of the division, is decom-
posed into partial fractions. The resulting terms constitute the second part (zero or
more terms) of the sum returned by partfrac.
The importance of partial fraction decomposition primarily lies in the fact that the
resulting terms are much easier to integrate than the original rational function
(method of integration by partial fractions).
121
Chapter 18
Solving Equations
18.1.2 Algsys
Solves a system of polynomial equations.
18.1.3 Solve
Maxima’s primary solver solve was written by Richard J. Fateman. It calls algsys.
It was written before the knowledge database was introduced, so solve does not
consider assumptions declared with assume.
fractional exponents should be eliminated from any equation befor using it with
solve. See the thread Pandora’s box, Jan. 28, 2021.
122
Like solve, to_poly_solve uses algsys. Unlike solve, fractional exponents are elim-
inated from equation automatically by to_poly_solve. Sometimes this is not suc-
cessful, though, and it is better to do this manually as for solve.
to_poly_solve ( eq [eq1 , . . . , eqn ] {eq1 , . . . , eqn } , [1 , . . . , k ] {1 , . . . , k } , [optons] )
[function of to_poly_solve]
%solve(. . . ) [alias of to_poly_solve]
Tries to solve the equation or list of equations given in the first argument for the
variable or list of variables given in the second argument, possibly followed by
options. When to_poly_solve is able to determine the solution set, each element of
the solution set is a list of one element in a %union object.
(%i1) load(to_poly_solve)$
(%i2) to_poly_solve(x*(x-1), x);
(%o2) %non([ = 0], [ = 1])
(%i5) nicedummies(%);
(%o5) %non([ = 2 %p %z0 + %p], [ = 2 %p %z1])
123
(%i1) eq1: 2*x^2 +y*x +z;
(%o1) z + y + 22
(%i2) eq2: 3*x +5*y -z -1;
(%o2) −z + 5y + 3 − 1
(%i3) eq3: z^2 +x -y^2 +5;
(%o3) z2 − y2 + + 5
(%i4) eliminate([eq1, eq2, eq3], [y,z]);
(%o4) [2 (454 + 33 + 112 + 81 + 124)]
The to_poly_solve package contains equivalent functions elim and elim_allbut. See
sect. 18.2.2 for an application of both eliminate and elim_allbut.
(%i4) eliminate(e3,[exp(%i*%phi)]);
[4r 2 −r 2 + y 2 + 2 ]
(%o4)
(%i3) load(to_poly_solve)$
(%i4) e3: to_poly([e1,e2],[%phi]);
[[% %g252 − 1 r + 2 %g25y, −%g252 − 1 r + 2 %g25],
(%o4)
[2 %g25 6= 0, 2 %g25 6= 0], [%g25 = %e%φ ]]
(%i5) elim_allbut(first(e3),[x,y,r]);
[ [r r 2 − y 2 − 2 ], [%g252 r + r − 2 %g25]]
(%o5)
124
Chapter 19
Linear Algebra
19.1 Introduction
19.1.1 Operation in total or element by element
A clear conceptional distinction should be made between operations which apply
to a structure (vector, matrix, etc.) as a whole, and operations which apply to all
the elements of a structure individually, i.e. element by element, joining the results
to a structure of the original kind to be returned. Examples of operations in total
are scalar product or matrix inversion, while examples of operations element by
element are scalar multiplication of a vector or matrix, or integration of a vector or
matrix, if their elements are functions.
19.2.1 Exponentiation
(%i1) a.a;
(%o1) <2>
(%i2) b*b;
(%o2) b2
125
19.2.2 Option variables for the dot operator
The dot operator is controlled by a large number of flags. They influence the rules
which govern its simplification.
19.3 Vector
19.3.1 Representations and their internal data structure
Maxima does not have a specific data structure for vectors. A vector can be repre-
sented as a list or as a matrix of either one column or one row. The following shows
the internal data structure of these representations. Note that a matrix internally
126
is a special list of MaximaL lists, each of them representing one row, see section
19.4.1.
(%i1) u:[x,y,z];
(%o1) [x, y, z]
(%i2) :lisp $U
((MLIST SIMP) x y z)
(%i3) v:covect(u);
(%o3)
y
z
(%i4) :lisp $V
(($MATRIX SIMP) ((MLIST SIMP) x) ((MLIST SIMP) y) ((MLIST SIMP) z))
(%i5) w:transpose(u);
(%o5) y z
(%i6) :lisp $W
(($MATRIX SIMP) ((MLIST SIMP) x y z))
(%i1) v:[x,y,z];
(%o1) [x, y, z]
Special functions for creating lists (e.g. makelist and create_list) are described in
section 8.1.
127
constructs a row vector which is a matrix of one row and n columns, containing the
arguments.
(%i1) CVect(x,y,z);
(%o1)
y
z
(%i2) RVect(x,y,z);
(%o2) y z
(%i1) x:MakeList(x,3);
(%o1) [1 , 2 , 3 ]
(%i2) y:MakeCVect(y,3);
y1
(%o2)
y 2
y3
(%i3) z:MakeRVect(z,3);
(%o3) z1 z2 z3
System function genmatrix can be used to construct a column or row vector from
an undeclared array, too, but with symbolic elements having two indices instead of
one, as for matrices.
(%i1) x:genmatrix(x,3,1);
1,1
(%o1)
2,1
3,1
(%i2) x:genmatrix(x,1,3);
(%o2) 1,1 1,2 1,3
128
(%i1) covect([x,y,z]);
(%o1)
y
z
129
Scalar multiplication of a vector and arithmetic operations between vectors work
element by element, if the flag listarith is true, which is the default. They are only
possible between vectors of the same type, with the exception that lists and column
vectors can be combined. In this case, the result will be a column vector.
The scalar product, dot product, or inner product · of two real valued vec-
tors v and w, which, in case of a list representation of the vectors, is equal to sum
(v[i]*w[i], i, 1, length(v)) can be built with the dot operator for the non-commutative
matrix product, see sect. 19.4.9.1. The arguments need to have the same dimen-
sion, but can be of any representation, except for the combination c.r, where c is
a column vector and r is a row vector or a list. This combination, instead, will re-
turn the tensor product of two vectors, see sect. 19.3.8. Hence, this operator is
non-commutative with respect to the combination of vector representations. For
a commutative way (with respect to the combination of vector representations) of
computing the scalar product see the operator SP. The non-commutative scalar
product of complex valued vectors can be computed with SP, too, of with functions
inprod or Inprod.
(%i1) powerdisp:true$
(%i2) v:MakeCvect(v,3)$ w:MakeCvect(w,3)$
(%i3) v . w;
(%o3) 1 1 + 2 2 + 3 3
The dot operator is controlled by a number of flags which are described in section
19.2.
conjgte() . ,
where "." is the dot operator. This function can be applied to complex and real
valued vectors.
130
Inprod (v,w) [function of rs_vector]
Returns, under the same conditions as inprod,
. conjgte(),
19.3.7.3 SP
131
1 1 2 2 1 3
(%o2)
2 1 2 2 2 3
3 1 3 2 3 3
Normalize (v ,ip ) [function of rs_vector]
NormalizeColumns default: true [option variable]
Function Normalize Normalizes a column vector, row vector, list or matrix (column-
wise, if the global flag NormalizeColumns is true, row-wise otherwise) by dividing
each vector by its separation (e.g. norm) using function VNorm. If a function differ-
ent from SP shall be used by VNorm for the inner product, it has to be supplied as
the second argument to Normalize. If it is an infix operator, it has to be enclosed
in double quotes. The return value will be of the same type as obj and have a
separation equal to 1 (matrix: column-wise resp. row-wise).
(%i1) X:matrix([2,1,1],[0,3,0],[-1,0,4]);
2 1 1
(%o1)
0 3 0
−1 0 4
(%i2) Normalize(X);
2 1 1
p p p p
5 2 5 17
3
(%o2)
0 p p 0
2 5
− p1 0 p
4
5 17
(%i3) Normalize(X), NormalizeColumns:false;
p
2 1 1
p p p p p
3 2 3 2 3
(%o3)
0 1 0
− p1 0 p
4
17 17
132
Returns the normalized vector / norm(), probably using eigen’s function inner-
product for the inner product. This means that it can be used for the standard
Euclidean or complex (positive definite) scalar product only.
133
(%i7) expand(u VP (v VP w));
1 3 3 − 1 3 3 + 1 2 2 − 1 2 2
(%o7) 2 3 3 − 2 3 3 − 1 1 2 + 1 1 2
−2 2 3 − 1 1 3 + 2 2 3 + 1 1 3
19.3.13 Basis
In order to avoid problems arising from the way Maxima implements indexed data
objects, i.e. by using undeclared arrays, it is advisable instead to define a basis
by using a matrix and to implement any operation on the basis as a whole as an
operation on this matrix. Although a matrix in Maxima is structured by rows, it is
preferable to consider the individual vectors as columns, as it is usually done in
mathematics, e.g. for a basis transformation matrix. In this case a vector cannot
be addressed by simply indexing the matrix, its representation being a list. But
this representation of a vector is seldomly used and does not balance the drawback
of mentally having to transpose a row-wise representation of the basis. It is easy
to transform the matrix into a list of column vectors. In the following example, the
individual column vectors can be addressed either as e, = 1, 2, 3, or as e[]. In the
last line, the metric tensor (Gram’s matrix, positive definite representation matrix)
of the Euclidean scalar product ist generated from this particular basis.
(%i1) E:matrix([1,0,0],[0,1,0],[0,0,1]);
1 0 0
(%o1)
0 1 0
0 0 1
(%i2) e:makelist(concat(e,i)::col(E,i),i,1,3);
1 0 0
(%o2) [ 0 , 1 , 0]
0 0 1
(%i3) e1;
1
(%o3)
0
0
(%i4) e[1];
1
(%o4)
0
0
(%i5) genmatrix(lambda([x,y],e[x] . e[y]),3,3);
1 0 0
(%o5)
0 1 0
0 0 1
134
19.4 Matrix
19.4.1 Internal data structure
A matrix internally is a list of MaximaL lists, each of them representing one row.
Nevertheless, a matrix has its own special data type in Maxima. Thereby Maxima
can distinguish between a matrix and any other 2-dim. list structure.
(%i1) M:matrix([1,2,3],[4,5,6],[7,8,9]);
1 2 3
(%o1)
4 5 6
7 8 9
(%i2) :lisp |$m|
(($MATRIX SIMP) ((MLIST SIMP) 1 2 3) ((MLIST SIMP) 4 5 6) ((MLIST
SIMP) 7 8 9))
19.4.1.1 matrixp
(%i3) matrixp(M);
(%o3) true
(%i4) M[2,1];
(%o4) 4
135
When domxmxops is true, all matrix-matrix or matrix-list operations are carried
out, but not scalar-matrix operations; if this switch is false, such operations are not
carried out.
136
19.4.4.1 Enter a matrix
(%i1) M:matrix([1,2,3],[4,5,6],[7,8,9]);
1 2 3
(%o1)
4 5 6
7 8 9
A matrix can be constructed by starting with a column or row vector and appending
columns at the right or rows at the bottom one by one. In the same way, columns
or rows can be appended to any existing matrix, too. The following functions can
even be used to append whole matrices at the right or bottom of an existing matrix.
(%i1) M:Cvect(a,b,c);
(%o1)
b
c
(%i2) N:addcol(M,[d,e,f]);
d
(%o2)
b e
c ƒ
(%i3) addcol(N,N);
d d
(%o3)
b e b e
c ƒ c ƒ
137
(%i4) addcol(N,[1,2,3],N,[4,5,6]);
d 1 d 4
(%o4)
b e 2 b e 5
c ƒ 3 c ƒ 6
19.4.4.5 Genmatrix
genmatrix (, 2 , j2 , 1 , j1 ) [function]
138
This function creates a matrix
j ··· 1 j2
11
.. ..
. .
2 j1 ··· 2 j2
from argument , which must be either a declared array (created by array, but not
by make_array), an undeclared array, an array function or a lambda function of
two arguments, taking [1 , j1 ] as the first and [2 , j2 ] as the last element of the
matrix. If j1 is omitted, it is assumed to be equal to 1 . If both j1 and 1 are omitted,
both are assumed to be equal to 1.
An example with an undeclared array is given in section 19.3.3, with a lambda
function in section 19.3.13.
(%i1) L:[[1,0,0],[0,1,0],[1,2,3]];
(%o1) [[1,0,0],[0,1,0],[1,2,3]]
(%i2) M:apply(matrix,L);
1 0 0
(%o2)
0 1 0
1 2 3
A matrix can be transformed into a list of column vectors, see example in sect.
19.3.13. In the following example we use the transpose of matrix M generated
above.
(%i3) N:makelist(col(transpose(M),i),i,1,3);
1 0 1
(%o3) [ 0 , 1 , 2]
0 0 3
139
19.4.5.3 List of column vectors -> list of sublists
(%i4) map(VtoList,N);
(%o4) [[1,0,0],[0,1,0],[1,2,3]]
matrixmap (ƒ , M1 , . . . , Mn ) [function]
Applies an arbitrary function or operator f of n arguments to matrices M1 , . . . , Mn el-
ement by element, returning a matrix with element [i,j] equal to ƒ (M1 [, j], . . . , M1 [, j]).
The number of matrices has to correspond to the number of arguments required by
f. matrixmap is a version of function map being applicable to matrices (which map
is not). See there for more explanations and examples.
In the following example, f is unbound at first and as such can have an arbitrary
number of arguments, always returning a noun expression.
140
(%i7) matrixmap("=",N,M);
=1 b=2 c=3
(%o7) d = 4 e=5 ƒ = 6
g=7 h=8 =9
fullmapl (ƒ , M1 , . . . , Mn ) [function]
fullmapl is a version of function fullmap being applicable to lists and matrices. See
section 8.1 for explanations and examples.
19.4.7 Transposition
19.4.8 Inversion
Matrix inversion can be carried out with function invert, or directly by matrix expo-
nentiation with -1. Both methods are equivalent.
invert (M) [function]
invert(M) is equivalent to M^^−1 , that is M<−1> . The inverse of the matrix M is
returned. The inverse is computed via the LU decomposition.
When ratmx is true, elements of M are converted to canonical rational expressions
(CRE), and the elements of the return value are also CRE. When ratmx is false,
elements of M are not converted to a common representation. In particular, float
and bigfloat elements are not converted to rationals.
When detout is true, the determinant is factored out of the inverse. The global flags
doallmxops and doscmxops must be false to prevent the determinant from being
absorbed into the inverse. xthru can multiply the determinant into the inverse.
invert does not apply any simplifications to the elements of the inverse apart from
the default arithmetic simplifications. ratsimp and expand can apply additional
simplifications. In particular, when M has polynomial elements, expand(invert(M))
might be preferable.
19.4.9 Product
19.4.9.1 Non-commutative matrix product
The the non-commutative matrix product can be built with the dot operator, see
section 19.2. The number of rows of argument a has to equal the number of
columns of b. The dot operator is controlled by a number of flags which are de-
scribed in section 19.2.
141
19.4.10 Rank
19.4.11.2 Orthonormalize
GramSchmidt (M , p ) [function of rs_vector]
Carries out the Gram-Schmidt orthonormalization procedure on a set of vectors,
given either as the columns of a matrix M, a list of column vectors or a list of
lists, the sublists each having the same number of elements. M is not modified by
GramSchmidt.
GramSchmidt calls function gramschmidt.
The return value is a matrix, the vectors being its columns. The vectors are not only
orthogonal and span the same space as x, but they are also normalized.
19.4.12 Triangularize
142
nonzero coefficient in each row is not normalized to 1.
The matrix M is positive definite, iff all diagonal elements of triangularize(M) are [wikDefin]
positive. No statement on other forms of definiteness can be made. See math sect.
47.9.3.6.
(%i1) M: matrix([5/4,1/2,1/2],[1/2,5,-1],[1/2,-1,2]);
5 1 1
4 2 2
1
(%o1) −1
2 5
1
2
−1 2
(%i2) float(ratsimp(rectform(eigenvalues(M))));
(%o2)
[[2.124542032328667,0.7946677527382047,5.330790214933128],[1.0,1.0,1.0]]
143
19.5 Determinant
144
Chapter 20
Limits
145
Chapter 21
A consecutive sum, with the index running over a range of consecutive integers,
can be created with function sum. I can be displayed in sigma notation, simplified
and evaluated. Sums can also be differentiated or integrated, and they can be
subject to limits.
A selective sum, with the index only taking selected indices from a list, is created
with function lsum.
(%i1) ’sum(1/k!,k,0,4);
4 1
X
(%o1)
k=1
k!
(%i2) sum(1/k!,k,0,4);
65
(%o2)
24
(%i3) sum(1/k!,k,1,n);
n 1
X
(%o3)
k=1
k!
146
21.1.1.2.1 Simplification
21.1.1.2.1.1 Simpsum
Some basic rules are applied automatically to simplify sums. More rules are acti-
vated by setting the flag simpsum to true.
21.1.1.2.1.2 Simplify_sum
Package simplify_sum contains function simplify_sum which is more powerful in
finding closed forms than setting flag simpsum.
(%i1) load(simplify_sum);
( %o1) C : / maxima− 5 . 4 0 . 0 / . . / share /maxima/ 5 . 4 0 . 0 / share / solve_rec / simplify_sum .mac
(%i2) sum(2^k+k^2,k,0,n);
n
X
(%o2) 2k + k 2
k=0
(%i3) simplify_sum(%);
2 n3 + 3 n2 + n
(%o3) 2n+1 + −1
6
147
21.1.1.4 Nusum
(%i3) unsum(%,n);
n4 4n
(%o3)
2n
n
(%i1) s:sum((x-x0)^k,k,1,n);
n
X
(%o1) ( − 0 )k
k=1
(%i2) ’diff(s,x) = diff(s,x);
n
d X n
X
(%o2) ( − 0 )k = k ( − 0 )k−1
d k=1 k=1
148
21.1.1.7 Unsum: undoing a sum
(%i1) nusum(i^2,i,0,n);
n (n + 1) (2n + 1)
(%o1)
6
(%i2) unsum(%,n);
(%o2) n2
(%i3) nusum(i^2,i,m,n);
(n − m + 1) 2n2 + 2mn + n + 2m2 − m
(%o3)
6
(%i2) unsum(%,n);
(%o2) n2
21.1.2 Products
21.2 Series
21.2.1 Introduction
Maxima contains functions powerseries and taylor for finding the series of differen-
tiable functions. It also has tools such as nusum capable of finding the closed form
of some series. Operations such as addition and multiplication work as usual on
series. This section presents the global variables which control the expansion.
Series, including power series and truncated taylor expansions, can be differenti-
ated and integrated.
(%i1) ’sum(x^i,i,0,inf);
149
∞
X
(%o1)
=0
Function nusum has a different strategy of informing the user about the conditions
for convergence and divergence of the series.
(%i1) nusum(x^i,i,0,inf)$
(%i2) ChangeSign(ChangeSign(%,2),2,2);
∞+1 1
(%o2) +
−1 1−
(%i1) powerseries(sin(x),x,0);
∞ (−1)1 2 1+1
X
(%o1)
1=0
(2 1 + 1)!
When verbose is true, powerseries prints progress messages before returning the
result.
150
g494 cot (g494) − 1
−
g494
powerseries: attempt rational function expansion of
1
g494
∞ (−1)2 22 2−1 bern (2 2) 2 2
X
(%o3)
2=1
2 (2 2)!
The advanced running index of the g-variable generated by Maxima indicates that
during computation the preceding ones have already been used internally.
(%i1) taylor(sqrt(x+1),x,0,3);
2 3
(%o3) /T/ 1+ − + + ...
2 8 16
We can evaluate both the original function and Taylor expansions of various orders
at a point near a with function at to see how the approximation proceeds.
(%i1) t1:taylor(sqrt(x+1),x,0,1);
t2:taylor(sqrt(x+1),x,0,2);
t3:taylor(sqrt(x+1),x,0,3);
t5:taylor(sqrt(x+1),x,0,5);
at([t1,t2,t3,t5,sqrt(x+1)],x=0.3);
151
(%o1) /T/ 1+ + ...
2
2
(%o2) /T/ 1+ − + ...
2 8
2 3
(%o3) /T/ 1+ − + + ...
2 8 16
2 3 54 75
(%o4) /T/ 1+ − + − + + ...
2 8 16 128 256
(%o5) [1.15, 1.13875, 1.1404375, 1.1401875390625, 1.140175425099138]
(%i1) taylor(sin(x+y),[x,y],0,5);
expand(%);
3 + 3y 2 + 3y 2 + y 3
(%o1) /T/ y+− + ...
6
y3 y2 2 y 3
(%o2) − − − +y− +
6 2 2 6
(%o3) taylor(sin(x+y),[x,0,2],[y,0,3]);
expand(%);
y3 y2 y3
y
(%o3) /T/ y− + ... + 1 − + ... + − + + ... 2 + ...
6 2 2 12
2 y 3 y3 y2 2 y
(%o4) − − − +y+
12 6 2 2
The option ’asymp can be applied to both the single- and the multi-variable form
of taylor. It returns an expansion of expr in negative powers of − . The highest
order term is ( − )−n .
152
21.2.4.4 Option variables
153
Chapter 22
Differentiation
(%i1) diff(3*x^4*sin(x),x);
(%o1) 123 sin() + 34 cos()
1 Here we use the term function in the mathematical sense, not in the sense of MaximaL. In MaximaL
this would be called an expression.
2 See sect. 22.5.4.2 for using a derivative noun form for x.
154
(%i2) at(%,x=%pi/2);
3π 3
(%o2)
2
diff (f, 1 , p1 , . . . , n , pn )
This form returns the mixed partial derivative of function f according to the formula
∂p1 +···+pn ƒ
p p
∂11 . . . ∂nn
where differention is carried out from right to left with respect to the variables listed
in the denominator, starting with variable n to the order of pn . Thus, the above
form is equivalent to the nested form diff (. . . (diff(ƒ , n , pn ), . . . ), 1 , p1 ).
Note, however, that according to Schwarz’s theorem the order of taking multiple
partial derivatives does not matter, if all partial derivatives of f up to the desired
degree are continuous. This regularity of f can be assumed in most cases.
22.1.2.1.1 Hessian
hessian (f, [1 , . . . , n ]) [function]
Function hessian can be used to compute the (symmetric) Hessian matrix of the
second partial derivatives of function f with respect to the list of variables [1 , . . . , n ]
according to the scheme
∂1 ∂1 ƒ · · · ∂1 ∂n ƒ
.. ..
..
Hƒ = . . . .
∂n ∂1 ƒ · · · ∂n ∂n ƒ
155
22.1.2.2.1 Gradient
22.1.2.2.2 Jacobian
(%i1) atvalue(f(x,y),[x=0,y=1],a^2);
(%o1) 2
(%i2) atvalue(’diff(f(x,y),x),x=0,1+y);
(%o2) @2 + 1
(%i3) at(’diff(f(x,y),x)=a,[x=0,y=1]);
(%o3) 2=
(%i4) at(’diff(f(x,y),x)=a,[x=1,y=1]);
d
(%o4) f (, 1) =
d =1
Typically, initial values (IVP) or boundary values (BVP) for solving differential equa-
tions are established by this mechanism. For an example see sect. 24.2.2.
156
printprops ( ƒ [ƒ1 , . . . , ƒn ] , te)
[function]
This function displays the atvalues of either function f, the functions defined in the
list, or all functions which have atvalues defined by function atvalue.
In the first way, MaximaL variables, which may be either unbound or bound (with
the : operator) to a specific expression being the value of this variable, are used
to represent mathematical functions, and their dependencies on other variables
(which themselves can have dependencies, therefore representing mathematical
functions) are explicitly declared with depends. When using these variables, their
functional dependencies are not immediately visible to the user, since they are not
following the variable name in parentheses like they do in the other way described
below, when MaximaL functions are used instead. Declared dependencies of vari-
ables can only be made visible by using system variable dependencies.
This way to implement mathematical functional dependencies in MaximaL is often
easier, mathematical expressions are visually shorter and clearer. However, depen-
dencies established with depends are recognized only by diff , not by integrate or
other MaximaL functions.
In the second way, MaximaL functions are used to represent mathematical func-
tions. These MaximaL functions can be either undeclared or declared (with the :=
157
operator) to be a specific expression (here we don’t speak of the value of a function,
but of its definition). Dependencies of the functions are now established implicitly
by their arguments, which have to be provided both in the function definition and
in the function call.
Note that one and the same symbol can be used in parallel both as a variable and a
function; it can have a double life. This is possible because MaximaL functions are
implemented as properties, not as values. The user’s possibility to make deliberate
use of this double life certainly is one of Maxima’s highlights.
This way to represent mathematical functions and functional dependencies is gen-
erally preferable. It enables the user to easily use noun form differentiation and
noun form (indefinite or definite) integration, thus freely employing the fundamen-
tal theorem of calculus.
The drawback of this method is its more complicated handling. For instance, if (part
of) the return value of some computation is to become the function block of a new
function, this has to be done according to the following example
(%i1) solve(x(t)^2+y(t)^2=a^2,x(t));
Ç Ç
(%o1) [(t) = − 2 − y(t)2 , (t) = 2 − y(t)2 ]
Furthermore, careful attention has to be paid for symbols that need to be quoted in
the function block, e.g. the second parameter in functions diff or integrate.
158
common variable, or a function can be declared to depend on multiple variables, or
these features are even combined.
dependencies (y1 (1 , . . . , k ), y2 (z))) is equivalent to depends (y1 , [1 , . . . , k ], y2 , z).
depends evaluates its arguments and returns a list of the dependencies established.
The dependencies are appended to the global variable dependencies.
depends (y, x) returns an error, if y is bound. However, y can be bound after
depends (y, x) has been executed. Alternatively, a bound variable y can be declared
to depend on x by using a noun form of y: depends (’y,x).
diff is the only MaximaL system function which recognizes functional dependencies
established with depends; integrate or other functions don’t recognize dependen-
cies established for variables. diff uses the chain rule when it encounters indirect
functional dependencies. Note that in the last line the differentiation is not carried
out, because here x is not regarded as a variable, although it has been evaluated
as such, but as an undeclared function.
(%i1) depends([x,y,r,θ],t);
(%o1) [x(t),y(t),r(t),θ(t)]
(%i2) x:r*cos(θ)$
(%i3) y:r*sin(θ)$
(%i4) diff(x,t);
d d
(%o4) r cos (θ) − r sin (θ) θ
dt dt
(%i5) diff(y,t);
d d
(%o5) r cos (θ) θ + r sin (θ)
dt dt
(%i6) diff(x(t),t);
d
(%o6) (r cos (θ)) (t)
dt
A variable f which has been declared a functional dependency with depends re-
mains, although this dependency is returned by Maxima as f(x), a variable and is
159
not an undeclared function f(x). A MaximaL function is denoted as a symbol fol-
lowed by its arguments in parentheses, both in the function definition and in the
function call. Whether declared or not, a function is treated in a completely differ-
ent way by Maxima than a variable. In fact, a symbol f can mean a variable f and
a function f(x) at the same time, the variable being bound or not, and the function
being defined or undefined.
A function definition alone, section 31.2, like f(x):=3*x does not yet create a math-
ematical functional dependency f(x). In the function definition, x is just a formal
parameter, which could be replaced by any other. The actual functional depen-
dency is only established by the function call f(x). For instance, diff (f(x), x) returns
3, because f(x) evaluates to 3*x. diff (f(y), y) also returns 3, because f(y) evaluates
to 3*y. But diff (f(y), x) returns zero. diff (f, x) also returns zero, because f refers to
the variable f (which here we assume unbound), not the defined function f(x).
An undeclared function, as the name implies, is not defined. The call f(x) of an
undeclared function, however, establishes a functional dependency which is rec-
ognized by diff and any other MaximaL function, e.g. integrate. In this case, diff
always returns a noun form; the Leibniz quotient is never evaluated. However, it
may be simplified.
(%i1) diff(f(t),t);
d
(%o1) f(t)
dt
(%i1) diff(a*f(t),t,2)$ Pr()$
d2
2
d
(%o1) ( f(t)) = f(t)
dt 2 dt 2
In a call of diff we can even use a function call as the variable with respect to which
is to be differentiated.
(%i1) g(x):=f(x)^2$
(%i2) diff(g(x),x);
d
(%o2) 2 f() f()
d
(%i3) diff(g(x),f(x));
(%o3) 2 f()
If this function has been declared, it has to be quoted in case it shall not be eval-
uated immediately. For quoting function calls see sect. 31.2.2.1. The following
example illustrates the chain rule.
160
(%i4) f(x):=3*x$
(%i5) g(x):=x^2$
(%i6) diff(g(f(x)),x);
(%o6) 18
(%i7) diff(g(’f(x)),’f(x)) * diff(f(x),x);
(%o7) 6 f()
(%i8) ev(%, nouns);
(%o8) 18
Derivative noun forms can themselves be differentiated, that is, they can appear in
the expression to be differentiated. Both the derivative noun form used in the ex-
pression and the outer function call of diff have to be quoted, unless its respective
dependencies have been declared with depends.
(%i1) ’diff(’diff(r,t),s);
d2
(%o1) r
dsdt
(%i1) T: (m*r^2*(’diff(θ,t,1))^2+m*(’diff(r,t,1))^2)/2
2 2
d d
m r 2 dt θ + m dt r
(%o1)
2
(%i2) diff(T,’diff(r,t));
d
(%o2) m r
dt
(%i1) eq1:l*(diff(q(t),t,2))+g*q(t)+(diff(x_1(t),t,2))=0;
161
d2 d2
(%o1) 2
q(t) + 1 (t) + gq(t) = 0
dt dt 2
(%i2) x_1(t):=-(l*m_2*q(t))/(m_2+m_1);
− m2 q(t)
(%o2) 1 (t) :=
m2 + m1
(%i3) ev(eq1);
d2
2
m2 q(t) d
(%o3) − + q(t) + gq(t) = 0
dt 2 m2 + m1 dt 2
(%i4) ev(eq1,nouns); 2
d
m2 dt 2 q(t)
2
d
(%o4) − + q(t) + gq(t) = 0
m2 + m1 dt 2
162
(%i1) diff(g(3*x-2*y),x);
d
(%o1) g (3 − 2y)
d
(%i2) gradef(g(z),G(z));
(%o2) g(z)
(%i3) diff(g(3*x-2*y),x);
(%o1) 3*G(3*x-2*y)
gradef cannot define partial derivatives for a function already defined. (Defining the
derivatives before defining the function does not help, because the latter overwrites
the derivatives defined by gradef.) However, partial derivatives can be defind for
a noun form of a function already defined. In this case, the defined function and
its noun form will behave differently under diff, the noun form not resulting in the
usual symbolic Leibniz notation, but in the expression defined by gradef.
(%i1) f(x):=x^2;
(%o1) f() := 2
(%i2) diff(f(x),x);
(%o2) 2x
(%i3) diff(f(log(x)),x);
2 log ()
(%o3)
(%i11) ev(diff(’f(log(x)),x),nouns);
2 log ()
(%o11)
In case of a variable, however, gradef can be defined for a bound variable. Then,
again, the bound variable and its noun form will behave differently under diff.
163
(%i1) depends ([r,v,e_r,e_v],t)$
(%i2) r_: r*e_r$
(%i3) gradef(r_,t,e_v*r*(diff(v,t,1))+e_r*(diff(r,t,1)))$
(%i4) diff(r_,t);
d d
(%o4) e_r r + e_r r
dt dt
(%i5) diff(’r_,t);
d d
(%o5) e_ r + e_r r
dt dt
22.7 Gradient
Grad (f, n , [1 , . . . , n ] ) [function of cartesian_coordinates]
Computes the gradient of the n-dim. scalar field f. The last parameter gives a list
of the variable names or a singe variable name, if the variables of f are elements of
an undeclared array of that name. Grad returns an n-dim column vector.
164
Chapter 23
Integration
165
Chapter 24
Differential Equations
24.1 Introduction
24.1.1 Overview
Only a small portion of the ODEs encounterd in research and engineering have
known exact solutions and can be solved by analytical methods. Even if they can,
sometimes their solutions involve complicated expressions with special functions
and are of no real help. In this case, the user might prefer to look for an approximate
numerical solution instead.
Maxima cannot solve PDEs.
Maxima provides function ode2 to analytically find the general solution of elemen-
tary (not necessarily linear) ODEs of first or second order. On the basis of this
solution, the initial value problem can be solved by ic1 or ic2, depending on the
order of the ODE. Function bc2 solves the boundary value problem.
In addition, David Billinghurst has developed a new package contrib_ode which
employs some more methods for solving first order ODEs and linear homogeneous
second order ODEs.
A linear ODE of order n or a system of such ODEs can be solved by desolve which
uses Laplace transformation.
Maxima cannot solve nonlinear ODEs of higher order by analytical means. Note
that any (system of) higher order ODE(s) can be transformed into a system of first
order ODEs. If this resulting system is linear, it can possibly be solved with desolve.
166
24.1.1.2 Numerical methods
24.2.1.1.1 ode2
167
oscillator without damp, Satz 5.10, given by
d2 φ g
+ φ(t) = 0 (24.1)
dt 2
under the assumptions that g, > 0. We will continue this example for an IWP to
be solved by ic2, and later we will solve equation and IWP again with the help of
desolve to show the differences.
(%i1) assume(g>0,l>0)$
(%i2) eq:diff(φ(t),t,2)+g/l*φ(t);
d2 g
(%o2) φ(t) + φ(t)
dt 2
(%i3) gensol: ode2(eq,φ(t),t),rootscontract;
v v
tg tg
(%o3) φ(t) = %k1 sin t + %k2 cos t
Note that one side of the equation can be omitted, because it is zero, see sect. 9.5.
Note also that the solution returned by ode2 is not an assignment, it does not bind
the variable φ. The constants %k1, %k2 inserted by Maxima can be specified by
solving an initial value problem, see function ic2, or a boundary value problem, see
function bc2.
24.2.1.1.2 contrib_ode
1 The value of 0 does not have to be zero. Any point in the domain of y can be selected.
168
follows the name and the initial value of the dependent variable, where y0 = y(0 ).
The last argument gives the initial value of the first derivative of the dependent
variable with respect to the independent variable, evaluated at 0 .2
As an example, we want to solve the IVP for the general solution of the oscillator
equation found in the example to function ode2, first with initial values t = 0, φ(t) =
1, φ(t)0 = 0, then with t = 0, φ(t) = 1, φ(t)0 = 1.
As with any result obtained for a differential equation, it should be checked to see
whether it is really a solution. We show this for the second case. First we proof that
it satisfies the conditions given to ic2. In order to avoid error messages, we use at
rather than ev for the derivative.
(%i6) ivpsol,t=0;
(%o6) φ=1
(%i7) at(diff(rhs(ivpsol),t),t=0),ratsimp;
(%o7) 1
Then we insert the result in our equation eq. The following input is equivalent to
ev(eq, ivpsol, diff, ratsimp) and causes rhs(ivpsol) to be substituted for φ in eq, then
the differentiations to be carried out and finally a simplification. Note that diff here
is not the function but an evaluation flag.
(%i8) eq,ivpsol,diff,ratsimp;
(%o8) 0
The result is the missing rhs of eq. Therefore, ivpsol is a valid solution of eq. Since
the solution of the IVP is unique, it is the only solution.
Finally we want to solve the IVP at points other than zero. This time, first we select
t = π/ (2 ∗ sqrt(g/ )), φ(t) = 1, φ(t)0 = 0, then t = π/ (3 ∗ sqrt(g/ )), φ(t) = 1, φ(t)0 =
0. We see that this works just as well.
(%i9) ic2(gensol,t=π/(2*sqrt(g/l)),φ=1,’diff(φ,t)=0),rootscontract;
v
tg
(%o9) φ = sin t
(%i10) ic2(gensol,t=π/(3*sqrt(g/l)),φ=1,’diff(φ,t)=0)$
(%i11) PullFactorOut([%,2,1],sqrt(3)/2)$
(%i12) PullFactorOut([%,2,2],1/2),rootscontract;
2 Althoughquoting diff is not absolutely necessary, it is recommended, because sometimes this will
prevent unexpected errors from occurring.
169
p v v
3 tg 1 tg
(%o12) φ= sin t + cos t
2 2
For a first order ODE, the boundary value problem (BVP) is equivalent to the initial
value problem.
170
because desolve uses Laplace transform, this is only possible for initial or bound-
ary conditions specified at t=0, with t being the independent variable. If one has
initial or boundary conditions imposed elsewhere, one can impose these on the
general solution returned by desolve and eliminate the constants by solving the
general solution for them and substituting their values back. Let’s demonstrate all
this with the same example we used for ode2 and ic2. First we use initial values
t = 0, φ(t) = 1, φ(t)0 = 1.
(%i1) assume(g>0,l>0)$
(%i2) eq: ’diff(φ(t),t,2)+g/l*φ(t);
d2 g φ(t)
(%o2) φ(t) +
dt 2
(%i3) gensol: desolve(eq,φ(t)),expand,rootscontract;
v v v
t tg d tg
u
(%o3) φ(t) = sin t φ(t) + φ(0) cos t
g dt t=0
(%i4) atvalue(φ(t),t=03 ,1)$ atvalue(’diff(φ(t),t),t=03 ,1)$
(%i5) desolve(eq,φ(t)),expand,rootscontract;
v v v
t tg tg
u
(%o5) φ(t) = sin t + cos t
g
The result can be checked in the same way as it was demonstrated for ic2.
Now we will show how an IVP with initial values at a point other than zero can be
solved, selecting t = π/ (3 ∗ sqrt(g/ )), φ(t) = 1, φ(t)0 = 0, like in the example
of ic2. Suppose that in the above example we have come untill (%o3), which is
the general solution, but with two unknown variables φ(0) and φ0 (0). We proceed
as follows: First we specify our atvalues φ(t) and φ0 (t). With the first of them
we go into gensol, evaluated at t. Then we differentiate gensol and go into the
result, evaluated at t again, with φ0 (t). This provides us two equations for the two
unknown variables, which we can now solve and substitute back into the general
solution. For this last step we use subst; at doesn’t work properly in this case, since
one of the variables is itself a noun at form. Note also, that we can’t use ev instead
of at for the evaluations of gensol and dgensol at t, also due to the noun at form.
In an expression like gensol, t=π/(3*sqrt(g/l)); the rhs of the equation would be
substituted for t everywhere in gensol, including in the noun at form. This destroys
it and makes it evaluate to zero, giving an incorrect overall result. Here we see
that the three seemingly equivalent methods of evaluation at a point (ev, at, subst)
have subtle differences that want to be considered carefully.
(%i4) atvalue(φ(t),t=t=π/(3*sqrt(g/l)),1)$
(%i5) atvalue(’diff(φ(t),t),t=t=π/(3*sqrt(g/l)),0)$
(%i6) at(gensol,t=π/(3*sqrt(g/l))),ratsimp$ expand(%)$
(%i7) PullFactorOut([%,2,1],sqrt(3)/2*sqrt(l/g))$
(%i8) at1sol: PullFactorOut([%,2,2],1/2);
p p !
3 d 1
(%o8) 1= p φ(t) + φ(0)
2 g dt
t=0 2
3 The value of t here has to be zero, because desolve uses Laplace transform.
171
(%i9) dgensol:diff(gensol,t);
v v v v v
d tg u
t tg d tg tg
(%o9) φ(t) = cos t φ(t) − φ(0) sin t
dt g dt t=0
(%i10) at(dgensol,t=π/(3*sqrt(g/l))),ratsimp$
(%i11) at2sol:2*sqrt(l)*%;
d
p p
0=
p
(%o11) φ(t) − 3 φ(0) g
dt t=0
(%i12) linsolve([rembox(at1sol),at2sol],[φ(0),at(’diff(φ(t),t,1),t=0)]);
p p
1 d 3 g
(%o12) [φ(0) = , φ(t)
= p ]
2 dt t=0 2
(%i13) subst((sqrt(3)*sqrt(g))/(2*sqrt(l)),at(’diff(φ(t),t,1),t=0),gensol)$
(%i14) subst(1/2,φ(0),%),ratsimp$ expand(%)$
(%i15) PullFactorOut([%,2,1],sqrt(3)/2)$
(%i16) PullFactorOut([%,2,2],1/2),rootscontract;
p v v
3 tg 1 tg
(%o16) φ(t) = sin t + cos t
2 2
In sect. 27.1.2 we solve the same ODE explicitely with laplace, thus demonstrating
what desolve does internally.
[function]
Numerically solves an initial value problem (IVP) of either a single or a system of
1. order ODE(s) given in explicit form by eq or the list [eq1 , . . . , eqn ], with the de-
pendent variable(s) being y or [y1 , . . . , yn ] and having initial value(s) y0 = y(0 ) or
[y01 , . . . , y0n ]. The independent variable x is evaluated in the interval [0 , e ] with
constant increment inc. Any of the dependent variables yk , k = 1, . . . , n, can appear
in any of the equations eqk . The return value of rk can be plotted immediately with
plot2d.
As an example we want to solve the ODE
dy
= − y2
d
in the range of ∈ [0, 8] with a constant increment of 0.1 for an initial value of
y0 = y(0 ) = y(0) = 1.
(%i1) rk(t-x^2,x,1,[t,0,8,0.1])$
(%i2) plot2d ([discrete, %])$
172
Figure 24.1 shows the resulting plot. In the next example we solve the system
dy1 dy2
= 4 − y12 − 4y22 and = y22 − y12 + 1
d d
in the range of ∈ [0, 4] with a constant increment of 0.02 for initial values of
y01 = −1.25, y02 = 0.75 at x=0.
173
24.4 Graphical estimate
24.4.1 Direction field
Direction fields can be plotted either with function plotdf, which uses xMaxima, or
with function drawdf, which uses Gnuplot’s draw.
24.4.1.1 plotdf
plotdf is a function to plot the direction field of one or two first-order ODEs, possibly
together with the specific solution of an initial value problem (IVP). plotdf uses
xMaxima and depends on it being installed; but it can be used also from other
interfaces, e.g. wxMaxima or the console. plotdf can export plots only in postscript
format (.ps). External programs can be used to transform such files into .jpg or .png
format; we use the downloadable freeware XnConvert.
plotdf ( eq [eq1 , eq2 ] , [, y] , [opt1 ], . . . , [optn ] )
[function]
Creates a plot of the direction field of either one first-order ODE or a system of two
of them, given in explicit form. In the first case, eq is the right-hand side of the ODE
while in the second case, the list [eq1 , eq2 ] contains the right-hand sides of the
ODEs
0 (t) = F1 (t, ) and y 0 (t) = F1 (t, y).
In the first case, the second argument provides the names of the independent and
the dependent variable; in the second case, it provides the two dependent vari-
ables, the independent variable always being t. The second argument can be omit-
ted in either case, if the names are "x" and "y".
The following options, each of them enclosed in a list and separated by commas,
can be used:
[trajectory_at,0 , y0 ]: Initial value problem (IVP) with initial values 0 , y0 .
As a first example, we plot the direction field of the first-order ODE
y 0 () = e− y
(%i1) rk(t-x^2,x,1,[t,0,8,0.1])$
(%i2) plot2d ([discrete, %])$
24.4.1.2 drawdf
174
Figure 24.3 – Plot of the direction field of a first-
order ODE together with an IVP.
175
Part V
Special applications
176
Chapter 25
Analytic geometry
These functions transform an angle from degrees (decimal) to radians and vice
versa.
Deg2Rad transforms an angle given in decimal degrees to radians. The result is
a term consisting of pi and a factor. float(Deg2Rad(degrees)) returns a float. If a
second argument n>0 is present, the factor of pi is rounded to n digits after the
dot. If any third argument is present, Deg2Rad will return a float rounded to n digits
after the dot.
Rad2Deg transforms an angle given in radians to decimal degrees. If a second
argument n ≥ 0 is present, in case of n=0 the result is rounded to integer, and in
case of n>0 the float result is rounded to n digits after the dot. Note that a float
result with maximum precision can be obtained by float(Rad2Deg(radians, 〈, n〉)).
177
Dec2Min converts an angle given in decimal degrees into a list of 3 elements con-
taining degrees, minutes and seconds. The first two elements are integers. If a
second argument n ≥ 0 is present, seconds are rounded to n digits after the dot.
Min2Dec converts an angle given as a list of 3 elements containing degrees, min-
utes and seconds into decimal degrees. If a second argument n ≥ 0 is present, the
value returned is rounded to n digits after the dot.
ConcMinSec converts an angle given as a list of 3 elements containing degrees,
minutes, and seconds into a string with the elements followed by °, ’ and ” respec-
tively.
178
Chapter 26
179
26.2 Polar coordinates
180
Chapter 27
Integral transformation
181
laplace recognizes convolution integrals of the form
Z t
ƒ (t − τ) g(τ) dτ.
0
(%i1) %e^(2*t+a)*sin(t)*t;
(%o1) t %e2t+ sin (t)
(%i2) laplace(%,t,s);
%e (2s − 4)
(%o2) 2
s2 − 4s + 5
(%i3) laplace(’diff(f(t),t),t,s);
(%o3) s*laplace(f(t),t,s)-f(0)
(%i4) assume(n>0)$
(%i5) laplace(t^n,t,s);
(n + 1)
(%o5)
sn+1
(%i1) laplace(b(t),t,s);
(%o1) pce(b(t), t, s)
| {z }
Lb(s)
(%i2) ilt(%,s,t);
(%o2) b(t)
182
27.1.2 Solving differential or convolution integral equations
The method of Laplace transformation is a powerful tool in science and engineering.
By using laplace and the inverse transformation with function ilt together with solve
or linsolve, Maxima can solve a single or a system of linear, constant coefficient dif-
ferential or of convolution integral equation(s). We demonstrate the procedure with
the second order linear ODE we already solved with ode2/ic2 and desolve/atvalue.
(%i1) assume(g>0,l>0)$
(%i2) eq: ’diff(φ(t),t,2)+g/l*φ(t)$
d2 g φ(t)
(%o2) φ(t) +
dt 2
(%i3) laplace(eq,t,s);
d g lplce (φ(t), t, s)
(%o3) − φ(t) + s2 lplce (φ(t), t, s) + − ϕ(0)s
dt t=0
(%i4) first(linsolve([%],[laplace(φ(t),t,s)]));
d
dt φ(t) + φ(0)s
t=0
(%o4) lplce (φ(t), t, s) =
s2 + g
(%i5) φ(t)=ilt(rhs(Leq1),s,t)$
(%i6) expand(%),rootscontract;
v v v
t tg d tg
u
(%o6) φ(t) = sin t φ(t) + φ(0) cos t
g dt t=0
Here we have achieved exactly the result from desolve,1 the general solution from
(%o3) of sect. 24.2.2. For an IVP with initial values at zero or at a point other than
zero we proceed exactly as we did there. Next we show, how a single convolution
integral equation can be solved with laplace.
1 Note that desolve in fact uses laplace, so it does exactly what we have just done.
183
Part VI
Advanced Mathematical
Computation
184
Chapter 28
Tensors
The contravariant vectors are derived from the columns of M, while the covariant
vectors b are computed accordingly. The function returns a matrix A containing
the als columns and a matrix B with the respective b as rows. The function then
checks, whether the sum of the products equals M.
185
Chapter 29
Numerical Computation
186
Chapter 30
1 Inparticular, when stringdisp is false, as by default, and strings are not enclosed in double quota-
tion marks.
187
30.2.1 Expression → string
(%i1) a:5$
(%i1) str:concat(1+1,a,string(b+c),"we(");
(%o2) 25c+bwe(
(%i3) stringdisp:true$
(%i4) str;
(%o4) "25c+bwe("
2 Function string can be used to transform an argument evaluating to a non-atomic expression into
a string.
188
sconcat does the same as concat with the only differences, that arguments need
not evaluate to atoms and that the return value is always a string.
(%i1) i:3$
(%i2) sconcat("x[",i,"]:",expand((x+y)^2));
(%o2) x[3]:y^2+2*x*y+x^2
(%i1) concat(c,6)::7+1$
(%i2) c6;
(%o2) 8
189
Part VII
Maxima Programming
190
Chapter 31
Compound statements
31.1.2 Block
block ([1 , . . . , n ], epr1 , . . . , eprm ) [function]
block ([1 , . . . , n ], local (1 , . . . , n ), epr1 , . . . , eprm )
A block allows to make variables 1 , . . . , m local to the sequence of sub-statements
epr1 , . . . , eprm . If these variables (symbols) are already bound, block saves their
current values upon entry to the block and then unbinds the symbols so that they
evaluate to themselves. The local variables may then be bound to arbitrary values
within the block. When the block is exited, the saved values are restored, and the
values assigned within the block are lost.
Note that the block declaration of the first line will make variables 1 , . . . , m local
only with respect to their values. However, in Maxima, just like in Lisp, a large num-
ber of qualities can be attributed to symbols by means of properties. Properties of
1 , . . . , m are not made local by a plain block declaration! They stay global, which
means that properties already assigned to these symbols on entry to the block will
remain inside of the block, and properties assigned to these symbols inside of the
block will not be removed on exiting the block. In order to make symbols 1 , . . . , m
local to the block with respect to their properties, too, they have to be declared
with function local inside of the block. For example, some declarations of a symbol
are implemented as properties of that symbol, including :=, array, dependencies,
atvalue, matchdeclare, atomgrad, constant, nonscalar, assume. local saves and
removes such declarations, if they exist, and makes declarations done within the
block effective only inside of the block; otherwise such declarations done within a
block are actually global declarations.
191
A block may appear within another block. Local variables are established each
time a new block is evaluated. Local variables appear to be global to any enclosed
blocks. If a variable is non-local in a block, its value is the value most recently
assigned by an enclosing block, if any, otherwise, it is the value of the variable in
the global environment. This policy may coincide with the usual understanding of
dynamic scope.
The value of the block is the value of its last sub-statement, or the value of the
argument to the function return, which may be used to exit explicitly from the
block at any point.
The function go may be used to transfer control to the statement of the block that
is tagged with the argument to go. To tag a statement, precede it by an atomic
argument as another sub-statement in the block. For example:
block ([x], x:1, loop, x: x+1, ..., go (loop), ...).
The argument to go must be the name of a tag appearing within the block; one
cannot use go to transfer to a tag in a block other than the one containing the go.
Using labels and go to transfer control, however, is unfashionable and not recom-
mended.
31.2 Function
31.2.1 Function definition
31.2.1.1 Defining the function
:= [infix operator]
f(1 , . . . , n ) := expr
":=" ƒ (1 , . . . , n ), epr
192
define (funmake (ƒ [1 , . . . , n ], [y1 , . . . , yn ]), expr)
define (arraymake (ƒ , [1 , . . . , n ]), expr)
define (ev (epr1 ), epr2 ).
The first expression using funmake returns an ordinary function with parameters
in parentheses, see section 31.2.3. The expression using arraymake returns an
array function with parameters in square brackets, see section 31.2.4. The second
expression using funmake returns a subscripted function, see section 31.2.5. The
expression with ev can be used in any case.
fundef(f) [function]
Returns the definition of function f. fundef quotes its argument; the quote-quote
operator 0 0 defeats quotation. The argument may be the name of a macro (defined
with ::=), an ordinary function (defined with := or define), an array function (defined
with := or define, but enclosing arguments in square brackets []), a subscripted
function (defined with := or define, but enclosing some arguments in square brack-
ets and others in parentheses ( )), one of a family of subscripted functions selected
by a particular subscript value, or a subscripted function defined with a constant
subscript.
dispfun( ƒ1 , . . . , ƒn ) [function]
Displays the definition of the user-defined functions ƒ1 , . . . , ƒn . Each argument may
be the name of a macro (defined with ::=), an ordinary function (defined with :=
or an array function (defined with := or define, but enclosing arguments in square
brackets []), a subscripted function (defined with := or define, but enclosing some
arguments in square brackets and others in parentheses ( )), one of a family of sub-
scripted functions selected by a particular subscript value, or a subscripted function
defined with a constant subscript. dispfun (all) displays all user-defined functions
as given by the functions, arrays, and macros lists, omitting subscripted functions
defined with constant subscripts. dispfun creates an intermediate expression label
(%t1, %t2, etc.) for each displayed function, and assigns the function definition to
the label. dispfun quotes its arguments; the quote-quote operator 0 0 defeats quo-
tation. dispfun returns the list of intermediate expression labels corresponding to
the displayed functions. For an example and the use of these expression labels see
[MaxiManE].
193
31.2.2 Function call
31.2.2.1 Quoting a function call
A function call can be quoted in two different ways: ’f(x) is the noun form of the
function call and has to be evaluated with the nouns flag set in ev. ’(f(x)) quotes
the whole expression and can be evaluated without the noun flag set. In order to
see whether a function call is a noun form or not, the flag noundisp can be set, see
Stavros’ mail from Oct. 26, 2020 in Maxima discuss .
(%i1) properties(x);
(%o1) []
(%i2) f(x):=block([a], local(a), a:1, declare (x,odd), x:a)$
(%i3) properties(x);
(%o3) []
(%i4) f(3);
(%o4) 1
(%i5) properties(x);
(%o5) [database info, kind(x,odd)]
(%i6) kill(all)$
(%i7) f(x):=block([a], local(x,a), a:1, declare (x,odd), x:a)$
(%i8) f(3);
(%o8) 1
(%i9) properties(x);
(%o9) []
If some parameter k is a quoted symbol (for define: after evaluation), the function
defined does not evaluate the corresponding argument when it is called. Otherwise
all arguments are evaluated.
(%i1) f(x):=x^2;
194
(%o1) ƒ () := 2
(%i2) a:b$ f(a);
(%o2) b2
(%i3) f(’x):=x^2;
(%o3) ƒ (0 ) := 2
(%i4) a:b$ f(a);
(%o4) 2
(%i5) define(f(’x),x^2);
(%o5) ƒ () := 2
(%i6) a:b$ f(a);
(%o6) b2
(%i7) define(f(’(’x)),x^2);
(%o7) ƒ (0 ) := 2
(%i8) a:b$ f(a);
(%o8) 2
195
31.2.5 Subscripted function
f[1 , . . . , n ](y1 , . . . , ym ) := expr
define (f[1 , . . . , n ](y1 , . . . , yn ), expr)
An subscripted function f[1 , . . . , n ](y1 , . . . , ym ) := expr is a special case of an
array function f[1 , . . . , n ] which returns a lambda expression with parameters
y1 , . . . , ym . The function body of the subscripted function is evaluated only once for
each distinct value of its parameters (subscripts) 1 , . . . , n , and the correspond-
ing lambda expression is that value returned. If the subscripted function is called
not only with subscripts 1 , . . . , n in square brackets, but also with arguments
y1 , . . . , yn in parentheses, the corresponding lambda expression is evaluated and
only its result is returned.
Note that a normal array function, see section 31.2.4, is also represented by Maxima
with its parameters as subscripts, because they appear in square brackets. This is
somewhat misleading, since they don’t constitute real indices, but plain variables.
Therefore we don’t call such a function a subscripted function.
In the following example, the function body is a simple sequential compound state-
ment, a list of expressions in parentheses, which are evaluated consecutively. Only
the value of the last of them is returned.
196
31.2.6.2 Funmake: construct only
funmake can be used in a function definition with define to evaluate the function
name.
197
31.3 Lambda function, anonymous function
lambda ([1 , . . . , m ], epr1 , . . . , eprn ) [function]
This is called a lambda function or anonymous function. It defines and returns what
is called a lambda expression, but does not evaluate it.
(%i1) lambda([x],x+1);
(%o1) lambda([x],x+1)
(%i1) lambda([x],x+1)(3);
(%o1) 4
(%i1) x:a$
(%i2) lambda([x],x+1);
(%o2) lambda([x],x+1)
(%i3) lambda([x],x+1)(3);
(%o3) 4
(%i1) x:a$
(%i2) lambda([’’x],x+1);
(%o2) lambda([a],x+1)
(%i3) lambda([’’x],x+1)(3);
(%o3) a+1
198
(%i1) x:a$
(%i2) lambda([’’x],’’x+1);
(%o2) lambda([a],a+1)
(%i3) lambda([’’x],’’x+1)(3);
(%o3) 4
(%i1) v:lambda([x],x+1);
(%o1) lambda([x],x+1)
(%i2) v(3);
(%o2) 4
(%i3) properties(v);
(%o3) [value]
(%i4) u(x):=x+1;
(%o4) u(x):=x+1
(%i5) u(3);
(%o5) 4
(%i6) properties(u);
(%o6) [function]
(%i1) f(x):=2*x$
(%i1) map(f,[1,2,3,4,5]);
(%o1) [2,4,6,8,10]
(%i2) map(lambda([x],2*x),[1,2,3,4,5]);
(%o2) [2,4,6,8,10]
199
In many cases the effect of a macro function call is equivalent to an ordinary func-
tion call plus one additional evaluation with either quote-quote or ev. Note that ad-
ditional and even multiple evaluations with either quote-quote or ev can follow both
an ordinary and a macro function call. See "Macro function demonstration.wxm" for
an illustrative comparison of two macro functions with their corresponding ordinary
functions.
200
Chapter 32
Program Flow
201
Part VIII
202
Chapter 33
User interfaces
203
Chapter 34
Package libraries
204
Part IX
Maxima development
205
Chapter 35
MaximaL development
35.1 Introduction
This chapter describes from the practical viewpoint how larger programs to be writ-
ten in MaximaL can be developed and how they are made available to be used
for the practical work with Maxima. The next chapter will describe the same for
developments done in Lisp.
In general, we will want to use MaximaL whenever possible for solving mathemati-
cal problems. This language is much easier to learn and to use than Lisp. MaximaL
is Maxima’s primary user interface. This language has some limitations, though.
Since it is not lexically but dynamically scoped, there might be problems with name
spaces for variables and functions, if large user packages are to be used. We will
focus on these problems later and show what can be do to limit them as much as
possible when programming the package and when using it.
Lisp has to be used whenever system features of Maxima shall be changed or
amended. In addition, it might be considerable to use Lisp instead of MaximaL if
scoping is an issue. Contrary to MaximaL, Lisp comprises strong concepts of lexical
scoping.
It is also possible to call Lisp functions from MaximaL and to call MaximaL functions
from Lisp. So we can combine both languages in order to find the most efficient
programming solution for our problem.
Both MaximaL and Lisp programs can be compiled instead of just interpreted (as
Maxima and Lisp usually do). This may be useful for reasons of speed. We will show
when this is advisable and how it is done.
Let’s start with MaximaL now. To summarize, there are two major issues. The first
one is how to support programming packages in the Maxima language. There is no
particular IDE available for MaximaL programming, so we have to invent our own
development environment.
The second issue is how MaximaL packages we have written can be made available
efficiently for our practical computational work with Maxima and possibly for other
Maxima users, too.
The source code for MaximaL programs is generally stored in .mac files and can be
loaded into a running Maxima session from the command line or from within other
206
programs. This is possible with all Maxima interfaces. Another option when working
with wxMaxima is to store work in .wxm or .wxmx files. But these file types can only
be read by this interface. However, a feature to export them to the .mac format is
available in wxMaxima, too.
Due to its concept of input cells instead of the purely linear input and output stream
of the usual Maxima REPL (read evaluate print loop) that all other interfaces pro-
vide, we feel that wxMaxima is most apt as a MaximaL development platform. How-
ever, a major drawback is that it suppresses most of MaximaL’s debugging facilities
and that it has almost no error handling.
207
35.3.2 Tracing
35.3.3 Analyzing data structures
208
Chapter 36
Lisp Development
209
The MaximaL function to_lisp opens an interactive Lisp session. Entering the Lisp
form (to-maxima) closes the Lisp session and returns to MaximaL.
calls the Lisp function foo with MaximaL variables x and y as arguments. The :lisp
construct can appear at the interactive Maxima or debugger prompt or in a file
processed by batch or demo, but not in a file processed by load, batchload, trans-
late_file, or compile_file.
Further examples: Use primitive (i.e. standard CL function) "+" to add the values
of MaximaL variables x and y:
(%i1) x:10$ y:5$
(%i3) :lisp (+ $x $y)
15
Use Maxima Lisp function add to symbolically add MaximaL variables a and b, and
assign the result to c:
(%i1) :lisp (setq $c (add ’$a ’$b))
((MPLUS SIMP) $A $B)
(%i1) c;
(%o1) b + a
with some Lisp function foo is written when called from MaximaL as
210
?foo (a, b, c);
Note that this mechanism does not work for all Lisp functions.
In particular, some Lisp functions are shadowed in Maxima, namely the following:
complement, continue, "//", float, functionp, array, exp, listen, signum, atan, asin,
acos, asinh, acosh, atanh, tanh, cosh, sinh, tan, break, gcd.
211
36.2 Using the Emacs IDE
36.3 Debugging
36.3.1 Breaks
36.3.2 Tracing
36.3.3 Analyzing data structures
The user can, at the start or at any later point within a running Maxima session,
modify the code of Maxima itself. This is done by reloading files containing Max-
ima system or application Lisp code, or even by reloading only individual functions
from them. All function definitions, system variables, etc., of a reloaded file or
only the individually reloaded functions will overwrite the existing system function
definitions and variables of the same name. This is independent of whether the
existing file or function was compiled or not. Depending on the Lisp used and on
the setting of Lisp system variables, the system may issue a warning concerning
the redefinition of each function or variable, but it will not decline to do so. From the
moment on where it has been successfully loaded, the new function definition will
be used whenever the function is called. So any Maxima system function can easily
be changed by just reloading a modified version of its definition. It is not necessary
to reload the whole system file which contains it, and it is not necessary for the file
that contains the modified function to have the same name as the original system
file. Only the name of the function has to be identical. Of course, new functions can
be added this way, too.
This method is so easy that most people will want to try it out and see whether it is
sufficient for their needs.
The substitution or adding of function definitions can be automated by incorporating
the reload procedure in the maxima-init.lisp or maxima-init.mac files to be executed
at Maxima startup time. Even after a new Maxima release, the procedure does not
212
have to be changed. So in some kind, we can apply our changes on top of the latest
Maxima release.
213
Part X
Developer’s environment
214
Chapter 37
It should be mentioned first that I owe large parts of the information provided in this
chapter to the kind help of Michel Talon and Serge de Marre. Michel could answer
almost any question about how to set up the environment under Windows, although
he himself does not have a Windows machine at all. Serge was maybe the first one
who had figured out how to fully set it up under Windows. With videos on Youtube
he showed how it works. Both helped me for weeks with this non-trivial matter.
Thanks a lot to both of you.
Hopefully, what took me months to find out and set up can be accomplished by the
reader of the following instructions in a couple of days.
37.2 Maxima
As a basis we need to have Maxima installed. There are two basic options.
37.2.1 Installer
The easiest way to install Maxima on Windows is to use the Maxima installer which
can be downloaded from Sourceforge and which is available for every new release.
Download the latest Maxima installer and install it in C:/Maxima/, disregarding the
default. Copy shortcuts for wxMaxima, console Maxima and XMaxima to the desk-
top. Special icons for the latter two can be found in the directory tree.
The installer comes with 64 bit SBCL and Clisp. Although it is preset to Clisp, it is
recommended to set the standard Lisp to SBCL, because it is much faster and much
more powerful. We will only use SBCL. Note that Clisp does not support threading
and does not work properly under Emacs in combination with Slime, especially if it
comes to the slime-connect facility, see below.
215
Use the Configure default Lisp for Maxima feature from the Windows program menu
to set Lisp to SBCL.
37.4 7zip
Install 7zip, because you will need to unzip .tar.gz files soon.
216
37.5 SBCL: Steel Bank Common Lisp
A considerable number of Lisp compilers is available, and Maxima supports many
of them. The Windows installer comes with SBCL and Clisp. Independently of this,
we use SBCL for a number of reasons. It is fast, provides a wide range of facili-
ties, usually creates no problems with Maxima and has become a kind of de facto
standard for Common Lisp use. See the SBCL User Manual for reference. [SbclMan]
In principle we can use the SBCL installation coming with the Maxima installer as
inferior Lisp under Emacs, too. However, we can also install SBCL separately in
addition, for instance if we want to use a different (newer) version or if we want to
be independent of what happens to come with the consecutive installers. We prefer
the latter option.
37.5.1 Installation
Install the latest version of SBCL in the default directory, that is in C:/Program
Files/Steel Bank Common Lisp/<version>. The Windows path and the environment
variable SBCL_HOME will be created automatically for our active Windows user, if
they don’t exist yet. However, a Windows restart is necessary to activate them.
Check that they are properly set with left click on Dieser PC, properties, Erweiterte
Systemeinstellungen, environment variables, looking at the lower field for our ac-
tive Windows user. We should see appended at the end of the path variable the
path
C : \ Program F i l e s \ Steel Bank Common Lisp \ 1 . 4 . 2 \ .
In addition, we should see the environment variable SBCL_HOME with the value
C : \ Program F i l e s \ Steel Bank Common Lisp \ 1 . 4 . 2 \ .
If, later under Emacs, we want to use the separately installed SBCL and the one
from the Maxima installer alternately, we do not need to change the Windows en-
vironment variables any more. Instead, the local copies of them, which Emacs
actually uses, can be adjusted easily in the .emacs init file, see section 37.6.3.2.
SBCL uses this environment variable to locate the folder where to search for its core
file. If the folder does not match the SBCL version that was invoked with the .exe
file, a severe error situation will arise and it will not be able to start SBCL.
To update the SBCL version, just execute the new SBCL installer. We do not need
to deinstall the old one first. A subfolder with the new version will be created and
the Windows environment variables will be adjusted automatically. We only need
to adapt our personal setup and initialization files (e.g. .emacs, see below).
37.5.2 Setup
37.5.2.1 Set start directory
The directory from which SBCL is started is called the SBCL start directory. The
SBCL system variable *default-pathname-defaults* will be set to this directory and
make it the so-called current directory. This will be the default path for file loads
from within SBCL. Note that relative paths can be used on the basis of the current
217
directory, and the standard file extension .lisp can be omitted. This also works
under Maxima, if a Lisp load command is executed, e.g.
: l i s p ( load "System /Emacs/ startswank " )
However, if we load with the Maxima command, we can use relative paths, too, but
we have to include the file extension .lisp
load ( "System /Emacs/ startswank . l i s p " )
A Lisp init file named ".sbclrc" can be created. It will be loaded and executed every
time SBCL starts. Unfortunately, this file has to be placed in two different locations:
C:/Users/<user>
for wxMaxima, xMaxima, the Maxima console under Windows and the SBCL console
(64 bit) under Windows.
C:/Users/<user>/AppData/Roaming
for all applications under Emacs and for the SBCL console (32 bit) under Windows.
In order to find out where the init-file is supposed to be for a specific SBCL applica-
tion, use one of the following commands from within the particular application:
( sb−impl : : userinit−pathname )
( f u n c a l l sb−ext : * userinit− pathname− function * )
If it is a Maxima application, simply preceed each Lisp command by ":lisp " at the
Maxima prompt:
: l i s p ( sb−impl : : userinit−pathname )
: l i s p ( f u n c a l l sb−ext : * userinit− pathname− function * )
The copies from both directories can be loaded into Notepad++ simultaneously
under identical file names; as you will soon see, we will introduce a tiny difference
between the two copies.
For our Maxima Lisp developer’s environment this file should contain the following
forms. The complete model file can be found in Annex B.
218
( s e t f sb−impl : : * default− external− format * : utf−8 )
( format t "~%~a" " External format set to UTF−8. " )
We can start an SBCL session from the Windows console. Open the Windows shell
(DOS prompt), cd to what you want to have as the start directory and type SBCL.
To invoke the command history, type C-<uparrow>.
37.6 Emacs
37.6.1 Overview
Emacs is a Lisp based IDE and much more. The Emacs Manual provides an impres- [EmacsMan]
sive description.
37.6.1.1 Editor
Emacs is written in eLisp, a dialect of Common Lisp. eLisp must be used to program
the .emacs init file and any file to be loaded from it. But of course eLisp can also be
used under Emacs for any other purpose. Emacs supplies is with special debugging
facilities. See the extensive eLisp Manual for details. [eLispMan]
219
37.6.1.3 Inferior Lisp under Emacs
Any other Common Lisp variant installed on the computer can be set up to be used
as inferior Lisp under Emacs. This setup is done in the .emacs init-file. We will
use SBCL. Note that inferior Lisp is independent of the Lisp used by Maxima and of
eLisp. All can be different.
The Emacs IDE can thus be used for any other Lisp development independent of
Maxima.
There are various Maxima interfaces that work under Emacs. We use the Maxima
console and iMaxima which provides output created with LateX.
The iMaxima interface and how to set it up under Emacs and Windows is described
in detail on Yasuaki Honda’s iMaxima and iMath website. [iMaximaHP]
37.6.3 Setup
37.6.3.1 Set start directory
We can set the Emacs start directory in its desktop shortcut (right click / properties
/ execute in). We use the path
D: \ Programme\ Lisp
220
This will be the default path for file loads from within Emacs (by typing C-x C-f in the
mini buffer). This will also be the default for the start directory and therefore the
current directory for SBCL (in case we invoke it from within Emacs), to which the
variable *default-pathname-defaults* will be set. To show or change it from within
SBCL use
* default−pathname−defaults *
( s e t f * default−pathname−defaults * #P"D: / Maxima/ Repos / " )
If we want a different SBCL start directory than the one for Emacs, we can in start-
sbcl.bat (see below) cd to a different directory prior to invoking SBCL.
2. Set inferior Lisp to SBCL. We write a short Windows batch-file start-sbcl.bat which
we place e.g. in D:/Programme/Lisp/System/SBCL and which we use to start SBCL.
It allows us (by means of the Windows cd command) to preselect the start directory
for SBCL. It will be SBCL’s current directory. If we do not set the start directory in
this file, the Emacs start directory will be used as default. The batch file is
"C : / Program F i l e s / Steel Bank Common Lisp / 1 . 4 . 2 / sbcl . exe"
rem "C : / Maxima− 5.41.0/ bin / sbcl . exe"
The above assumes that we use a separately installed SBCL. If instead we want to
use the SBCL from the Maxima installer, we have to activate the out-commented
path instead. In the init-file we write
( setq inferior− lisp− program "D: / Programme/ Lisp / System /SBCL/ start− sbcl . bat " )
3. Setup Maxima. We need to load the system eLisp file setup-imaxima-imath.el [iMaximaHP]
which comes with Maxima. Best is to create a local copy in a fixed place on our
computer, so we do not always have to adapt the path to the file if we use different
Maxima installations. This file sets up Emacs to support Maxima and the Latex-
based interface iMaxima. We do not need to customize this file. But before loading
the file we set two system variables. *maxima-build-type* specifies whether we use
221
Maxima from an installer or whether we have built Maxima from a tarball or a local
copy of the repository. *maxima-build-dir* specifies the path to the root directory
of the Maxima we want to use. If we do not specify these two system variables, the
first Maxima installer found in "C:/" will be used. (Note that this is the oldest one
installed.) So in the init-file we write
; * maxima−build−type * can be " repo− tarball " or " i n s t a l l e r "
( defvar * maxima−build−type * " i n s t a l l e r " )
4. Key reassignments for Slime. In order to ease our work under Slime we change [SlimeMan]
the keys for a number of its system functions.
( eval− after− load ’ slime
‘ ( progn
( global−set−key (kbd "C−c a" ) ’ slime− eval− last− expression )
( global−set−key (kbd "C−c c" ) ’ slime−compile−defun )
( global−set−key (kbd "C−c d" ) ’ slime−eval−defun )
( global−set−key (kbd "C−c e" ) ’ slime− eval− last− expression− in− repl )
( global−set−key (kbd "C−c f") ’ slime− compile− file )
( global−set−key (kbd "C−c g" ) ’ slime−compile−and−load−file )
( global−set−key (kbd "C−c i ") ’ slime− inspect )
( global−set−key (kbd "C−c l ") ’ slime− load− file )
( global−set−key (kbd "C−c m" ) ’slime−macroexpand−1)
( global−set−key (kbd "C−c n" ) ’ slime−macroexpand−all )
( global−set−key (kbd "C−c p" ) ’ slime− eval− print− last− expression )
( global−set−key (kbd "C−c r") ’ slime−compile−region )
( global−set−key (kbd "C−c s" ) ’ slime− eval− region )
))
5. Customizing Emacs. Emacs can be extensively customized. The changes made [EmacsMan]
are stored automatically at the end of ".emacs". For example, the following code
will be inserted when we do
M-x customize, Editor, Basic settings, Tab width, default 8 -> 2, Save.
( custom−set−variables
; ; custom−set−variables was added by Custom .
; ; I f you edit i t by hand , you could mess i t up , so be careful .
; ; Your i n i t f i l e should contain only one such instance .
; ; I f there i s more than one , they won’ t work r i g h t .
’ ( safe− local− variable− values ( quote ( ( Base . 10) ( Syntax . Common−Lisp) (
Package . Maxima) ) ) )
’ ( tab−width 2) )
( custom−set−faces
; ; custom−set−faces was added by Custom .
; ; I f you edit i t by hand , you could mess i t up , so be careful .
; ; Your i n i t f i l e should contain only one such instance .
; ; I f there i s more than one , they won’ t work r i g h t .
)
222
37.6.3.3 Customization
In Emacs Options/Set Default Font set Courier New size to 12. Store this with Save
Options, so I don’t have to set it again on every start of Emacs. This will be written
automatically into the .emacs file.
A special setup is necessary for running Maxima or iMaxima under Emacs with
Slime. We have to write a short Lisp program named startswank.lisp and place it
e.g. in
D: / Programme/ Lisp / System /Emacs
To start a Lisp session under Emacs without Slime, type Alt-X and then in the
minibuffer run-lisp or inferior-lisp.
The error message spawning child process is a typical sign of SBCL searching in the
wrong directory for its core file. Check that the path specified in start-sbcl.bat is
correct. Check that the Windows environment variables of the current user (PATH
and SBCL_HOME) are properly set, see above.
To invoke the command history under SBCL, type Ctrl-<uparrow>.
To start a Lisp session under Emacs with Slime, type Alt-X and then in the minibuffer
slime. The screen will split and the Slime prompt will show up.
To start a console Maxima session under Emacs without Slime, type Alt-X and then
in the minibuffer "maxima".
To start an iMaxima session under Emacs without Slime, type Alt-X and then in the
minibuffer "imaxima".
To start a console Maxima or iMaxima session under Emacs with Slime, proceed as
follows
1. Start Maxima or iMaxima under Emacs as described above.
2. At the Maxima prompt, enter
load ( "System /Emacs/ startswank . l i s p " ) ;
3. If the load succeeded, type Alt-X and then in the minibuffer "slime-connect".
4. At the message Host: 127.0.0.1 hit return in the minibuffer.
5. At the message Port: 4005 again hit return in the minibuffer.
223
Now the Emacs screen splits and a new window is opened with a prompt Maxima>.
This is a Lisp session under Slime inside of the running Maxima session. All Maxima
variables and functions can be addressed from it. This Emacs buffer can be used to
debug or make modifications to the Maxima source code while Maxima is running.
We can switch back and forth between the Maxima-Lisp and the Maxima-MaximaL
windows by "Ctrl-x o" and enter input in both. The first time we switch back to
the MaximaL window, there will be no Maxima prompt visible. Nevertheless, we
can enter something followed by a semicolon, e.g. "a;" and the input prompt will
reappear. Note that MaximaL variables have slightly different names under Lisp:
they have to be preceeded by a "$" character, so e.g. the variable "a" has to be
addressed as "$a" from the Lisp window. And as always in Lisp, commands are not
terminated by a semicolon as they are in MaximaL.
It should be noted here that we won’t have Slime’s full functionality unless we use
a Maxima built by ourselves. See chapter 39 for how this is done. Then, if the build
succeeded, set up Emacs to use this build. Only this will allow Slime to interactively
find the source code of Maxima functions while Maxima is running in parallel with a
Lisp session under Emacs.
37.7 Quicklisp
Quicklisp is a Lisp library and installation system. It runs under Lisp, so we will
install it and use it from SBCL. A good introduction and instruction how to use it can
be found at https://www.quicklisp.org/beta/. We will soon use Quicklisp to install
Slime.
37.7.1 Installation
Quicklisp will be installed via our Lisp system, which is SBCL. Download the file
quicklisp.lisp from the Quicklisp homepage. Start SBCL from the Windows console
by typing "SBCL" at the DOS prompt. See that you are connected to the internet.
Then, at the SBCL prompt, enter the following Lisp commands one by one. This will
install Quicklisp in "C:/Quicklisp". Don’t install it in the program files subdirectory,
because Quicklisp does not like blanks in the filename. Then Quicklisp is loaded
and some code is added to our .sbclrc init-file, see section 37.5.2.2, in order for
Quicklisp to be loaded automatically whenever we start SBCL.
( load "C : / Users/<user>/Downloads / q u i c k l i s p . l i s p " )
( quicklisp− quickstart : i n s t a l l : path "C : / Quicklisp / " )
( load "C : / Quicklisp / setup . l i s p " )
( ql : add− to− init− file )
Now that we have installed Quicklisp, we stay in SBCL to continue with installing
Slime.
224
37.8 Slime
If we install Slime via Quicklisp (alternatively it can be installed from Melpa), it will
be stored inside of C:/Quicklisp. Under SBCL, execute the following Lisp forms one
by one. This will install Slime including the Swank facilities. The last form will install
slime-helper.el and add some code to our .emacs init file, see section 37.6.3.2, in
order to load it and facilitate working with Slime. See http://quickdocs.org/quicklisp-
slime-helper/.
( ql : update− client )
( ql : update− dist " q u i c k l i s p " )
( ql : system−apropos " slime " )
( ql : quickload "swank" )
( ql : quickload " quicklisp− slime− helper " )
37.9 Asdf/Uiop
ASDF (Another system definition facility) is a Lisp build system. See https://common-
lisp.net/project/asdf/ for a description. UIOP is an extension of ASDF which signifi-
cantly enhances Common Lisp’s functionality. For instance, it emulates file handling
procedures for Windows.
37.9.1 Installation
Our Quicklisp installation comes with a Lisp source file asdf.lisp in the main folder.
But Asdf/Uiop is already included in our SBCL installation, too. Here, in the contrib
folder, we find the compiled files asdf.fasl and uiop.fasl. These are the files used by
SBCL. It is important to have the latest possible version of Asdf/Uiop installed here.
To find out which version we have in our SBCL installation, we can do from SBCL
( require ’ asdf )
asdf : : * asdf− version *
" 3.3.1 "
The version of the asdf.lisp in our Quicklisp installation can be found in the source
code itself. Just open the file with Notepad++. It turns out to be much older, in our
case it is 2.26. We continue our investigations from SBCL:
( ql : update− client )
( ql : update− dist " q u i c k l i s p " )
( ql : system−apropos " asdf " )
tells us that the Quicklisp library has version 3.3.1 available. Finally, we take a look
at the Asdf homepage and find out that the latest released version is 3.3.2. So we
225
download the corresponding asdf.tar.gz and unpack it with 7zip (This goes in two
steps: first we unzip the .tar.gz, then the resulting .tar). In addition, we download
the latest asdf.lisp file from the Asdf archive. Oops, if we just click on the file, we
get one very long string without any line breaks. But what we want can be done in
the following way: rightclick on the file in the archive, select "save as" and set the
file name to asdf.lisp. Then we open the file with Notepad++. Now we have the
correct Windows line endings (CR/LF instead of Unix LF only)! What we want to do
now is compile this file ourselves to create the asdf.fasl (which should include Uiop
as well and) which we will insert into our SBCL/contrib folder to replace the existing
version. We always save the existing versions, of course, by renaming them. Let’s
assume the asdf.lisp is in the downloads folder. Then we continue with SBCL
( compile− file "C : / Users/<user>/Downloads / asdf . l i s p " )
and wait patiently until the compilation process is finished. Check that there were
no error conditions. We got three, so we fall back to asdf 3.3.1. With this version,
compilation was successful. Now the asdf.fasl file should be in the download folder,
too. We copy it into the folder Program Files/Steel Bank Common Lisp/1.4.2/contrib.
Then we leave SBCL by entering (quit), start it again from the Windows DOS prompt
and continue with checking
( require ’ asdf )
asdf : : * asdf− version *
" 3.3.1 "
37.10 Latex
We need to have a Latex installation on our system if we want to use the iMaxima
interface, which runs under Emacs and gives LateX output.
37.10.1 MikTeX
MikTeX provides the Latex environment needed for iMaxima. This is a very compli-
cated system, and it is important to follow the installation instruction carefully.
Download the latest version from miktex.org. Execute the program as administrator
(Rightclick). Install MikTeX in the default directory C:/Program Files/MikTeX 2.9. Load
packages on the fly: "yes". If during installation your antivirus program complains,
ignore it this time and continue the installation.
For maintenance always use the subdirectory Maintenance(Admin). After the instal-
lation, open the MikTex packet manager from the MikTeX 2.9/Maintenance(Admin)
directory in the program menu. Install packages mhequ, breqn, mathtools, l3kernel,
unicode-data. These files are needed for iMaxima. Immediately run Update from
Maintenance(Admin), too, and install all the available updates proposed.
226
37.10.2 Ghostscript
Ghostscript is needed for iMaxima, too.
Install Ghostscript in the default directory C:/Program Files/gs. An overview about
the software is to be found under C:/Program Files/gs/gs9.21/doc/Readme.htm.
37.11.2 MinGW
Install MinGW in C:/Program Files/MinGW.
37.11.3.2 Linux
227
Chapter 38
38.1 Introduction
This chapter follows up on the discussion of section 36.5.
228
PDF in the net for free. All the details you ever want to know can be found in the
Git Online Reference. It should also be mentioned that almost any special question [GitRef]
around Git has already been asked on Stackoverflow.
38.1.2.1 KDiff3
We will use KDiff3 to help us resolve merge conflicts arising under Git when we
rebase our own changes onto the original branches from the Sourceforge repository.
Install the 64bit version of KDiff3 with the defaults in the default location.
1 RS only: When CMD is started, rightclick on the upper margin of the window and in properties set
font size to 20. For Git bash, rightclick on the upper margin of the window and set options/text/font
to Courier new, size 14.
229
38.2.1.3 Configuring Git
Git allows configuration at various levels: system, user, project. Configuration files
are therefore created in various locations. In C:/Users/<username>/ we place the
file .gitconfig given in Annex D, after having done our personal adjustments to it.
Most important is to substitute your name and email. We have also specified the
text editor to be used for commit messages and the merge tool. The autocrlf com-
mand allows for the correct transformation of line endings from Unix to Windows
and vice versa. The whitespace command causes git-diff to ignore "exponentialize-
M" characters. In addition we have defined some shortcuts for the most frequent
commands (st, ch, br, logol). With
g i t config −−global −−edit
from the Git prompt (note the blank and the double dashes before each option)
Notepad++ should open and display the file .gitconfig.
There is a known problem with Git not handling UTF-8 characters correctly, for in-
stance when displaying committ messages which contain German umlauts in the
name of the committer, see stackoverflow. We want to apply the proposed solu-
tion and create a Windows environment variable LC_ALL which we assign the value
C.UTF-8. Don’t define it under "‘Admin"’, but under "‘System variables"’. This defi-
nition will solve the problem permanently for both Git CMD and Git bash.
Under Git bash, directory paths are written like e.g. /d/maxima/repos. Changing
the current directory is done with e.g. cd /c/users/<username>.
38.2.2 GitHub
38.2.2.1 Creating a GitHub account
230
which leads us to this page, because everything else will start from here. Just to
give you a glimpse at how we will continue: click on the little triangle to the right of
the "+" sign in the upper right corner and you will see the options New repository
and Import repository which we will soon make use of.
We will use only plain command line Git to communicate with our GitHub reposito-
ries. There are special programs from GitHub to do so, too, e.g. the GitHub desktop,
but in our opinion it is a waste of time and effort to learn them. Git is the underlying
software in any case and in order to have full control of what we want to do, we
better stay at this ground level. Every other program on top of it will hide informa-
tion from us that at one point or another we will urgently need in order to make
Git do exactly what we want. This can be complicated at times, we need to learn a
number of Git commands, but there is no way around it.
where rMaxima ist our destination subfolder. And now we wait patiently until the
latest snapshot (meaning: the actual status) of the Maxima repository from Source-
forge has been completely copied.
231
and then a name for the mirror on our GitHub account, let’s say "rMaxima", too.
Then we click on Begin import. The import from Sourceforge to GitHub can take a
couple of minutes.
Once we have receivd the email notification about our mirror having been success-
fully installed on GitHub, we go to our account profile again and Customize our
pinned repositories by selecting our new repository Maxima. Now it will be visible
on our account profile and we can always find it and move to it easily. On selecting
our new repository, a short description of it can be given which will be displayed on
the acount profile together with its name.
In Git, origin is the shortname of our source repository, which is Maxima at Source-
forge. The above command gives us an overview of what branches exactly we’ve
just cloned from there.
The most interesting of the remote branches we see is master. It is the official,
the decisive, the relevant branch with the actual status of the Maxima repository
at Sourceforge. Our local branch master corresponds to it. Our local master shall
always be a true copy of the present status at Sourceforge. So we never com-
mit changes to it, we only use it for pulling from Sourceforge and for pushing the
changes which come from Sourceforge to our Maxima repository at GitHub. Our
own work we will do on other branches which we create from our local branch mas-
ter.
Updating our local master branch from Sourceforge is simply done by
g i t ch master
git pull
Note that we use the shortnames defined in .gitconfig, see. Annex D. With the
option pull −−all, not only master, but all tracked branches will be pulled (i.e. up-
dated) from origin into their respective local branches. When using these com-
mands for the first time or after a long time of not having used them, they can take
a while, because Git does a lot of checking in the background, so be patient.
232
New branches on Sourceforge will be shown in the list by the remote show origin
command, marked as new. On the next git pull they will automatically be tracked.
Branches deleted on Sourceforge will be marked in the list as stale. They will not
be deleted automatically by pull, instead we have to remove them manually with
g i t ch master
g i t remote prune o r i g i n
Then we take a look at our GitHub repository, as it is mirrored on our local machine,
by entering
g i t remote show github
Just as our local master shall always be a true copy of master at Sourceforge, our
master at GitHub shall always be a true copy of our local master. Updating master
on GitHub from our local master is done by
g i t ch master
g i t push github
In this proces we might be asked to enter our GitHub username and password. With
the option push github −−all, all local branches configured for push (see list remote
show github) will be pushed to GitHub. In order to configure a branch for push
to GitHub or to forward a new (e.g. release) branch from Sourceforge to GitHub,
we have to track the branch first in our local repository, done with the checkout
command, and then push it to GitHub:
g i t ch <name of new branch>
g i t push github <name of new branch>
In the push command the name of the branch is not necessary, if we are on this
branch already. If we want to delete a branch from GitHub, for instance because it
has been deleted from Sourceforge, we do
g i t push github −d <name of branch to be deleted>
To update the repository completely with all branches from Sourceforge after a year
or more, it is easiest to delete the GitHub repository, clone it newly and push all my
own branches again.
233
correspond to Windows explorer directories! What branch we are in, can only be
seen in Git itself, not in the explorer. Changes to files in one branch, even addition
and deletion of files, will not be visible in the same Windows folder any more, if
we switch to another branch where these changes have not been incorporated. Be
sure to have understood that very clearly before working with Git. This will prevent
you from some severe headaches (you will probably get others with Git at some
point or another anyways).
We can create a new branch from an existing one and switch to it by doing
g i t ch <name of the branch we want to branch from>
g i t ch −b <name of the new branch>
In order to obtain a compact log output of the last n commits we can type
g i t logol −n
234
Chapter 39
39.1 Introduction
In this section we show how Maxima can be built on the local computer under the
Windows operating system. Maxima is primarily designed for Unix-based operat-
ing systems, especially Linux. Sophisticated system definition and build tools are
employed to automate as much as possible the complicated build process. Since
these tools (in particular GNU autotools) are not available under Windows, there are
two ways how Maxima can be built here. The first one makes use of the Unix-based
tools and thus needs an environment which supports them. Such an environment is
Cygwin, a Unix-like shell running under Windows and in which Windows executables
can be produced. The second one does not use the Unix-based build tools at all,
but an (almost) purely Lisp-based method. It can be accomplished under the plain
Windows command line shell. All we need is a Lisp system installed. Since this is
the simpler and easier method, we demonstrate it first. Note however, that not all
Maxima user interfaces and features are supported with this build.
235
39.2.2 Recipe
1. Install the Windows installer of the latest release in C:/Maxima/maxima-5.41.0.
Download the source code file maxima-5.41.0.tar.gz of the latest Maxima release
from https://sourceforge.net/projects/maxima/files/Maxima-source/5.41.0-source/ and
extract the tarball with 7zip in the folder D:/Maxima/Tarballs/.
2. Create the directory of the new build and name it appropriately, e.g. D:/Maxima/
Builds/<lob-2017-12-09-lb>, now called the build directory.
3. Depending on what to build from,
3a. either copy the extracted source code from the release tarball into the build
directory; or
3b. select the branch of the local repository D:Maxima/Repos/rMaxima from which
to build. Pull master and rebase this branch on master first in order to have our
changes rebased on the latest Git snapshot from Sourceforge. Copy the selected
branch into the build directory.
3c. In both cases, copy the PDF version of the documentation, the file maxima.pdf,
from the subfolder share/doc of the Windows installer into the subfolder doc/info of
the build directory.
4. The tarball contains the complete documentation of the latest release with the
exception of the PDF version. In case the documentation shall not be built (also if
we build from a repository snapshot), it can be simply be copied from the tarball
into the build directory:
4a. For the online help system: From doc/info take maxima-index.lisp and all files
*.info* and copy them into doc/info of the build directory.
4b. For the html version: From doc/info take all files *.html and copy them into
doc/info of the build directory.
5. Now we use Lisp. The following steps can be executed either using SBCL form a
Windows command line shell or under Emacs/Slime (Note, however, that dumping
can be done only from the Windows command line!): 5a. Open a Windows com-
mand shell and cd to the top-level of the build directory (i.e., the directory which
contains src/, tests/, share/, and other directories). Then launch SBCL. Alternatively,
5b.
236
Part XI
237
Chapter 40
238
Chapter 41
239
Part XII
240
Chapter 42
241
Part XIII
Appendices
242
Appendix A
Glossary
Argument
If a function f has been defined with parameters, a function call of f has to be sup-
plied with corresponding arguments. When f is evaluated, arguments are assigned
to their corresponding parameters. For the distinction of required and optional ar-
guments, see section 31.2.3.
Array
An array is a data structure ...
Assignment
Binding a value to a variable. This is done explicitly with the assignment operator.
The value can be a number, but also a symbol or an expression. In an indirect
assignment, done with the indirect assignment operator, not a symbol is bound
with a value, but the value of the symbol, which must again be a symbol, is bound.
Atom
An atom is an expression consisting of only one element (symbol or number).
Binding
A binding ...
Constant
There are numerical constants and symbolical constants. A number is a numerical
243
constant. Maxima also recognizes certain symbolical constants such as %pi, %e and
%i which stand for π, Euler’s number e and the imaginary unit , respectively. For
Maxima’s naming conventions of system constants see section 3.4.2.2. Of course
the user may assign his own symbolical constants.
Equation
An equation is an expression comprising an equal sign =, one of the identity oper-
ators, as its major operator. An unequation is an expression with the unequation
operator # as its major operator.
Expression
Any meaningful combination of operators, symbols and numbers is called an ex-
pression. An expression can be a mathematical expression, but also a function call,
a function definition or any other statement. An expression can have subexpres-
sions and is build up of elements. An atom or atomic expression contains only one
element. A complete subexpression ... See subst (eq_1, expr) for an example.
See also lambda expression.
Function
A function is a special compound statement which is assigned a (function) name,
has parameters and in addition can have local variables. Maxima comprises a large
number of system functions, as for instance diff and integrate. Furthermore, the
user can define his own user functions. A special operator, the function definition
operator :=, is used for this purpose. On the left hand side, the function name
and its parameters are specified, while on the right hand side, the function body.
Alternatively, function define can be used.
On calling a function, arguments 1 are passed to it which are assigned to the func-
tion’s parameters at evaluation time. The result of the function’s subsequent com-
putations, i.e. the evaluation of the function, is returned. We speak of the return
value of a function call. A function call can be incorporated in an expression just
like a variable. An ordinary function is evaluated on every call, see section 31.2.3.
An array function stores the function value the first time it is called with a given
argument, and returns the stored value, without recomputing it, when that same
argument is given. Such a function is known as a memoizing function, see section
31.2.4.
A subscripted function is a special kind of array function which returns a lambda
expression. It can be used to create a whole family of functions with a single defi-
nition, see section 31.2.5.
In addition there are functions without name, so-called lambda functions or anony-
mous functions, which can be defined and called at the same time. Their return
value is called a lambda expression. See section 31.3.
1 Instead of parameter and argument, the terminology formal argument and actual argument is
used in the Maxima Manual.
244
A macro function is similar to an ordinary function, but has a slightly different be-
havior. It does not evaluate its arguments and it returns what is known as a macro
expansion. This means, the return value is itself a Maxima statement which is
immediately evaluated. Macros are defined with the macro function definition op-
erator ::=.
An undeclared function is just a symbol which stands for a function, possibly fol-
lowed by one or more arguments in parentheses. It has not been declared with a
function definition. It is not bound. On calling it, it evaluates to itself. However,
for the purpose of differentiation, dependencies of the function on certain variables
can be declared with depends.
Lambda expression
The return value of a lambda function is called a lambda expression. See section
31.3.
Macro expansion
Macro expansion is part of the mechanism of a macro function.
Operator
A Maxima operator can be view in a way similar to a mathematical operator. The
arithmetic operators +, -, *, /, for example, are employed in an infix notation just as
in mathematics.
The equal sign =, the assignment : or the function definition := are examples of
other Maxima system operators.
Maxima even allows the user to define his own operators, be they used in prefix,
infix, postfix, matchfix or other notations.
Parameter
A parameter is a special local variable defined for a function, which is assigned the
value of a corresponding argument at function call.
Pattern matching
For the definition see section 14.1.1.
Predicate
A predicate is an expression returning a Boolean value. This may be a function or a
lambda expression with a Boolean return value, a relational expression evaluated by
is, or the Boolean constants true and false. For a match predicate see matchdeclare.
Property
A MaximaL property ... A Lisp property ...
Rule
245
A rule ...
Scope
Symbol, identifier
Maxima allows for symbolical computation. Its basic element is the symbol, also
called identifier. A symbol is a name that stands for something else. It can stand
for a constant (as we have seen already), a variable, an operator, an expression, a
function and so on.
Statement
An input expression terminated by ; or $ which is to be evaluated is called a state-
ment. In Lisp it would be called a form.
If a number of statements are combined, e.g. as a list enclosed in parentheses and
separated by commas, called a sequential, we speak of a compound statement. The
statements forming a compound statement are called its sub-statements. Block
and function are other special forms of a compound statement. A block is a com-
pound statement which can have local variables, a function is assigned a name and
can have parameters, see chapter 31.
Value
A symbol (i.e. a variable, a constant, a function, a parameter, etc.) can be unbound;
then it has not been assigned a value. When a value has been assigned to the
symbol, it is bound. Binding a value to a symbol is called assignment. Retrieving
the value of a symbol is called referencing or evaluation.
The return value is what a function returns when it is called and evaluated.
Variable
A variable has a name (which is represented by a symbol) and possibly a value.
Assignment of a value to a variable is called binding. We say: the variable is bound
to a value. When a variable has been bound, it is referencing this particular value.
Evaluation in the strict sense means dereferencing, which is: obtaining from a vari-
able the value which was bound to it previously.
In general, Maxima does not require a variable to be defined explicitly by the user
before using it. In particular, Maxima does not require a variable to have a specific
type (of value). Just as when doing mathematics on a sheet of paper, we can start
using a variable at any time. It will be defined (allocated) at use time by Maxima
automatically. We can start using a variable without binding it to a value. Maxima
recognizes the symbol, but it remains unbound. But we can also bind it at any time,
even right at the beginning of its use. The type of value of a specific variable may
change at any time, whenever the value itself changes.
The value of a variable does not need to be a numerical constant. It can be another
variable or any combination of variables and operators, that is, an expression. It
246
can even be much more than this. The variety of types (of values) of a variable is
so broad that in Lisp and in Maxima we generally use the term symbol to denote
not only the name of variable, but the variable as a whole.
One of the specific features of Lisp is that a symbol not only can have a value, but
also properties. A Maxima symbol can have properties, too, as we will see later. It
can even have two types of properties, Lisp properties and Maxima properties.
There are user variables, which the user defines, and system variables. System
variables which can be set by the user to select certain options of operation are
called option variables. With respect to the name space where the variable appears
we distinguish between global variables and local variables. For a match variable
see matchdeclare.
247
Appendix B
The following is a model of the complete SBCL init file ".sclrc" to be placed both in
C:/Users/<user> and C/:Users/<user>/AppData/Roaming. See section 37.5.2.2 for
explanations.
; i n i t i a l i z e Quicklisp
#−q u i c k l i s p
( l e t ( ( q u i c k l i s p − i n i t (merge−pathnames "C : / q u i c k l i s p / setup . l i s p " (
user−homedir−pathname) ) ) )
(when ( probe− file q u i c k l i s p − i n i t )
( load q u i c k l i s p − i n i t ) ) )
( format t "~%~a" " Quicklisp loaded . " )
; display f i n a l messages
( format t "~%~a" " I n i t − F i l e C : / Users/<user >(/AppData / Roaming) / . sbclrc
completed . " )
( format t "~%~a~a" " Current directory ( also from Maxima) i s " *
default−pathname−defaults * )
( format t "~%~a" "To change the current directory use ( setq *
default−pathnames−default * #P \ "D: / Maxima/ Builds / \ " ) . " )
( format t "~%~a" " Relative paths can be used and standard f i l e extension .
l i s p omitted , e . g . : ( load \ " subdir / subdir / filename \ " ) . " )
( format t "~%~a" " " )
248
Appendix C
The following is a model of the complete Emacs init file .emacs to be places in
C:/Users/<user>/AppData/Roaming. See section 37.6.3.2 for explanations.
; set up Maxima
; * maxima−build−type * can be " repo− tarball " or " i n s t a l l e r "
( defvar * maxima−build−type * " i n s t a l l e r " )
; * maxima−build−dir * contains the root directory of the build , terminated
by a slash .
( defvar * maxima−build−dir * "C : / Maxima/maxima−5. 4 1 . 0 / " )
; ( defvar * maxima−build−dir * "D: / Maxima/ builds / lob−2017−04−04−lb / " )
( load "D: / Programme/Maxima/ System /Emacs and Slime setup f o r Maxima/
setup−imaxima−imath . e l " )
249
( global−set−key (kbd "C−c p" ) ’ slime− eval− print− last− expression )
( global−set−key (kbd "C−c r " ) ’ slime−compile−region )
( global−set−key (kbd "C−c s " ) ’ slime− eval− region )
))
250
Appendix D
251
Appendix E
blanco
(%i1)
(%i2)
(%i3)
(%o1)
(%o2)
(%o3)
(%o1)
(%i2)
(%o2)
(%i3)
(%o3)
(%i4)
(%o4)
252
Index
,18 activate, 88
, 18 activecontexts, 89
”, double qoute marks, 187 addcol, 137
’ ’, quote-quote, 79 additive, 94
(), 18 addrow, 137
, comma, 19, 27 algsys, 122
., 125 alphabetic, 22
/* ... */, 21 angles
:, 19 representation and transformation, 177
::, 20 anonymous function, 244
::=, 200 antisymmetric, 94
:=, 192 apply, 196
;, 27 apply1, 111
<, 74 apply2, 111
<=, 74 Apply2Part, 82
=, 66, 71 applyb1, 111
>, 74 argument, 243, 244
>=, 74 actual, 244
?, 21 formal, 244
[], 19 optional, 195
#, 72 required, 195
$, 27 array, 243
%, 27, 29 ASCII, 22
%%, 29 ASDF, 225
%e, 244 UIOP, 225
%e_to_numlog, 118 assignment, 243
%emode, 118 indirect, 243
%enumer, 119 assignment operator, 19
%gamma, 23 indirect, 20
%i, 56, 244 assume, 96
%in, 28 at, 80, 156
%on, 29 atom, 243
%pi, 244 atomgrad
%solve, 123 printprops, 164
%th, 29 remove, 164
_, 28 atvalue, 156
__, 29
^^, 125 bc2, 170
{}, 19 bfloatp, 56
binding, 243, 246
253
binomial, 115 declare (p , feature), 94
block, 191 decomposition
box, 69 partial fraction, 120
braces, 19 decreasing, 93
break command, 207 define, 192
defmatch, 105
cabs, 59
defrule, 106
canonical rational expression (CRE), 65,
Deg2Rad, 177
243
DegRange0to2, 177
carg, 59
DegRange1to1, 177
case-sensitivity, 22
demoivre, 81, 118
cell
flag, 81
wxMaxima, 17
dependencies, 158
ChangeSign, 83
system variable, 159
character
depends, 158
alphabetic, 22
dereferencing, 246
special, 22
desolve, 170
charpoly, 143
determinant, 143
clear_rules, 112
diagmatrix, 138
Clisp, 215
diff, 154
col, 138
evaluation flag, 157
columnvector, 128
dispfun, 193
comment operator, 21
disprule, 112
Common Lisp, 16
distribute_over, 130
commutative, 94
divide, 120
complex, 92
division
complex numbers, 56
polynomial, 120
complexp, 60
doallmxops, 135
concat, 188
documentation operator, 21
ConcMinSec, 177
domain, 116
conjugate, 59
domxmxops, 135
constant, 23, 92, 243
domxnctimes, 136
numerical, 243
doscmxops, 136
symbolical, 243
doscmxplus, 136
system, 244
dot operator, 125
constantp, 92
dot product, 125
context, 88
dot0nscsimp, 126
contexts, 88
dot0simp, 126
contour_plot, 39
dot1simp, 126
covect, 128
dotassoc, 126
CRE, 243
dotconstrules, 126
CRE, canonical rational expression, 65
dotdistrib, 126
CVect, 127
dotexptsimp, 126
Cygwin, 215
dotident, 126
deactivate, 89 dotscrules, 126
Dec2Min, 177 double_factorial, 114
declare, 91 draw, 45
254
draw option lambda, 198, 244
2D macro, 245
yrange, 49 memoizing, 195
draw2d, 46 ordinary, 194, 244
draw3d, 47 subscripted, 196, 244
undeclared, 245
eigenvalues, 143
fundef, 193
eivals, 143
funmake, 197
ElemTensorDecomp, 185
elim, 124 genfact, 115
elim_allbut, 124 genmatrix, 138
ElimCommon, 85 get_plot_option, 32
eliminate, 123 Ghostscript, 227
eLisp, 219 GIF, general internal representation, 64
Emacs, 219 Git, 228
.emacs init file, 221 GitHub, 229
equal, 72 Gnuplot, 17
equation, 66, 244 gr2d, 46
ev, 77 gr3d, 47
eval_string, 188 Grad, 164
evaluation, 246 gradef, 162
even, 92 printprops, 164
evenfun, 93 remove, 164
evenp, 54 gradefs, 164
exp, 117 kill, 164
explicit gramschmidt, 142
draw object
2D, 46 hessian, 155
draw objects
ic1, 168
3D, 48
ic2, 168
exponentialize, 81
ident, 138
flag, 81
identifier, 246
expression, 244
naming specifications, 22
lambda, 245
ilt, 182
ExtractCEquations, 133
imaginary, 92
factorial, 114 imagpart, 59
FactorTerms, 83 iMaxima interface, 220
facts, 88 implicit
featurep, 95 draw object
features, 95 2D, 47
forget, 96 draw objects
form, 247 3D, 48
user visible (UVF), 63 implicit_plot, 38
fullmapl, 141 inchar, 27
function, 244 increasing, 93
anonymous, 244 innerproduct, 130
array, 195, 244 Inprod, 130
255
inprod, 130 MakeRVect, 128
input tag, 26 match variable, 100
integer, 91 mathchdeclare, 103
integerp, 54 matrix, 137
integervalued, 93 positive definite, 142
invert, 141 matrix product, 141
irrational, 92 matrix_element_add, 136
is, 74, 97 matrix_element_mult, 136
matrix_element_transpose, 136
jacobian, 156 matrixmap, 140
kdelta, 185 matrixp, 135
KDiff3, 229 Maxima
kill installer, 215
gradefs, 164 repository, 216
kill rules, 112 tarball, 216
killcontext, 89 MaximaL, 16
kron_delta, 185 MikTeX, 226
Min2Dec, 177
label MinGW, 215
intermediate expression, 193 mod, 114
lambda expression, 245 multiplicative, 94
lambda function, 244
Names
laplace, 181
specifications, 22
lassociative, 94
naming conventions, 23
Leng, 179
newcontext, 88
linear, 94
nonarray, 93
linenum, 26
noninteger, 91
linsolve, 122
nonintegerp, 54
Lisp, 16
nonscalar, 92
Common, 16
nonscalarp, 92
inferior, 220
Normalize, 132
list, 18
NormalizeColumns, 132
listarith, 129
Notepad++, 216
local, 192
notequal, 72
logsimp, 118
number
MacLisp, 16 complex, 56
macro, 199 numberp, 52
macro expansion, 199, 245 nusum, 148
macro function, 245
odd, 92
macro function definition operator, 200
oddfun, 93
macroexpand, 200
oddp, 54
macros, 200
ode, 168
make_transform, 43
ode2, 167
MakeCVect, 128
operator, 245
MakeList, 128
relational, 74
makelist, 62
order, canonical, 65
256
outative, 93 printprops
outchar, 27 atomgrad, 164
output tag, 26 atvalue, 157
gradef, 164
parameter, 244, 245 product
parentheses, 18 commutative, 125
parse_string, 188 dot, inner, scalar, 130
part, 66 non-commutative, 125
partfrac, 120 prompt, 16, 17
pattern, 99 properties, 91
pattern matching, 99, 245 property, 245, 247
pattern variable, 100 proportional_axes
plot draw option, 49
axes, 39 props, 91
box, 33 propvars, 91
color, 33 PullFactorOut, 84
legend, 33 PullFactorOut2, 84
logx, 33
logy, 33 Quicklisp, 224
plot_format, 33 quote-quote, 245
plot_realpart, 34 quotient, 120
point_type, 39
Rad2Deg, 177
same_xy, 34
radcan, 118
same_xyz, 44
radexpand, 116
style, 39
RadRange0to2, 177
transform_xy, 44
RadRange1to1, 177
xlabel, 34
radsubstflag, 69
ylabel, 34
rank, 141
yx_ratio, 40
rassociative, 94
zlabel, 34
rational, 92
plot2d, 35
rationalize, 54
plot3d, 40
ratmx, 136
plotdf, 174
ratnump, 54
polar
ratsubst, 69
draw object, 47
real, 92
polarform, 59
realpart, 59
polynomial, 120
rectform, 58
posfun, 93
referencing, 246
powerdisp, 30
remainder, 120
powerseries, 150
rembox, 69
Pr, 30
remove, 91
Pr0, 30
atomgrad, 164
Pr00, 30
dependeny, 159
predicate, 245
gradef, 164
match, 245
remove_plot_option, 32
print, 30
remrule, 111, 112
print0, 30
REPL, 16
257
replacement, 100 naming specifications, 22
representation symmetric, 94
general internal (UVF), 64 syntax description operator, 18
return value, 244, 246
rk, 172 taylor, 151
rootsconmode, 116 taylordepth, 153
rootscontract, 116 tellsimp, 109
RotMatrix, 179 tellsimpafter, 109
row, 138 TeXstudio, 227
rule, 100, 245 to_poly_solve, 123
rules, 112 TP, 131
RVect, 127 Transpose, 129
transpose, 129, 141
SBCL: Steel Bank Common Lisp, 215, 217 triangularize, 142
.sbclrc init-file, 218
scalar, 92 Uiop, 225
scalarmatrixp, 136 undeclared function, 245
scalarp, 92 Unicode, 22
scene, 45 unitvector, 132
sconcat, 188 unsum, 149
scope, 246 uvect, 132
dynamic, 246 UVF, user visible representation, 63
lexical, 246 value, 246
sequential, 191 return, 246
set_draw_defaults, 45 variable, 246
set_plot_option, 32 global, 247
Short, 179 local, 247
simplify_sum, 147 match, 100, 247
simpsum, 147 option, 247
Slime, 220 pattern, 100
slime-connect, 220, 223 system, 247
SP, 131 user, 247
sparse, 144 VDim, 129
specint, 182 vect, 127
sqrt, 116 vect_cross, 127
square brackets, 19 verbose, 30
statement, 246 VirtualBox, 215
compound, 246 VNorm, 132
string, 188 VP, 133
stringdisp, 188 VtoCVect, 129
sublis, 68 VtoList, 129
submatrix, 138 VtoRVect, 129
subst, 67
substpart, 67 wxcontour_plot, 39
sum, 146, 147 wxdraw2d, 46
supcontext, 88 wxdraw3d, 47
symbol, 246 wximplicit_plot, 38
258
wxMaxima, 17
wxplot2d, 35
wxplot3d, 40
wxWidgets, 17
XnConvert, 174
xrange
draw option
2D, 49
zeromatrix, 138
259