0% found this document useful (0 votes)
356 views139 pages

Computer Mathematics for Engineers

This document provides an introduction to the lecture notes for the course "Computer Mathematics for the Engineer: Efficient Computation and Symbolic Manipulation" taught at Åbo Akademi University. The notes were compiled by Tom Fredman of the Laboratory of Thermal and Flow Engineering and are based on various literature sources. The material introduces students to computer-aided mathematical tools like wxMaxima and Octave through examples from engineering topics. It is meant as a hands-on guide for using these tools rather than a complete manual.

Uploaded by

Lorenzo Hudson
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
356 views139 pages

Computer Mathematics for Engineers

This document provides an introduction to the lecture notes for the course "Computer Mathematics for the Engineer: Efficient Computation and Symbolic Manipulation" taught at Åbo Akademi University. The notes were compiled by Tom Fredman of the Laboratory of Thermal and Flow Engineering and are based on various literature sources. The material introduces students to computer-aided mathematical tools like wxMaxima and Octave through examples from engineering topics. It is meant as a hands-on guide for using these tools rather than a complete manual.

Uploaded by

Lorenzo Hudson
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 139

Computer Mathematics for the Engineer:

Efficient Computation and


Symbolic Manipulation
Lecture Notes
Compiled by
Tom Fredman
Laboratory of Thermal and Flow
Engineering, bo Akademi University
2011
1
These lectures were compiled for the course Computer Mathematics for the
Engineer: Ecient Computation and Symbolic Manipulation (3/5 cr. ECTS)
aimed at students on the advanced or graduate levels at bo Akademi Univer-
sity. The course is arranged by the Laboratory of Thermal and Flow Engineer-
ing at bo Akademi University and supported by the Finnish national graduate
programme Graduate School in Chemical Engineering.
The material included in these notes is based on the literature cited below and
should not be regarded as a complete users manual for the computer-aided
mathematical tools presented in the course, but merely as an introduction to
how these can be used for improving and assisting day-to-day mathematical
chores of the modern engineer. We begin with a minimal introduction of the
software packages adopted for the course and continue with details from various
engineering topics. To encourage the reader to engage in a hands-on learning
process, we tend to give only the necessary input for dierent themes and leave
it to the reader to try the various cases for him/herself. Comments on the
expected output is provided in most cases, however.
bo, November 2011,
2
Bibliography
[1] M. B. Cutlip, J. J. Hwalek, H. E. Nuttall, M. Shacham et. al The Use of
Mathematical Software Packages in Chemical Engineering.
Chemical Engineering Summer School, Snowbird UT., August 1997.
[2] R. Pich and K. Ruohonen Partial Dierential Equations with Maple.
Tampere University of Technology, December 1997.
[3] R. W. Pike Optimization for Engineering Systems.
Louisiana State University, Minerals Processing Research Institute, 2001.
[4] C. Moler Cleves Corner: Sti Dierential Equations.
Matlab News & Notes, May 2003.
[5] R. Dodier Minimal Maxima.
http://maxima.sourceforge.net/docs/tutorial/en/minimal-maxima.pdf
September 2005
[6] J. H. Mathews Module for Monte Carlo Integration.
http://math.fullerton.edu/mathews, 2005.
[7] J. W. Eaton, D. Bateman and S. Hauberg GNU Octave. A high-level
interactive language for numerical computations. Ed. 3 for Octave version
3.2.2., July 2007.
[8] P. Lutus Symbolic Mathematics Using Maxima.
http://www.arachnoid.com/maxima/index.html, 2007.
[9] H. Selhofer, M. Oliver and T. L. Scoeld Introduction to GNU Octave.
August 2008.
[10] E. L. Wollett Maxima by Example: A Series of Tutorial Notes.
Department of Physics, CSULB San Luis Obispo, CA, 2009.
[11] R. H. Rand Introduction to Maxima.
Department of Theoretical and Applied Mechanics, Cornell University
Ithaka, NY, 2010.
[12] Maxima, a Computer Algebra System.
http://maxima.sourceforge.net/documentation.html
[13] E. Gkioulekas Introduction to Maxima.
Department of Mathematics, University of Texas-Pan American Edinburg,
TX, 2011.
3
4 BIBLIOGRAPHY
Contents
1 An Overview of wxMaxima 11
1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3 Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.3.1 Utility Functions . . . . . . . . . . . . . . . . . . . . . . . 18
1.3.2 Expression Construction . . . . . . . . . . . . . . . . . . . 19
1.4 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.4.1 Evaluation of Atomic and Non-Atomic Expressions . . . . 20
1.4.2 Modications of Evaluations . . . . . . . . . . . . . . . . 20
1.4.3 Defaults and Argument Evaluation . . . . . . . . . . . . . 21
1.4.4 Callable Functions . . . . . . . . . . . . . . . . . . . . . . 22
1.4.5 Automatically Quoted Arguments . . . . . . . . . . . . . 22
1.4.6 Preventing Evaluation . . . . . . . . . . . . . . . . . . . . 24
1.4.7 Extra Evaluation . . . . . . . . . . . . . . . . . . . . . . . 24
1.4.8 Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.4.9 Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.5 Simplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.5.1 Examples of Maxima Simplication . . . . . . . . . . . . 28
1.5.2 Exceptions to Maxima Simplication . . . . . . . . . . . . 29
1.6 Special Purpose Functions . . . . . . . . . . . . . . . . . . . . . . 29
1.6.1 Applying arguments to functions . . . . . . . . . . . . . 29
1.6.2 The mapping function . . . . . . . . . . . . . . . . . . . 30
1.6.3 The lambda-function . . . . . . . . . . . . . . . . . . . . 31
1.7 Built-in object types . . . . . . . . . . . . . . . . . . . . . . . . . 31
1.7.1 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
1.7.2 Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
1.7.3 Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
1.8 Maxima Programming . . . . . . . . . . . . . . . . . . . . . . . . 34
1.8.1 Branching . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
1.8.2 Iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
1.9 Some Useful Flags . . . . . . . . . . . . . . . . . . . . . . . . . . 40
1.10 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5
6 CONTENTS
2 Symbolic Calculation 43
2.1 Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
2.2 Saving and Loading . . . . . . . . . . . . . . . . . . . . . . . . . 45
2.3 Functions and Equations . . . . . . . . . . . . . . . . . . . . . . . 47
2.3.1 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
2.3.2 Equations - A Practical Application . . . . . . . . . . . . 49
2.4 Evaluating Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
2.5 Dierential Calculus . . . . . . . . . . . . . . . . . . . . . . . . . 53
2.5.1 Computation of Solutions with the Laplace Transformation 56
2.5.2 Dierentiation Using the Chain Rule . . . . . . . . . . . . 60
2.6 Integral Calculus . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
2.6.1 Integration Examples . . . . . . . . . . . . . . . . . . . . 64
2.6.2 Integration by Parts . . . . . . . . . . . . . . . . . . . . . 70
2.6.3 Change of Variable . . . . . . . . . . . . . . . . . . . . . . 71
2.7 Matrix Computations . . . . . . . . . . . . . . . . . . . . . . . . 73
2.8 Visualization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
2.9 Numerical Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
3 An Overview of Octave 75
3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
3.1.1 Help! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
3.1.2 Input Conventions . . . . . . . . . . . . . . . . . . . . . . 76
3.1.3 Variables and Standard Operations . . . . . . . . . . . . . 76
3.2 Vector and Matrix Operations . . . . . . . . . . . . . . . . . . . . 77
3.2.1 Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
3.2.2 Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
3.2.3 Element-wise Operations . . . . . . . . . . . . . . . . . . 78
3.2.4 Indexing and Slicing . . . . . . . . . . . . . . . . . . . . . 79
3.2.5 Solving Linear Systems of Equations . . . . . . . . . . . . 79
3.2.6 Inverses, Decompositions and Eigenvalues . . . . . . . . . 79
3.2.7 Testing for Zero Elements . . . . . . . . . . . . . . . . . . 80
3.3 Control Structures . . . . . . . . . . . . . . . . . . . . . . . . . . 80
3.3.1 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
3.3.2 Global Variables . . . . . . . . . . . . . . . . . . . . . . . 81
3.3.3 Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
3.3.4 Branching . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
3.3.5 Functions of Functions . . . . . . . . . . . . . . . . . . . . 82
3.3.6 Eciency Considerations . . . . . . . . . . . . . . . . . . 83
3.4 Input and Output . . . . . . . . . . . . . . . . . . . . . . . . . . 83
3.5 Graphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
3.5.1 2D Graphics . . . . . . . . . . . . . . . . . . . . . . . . . 84
3.5.2 3D Graphics . . . . . . . . . . . . . . . . . . . . . . . . . 84
3.5.3 Commands for 2D and 3D Graphics . . . . . . . . . . . . 85
CONTENTS 7
4 Numerical Computation 87
4.1 Preliminaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
4.1.1 Running Octave . . . . . . . . . . . . . . . . . . . . . . . 87
4.1.2 Editing What You Have Typed . . . . . . . . . . . . . . . 87
4.1.3 Startup Files . . . . . . . . . . . . . . . . . . . . . . . . . 88
4.1.4 Quitting Octave . . . . . . . . . . . . . . . . . . . . . . . 88
4.1.5 Help and Documentation . . . . . . . . . . . . . . . . . . 89
4.2 Functions and Scripts . . . . . . . . . . . . . . . . . . . . . . . . 89
4.2.1 Dening Functions . . . . . . . . . . . . . . . . . . . . . . 90
4.2.2 Multiple Return Values . . . . . . . . . . . . . . . . . . . 92
4.2.3 Variable-length Argument Lists . . . . . . . . . . . . . . . 93
4.2.4 Variable-length Return Lists . . . . . . . . . . . . . . . . 94
4.2.5 Returning From a Function . . . . . . . . . . . . . . . . . 95
4.2.6 Function Files . . . . . . . . . . . . . . . . . . . . . . . . 95
4.2.7 Subfunctions . . . . . . . . . . . . . . . . . . . . . . . . . 96
4.2.8 Private Functions . . . . . . . . . . . . . . . . . . . . . . . 96
4.2.9 Script Files . . . . . . . . . . . . . . . . . . . . . . . . . . 97
4.2.10 Function Handles, Inline Functions, and Anonymous Func-
tions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
4.3 Equations and Optimization . . . . . . . . . . . . . . . . . . . . . 99
4.3.1 Nonlinear Equations . . . . . . . . . . . . . . . . . . . . . 99
4.3.2 Optimization . . . . . . . . . . . . . . . . . . . . . . . . . 101
4.4 Boundary/Initial Value Problems . . . . . . . . . . . . . . . . . . 103
4.4.1 Integrating Dierential Equations . . . . . . . . . . . . . . 103
4.5 Partial Dierential Equations . . . . . . . . . . . . . . . . . . . . 104
4.6 Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
4.6.1 Functions of One Variable . . . . . . . . . . . . . . . . . . 104
4.6.2 Functions of Multiple Variables . . . . . . . . . . . . . . . 106
5 Exercises 109
5.1 wxMaxima . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
5.1.1 Inverse Functions . . . . . . . . . . . . . . . . . . . . . . . 109
5.1.2 Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
5.1.3 Dierentiation . . . . . . . . . . . . . . . . . . . . . . . . 110
5.1.4 Integration . . . . . . . . . . . . . . . . . . . . . . . . . . 111
5.2 Octave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
5.2.1 Linear Algebra . . . . . . . . . . . . . . . . . . . . . . . . 111
5.2.2 Timing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
5.2.3 Stability Functions of BDF-integrators . . . . . . . . . . . 112
5.2.4 3D Plotting . . . . . . . . . . . . . . . . . . . . . . . . . . 112
5.2.5 Hilbert Matrix . . . . . . . . . . . . . . . . . . . . . . . . 113
5.2.6 Least Square Fit of a Straight Line . . . . . . . . . . . . . 114
5.2.7 Trapezoidal Rule . . . . . . . . . . . . . . . . . . . . . . . 114
8 CONTENTS
6 Course problems 117
6.1 Single Nonlinear Equation . . . . . . . . . . . . . . . . . . . . . . 117
6.2 Another Single Nonlinear Equation . . . . . . . . . . . . . . . . . 118
6.3 A Set of Linear Equations . . . . . . . . . . . . . . . . . . . . . . 119
6.4 Nonlinear Regression . . . . . . . . . . . . . . . . . . . . . . . . . 121
6.5 A Set of Nonlinear Equations . . . . . . . . . . . . . . . . . . . . 122
6.6 A Set of Ordinary Dierential Equations . . . . . . . . . . . . . . 123
6.7 Another Set of Ordinary Dierential Equations . . . . . . . . . . 124
6.8 A Second-Order Ordinary Dierential Equation . . . . . . . . . . 126
6.9 Ordinary Dierential Equations and Algebraic Equations . . . . 126
6.10 A Control Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
6.11 Sti Dierential Equations . . . . . . . . . . . . . . . . . . . . . . 129
6.12 Partial Dierential Equations . . . . . . . . . . . . . . . . . . . . 130
6.13 Integral Equations . . . . . . . . . . . . . . . . . . . . . . . . . . 131
6.14 Special Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
6.14.1 Perturbation Theory . . . . . . . . . . . . . . . . . . . . . 133
6.14.2 Calculus of Variations . . . . . . . . . . . . . . . . . . . . 134
6.14.3 JWKB-approximation . . . . . . . . . . . . . . . . . . . . 135
6.14.4 Monte Carlo Methods . . . . . . . . . . . . . . . . . . . . 137
6.14.5 Coding Theory . . . . . . . . . . . . . . . . . . . . . . . . 138
Background
The use of advanced mathematical methods has become increasingly signicant
for many modern engineering disciplines. As many of these methods nowadays
are computer-aided, their ecient use requires apart from underlying theoretical
knowledge also familiarity with relevant software packages. The aim of these
notes is to combine these two into an engineering introduction to computer-aided
mathematics, with emphasis on symbolic manipulation.
We will use the freeware applications wxMaxima for symbolic calculation
and Octave for numerical calculation. Our main focus for both of these is based
on command-driven use, although the former of these also features interactive
menus and initialization windows. The reason for this is that menu-driven use of
the software is to large extent self-instructive and our preference to learn how to
program batch computations later on. Therefore, we choose to leave the details
for using integrated menus to the interested student and proceed to a survey
of the relevant commands involved in the themes treated in this course. In our
attempt to awake interest for further learning, we will start with a minimal
introduction to Maxima and later to Octave.
Both Maxima and Octave invoke the public-domain graphics package Gnu-
plot for visualizing computation results. The graphs produced this way cannot
be as readily customized as by using Gnuplot in a standalone fashion, however.
For example, if graphs are intended for use in a L
A
T
E
X-document, correct fonts
and formulas can be produced by exporting the data from Maxima and Octave
to Gnuplot and using its features for L
A
T
E
X-typesetting independently of Max-
ima or Octave. Information on how to proceed with this can be found in the
documentation for Gnuplot.
9
10 CONTENTS
Chapter 1
An Overview of wxMaxima
1.1 Introduction
wxMaxima is a system, consisting of the core code package Maxima that does
the actual computations and an interactive user interface based on so called
x-widgets. The main working prupose is to handle expressions, such as x + y,
sin(a+b), and uvvu. It is up to the user whether an expression is meaningful
or not, however, manilpulations can be done without assigning numerical values
to variables and parameters.
Maxima belongs to a category of mathematics software known as computer
algebra systems or CAS for short. This implies that Maxima is a tool primarily
for manipulation of mathematical objects as symbols rather than as numerical
entities. The package Octave, which will be introduced later during the course,
is more suitable for doing numerical computation.
Running wxMaxima opens an interactive window with several dierent menus
and shortcuts across the headbord. These, which are designed for utilities as
well as for dierent types of calculations, will be discussed in detail later. Com-
mands can be entered both through submenus invoked by these and by using
the command prompt. In earlier versions of wxMaxima, the command prompt
is visible throughout, however, in later versions various prompts are chosen from
Cell in the Edit-menu with shortcuts:
F5 New Input Cell
F6 New Text Cell
F7 New Subsection Cell
F8 New Section Cell
F9 New Title Cell
For these, hitting Enter in the earlier version corresponds to choosing Evaluate
All Cells from the same submenu or the shortcut Ctrl-R. For instance, the result
11
12 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
Figure 1.1: The wxMaxima graphical interface.
displayed in Figure 1.1 can be rendered in L
A
T
E
Xby selecting Display TeX-form
from the Maxima-menu to give:

2 i +

sin 1 +

2 i

cos 1

erf

2 i+

2 i

sin 1 +

2 i +

cos 1

erf

2 i

8
1.2 Examples
In the following, we will take a look at some brief examples on the use of
wxMaxima.
Example 1.2.1. The command stardisp controls the way wxMaxima displays
the operation of multiplication. Setting
(%i1) stardisp:true;
will show all multiplications with an asterisk. The value false shows products
with a blank space, which can distracting in more complicated expressions.
Example 1.2.2. The sequence
(%i2) V:4/3 * %pi * r^3;
1.3. EXPRESSIONS 13
assigns the value
4r
3
3
to the name V . Names in Maxima are also termed iden-
tiers. The value of the name r (for radius) is itself , in place of a specic
numerical value, at this point that is, r is r. Note that the number pi is en-
tered using the Maxima special character %pi. Now, we assign the value r = 10
to the radius
(%i3) r:10;
As seen, the way to assign a specic value to a name is by using a colon character
(:) and not the symbol equal to. We can think of this as assigning equality
by denition. So, we dened the value of V to be equal to the expression above
and the radius equal to 10, demonstrating that names may be assigned dierent
kinds of objects. It should be noted that V does not change after assigning a
numerical value to the radius r - it is still an expression. If we want to evaluate
this expression with the value assigned to r, we use double single quotes according
to:
(%i5) V;
This results in r = 10 being substituted into the expression for V and the nu-
merical constants, except , being simplied (also try what happens if the as-
signment r = 10 is done before assigning the expression to V !). All irrational
numbers having similar special symbols, i.e. starting with % are treated like
this in Maxima. In a situation where we want a numerical result, however, an
approximation has to be used for . This is done as follows:
(%i6) V, numer;
producing a oating-point number approximation for the volume V .
1.3 Expressions
Essentially everything in Maxima is expressions, which can be divided into three
types or classes:
(1) Mathematical expressions
(2) Object expressions
(3) Programming constructs
A Maxima expression is built up from atoms and operators with corresponding
arguments.When an expression is evaluated, the result is its value which can
dier from the expression itself. This was illustrated above. For example, in
the expression 1 +2, we have the operator + (the binary operator of addition).
The two arguments to this operator are literal numerals in the form of the
two atoms 1 and 2. The expression sin(x) consists of an operator with one
argument, the single letter symbol x an atom in the form of a literal name.
14 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
The value of x may be itself if no other value has been assigned x is x, or x
is, e.g., 10 (from the input x:10).
An atom can be a name (a character symbol like V , x and r above), a string
enclosed in quotation marks (e.g., "volume" and "radius"), or a numeral such
as an integer or decimal number like 1, -5, 3.14159, etc.
Expressions in Maxima not consisting of atoms are termed non-atomic
and can be represented as op(a1, . . . , an), where op is an operator and
(a1, . . . , an) are its n arguments. This format is also used internally
by Maxima, including the basic arithmetic operations such as addition, sub-
traction, multiplication and division which are input conventionally using the
symbols + * - /. These are seen by Maxima in the form op(a,b) for ex-
ample 1 + 2 is represents op(1,2), where "op" is the appropriate operation for
addition. Similar operators are used for function evaluation, e.g., in connection
with trigonometric and special functions.
More complex mathematical expressions may involve combinations of names,
literal numerals, and operators. Literal numerals include constants with special
Maxima names such as %pi and %e. As listed above, in Maxima objects are also
expressions.
Example 1.3.1. A list [a1, . . . , an] of n objects is an object expression.
These can be created with the operation (oplist) = and arguments. In the case
of a matrix object, which also is an expression, we have ( op = matrix ):
matrix(list((a1,1), (a1,2),. . . , (a1,n))
, . . . , list((am,1), (am,2),. . . , (am,n)))
These arguments are non-atomic, they are list object expressions each of which
may or may not be composed of atoms. The value of these expressions is the
list object or the resulting matrix object.
Observation 1.3.2. While all expressions have a value, the value of an ex-
pression may be lost unless the expression is assigned a name using the the
: operator. Merely entering an expression as Maxima input will result in the
display of the value of the expression (unless suppressed), and then the object
and its value passes out of existence. Sometimes this is okay, for example when
Maxima is being used as a symbolic calculator. However, Maxima has a built-in
feature that mitigates this issue signicantly.
The special Maxima name % is assigned the value of the last entered expres-
sion and may be used like any name assigned a value. Of course, the value of
% changes with each new expression entered as input. The values of each en-
tered expression are saved in the special names prexed as %o with a sequential
numeral for each line of output These %o names (e.g, %o1, %o2, ..., %on)
may be used in Maxima expressions as names with the values of the displayed
output.
The downside to the frequent use of this feature is that these generic names
generated by Maxima have little if any literal signicance. One can easily recog-
nize that V means volume and r means radius, but what does %*(%o7-%o5)/%o3
signify?
1.3. EXPRESSIONS 15
Programming constructs are also expressions. A code block is represented
internally to Maxima as an expression with an operator and arguments. Hence, a
conditional statement (if a then b elseif c then d) is represented as if (a, b, c, d)
and a loop (for a in L do S) as mdoin(a, L, S).
Maxima has two functions to help evaluate what kind an expression is. The
function atom(expr) takes an expression as an argument and indicates whether
this is simply atomic. The function op(expr) returns the overall operation of
an expression if it is not simply atomic. Expressions of this class have values
which vary according to the type of programming construct. For example, the
value of a loop expression may be done while the value of a block expression
is the value of the last argument listed.
Example 1.3.3. Maxima expressions
1. Atoms are symbols, strings, and numbers. Below, we have a various of
these grouped into a list:
(%i9) [a, foo, foo_bar, "Hello, world!", 42, 17.29];
2. Mathematical expressions
(%i10) [a + b + c, a * b * c, foo = bar, a*b < c*d];
These may simply be combinations of atoms and operators or may also be
relations between expressions. For example foo = bar is considered to be
a mathematical expression. This expression does not say that foo is equal
bar, instead it is merely a logical relation between (in this case two atoms)
the names foo and bar. The relation between the two names holds only
when their values are the same, resulting in the value true and otherwise
false.
3. Object Expressions Lists and matrices The elements of a list or matrix
can be any kind of expression, even another list or a vector/matrix.
(%i11) L:[a, b, c, %pi, %e, 1729, 1/(a*d - b*c)];
This input is a list object expression assigned to the name L. The elements
of this list are all atoms except the last which is a mathematical expression.
Now, look at the input.
(%i12) L2:[a, b, [c, %pi, [%e, 1729], 1/(a*d - b*c)]];
16 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
This is a dierent list object expression assigned to the name L2. The last
element is itself a list object consisting of two atoms, another list object
and a mathematical expression. These objects result in index names being
created when assigned to a name. The values are accessed by appending
brackets to the object name:
(%i13) L[7];
which returns the seventh element of the list L. Similarly,
(%i14) L2[3];
returns the third element of the list L2, which is in itself a list. The
assignment
(%i15) M:matrix ([%pi, 17], [29, %e]);
denes the matrix M =
_
17
29 e
_
. It is also possible to assign matrices
with elements consisting of submatrices:
(%i16) M2:matrix ([[%pi, 17], a*d - b*c],
[matrix ([1, a], [b, 7]), %e]);
The submatrix
_
1 a
b 7
_
on the second row, rst column can be references
with the command:
(%i18) M2[2][1];
Example 1.3.4. Programming constructs
These are expressions such as x : y which means assign y to x; the value
of the assignment expression is the value of y. There is probably no better
example of the dierence between an expression and its value than this object.
This expression is always non-atomic, but its value is atomic if the value of y
is atomic.
The block operation groups several expressions, and evaluates them one af-
ter another; the value of the block operation expression is the value of the last
expression of the block. Try to guess the value of the expression below before
entering it as input.
(%i19) ("a block", a:42) - ("another block", b:17);
1.3. EXPRESSIONS 17
We observe that this expression is the dierence between the values of two block
expressions. The string atoms that are the rst argument of each block do noth-
ing. They are unassigned atoms and they pass out of existence after the value
of the statement is displayed. Their purpose is to merely serve as arguments to
demonstrate a block expression. This input does two things in one statement.
First, it assigns 42 to the name a and 17 to the name b, and then it performs the
dierence operation using the value of these assigment statements as arguments.
However, an assignment is not itself an operation. Entering op(a:42) results in
an error message. This is because Maxima sees a:42 as an atom. The input
atom(a:42) and the value is true. (a:42) - (b:17) is merely a mathematical
expression with two atoms as arguments. The value of this expression is 25. If
you input op((a:42) - (b:17)) the result is +. This peculiarity is due to the
fact that Maxima is true to mathematics in the sense that subtraction is dened
in terms of the sum of a and the additive inverse of b ab means by denition
a + (b).
The result of
(%i20) [a, b];
illustrates that the although the string atoms of the block expressions were lost,
and the block expressions themselves are gone, the names a and b have values
that persist. This is a list expression object formed using the atoms a and b as
arguments with values 42 and 17 respectively.
Consider
(%i21) block ([a], a: 42, a^2 - 1600) + block ([b], b: 5, %pi^b);
This is a Maxima block programming construct object expression formed using
two block operations ( op = block) with the arguments as shown. Notice that
the block operation returned the value of
a^2 - 1600 + block ([b], b: 5, %pi^b) ,
where the last term in this argument was also a block operation. It returned a
value of %pi^5 this was added to the 164 from the result of 42
2
1600 = 164
to yield the nal output of
5
+ 164. Moreover
(%i22) (if a > 1 then %pi else %e) + (if b < 0 then 1/2 else 1/7);
shows two programming object expressions as arguments to the addition opera-
tion. The characteristic operation of this expression is addition op = +. The
arguments are the two if operations that result in the two values and
1
7
that are
the addends of the total expression. Note that the arguments to the if operations
(op is if) may be relational mathematical expressions (a > 1) and (b < 0).
These are evaluated as arguments in this case. What is interesting to note is
that because the overall operator of this expression is +, this is a mathematical
expression in the end. The values of the op = if expressions are atomic
and
1
7
. The expressions themselves are non-atomic.
18 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
1.3.1 Utility Functions
These functions demonstrate how Maxima works and we have already seen ex-
amples of their use. The function op(expr) returns the overall (or character-
istic) operator of a expression while args(expr) returns the arguments, and
atom(expr) tells whether an expression is an atom.
Example 1.3.5. Lets try the following:
(%i23) op(p + q);
The result of this is +. When an expression contains more than one operator,
the outermost of these is obtained:
(%i24) op(p + q > p*q);
Similarly when we have nested functions; the outer function is picked up:
(%i25) op(sin (p + q));
We can also pick up the operator of a function dened in the same expression,
e.g.,
(%i26) op(foo (p, q) := p - q);
gives the assignment operator :=.
The corresponding utility for picking up function arguments is the function
args, try
(%i27) args(p + q);
giving [q,p]. A composite expression like
(%i28) args(p + q > p*q);
yields [q+p,p*q]. A curiosity is revealed when we try
(%i29) args(foo (p, q));
for the function dened above. It turns out that Maxima interprets subtraction
as addition of the corresponding number with opposite sign. In this case the
result is [p,-q]. As already noted, the function atom returns true for an
expression being purely atomic and false otherwise, e.g.,
(%i30) atom(p);
(%i31) atom(p + q);
(%i32) atom(sin (p + q));
1.3. EXPRESSIONS 19
1.3.2 Expression Construction
The single quote tells Maxima to construct an expression but suppresses eval-
uation of the expression. It is important to note the dierence between the
assignment operator :, evaluation and the single quote. This is illustrated in
the following
Example 1.3.6. Consider the results of the following inputs.
(%i33) x:2+3;
(%i34) x;
(%i35) x;
(%i36) op(x);
(%i37) op(x);
(%i38) x;atom(x);
(%i39) x;atom(x);
The results of the above show that the value of an expression and its constructed
value may be dierent even if both are atoms.
Example 1.3.7. Consider the assignment
(%i40) x:if p > q then p else q;
In this case, x itself is the assigned expression, while the single quote results in
just x. Compare the results of the following:
(%i41) op(x);
(%i42) op(x);
So, there is a dierence between value and constructed value also for non-atomic
expressions.
Observe that x is atomic but (if p > q then p else q) is not. The
former does not return an operator as already seen and the latter returns the
operator if. The expression using the if programming construct is constructed
as an argument to op, but it is not evaluated it remains a non-atomic expres-
sion. Thus the characteristic operation of this expression is op = if. In a
situation where p and q are atoms with certain values, the value of the expres-
sion (if p > q then p else q) is dierent from its constructed value:
(%i43) p:3;q:%pi;(if p > q then p else q);(if p > q then p else q);
Now, we consider a block programming construct
20 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
(%i44) args((block ([a], a: 42, a^2 - 1600)));
(%i45) (block ([a], a: 42, a^2 - 1600));
(%i46) (block ([a], a: 42, a^2 - 1600));
In the rst case, [[a], a: 42, a^2 - 1600] are returned, in the second case
the declaration of the construct and in the last case the value 42
2
1600 = 164.
The expression using the block programming construct is constructed as an
argument to args, but it is not evaluated it remains a non-atomic expression.
Thus the arguments of this expression are the elements of the list returned as
output. The constructed expression has a value of itself. The value of the
expression is 164.
For our previous conditional programming construct, we try
(%i47) args((if p > q then p else q));
yielding the list [p>q,p,true,q].
1.4 Evaluation
In Maxima, the value of a symbol (name or identier) is an expression associated
with the symbol. Every symbol has a value and if not otherwise assigned a value,
a symbol evaluates to itself e.g., x evaluates to x.
1.4.1 Evaluation of Atomic and Non-Atomic Expressions
Numbers and strings are atoms and always evaluate to themselves. Names are
atoms and evaluate to themselves or to an assigned value an expression which
may be atomic or non-atomic.
Non-atomic expressions are evaluated approximately as follows:
1. Each argument of the operator of the expression is evaluated.
2. If an operator is associated with a callable function, the function is called,
and the return value of the function is the value of the expression.
1.4.2 Modications of Evaluations
Expressions can be modied in ways that cause less or more evaluation. Less
evaluation is obtained by using certain functions that do not evaluate som of
their arguments. A single quote character () as a prex prevents evaluation,
but not construction of an expression see the section above about expression
construction.
More evaluation is caused by using two single quotes (), resulting in an
extra evaluation at the time the expression is parsed as input. This means that
modication occurs only at input time for expressions prexed with . When
applied to a general expression (e.g., expr), the value of expr is substituted for
expr in the input. The function ev(a) causes an extra evaluation of a every time
1.4. EVALUATION 21
ev(a) is evaluated. apply(f, [a1, a2, . . . , an]) causes the evaluation
of the arguments (a1, . . . , an) even if f ordinarily quotes them. The
function define(f (a1, . . . , an), expr)constructs a function denition
like f(a1, . . . , an) : = expr, but evaluates the function body ( expr )
while := does not.
The following sections explain and provide some examples of evaluation.
1.4.3 Defaults and Argument Evaluation
Symbols evaluate to themselves if not otherwise assigned a value. If assigned
a value names evaluate to those values. Consider a block expression assigning
values to the names a, b and e. The return value is the value of the last
expression in the block e = 5 in this case. These are atoms.
(%i48) block(a: 1, b: 2, e: 5);
Arguments of operators are ordinarily evaluated unless evaluation is prevented
in some way. Look at the assignment
(%i49) block(x: %pi, y: %e);
(%i50) x;y;
We have a block expression assigning values to the names x and y. As previously,
the return value is the value of the last expression in the block %e in this case.
The arguments were evaluated. Hence the return value for x of %pi and not x.
In the case of a function, such as
(%i51) sin(x + y);
we see that the function is evaluated according to the trigonometric identity
sin( + e) = sin ( + e) = sine. An expression containing a relation, e.g.,
(%i52) x > y;
evaluates using values assigned to the names x and y. The return value is the
expression itself with the the assigned values of the names x = %pi and y = %e.
To nd out if > e is true we can use
(%i53) is(x>y);
For comparison, try
(%i54) is(x=y);
To illustrate the dierence between default evaluation and calculation of numer-
ical value for a function, consider the factorial function
(%i55) x!;
(%i56) x!, numer;
In the latter case, a numerical evaluation based on the well-known relation
between the gamma- and factorial functions takes place:
n! = (n + 1) =
_

0
e
t
t
n
dt .
22 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
1.4.4 Callable Functions
All operators consisting of callable functions result in calls to those functions.
If this is prevented, another expression with the same operator is obtained.
Consider the function denition
(%i57) foo(p, q) := p - q;
This is a callable function, i.e., if we assign the value
(%i58) p: %phi;
(%i59) q: %pi;
Here, %pi is and %phi is a reserved name for the constant ratio
_
1+

5
2
1.618034
_
of the golden mean. Now, try the calls
(%i60) foo(p, q);
(%i61) foo(p, q), numer;
We observe that the value of the call to foo is the value of the evaluated argu-
ments ( p and q) applied to the expression used to dene the function foo. For
comparison, we call
(%i62) bar(p, q);
The function bar is not callable with arguments p and q it has not been as-
signed any expression, merely created as a name. The value of bar is hence itself.
In spite of this, the arguments (p and q) are evaluated however as displayed.
1.4.5 Automatically Quoted Arguments
Some functions quote their arguments automatically. Such built-in functions
are save(), := and kill(), which means that these by deafault behave like a
single quote being passed as a prex to their argument. Hence, if foo is called
as foo(p,q) the result is p-q and not %phi-q.
Try, e.g.,
(%i63) [foo(p,q),foo(p, q),foo(p, q)];
(%i64) block(a: 1, b: %pi, c: x + y);
(%i65) [a, b, c];
We note that in the last two lines of input the arguments of the expressions
were evaluated automatically. The function
save(filename, name1, name2, name3, ...)
(%i66) save("tmp.save", a, b, c);
1.4. EVALUATION 23
stores data in ther form of Lisp expressions the current values of name1, name2,
..., in filename. The arguments are the names of variables, functions, or other
objects and the value returned for save is filename. This function evaluates
filename and quotes all other arguments here names a, b, and c. The le
temp.save has the following as contents:
;;; -*- Mode: LISP; package:maxima; syntax:common-lisp; -*-
(in-package :maxima)
(DSKSETQ $A 1)
(ADD2LNC $A $VALUES)
(DSKSETQ $B $%PI)
(ADD2LNC $B $VALUES)
(DSKSETQ $C ((MPLUS SIMP) $%E $%PI))
(ADD2LNC $C $VALUES) ]
In this le there is a single quote prexed to the arguments and the arguments
are not evaluated. For a and b this is no huge issue since these are atoms to be-
gin with so they are the same whether or not evaluated. However, c is shown in
the le as having a value of $C ((MPLUS SIMP) $%E $%PI)) which is the con-
structed argument expression in the form of an op = + with arguments (%e,%pi).
Eectively, the above call is equivalent to save("tmp.save", a, b, c) only
here the quoting of arguments is automatic.
Consider the function and call
(%i67) f(a) := a^b;
(%i68) f(7);
The function f is dened using the := operation. The argument a and name
b are not evaluated in the value for f(a). However, the call f(7) results in
the evaluation of argument a and name b. Note that the value of a was set
to 1 above (a:1) but it is evaluated in the function call as an argument to f
and the value in this scope for a is 7. Moreover, the value of b was set to %pi
above (b:%pi) but it is not evaluated. Remember, the assignment := does not
evaluate the function body as an argument to a function denition statement
a and b are both part of the function body here.
All names dened by the user are displayed with the command
(%i69) values;
The kill function removes the values from the arguments, it does not evaluate
the arguments the return value of kill is done.
(%i70) kill(a, b, c, x,expr,L,L2);
The names in the argument are killed by this statement and their values thus
lost. The command values displays a list of all bound user names. The list
comprises symbols assigned expressions using : , ::, or :=.
24 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
(%i71) values;
Using values again shows that the killed names are no longer listed and their
values removed. The list expression [a,b,c] references these names again, but
these have no value assigned and are not saved as bound names.
1.4.6 Preventing Evaluation
A single quote prevents evaluation even if it would ordinarily happen. Consider
the function denition and evaluation
(%i72) foo(x, y) := y - x;
(%i73) block(a: %e, b: 17);
(%i74) foo(a, b);
The foo function returns the value of the evaluated arguments when called.
The call
(%i75) foo(a, b);
however, returns the function value with arguments unevaluated but instead
with their names. Furthermore, calling
(%i76) foo(a, b);
results in foo(%e,17). Here, the function itself is single quoted and hence not
evaluated, although the arguments ( a and b ) are. The returned value is the
function with the evaluated arguments. If we, instead of single quoting just the
function name, quote the entire function call:
(%i77) (foo(a, b));
we will get a result similar to what is obtained from the call foo(a, b);.
1.4.7 Extra Evaluation
Two single quotes ( or quote-quote) causes an extra evaluation at the time
the expression is parsed. Dierentiating the function sinx with respect to x is
done by
(%i78) diff(sin (x), x);
The function call diff(expr,x) returns the derivative (or dierential) of expr
with respect to the variable x. The result is cos x, as expected. Let us dene
our own function that does this dierentiation:
(%i79) foo(x) := (diff(sin (x), x));
This function returns the derivative from the built-in function diff. Recall that
the := operation does not evaluate the function body, i.e., exprx in f(x):=exprx
where exprx is some expression that denes the function, presumably involving
the argument name x . Evaluation in this case can be accomplished as:
1.4. EVALUATION 25
(%i80) foo(x) := (diff(sin (x), x));
Our function foo(x) is now redened with diff(sin(x),x) prexed by two
single quotes which returns the evaluated derivative (or dierential) of expr
with respect to the variable x. The result of the evaluation of diff(sin(x),x)
is cos(x).
Using ev(expr) causes an extra evaluation every time it is itself evaluated.
Contrast this with the eect of quote-quote() above:
The function block here assigns yy to the name xx and then zz to the name
yy.
(%i81) block(xx: yy, yy: zz);
(%i82) [xx, yy];
From the second input line, we see that both are evalated to their assigned
values. Now, we dene a function that uses the double quote to force evaluation:
(%i83) foo(x) := x;
The two single quotes prexed to x cause an extra evaluation of x when the
function foo(x) is called. Since x has no value then, the function denition
foo (x) := x is returned:
(%i84) foo(x);
Now, keeping in mind that xx was assigned the value yy which in turn was
assigned the value zz, try the call
(%i85) foo(xx);
This produced the value yy of the rst assignment. Remember that arguments
are evaluated when a function is called with arguments. We now dene a func-
tion using the ev operator
(%i86) bar(x) := ev (x);
This function denition for bar(x) uses the ev(expr) function instead of two
single quotes. This means that ev(expr) is retained as part of the function
denition for bar(x) as expected. When bar(expr) is called the argument
expr will be evaluated as an argument and then by ev(expr):
(%i87) bar(xx);
Here, the expression xx is evaluated as xxyy as the argument to bar(expr).
Then, because the function is dened using ev(expr) this is equivalent to
ev(yy), which returns the value of yy being zz. This is what we mean by
saying that ev(expr) is evaluated each time it is called.
26 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
1.4.8 Arguments
The function apply(f,[a1,a2,...,a]) causes the evaluation of arguments to
the function f in the list even if they are ordinarily quoted by f. In general,
some functions deal with certain arguments as though they are prexed by the
single quote character . Arguments are evaluated when a function is called
with arguments, although some functions deviate from this by single quoting
some arguments. For example, if the function f(x) is called with exprx as an
argument exprx is evaluated.
Example 1.4.1. Consider, e.g.,
(%i88) block(a: aa, b: bb, c: cc);
(%i89) block(aa: 11, bb: 22, cc: 33);
(%i90) [a, b, c, aa, bb, cc];
The two block expressions above assign aa to a, bb to b, and cc to c, then 11
to aa, 22 to bb and 33 to cc. The list expression above displays these values.
Now, try evaluating arguments to the kill-function:
(%i91) apply(kill, [a, b, c]);
The input kill(a,b,c) would not ordinarily result in the evaluation of argu-
ments, the function would only be applied to a, b and c. However, with the
above use of apply(), the arguments to kill will be evaluated. In this case the
result is the same as from calling kill(aa,bb,cc), as seen from the list:
(%i92) [a, b, c, aa, bb, cc];
The result of using apply with the is that the names a, b and c retain their
values aa, bb and cc, respectively. However, the names aa, bb and cc now
have the default values of themselves respectively as their assigned values were
killed. On the other hand, when kill is called with the arguments a, b and c
directly:
(%i93) kill(a, b, c);
their values are killed, as seen from:
(%i94) [a, b, c, aa, bb, cc];
Now, all the names assigned values above have lost these and assume default
values.
To summarize, we may think of the apply function (apply(f,[x]) as apply
to the function f the evaluated argument x.
1.5. SIMPLIFICATION 27
1.4.9 Arguments
Using define(f,[a1,a2,...,an],expr) evaluates the expression (expr) that
is body of the function denition. This is an alternative way to using the form
of f(a1,a2,...,an]):= expr to dene a function. In this case expr is not
evaluated. The define() function defeats this behavior.
Example 1.4.2. Let us do the denite integral
_

0
sin (ax) dx =
1 cos (a)
a
.
This is accomplished by the call
(%i95) integrate(sin (a*x), x, 0, %pi);
The nal form of the result can be obtained after simplication, using the call
(%i96) ratsimp(integrate (sin(a*x), x, 0, %pi));
Now, use this expression to dene a function:
(%i97) foo(x) := integrate(sin(a*x), x, 0, %pi);
Hence, the function foo(x) is dened as the same symbolic denite integral.,
but we see that the expression dening foo is not evaluated. In contrast, using
define() yields:
(%i98) define(foo (x), integrate(sin(a*x), x, 0, %pi));
In this case, the expression dening foo is evaluated. A shorter route to the
simplication we already looked at is
(%i99) ratsimp(define(foo(x), integrate(sin (a*x), x, 0, %pi)));
Let us next assign a value to the parameter a:
(%i100) block(a:3, define(foo (x), integrate(sin(a*x), x, 0, %pi)));
So, as well as the integral the value of the nal result is evaluated when define()
is applied.
Consequently, we may think of the function (define(f,[x],exprx) or
define(f(x),exprx)) as dene a function named f with the argument x as
the evaluated expression exprx.
1.5 Simplication
After evaluating an expression, Maxima attempts to nd an equivalent expres-
sion which is simpler. Maxima applies several rules for what is meant by
simplication. For example, 1 + 1 simplies to 2, x + 4 simplies to 2x, and
28 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
sin simplies to 0. However, many well-known identities are not applied auto-
matically. Such are, e.g., double-angle formulas for trigonometric functions, or
rearrangements of ratios such as
a
b
+
c
b
=
a+c
b
. These identities can be applied by
use of Maxima-functions and user-dened simplication rules can be specied
with the function tellsimpafter.
Remark 1.5.1. Simplication is a matter of convention to some degree. Most
people agree on what simpler means in most expression contexts. However,
on some points what is simpler is a matter of personal preference or convention.
Why are fractions expressed in lowest terms simpler? One answer is because
someone said so. Another answer could be because the numerals of the numer-
ator and denominator are the smallest and so forth.
1.5.1 Examples of Maxima Simplication
The following are some examples of simplication:
(%i101) [1 + 1, x + x, x * x,
sin(%pi),(a + b)^2,(a/b + c/b),
sin(2*x),a * exp(b * %i)];
The expressions in the above list of elements are simplied according to the
Maxima rules of simplication.
A quote single quote character as a prex prevents evaluation but not sim-
plication. When the global ag simp is false, simplication is prevented but
not evaluation.
(%i102) [1 + 1, x + x, x * x, sin(%pi),
(a + b)^2,(a/b + c/b),sin(2*x),
a * exp (b * %i)];
Remark 1.5.2. It is important to make clear the dierence between evaluation
and simplication. Recall that evaluation is a process that results in an ex-
pression in terms of the values of the ingredients (atoms and non-atoms) of an
expression. Simplication is an equivalent form of an expression that is simpler
by some criteria.
With simp set to false, we can try the following
(%i103) [1 + 1, x + x, x * x, sin(%pi),
(a + b)^2,(a/b + c/b),sin(2*x),
a * exp(b * %i)];
(%i104) block([x: 1], x + x);
and we observe that the expressions in the list and block statement are not
simplied. The automatic simplication can be switched on again, e.g., with
the command
(%i105) kill(all)$simp:true$
which clears values from names and sets the simplication ag to true.
1.6. SPECIAL PURPOSE FUNCTIONS 29
1.5.2 Exceptions to Maxima Simplication
As mentioned, some identities are not applied automatically. In these cases user
input is required in order to simplify certain expressions. Some functions which
apply identities that may result in simpler expressions are expand(), ratsimp(),
trigexpand() and demoivre(). Consider, e.g., the quadratic expression
(%i106) (a + b)^2;
To expand this expression, we must invoke the function
(%i107) expand((a + b)^2);
Neither is the sum
(%i108) a/b + c/b;
simplied automatically. Simplication of rational expressions is done by invok-
ing the function
(%i109) ratsimp(a/b + c/b);
Expandable trigonometric functions, like the sine for the double angle
(%i110) sin(2*x);
can be handled with the function
(%i111) trigexpand(sin(2*x));
Dealing with complex exponential functions is customarily done with the use
of Eulers formula:
e
i
= cos + i sin .
In Maxima, the exponential
(%i112) a * exp(b * %i);
is expanded according to Eulers formula by calling the function
(%i113) demoivre(a * exp (b * %i));
1.6 Special Purpose Functions
1.6.1 Applying arguments to functions
As have seen above in the examples of this function, the function
apply(f,[x1, x2, ... , xn])
constructs and evaluates an expression in the form of f(arg1, arg2, ... , argn)
where arg = x1, arg2 = x2, ... , argn = xn. The arguments of the expression
are always evaluated. Next, we construct sin(x) by applying x to the sine
function, after clearing all values from names:
30 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
(%i114) kill(all)$
(%i115) apply(sin, [x * %pi]);
Now, create the list
(%i116) L1:[a, b, c, x, y, z];
Addition of the elements in this list can now be done by applying addition to
the list, according to
(%i117) apply("+", L1);
Similarly, we can nd the smallest element of a list with
(%i118) L2:[1, 5, -10.2, 4, 3];
(%i119) apply(min,L2);
If we have a user-dened function
(%i120) F(x) := x / 1729;
we can assign F as a value to the name and display the function denition
(%i121) fname:F;
(%i122) dispfun(F);
The value of fname is now F. However, the call dispfun(fname) would produce
an error message since fname is not the name of the user-dened function. The
correct way to use dispfun in this case is
(%i123) apply(dispfun, [fname]);
1.6.2 The mapping function
Using the map() function constructs and evaluates an expression for each item in
a list of arguments. The arguments of the expression are always evaluated and
the result is a list object, consider a yet undened function foo and addition:
(%i123) kill(all)$
(%i124) map(foo, [x, y, z]);
(%i125) map("+", [1, 2, 3], [a, b, c]);
For the latter, note that the length of the lists must be the same or an error will
result since + is a binary operation. Mapping the atom()-function (checks
whether the argument is an atom or not) like
(%i126) map(atom, [a, b, c, a + b, a + b + c]);
yields true for the rst three arguments an false for the other two, since those
are expressions, not atoms.
1.7. BUILT-IN OBJECT TYPES 31
1.6.3 The lambda-function
Using lambda() denes and returns a lambda expression, i.e., an unnamed or
anonymous function. The lambda expression can be used in some contexts like
an ordinarily named function. However, lambda does not evaluate the function
body. Try the function call
(%i127) f:lambda ([x, y], (x + y)*(x - y));
Here, the name f is assigned the lambda expression. No function is dened and
no evaluation takes place. However, the call f(a, b) returns the value of the
lambda expression as though it were a function even though there is no function
named f. Instead f has the value of the lambda expression, as seen from:
(%i128) f;
We can apply the expression named by f to the elements of the argument list
(%129) apply(f, [p, q]);
We can apply the lambda expression named by f to pairwise elements, e.g., by
mapping it to two equally long lists, according to:
(%i130) map(f, [1, 2, 3], [a, b, c]);
We get a list of three expressions, one for each pair a and 1, b and 2 and c
and 3.
As we have seen, a lambda function is a means to have a name behave as a
function without being dened as a function.
1.7 Built-in object types
Objects are represented as expressions, which are made up of an operator and
its arguments. The most important built-in object types are lists, matrices, and
sets.
1.7.1 Lists
1. A literal list is indicated like this: [a, b, c].
2. If L is a list, L[i] is element i of the list.
3. map(f , L) applies f to each element of L.
4. apply("+", L) is the sum of the elements of L.
5. for x in L do expr evaluates expr for each element of L.
6. length(L) is the number of elements in L.
32 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
Example 1.7.1. (%i131) L:[a, foo, foo_bar, "Hello, world!", 42, 17.29];
(%i132) L[1];L[3];
(%i133) map(display,L)$
(%i134) apply("+",L);
(%i135) apply("+",[1,2,3,4]);
(%i136) for e in L do display(e)$
(%i137) length(L);
1.7.2 Matrices
1. A matrix is dened as:
matrix(L1 , . . . , Ln )
where L1 , . . . , Ln are lists which represent the rows of the matrix.
2. If M is a matrix, M [i, j] or M [i][j] is element (i,j).
3. The operator . represents non-commutative multiplication. M.L, L.M and
M.N are non-commutative products, where L is a list and M and N are
matrices.
4. transpose(M) is the transpose of M.
5. eigenvalues(M) returns the eigenvalues of M.
6. eigenvectors(M) returns the eigenvectors of M.
7. length(M) returns the number of rows of M.
8. length(transpose(M)) returns the number of columns of M.
Example 1.7.2. Consider a matrix and various operations of referencing its
elements:
(%i138) M:matrix([a, b, [c, %pi, {%e, 1729, 1/(a*d - b*c)}]]);
(%i139) M[1,1];M[1,3];
(%i140) M[1,3][3];
1.7. BUILT-IN OBJECT TYPES 33
The third element of the matrix M is a list. The above expression has a value of
the third element of that list a set object. Let us assign a matrix, by specifying
row vectors, and look at two ways of referencing elements and how to take the
transpose
(%i141) M:matrix([1,2],[3,4]);
(%i142) M[1,1];M[2][2];
(%i143) transpose(M);
Assign a larger, 3 3-matrix, and look at how to extract the number of rows
of a matrix. In this case we determine the number of columns by taking the
tranpose:
(%i144) M:matrix([1,2,3,4],[5,6,7,8]);
(%i145) length(M);length(transpose(M));
Consider a 2 2-matrix and compute its eigenvalues and eigenvectors:
(%i146) M:matrix([4,1],[3,2]);
(%i147) eigenvalues(M);
(%i148) X:eigenvectors(M);
We see that the eigenvalues of the matrix M =
_
4 1
3 2
_
are
1
= 1 and

2
= 5. The eigenvectors are x
1
=
_
1
3
_
x
2
=
_
1
1
_
. We also note that the
function eigenvectors() returns the eigenvalues as well in an output list with
the eigenvectors.
1.7.3 Sets
1. Maxima understands explicitly-dened nite sets. Sets are not the same
types of objects as are lists. Thus an explicit conversion is needed to
change one into the other.
2. A set is specied like this: {a,b,c, ... } where the set elements are
(a,b,c, ...). An alternative way to specify a set is to use the set func-
tion as in set(a,b,c, ... ).
3. union(A, B) is the union of the sets A and B.
4. intersection(A, B) is the intersection of the sets A and B.
5. cardinality(A) is the number of elements in the set A.
34 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
Example 1.7.3. Consider the set
(%i149) {9,8,7,6,5,4,3,2,1};S:{f,e,d,c,b,a};f;
Oops! The name f was assigned a lambda expression previously. Thus the name
f evaluates to this value when S is assigned the set object expression. Let us
redene some sets and make some set calculations
(%i150) kill(all)$S:set(f,e,d,c,b,a)$f;
(%i151) S;
(%i152) (A:{1,3,5,7,9},B:{1,2,4,6,8,9},union(A,B));
(%i153) intersection(A,B);
(%i154) cardinality(union(A,B));cardinality(S);
1.8 Maxima Programming
In Maxima, there is one and only one name space, which contains all Maxima
symbols. Parallel name spaces are not possible. All variables are global unless
are explicitly declared as local variables. Functions, lambda expressions, and
blocks can have local variables. The value of a variable is whatever was assigned
most recently, either by explicit assignment or by assignment of a value to a local
variable in a block, function, or lambda expression. This policy is known as
dynamic scope. If a variable is a local variable in a function, lambda expression,
or block, its value is local but its other properties (as established by declare)
are global. The function local() makes a variable local with respect to all
properties. By default a function denition is global, even if it appears inside a
function, lambda expression, or block. local(f ), f (x) : = . . . creates a
local function denition. trace(foo) causes Maxima to print an message when
the function foo is entered and exited.
We now consider some examples of Maxima programming.
Example 1.8.1. All variables are global unless they appear in a declaration
of local variables. Functions, lambda expressions, and blocks can have local
variables.
(%i155) (x: 42, y: 1729, z: foo*bar)$
(%i156) f(x, y) := x*y*z;
The name z does not appear in as a argument of the function f and it was
assigned the mathematical expression foo*bar. Then, with respect to f the
name z is global.
1.8. MAXIMA PROGRAMMING 35
(%i157) z;
(%i158) f(aa, bb);
When f is evaluated with x aa and y = b, these names are local to f and the
name z is not. Note that Maxima rearranges the order of the names that are the
factors of the value of f(aa,bb) alphabetically as shown above. The factors that
are the value of the global name z (foo and bar) appear in that order together
with the argument values for f, i.e., x and y which are aa and bb, respectively.
The global names x and y with values 42 and 1729 are not relevant to f.
Let us try an anonymous lambda expression, to which two names are applied:
(%i159) lambda([x, z], (x - z)/y);
(%i160) apply(%, [uu, vv]);
The anonymous lambda is assigned (as a feature of Maxima) as a value to the
name %. This name is used to reference the lambda expression in the next expres-
sion as an argument to the apply() function. The name y was not referenced
as part of an argument to the lambda expression. Therefore it is global with
respect to the value of the name %. The names x and z were referenced as part
of the arguments to the lambda expression and so these names are local with
respect to the value of the name %. The global value of y is evaluated in the
above expression as 1729. The global values of x and z (42 and foo*bar) are
irrelevant to the expression.
Try the block operation
(%i161) block([y, z], y: 65536, [x, y, z]);
Because the name z is referenced in the rst argument of the block operation
that is a list, it becomes local to the block. The last argument which is returned
is the value of the list [x,y,z]. The name x is global and has a value of 42.
The name y is local to the block having been assigned a value of 65536. The
name z is local to the block for the reason above but was assigned no value in
the block. Hence the value of z is itself and that is what is returned.
Example 1.8.2. The value of a variable is whatever was assigned most recently,
either by explicit assignment or by assignment of a value to a local variable.
(%i162) foo(y) := x - y;
(%i163) x:1729;
When foo(y) was assigned the expression x-y above the value of x was itself.
Here x is now explicitly assigned the atom 1729. If we call foo with the argument
y = %pi
(%i164) foo(%pi);
36 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
the result is our function expression with the explicitly assigned atom 1729 as
the value of x. Recall that callable functions are evaluated when referenced.
Dene the function dependent on x through foo as:
(%i165) bar(x) := foo (%e);
(%i166) bar(42);
Now the function bar(x) is dened using the value of the expression foo(%e),
which is x-%e. Recall that the expression of a function dened with := is not
evaluated by default. This explains why bar is x-%e and not 42-%e. The name
x is assigned the value 42 as a name local to bar when it is called as bar(42).
This is the most recent assignment of a value to x. Therefore when f(%e) is
evaluated in the context of bar the value of x is 42 and not 1729.
1.8.1 Branching
The if statement is used for conditional execution. The syntax is:
if <condition> then <expr_1> else <expr_2>
The result of an if statement is expr_1 if condition is true and expr_2 oth-
erwise. expr_1 and expr_2 can be any Maxima expressions (including nested
if statements), and condition is an expression which evaluates to true or false
and is composed of relational and logical operators which are as follows:
Operation Symbol Type
less than < relational inx
less than
or equal to <= relational inx
equality (syntactic) = relationall inx
negation of
equality relational inx
equality (value) equal relational inx
negation of
equality notequal relational inx
greater than
or equal to >= relational inx
greater than > relational inx
and and logical inx
or or logical inx
not not logical prex
1.8.2 Iteration
The do statement is used for performing iteration. Due to its great generality
the do statement will be described in two parts. First, the usual form will be
1.8. MAXIMA PROGRAMMING 37
given which is analogous to that used in several other programming languages
(Fortran, Algol, PL/I, etc.); then we move on to the other features.
There are three variants of this form that dier only in their terminating
conditions. They are:
for variable: initial_value step increment thru limit do body
for variable: initial_value step increment while condition do body
for variable: initial_value step increment unless condition do body
(Alternatively, the step may be given after the termination condition or limit.)
initial_value, increment, limit, and body can be any expressions. If the
increment is 1 then step 1 may be omitted.
The execution of the do statement proceeds by rst assigning the initial_value
to the variable (henceforth called the control-variable). Then:
(1) If the control-variable has exceeded the limit of a thru specication, or
if the condition of the unless is true, or if the condition of the while is
false then the do terminates.
(2) The body is evaluated.
(3) The increment is added to the control-variable.
The process from (1) to (3) is performed repeatedly until the termination con-
dition is satised. One may also give several termination conditions in which
case the do terminates when any of them is satised.
In general the thru test is satised when the control-variable is greater than
the limit if the increment was non-negative, or when the control-variable is
less than the limit if the increment was negative. The increment and limit
may be non-numeric expressions as long as this inequality can be determined.
However, unless the increment is syntactically negative (e.g. is a negative
number) at the time the do statement is input, Maxima assumes it will be
positive when the do is executed. If it is not positive, then the do may not
terminate properly.
Note that the limit, increment, and termination condition are evaluated
each time through the loop. Thus if any of these involve much computation,
and yield a result that does not change during all the executions of the body,
then it is more ecient to set a variable to their value prior to the do and use
this variable in the do form.
The value normally returned by a do statement is the atom done. However,
the function return may be used inside the body to exit the do prematurely
and give it any desired value. Note however that a return within a do that
occurs in a block will exit only the do and not the block. Note also that the go
function may not be used to exit from a do into a surrounding block.
The control-variable is always local to the do and thus any variable may be
used without aecting the value of a variable with the same name outside of the
do. The control-variable is unbound after the do terminates.
Example 1.8.3. Various loops.
38 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
(%i1) for a:-3 thru 26 step 7 do display(a)$
a = - 3
a = 4
a = 11
a = 18
a = 25
(%i1) s: 0$
(%i2) for i: 1 while i <= 10 do s: s+i;
(%o2) done
(%i3) s;
(%o3) 55
Note that the condition while i < = 10 is equivalent to unless i > 10 and
also thru 10.
(%i1) series: 1$
(%i2) term: exp (sin (x))$
(%i3) for p: 1 unless p > 7 do
(term: diff (term, x)/p,
series: series + subst (x=0, term)*x^p)$
(%i4) series;
7 6 5 4 2
x x x x x
(%o4) -- - --- - -- - -- + -- + x + 1
90 240 15 8 2
which gives 8 terms of the Taylor series for e
sin (x)
.
(%i1) poly: 0$
(%i2) for i: 1 thru 5 do
for j: i step -1 thru 1 do
poly: poly + i*x^j$
(%i3) poly;
5 4 3 2
(%o3) 5 x + 9 x + 12 x + 14 x + 15 x
(%i4) guess: -3.0$
(%i5) for i: 1 thru 10 do
(guess: subst (guess, x, 0.5*(x + 10/x)),
if abs (guess^2 - 10) < 0.00005 then return (guess));
(%o5) - 3.162280701754386
This iteration computes the negative square root of 10 using Newton-Raphson
iteration a maximum of 10 times. Had the convergence criterion not been met
the value returned would have been done.
Instead of always adding a quantity to the control-variable one may some-
times wish to change it in some other way for each iteration. In this case
one may use next expression instead of step increment. This will cause the
1.8. MAXIMA PROGRAMMING 39
control-variable to be set to the result of evaluating expression each time through
the loop.
(%i6) for count: 2 next 3*count thru 20 do display (count)$
count = 2
count = 6
count = 18
As an alternative to
for variable: value ...do...
the syntax
for variable from value ...do...
may be used. This permits the from value to be placed after the step or
next value or after the termination condition. If from value is omitted,
then 1 is used as the initial value.
Sometimes one may be interested in performing an iteration where the control-
variable is never actually used. It is thus permissible to give only the termination
conditions omitting the initialization and updating information as in the follow-
ing setting to compute the square-root of 5 using a poor initial guess.
(%i1) x: 1000$
(%i2) thru 20 do x: 0.5*(x + 5.0/x)$
(%i3) x;
(%o3) 2.23606797749979
(%i4) sqrt(5), numer;
(%o4) 2.23606797749979
If it is desired one may even omit the termination conditions entirely and just
give do body which will continue to evaluate the body indenitely. In this case
the function return should be used to terminate execution of the do.
(%i1) newton (f, x):= ([y, df, dfx], df: diff (f (x), x),
do (y: ev(df), x: x - f(x)/y,
if abs (f (x)) < 5e-6 then return (x)))$
(%i2) sqr (x) := x^2 - 5.0$
(%i3) newton (sqr, 1000);
(%o3) 2.236068027062195
(Note that return, when executed, causes the current value of x to be returned
as the value of the do. The block is exited and this value of the do is returned
as the value of the block because the do is the last statement in the block.)
One other form of the do is available in Maxima. The syntax is:
for variable in list end_tests do body
40 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
The elements of list are any expressions which will successively be assigned
to the variable on each iteration of the body. The optional termination tests
end_tests can be used to terminate execution of the do; otherwise it will ter-
minate when the list is exhausted or when a return is executed in the body. (In
fact, list may be any non-atomic expression, and successive parts are taken.)
Example 1.8.4. Alternative form of do-loop
(%i1) for f in [log, rho, atan] do ldisp(f(1))$
(%t1) 0
(%t2) rho(1)
%pi
(%t3) ---
4
(%i4) ev(%t3,numer);
(%o4) 0.78539816
1.9 Some Useful Flags
We have already seen use of the ag simp. There are several other system
variables that work in a similar way.
Example 1.9.1. For example, when exptdispflag is true, Maxima displays
expressions with negative exponents using quotients, e.g., x
1
as
1
x
. This is
done when simp is turned on, as seen from the calls below
(%i167) kill(all)$
exptdispflag:true;
(%i168) simp:false$
x^-1;
a*x^-2*y*z^-1;
simp:true$
x^-1;
a*x^-2*y*z^-1;
exptdispflag:false$
(%i169) 1/x;
Example 1.9.2. The function display (arg_1, arg_2, ...) displays iden-
tities for which the left side is each one of the arguments unevaluated, and whose
right side is the value of the expression centered on the line. This function is use-
ful in blocks and for statements in order to have intermediate results displayed,
consider:
(%i170) display(sqrt((x*y^2*((x*y^3))^(1/4))^(1/3)));
1.9. SOME USEFUL FLAGS 41
Note that an equality is displayed with the left hand side (lhs) being the uneval-
uated expression of the argument the right hand side (rhs) being the evaluated
expression with applicable simplication. The displayed output is an expression
itself (an equality relation expression) and that this expression is lost after it is
displayed since the value of the display function is done and not this equation
expression. To see this we use the rhs() function on the output % variable which
should return the right-hand side of a relation expression:
(%i171) rhs(%);
The result is 0. This makes sense since the rhs of the expression done is 0. A
way to get around this is to use the ldisplay() function:
ldisplay (arg1, arg2, ... , argn)
This function displays the argument expressions to the console as printed output.
Each expression is printed as an equation of the form lhs = rhs in which lhs is
one of the arguments of ldisplay and rhs is its value. The ldisplay() function
assigns an intermediate expression label to each equation and returns the list of
labels. The labels hold the value of the equation expressions.
(%i172) ldisplay(sqrt((x*y^2*((x*y^3))^(1/4))^(1/3)));
(%i173) %t172;
(%i174) rhs(%t172);
The expression resulting from the ldisplay() function is not done, rather it
is a labeled name %t172 in this case. This name holds the value of the equation
expression that was the result of the ldisplay() function and works like any
other name it has an expression as a value. The rhs() function results in an
expression that is the right hand side of the equation relation.
There are many useful Maxima ags (option variables) that may be used to
alter the behavior of Maxima and its functions in order to get desired results.
Refer to the Maxima Manual for a complete description of these ags and func-
tions. This how-to has demonstrated the use of a few of these. The last one
now follows:
Example 1.9.3. %edispflag
When %edispflag is true, Maxima displays the Napier number %e to a neg-
ative exponent as a quotient.
(%i175) %e^-2;
%edispflag:true$
%e^-2;
42 CHAPTER 1. AN OVERVIEW OF WXMAXIMA
1.10 Summary
The above sections cover most of the material of the Minimal Maxima document.
We have postponed many more specic how-to examples to separate treatment
later on.
The above examples and explanation do not exhaust all the features appli-
cable to Maxima basics. Enough has been demonstrated to be of use to the
most common purposes. The reader is directed to the Maxima documentation
related to set objects and related topics for more information and examples.
Chapter 2
Symbolic Calculation
We will continue here with wxMaxima and take a closer look at some useful
applications for various mathematical tasks an engineer would encounter in re-
search and routine computation. Focus will be on use of Maxima with the wx
graphical user interface and we are not attempting to include all the ne points
that would be available with a procient command-line use of the program.
Our goal is getting started with wxMaxima through the GUI. Since most cor-
responding command-line functions are shown simultaneously when the menus
are used, a heavy-user of the package is bound to learn these gradually along
the line.
2.1 Initialization
wxMaxima can be congured through the edit menu of the main GUI by choos-
ing congure and the desired options from the submenus. For example, ticking
the option for evaluating input cells at pressing enter is a handy adjustment to
the defaults. This menu also makes it possible to customize the appearance of
wxMaxima, such as fonts, input/output formats and numbering/indexing.
To get help with a name used by Maxima, just type ? name. For example,
the command
? integrate
launches a Maxima help dialog for the function integrate. Sometimes the help
nder does not match your entry exactly, then there will be a list of matches at
the left to choose from.
Maxima uses some nonintuitive syntax for assigning a value to a label. Here
are the rules:
Rule 2.1.1. Assigning values.
: used to assign a value to a variable: a : 3;, a : b; etc.
43
44 CHAPTER 2. SYMBOLIC CALCULATION
Figure 2.1: The conguration menu of wxMaxima.
= used to compare values for equality: a = 3; etc., moreover < (less than),
> (greater than) and (unequal).
:= used to dene a function: f(x) := x^2;
kill(name);= used to erase a previous assignment of a variable or function: kill(a);,
kill(f);
kill(all);= used to erase all assignments.
The order of precedence in computations is the customary: (1) powers (^)
and roots ( sqrt( )), (2) multiplication ( * ) and division ( / ) and (3) addi-
tion ( + ) and subtraction ( - ). To override this order, it is necessary to use
parentheses.
Example 2.1.2. Reserved numbers and display settings.
%pi; (this will appear as a Greek letter only if a Greek font has
been installed, see "Installation")
float(%pi); (meaning "give me the numerical value")
3.141592653589793
fpprec:1000; (increase the "floating point precision" or "fpprec")
1000
float(%pi); (again, "give me the numerical value")
3.141592653589793 (no change in the number of displayed places. Why?)
2.2. SAVING AND LOADING 45
bfloat(%pi); ("bfloat" means "big float")
3.1415926535897932384626433832[943 digits]
3001927876611195909216420196b0 (better, but not what I was hoping for)
set_display(ascii); (this is a special wxMaxima setting that forces all
the digits to be printed out)
set_display(ascii);
bfloat(%pi); (try again)
(a list of 1000 digits of pi)
set_display(xml); (return to the default way of displaying things)
set_display(xml);
The fpprec and set_display(ascii) settings only aect oating-point
numbers, integers are always printed out fully. The character % always refers
to the nearest prior result. To list all the digits of a oating-point value, we must
use set_display(ascii) and if we want wxMaxima to render equations and
functions in a pretty way, we can use set_display(xml). This will display
greek letters etc., however, it requires installation of greek fonts.
2.2 Saving and Loading
Assume we are in a work session and have produced some variable denitions
and functions worth keeping. Maxima saves this work using the command:
stringout("my_work.txt",values,functions);
This will save all dened variables and functions in a plain-text le, suitable for
editing and re-use in a later Maxima session. In the above example, the le will
be saved under our home directory, which if we are running Linux, typically
is /home/(username)/. Unfortunately, because of a programming error, un-
der Windows the le will be saved under the wxMaxima installation directory,
which is typically C:/Program Files/Maxima-(version)/wxMaxima/. One
can only hope this error will be corrected in a future version of wxMaxima
so the default directory for le operations will be the users home directory,
C:/Documents and Settings/(username)/.
Assuming we have made entries into Maxima in a particular order, and those
entries and their order is important we would like to preserve what we typed:
stringout("my_input.txt",input);
This saves an unedited list of everything you have typed since beginning your
Maxima session. To be useful, it might be edited, or parts of it extracted into
another le. But this form creates a record of all your inputs for later reference.
In case we don not recall all details and simply would like to save everything,
we can enter:
stringout("everything.txt",all);
46 CHAPTER 2. SYMBOLIC CALCULATION
Other options for this command are values and functions.
The two most useful loading commands are batch() and batchload().
These funny-sounding names go back to the early days of Fortran, when a
batch was a stack of 80-column program and data cards, and computers were
gigantic boxes kept in airtight rooms manned by people in white lab coats.
This naming style tells us how long Maxima, and its predecessor Macsyma,
have been around. There are any number of ways to create les suitable for
Maxima loading. One obvious way is to save a le as shown above, using
stringout(filename,values,functions);. Such a le is quite suitable
for reloading into Maxima, and it will restore all your denitions. Another
way is to write Maxima code into a le, then load it. In this approach, one
might extract useful sections from saved data les, and create new entries to
accomplish a particular goal. An easy way to go about this is to have a text
editor and wxMaxima running at once. One would type something into the text
editor, save the le in its current form, then turn to wxMaxima and issue one
of these two commands:
batch("everything.txt");
(to see each instruction as it is executed)
batchload("everything.txt");
(to load and execute instructions silently)
The second option above is quieter, but it will still print out results and create
graphs. Once a program is working, bug-free and has become a useful tool, the
second loading option is preferred.
Example 2.2.1. Now for an example of loading and running a Maxima program
le. Here is a listing of a very simple routine that prints a multiplication matrix:
for y:1 thru 12 do
(s:"",
for x:1 thru 12 do
s:sconcat(s,printf(false,"~4d",x*y)),
print(s));
To get this into Maxima, use your browser to save the le on your computer,
and provide the path and lename to Maxima using the batchload() com-
mand: batchload("/path/to/example/file.txt");. If you have done this
correctly, the following display will appear:
1 2 3 4 5 6 7 8 9 10 11 12
2 4 6 8 10 12 14 16 18 20 22 24
3 6 9 12 15 18 21 24 27 30 33 36
4 8 12 16 20 24 28 32 36 40 44 48
5 10 15 20 25 30 35 40 45 50 55 60
6 12 18 24 30 36 42 48 54 60 66 72
7 14 21 28 35 42 49 56 63 70 77 84
8 16 24 32 40 48 56 64 72 80 88 96
2.3. FUNCTIONS AND EQUATIONS 47
9 18 27 36 45 54 63 72 81 90 99 108
10 20 30 40 50 60 70 80 90 100 110 120
11 22 33 44 55 66 77 88 99 110 121 132
12 24 36 48 60 72 84 96 108 120 132 144
Windows note: Because of a programming error in wxMaxima at the time of
writing, you will have to use a full path to tell wxMaxima where your browser
put the le. Most likely it will be located here:
C:/Documents and Settings/(username)/My Documents/maxima_mult_matrix.txt
There are some le saving and loading features in wxMaxima that create
and read les with the sux .wxm, these represent an easy way to save and
load an entire session.
2.3 Functions and Equations
2.3.1 Functions
In the simplest cases, one can create a useful function with a few keystrokes:
average(a) := sum(a[i],i,1,length(a))/length(a)
As explained above, this denition will be saved along with all other user-dened
content with the command stringout(filename,values,functions). The
reason for creating functions is to encapsulate and name useful operations and
algorithms, just as the reason for creating variables is to encapsulate and name
useful values. Look at another example, there is no log10(x) function in
Maxima (or most other software), because there is no pressing need for this
to be explicitly dened. But there almost always is a log(x) function that
produces a natural logarithm for its input argument. Thus, we can dene the
function:
log10(x) := log(x)/log(10.0);
A test:
log10(1e6);
5.999999999999999
Not perfect (why?). It has to do with conversion between binary and decimal
number bases.
Not all function writing is as straightforward as the above example. It some-
times happens that one would like to capture the result of a prior calculation
and make it into a new function. This is a bit more complex. Take at look at:
a*x^2+b*x+c=0;
a x2 + b x + c = 0
solve(%,x);
48 CHAPTER 2. SYMBOLIC CALCULATION
At this point we need to introduce a new practice. To avoid a lot of confusion as
these examples get more complex, we save intermediate results under distinctive
variable names:
eq:a*x^2+b*x+c=0;
a x2 + b x + c = 0
sol:solve(eq,x);
This variable assignment will turn out to be very important below. Now we
want to capture the quadratic solution created above and put it into a function
that will accept any arguments for a, b and c, and produce numerical results
for numerical arguments. Omitting the details of how Maxima organizes and
stores its results, it should suce to say that we have saved the two roots of the
quadratic equation in a list named sol, and the list can be accessed by way of
an index. Like this:
sol[1];
sol[2];
Now, we can access the two roots independently. But for use in a function
denition, we need to get rid of the x = part of the expression. Try:
rhs(sol[1]);
rhs(sol[2]);
Build a function out of these pieces:
quad(a,b,c) := [ rhs(sol[1]), rhs(sol[2]) ];
Okay, we seem to have created the function. Let us test it:
quad(1,2,3);
This is wrong. We should have seen each appearance of a, b and c replaced with
the numerical values provided in the function call. The reason for this failure is
subtle, but included here because it is a common problem. Here is the solution:
quad(a,b,c) := ev([ rhs(sol[1]), rhs(sol[2]) ]);
This change works because the right-hand expression is evaluated (ev()) be-
fore being assigned to the function denition, and the evaluation replaces refer-
ences to list contents with the contents themselves. Test this new form:
quad(1,2,3);
Correct! (note the presence of i, which signies that the result is complex).
Now we can enter any desired arguments to our new quad() function and get
the two roots of the quadratic equation for those values. To reduce the output
to simple numeric quantities, we need only express it this way:
float(quad(1,5,3));
2.3. FUNCTIONS AND EQUATIONS 49
Just to demonstrate how powerful this approach can be, make some small edi-
torial changes in the above example:
eq:a*x^3+b*x^2+c*x+d = 0;
sol:solve(eq,x);
cubic(a,b,c,d) := ev([rhs(sol[1]),rhs(sol[2]),rhs(sol[3])]);
Remember about these examples that declaring a function in the default way
f(x) := x^2;
f(x) := x2
is only guaranteed to work in the simplest cases. Remember that the func-
tion ev() (meaning evaluate) can be used to solve some of the more dicult
assignment problems.
2.3.2 Equations - A Practical Application
We proceed to show how a single equation can be used to construct a set of
related equations. On this basis a set of functions can be created to solve an
entire class of problems.
Example 2.3.1. Future Value
In nance and banking, there is an equation that can be used to compute
the future value of an annuity not surprisingly it is called the future value
equation. It has several variations. One variation arises from the fact that a
payment into an annuity might be made at the beginning of the payment period,
or the end. Two forms of the future value equation exist to take this distinction
into account:
Payment at beginning:
fv =
(ir + 1) pmt (ir + 1)
np
(irpv + irpmt + pmt)
ir
,
Payment at end:
fv =
pmt (ir + 1)
np
(irpv + pmt)
ir
,
where
pv = Present value of the annuity, the account balance at the beginning of the
annuity term.
fv = Future value of the annuity, the account balance at the end of the annuity
term.
np = Number of payments into the annuity during its term.
pmt = Payment amount made during each period of the annuity.
50 CHAPTER 2. SYMBOLIC CALCULATION
ir = Interest rate per period.
There are a few important things to be aware of when dealing with nancial
equations. One is that amounts withdrawn from an annuity have a positive
sign, amounts deposited into an annuity have a negative sign. Adverse interest
rates have a negative sign. Another important point is that the interest rate
is per period, not per year or per term, so a 12 % annual interest rate means
1 % per period (assuming monthly payments), and the correct numerical value
for 1 % is 0.01, not 1. Each of the above variables can be positive or negative
numbers. A negative present value implies a deposit made at the beginning of
the annuitys term. A negative payment amount implies a net inow of cash
during each period. A negative interest rate implies an interest deduction from
the accounts balance each period. Here is an example annuity computation:
pv = 0
np = 120
pmt = -100
ir = 0.01
These values describe an annuity such as an investment, with a favorable in-
terest rate of 1 % per period, a deposit of 100 currency units per period, and
120 payment periods. For these values, and assuming payment at the end of
each period, the future value will be 23, 003.87 currency units (rounded to the
nearest
1
100
). For the case of payment at the beginning of the period, the future
value will be 23, 233.91 currency units. The reader can check these results using
a spreadsheet program, most of which have an FV() function available. Here are
typical spreadsheet entries for this problem:
Spreadsheet Entry Result Comment
=FV(0.01;120;-100;0;0) 23,003.87 Payment at end.
=FV(0.01;120;-100;0;1) 23,233.91 Payment at beginning.
Now, we want to create functions for each of the variables in the future value
equation, so we can solve for any value in an annuity. And it would be nice to
be able to deal with the issue of payment at beginning or end without having to
write two sets of equations. The rst step in our project is to create a meta-
equation that accommodates the issue of payment at beginning or end. The new
equation deals with this issue by including a new variable pb that makes the
equation switch between modes. Here is the meta-equation:
eq:fv=((pb*ir+1)*pmt-(ir+1)^np*((pb*ir*pmt)+pmt+ir*pv))/ir;
Now for a sanity check. Can we derive the two forms of the future value equation
from this meta-equation, simply by setting the value of of the variable pb? Lets
see:
eq; (lets check to see if the equation was read correctly)
pb:0; (set pb = 0, meaning payment at end)
ev(eq); (use "evaluate" to interpret the equation)
2.3. FUNCTIONS AND EQUATIONS 51
pb:1; (set pb = 1, meaning payment at beginning)
ev(eq); (use "evaluate" to interpret the equation)
Perfect result. Note that a variable that assumes values of zero or one can be
used as a switch, in eect adding or removing terms from an equation. The
function ev() simplies equations that are submitted to it, and in this case,
if the pb variable is set to zero, ev() eliminates any terms that are multiplied
by it. If the pb variable is set to one, the ev() function retains the associated
terms and eliminates only the pb variable itself. The meta-equation in essence
recreates the two canonical forms of the future value equation, and applying the
ev() function proves this. But its important to note that, even without this
term elimination, the original meta-equation will still deliver correct results if
the pb variable is set to zero or one to convey the users intentions. This idea
seems to be successful at setting the value of the pb variable in the meta-equation
appears to recreate the two original forms of the future value equation. This will
greatly reduce the number of required equation forms and the overall complexity
of the project.
Now we can create all the forms the future value equation can take, based on
the variables within it. First, some keyboard entries to make sure this approach
will work:
kill(pb); (remove any assignment to pb)
eq; (is our equation still present?)
sol:solve(eq,pv); (solve for variable pv, present value)
rhs(sol[1]); (isolate the body of the solution for use in a
function declaration)
It seems we can create versions of the meta-equation to provide results for each
of the variables in the original equation. Now write a function that automates
the process of solving for specic variables and isolating the desired expression:
solve_for_var(eq,v) := ev(rhs(solve(eq,v)[1]),fullratsimp);
The reader will appreciate that I have skipped over a few details in the design
of this function. The solve_for_var() function solves for a particular vari-
able, isolates the required expression, prepares it for assignment to a function
description, and simplies it (fullratsimp) if possible. Such a function has
the advantage that its actions are encapsulated, they dont have to be entered
repeatedly, and further, if a change is made to the algorithm, the change only
needs to be entered in one location to have an eect on all the derivations. Hav-
ing written a function to create equations for each of the variables, we can now
simply and quickly produce all the desired functions:
fpv(fv,np,pmt,ir,pb) := solve_for_var(eq,pv);
ffv(pv,np,pmt,ir,pb) := solve_for_var(eq,fv);
fnp(fv,pv,pmt,ir,pb) := solve_for_var(eq,np);
fpmt(fv,pv,np,ir,pb) := solve_for_var(eq,pmt);
fir(fv,pv,np,pmt,pb) := solve_for_var(eq,ir);
52 CHAPTER 2. SYMBOLIC CALCULATION
NOTE: The interest rate case cannot be solved in closed form, and the function
declaration is only present for completeness ... Even though there is a derivation
for ir, the interest rate, it turns out this case is not soluble in closed form,
as Isaac Newton discovered in his second career as Chancellor of the Exchequer,
during which time he applied his substantial mathematical gifts to the mundane
problems of nance. I only include the derivation to reveal something about
symbolic math packages. On occasion they will very happily produce meaningless
results. And if the resulting function is tested, it will ... well, how shall I say
this? ... go completely nuts. Try it:
fir(23003.87,0,-100,120,0);
This produces a huge display of garbage results. The reason for the crazy be-
havior? Simple solve() didnt really solve this one. The result created by
solve() has ir terms on both sides of the equals sign. An error message
would have been more convenient, but no symbolic math packages are perfect,
and Maxima is, after all, free. In normal practice, computing interest rates
involves a root nding approach using another form of the equation.
2.4 Evaluating Limits
Maxima is very good at evaluating limits. For example, to calculate
L = lim
x0
1 cos x
x
we can use the menu Calculus in the GUI or simply invoke the command:
limit((1-cos(x))/x, x, 0);
A one-sided limit, e.g.,
L = lim
x0
+
1 cos x
x
can be evaluated with
limit((1-cos(x))/x, x, 0, plus);
Similarly, the other one-sided limit can be evlauated with the option minus.
The names +inf and -inf for inf and +inf, respectively. For limit that
does not exist, Maxima returns ind or infinity. For a limit that does exist
and is innite, Maxima returns +inf or -inf. Finally, we look at a case
with a limit of an expression containing absolute values.
Example 2.4.1. The limit
lim
x0
x
2
+|x|
x
2
|x|
can be evaluated according to
limit((x^2+abs(x)/(x^2-abs(x))), x, 0);
2.5. DIFFERENTIAL CALCULUS 53
2.5 Dierential Calculus
wxMaxima can be used for dierentiating expressions and factoring the deriva-
tives. For example, consider the function
f(x) =
_
x
2
+ 3x + 2
_
2
(x + 1)
2
To nd f

(x) and f

(x) and simplify the resulting expressions, we can choose


from the GUI menus Calculus/Dierentiate and Simplify/Factor Expression
twice. In the dialog box, we can choose how many times to dierentiate, how-
ever, since we want both derivatives, we choose to dierentiate once repeatedly.
The corresponding command lines are:
f(x) := ( x^2 + 3*x + 2 )^2 * ( x + 1 )^2;
diff(f(x),x,1);
factor(%);
fp(x) := %;
diff(fp(x),x,1);
factor(%);
fpp(x) := %;
As mentioned earlier, % refers to the previous result and the double quote in the
asssignments for fp(x) and so on makes Maxima execute the dierentiation
and evaluate the expression. Numerical values for f

and f

can now be obtained


by referencing, e.g., fp(3/2) for a rational form and float( fp(3/2) ) for
oating-point value.
We now continue with a look at dierential equations. A dierential equation
is an equation expressing the relationship between a function and one or more of
its derivatives. When the equation is supplemented with an initial condition, we
have an initial value problem. When we have one or more boundary conditions,
we are dealing with a boundary value problem.
Example 2.5.1. A dierential equation with initial condition.
y(t) +rcy

(t) = b ,
y(0) = a .
In the rst equality, we see that an unknown function y(t) is added to its deriva-
tive y

(t), which is scaled by the two constant parameters r and c. In the second
equality, an initial value is assigned to the function y(t). The meaning of this
statement is that, when t = 0, y(t) = a. Unlike numerical equations, dierential
equations describe dynamic processes, i.e., things are changing. The derivative
term y

(t) describes the rate of change in y(t). If the variable t represents time
(although this is just an interpretation). At time zero, the function y(t) equals
a, therefore at that moment the derivative term y

(t) is equal to
ba
rc
. Notice that
y

(t), which represents the rate of change in y(t), has its largest value at time
zero. Because of how the equation is written, we see that the value of y

(t) (the
54 CHAPTER 2. SYMBOLIC CALCULATION
rate of change) becomes proportionally smaller as y(t) becomes larger. Even-
tually, for some very large value of t, the rate of change represented by y

(t)
becomes arbitrarily small, as y(t) approaches the value of b, but never quite gets
there. Put very simply, this equation describes a system in which the rate of
change in the value of y(t) depends on the remaining dierence between y(t)
and b, and as that dierence decreases, so does the rate of change. As it hap-
pens, this equation is used to describe many natural processes, among which are:
Electronic circuits consisting of resistors and capacitors (hence the terms r and
c), where the voltage on a capacitor changes in a way that depends on the cur-
rent owing through a resistor, and the value of the resistors current depends
on the voltage on the capacitor. Heat ow between a source of heat energy and
a cooler object being heated by it (like a pot on a stove). In such a system, the
temperature of the heated body changes at a rate that depends on the remaining
dierence in temperature between the two bodies. The rate of gas ow between
two pressure vessels with a constricted passage between them. In this system
also, the rate of gas ow depends on the remaining pressure dierence, and the
pressure dierence declines over time. This is by no means a comprehensive
list of applications. But the statements for a dierential equation are only the
beginning, and not all dierential equations have analytical solutions (solutions
expressible in closed form, consisting of normal mathematical operations). Oth-
ers require numerical methods and are only soluble in an approximate sense.
Lets see if Maxima can nd a solution for this equation. Here are the steps:
eq:y(t)+r*c*diff(y(t),t)=b;
atvalue(y(t),t=0,a);
sol:desolve(eq,y(t));
f(t,r,c,a,b) := ev(rhs(sol));
Note the way the equation and initial condition are dened in the rst two lines.
A higer derivative
d
n
y(t)
dt
n
can be dened with the command diff(y(t),t,n),
where the prime is included to force evaluation of the derivative when the equa-
tion is solved in the third line. From the fourth line we now have a function
that embodies the solution to our dierential equation. We can use it to solve
real-world problems. Heres an example from a eld in which I have spent a lot
of time electronics.
Example 2.5.2. R-C circuit diagram
In this experiment, we have an electronic circuit consisting of a resistor and a
capacitor. At time zero, we close a switch that connects our circuit to a battery,
we then use an oscilloscope to measure the voltage on the capacitor over time
(cf. the diagram 2.2). Here are the Maxima instructions to set up and graph
the response of the described circuit:
r:10000;
c:100e-6;
a:0;
b:12;
2.5. DIFFERENTIAL CALCULUS 55
Figure 2.2: An RC-circuit.
wxplot2d(f(t,r,c,a,b),[t,0,5],
[gnuplot_preamble, "set grid;"],
[nticks,12]);
We proceed to study a little more complex dierential equation belonging
to the same general class.
Example 2.5.3. Wave-driven equation
Consider an inhomogeneous dierential equation driven by a continuous
waveform. This could also be an R-C circuit, or any natural system in which
there is a path of resistance to the ow of something cyclical. Here are the
command lines:
eq:y(t)=-r*c*diff(y(t),t)+m*sin(%omega*t);
sol:desolve(eq,y(t));
There is a problem with this solution - the group of terms at the right includes
the familiar e

t
rc
expression that appears in equations with dened initial values.
But, because this equation describes a continuous process with no beginning and
no end, we need to set the conditions at time zero in such a way that all times will
be treated equally (and the right-hand subexpression will be eliminated). After
mulling this over, we decide the correct way to characterize the initial conditions
would be to submit the right-hand expression as a negative value at time zero,
which has the eect of preventing the assignment of a special time-zero value.
Here is that entry and the outcome:
init_val:-(c*m*r*(%e^-(t/r*c))*%omega)/(c^2*r^2*%omega^2+1);
atvalue(y(t),t=0,init_val);
sol:desolve(eq,y(t));
f(t,r,c,%omega,m) := ev(rhs(sol),fullratsimp,factor);
/* simplify, factor and declare a function */
56 CHAPTER 2. SYMBOLIC CALCULATION
Figure 2.3: A sinewave-driven RC-circuit.
We now have a working embodiment of this equation, and it turns out this
form has as many real-world applications as the earlier example. Here is another
electronic example using an R-C circuit, but this time with a sinewave generator
driving our circuit:
m:1;
f:440;
r:1000;
c:0.05e-6;
%omega:2*%pi*f;
wxplot2d([sin(%omega*t),f(t,r,c,%omega,m)],[t,0,.005],
[gnuplot_preamble, "unset key;
set title f = 440 Hz, r = 1000, c = 100 uf"]);
2.5.1 Computation of Solutions with the Laplace Trans-
formation
The Laplace transformation is a powerful tool to solve a vast class of ordi-
nary dierential equations. The principle is simple: The dierential equation
is mapped onto a linear algebraic equation, which is solved. The solution of
the algebraic equation is then mapped back onto the solution of the given dif-
ferential equation. The mathematical theory of the Laplace transformation is
not trivial, but for practical purposes it is often sucient to simply apply the
transformation.
The Laplace transformation maps a transcendental function onto a rational
expression in a new variable:
laplace(exp(-b*t)*cos(w*t),t,s);
s + b
--------------------
2 2 2
w + s + 2 b s + b
assume(w > 0);
[w > 0]
2.5. DIFFERENTIAL CALCULUS 57
Without that assumption, Maxima would ask later whether w is zero or nonzero.
The inverse Laplace transformation maps a rational expression onto a tran-
scendental function:
ilt(%, s, t);
- b t
%e cos(t w)
The knowledge of these functions is almost sucient to solve an ordinary dif-
ferential equation:
ode: diff(y(t), t, 2) + 5*diff(y(t), t) + 4*y(t) = t;
Recall the importance of writing a quoted diff to represent the derivative as
well as writing the function y with its formal argument: y(t). It is not sucient
to write diff(y, t, 2)
2
d d
--- (y(t)) + 5 (-- (y(t))) + 4 y(t) = t
2 dt
dt
Next, we specify the initial conditions. We do that with the function atvalue:
atvalue(y(t), t=0, 0);
0
atvalue(diff(y(t), t), t= 0, 0);
0
Now we can compute the Laplace transform of the equation:
lap_ode:laplace(ode,t,s);
2
s laplace(y(t), t, s) + 5 s laplace(y(t), t, s) +
1
4 laplace(y(t), t, s) = ---
2
s
This is a linear equation in the unknown laplace(y(t), t, s). We solve it
with solve:
sol: solve(%, laplace(y(t), t, s));
Note that you have to write the unknown with a quote. Without the quote,
Maxima would try to evaluate the expression laplace(y(t), t, s).
1
[laplace(y(t), t, s) = ----------------]
4 3 2
s + 5 s + 4 s
58 CHAPTER 2. SYMBOLIC CALCULATION
The answer is a list with one equation, the solution of the linear equation. Now,
we can apply the inverse Laplace transformation. To apply apply a transforma-
tion to the elements of a list, we have to use map:
map( lambda( [eq], ilt(eq, s, t)), sol);
- t - 4 t
%e %e t 5
[y(t) = ----- - ------- + - - --]
3 48 4 16
This is again a list with one equation. Note that the inverse Laplace transfor-
mation was applied to both sides of the equation: On the left hand side, the
application of the inverse Laplace transformation to the Laplace transformed of
y(t) yields y(t). On the right hand side, the application of the inverse Laplace
transformation yields the solution of the given dierential equation. It is of
course possible to solve this ordinary dierential equation with the command
ode2:
Next, we consider a system of two ordinary dierential equations. First, we
dene the equations:
assume(s>0);
[s > 0]
diff_eq1: diff(f(x),x,2) + diff(g(x),x) + 3*f(x) = 15*exp(-x);
diff_eq2: diff(g(x), x, 2) - 4*diff(f(x), x) + 3*g(x) = 15*sin(2*x);
Next, we dene the initial values. For this example, we have initial values for
both functions and their derivatives at point x = 0.
atvalue (f(x), x=0, 35);
35
atvalue (diff(f(x),x),x=0, -48);
- 48
atvalue (g(x), x=0, 27);
27
atvalue (diff(g(x), x), x=0, -55);
- 55
Now we can compute the Laplace transforms:
lap_eq1:laplace(diff_eq1,x,s);
lap_eq2:laplace(diff_eq2,x,s);
These are two linear equations in the unknowns laplace(f(x),x, s) and
laplace(g(x), x, s). We solve them with solve:
linsolve([lap_eq1,lap_eq2],[laplace(f(x),x,s),laplace(g(x),x,s)]);
The denominators of the solutions are polynomials in s of degree 7. The com-
putation of the inverse Laplace transform requires that the denominators are
decomposed into linear and quadratic factors. The function ilt does not always
factor denominators, so we do it:
2.5. DIFFERENTIAL CALCULUS 59
factored: map(lambda( [eq], factor(eq)), %);
Now we can apply the inverse Laplace transform to both equations:
sol: map(lambda( [eq], ilt(eq, s, x)), factored);
We obtain a solution for the given system of ordinary dierential equations:
- x
[f(x) = - 15 sin(3 x) + 2 cos(2 x) + 30 cos(x) + 3 %e ,
- x
g(x) = 30 cos(3 x) + sin(2 x) - 60 sin(x) - 3 %e ]
In principle we are done, but there is still one interesting technicality: How can
we prove that the solution satises the given system of equations? The proof
requires four additional steps. First, we write the two dierential equations as
a system:
ode_system: [diff_eq1, diff_eq2];
2
d d - x
[-- (g(x)) + --- (f(x)) + 3 f(x) = 15 %e ,
dx 2
dx
2
d d
--- (g(x)) - 4 (-- (f(x))) + 3 g(x) = 15 sin(2 x)]
2 dx
dx
Next we substitute the solution into that system:
ode_system, sol;
2
d - x
[--- (- 15 sin(3 x) + 2 cos(2 x) + 30 cos(x) + 3 %e )
2
dx
d - x
+ -- (30 cos(3 x) + sin(2 x) - 60 sin(x) - 3 %e )
dx
- x - x
+ 3 (- 15 sin(3 x) + 2 cos(2 x) + 30 cos(x) + 3 %e ) = 15 %e ,
d - x
60 CHAPTER 2. SYMBOLIC CALCULATION
- 4 (-- (- 15 sin(3 x) + 2 cos(2 x) + 30 cos(x) + 3 %e ))
dx
2
d - x
+ --- (30 cos(3 x) + sin(2 x) - 60 sin(x) - 3 %e )
2
dx
- x
+ 3 (30 cos(3 x) + sin(2 x) - 60 sin(x) - 3 %e ) = 15 sin(2 x)]
We obtain a list of two equations that contain symbolic derivatives. To enforce
the computation of the derivatives, we have to evaluate the equations:
map (lambda( [eq], ev(eq, diff)), %);
- x
[45 sin(3 x) + 3 (- 15 sin(3 x) + 2 cos(2 x) + 30 cos(x) + 3 %e )
- x - x
- 6 cos(2 x) - 90 cos(x) + 6 %e = 15 %e ,
- x
3 (30 cos(3 x) + sin(2 x) - 60 sin(x) - 3 %e ) - 270 cos(3 x)
- x
- 4 (- 45 cos(3 x) - 4 sin(2 x) - 30 sin(x) - 3 %e ) - 4 sin(2 x)
- x
+ 60 sin(x) - 3 %e = 15 sin(2 x)]
This looks better, but simplication is obviously needed:
trigsimp(%);
- x - x
[15 %e = 15 %e , 15 sin(2 x) = 15 sin(2 x)]
These two identities complete the proof. It should be noted that the equations
of this example can also be solved with desolve.
2.5.2 Dierentiation Using the Chain Rule
Working with derivatives of unknown functions can be cumbersome in Maxima.
If we want, for example, the rst order Taylor polynomial of f
_
x +x
2
_
about
x = 1, we get
2.5. DIFFERENTIAL CALCULUS 61
(%i1) taylor(f(x + x^2),x,1,1);
(%o1) f(2)+(at(diff(f(x^2+x),x,1),x=1))*(x-1)+...
To simplify the Taylor polynomial, we must assign a gradient to f
(%i2) gradef(f(x),df(x))$
(%i3) taylor(f(x+x^2),x,1,1);
(%o3) f(2)+3*df(2)*(x-1)+...
This method works well for simple problems, but it is tedious for functions of
several variables or high order derivatives. The positional derivative package
pdiff gives an alternative to using gradef when working with derivatives of
unknown functions.
To use the positional derivative package, you must load it from a Maxima
prompt. Assuming pdiff.lisp is in a directory that Maxima can nd, this is
done with the command
(%i4) kill(all)$
(%i1) load("pdiff.lisp")$
Use the full pathname if Maxima cannot nd the le. Note that the kill(all)
is needed because the gradef denition will conict with the proper functioning
of the diff commands. Loading pdiff.lisp sets the option variable use_pdiff
to true; when use_diff is true, Maxima will indicate derivatives of unknown
functions positionally. To illustrate, the rst three derivatives of f are
(%i2) [diff(f(x),x),
diff(f(x),x,2),
diff(f(x),x,3)];
(%o2) [f[(1)](x),f[(2)](x),f[(3)](x)]
The subscript indicates the order of the derivative; since f is a function of one
variable, the subscript has only one index. When a function has more than one
variable, the subscript has an index for each variable.
By an unknown function, we mean a function not bound to a formula and
that has a derivative unknown to Maxima.
(%i3) [diff(f(x,y),x,0,y,1), diff(f(y,x),x,0,y,1)];
(%o3) [f[(0,1)](x,y),f[(1,0)](y,x)]
Setting use_pdiff to false (either locally or globally) inhibits derivatives from
being computed positionally
(%i4) diff(f(x,x^2),x), use_pdiff : false;
(%o4) diff(f(x,x^2),x,1)
(%i5) diff(f(x,x^2),x), use_pdiff : true;
(%o5) f[(1,0)](x,x^2)+2*x*f[(0,1)](x,x^2)
Taylor polynomials of unknown functions can be found without using gradef.
An example:
62 CHAPTER 2. SYMBOLIC CALCULATION
(%i6) taylor(f(x+x^2),x,1,2);
(%o6) f(2)+3*f[(1)](2)*(x-1)+((2*f[(1)](2)+9*f[(2)](2))*(x-1)^2)/2+...
Additionally, we can verify that y = f(xct) +g(x+ct) is a solution to a wave
equation without using gradef
(%i7) y : f(x-c*t) + g(x+c*t)$
(%i8) ratsimp(diff(y,t,2) - c^2 * diff(y,x,2));
(%o8) 0
(%i9) remvalue(y)$
Expressions involving positional derivatives can be dierentiated
(%i10) e : diff(f(x,y),x);
(%o10) f[(1,0)](x,y)
(%i11) diff(e,y);
(%o11) f[(1,1)](x,y)
The chain rule is applied when necessary
(%i12) [diff(f(x^2),x), diff(f(g(x)),x)];
(%o12) [2*x*f[(1)](x^2),g[(1)](x)*f[(1)](g(x))]
The positional derivative package does not alter the way known functions are
dierentiated
(%i13) diff(exp(-x^2),x);
(%o13) -2*x*%e^(-x^2)
To convert positional derivatives to standard Maxima derivatives, use convert_to_diff:
(%i14) e : [diff(f(x),x), diff(f(x,y),x,1,y,1)];
(%o14) [f[(1)](x),f[(1,1)](x,y)]
(%i15) e : convert_to_diff(e);
(%o15) [diff(f(x),x,1),diff(f(x,y),x,1,y,1)]
To convert back to a positional derivative, use ev with diff as an argument
(%i16) ev(e,diff);
(%o16) [f[(1)](x),f[(1,1)](x,y)]
Conversion to standard derivatives sometimes requires the introduction of a
dummy variable. An example:
(%i17) e : diff(f(x,y),x,1,y,1);
(%o17) f[(1,1)](x,y)
(%i18) e : subst(p(s),y,e);
(%o18) f[(1,1)](x,p(s))
(%i19) e : convert_to_diff(e);
(%o19) at(diff(f(x,y),x,1,y,1),[y=p(s)])
2.5. DIFFERENTIAL CALCULUS 63
Dummy variables have the form ci, where i = 0,1,2. . . and c is the value
of the option variable dummy_char. The default value for dummy_char is %x.
If a user variable conicts with a dummy variable, the conversion process can
give an incorrect value. To convert the previous expression back to a positional
derivative, use ev with diff and at as arguments
(%i20) ev(e,diff,at)
(%o20) f[(1,1)](x,p(s))
Maxima correctly evaluates expressions involving positional derivatives if a for-
mula is later given to the function. (Thus converting an unknown function into
a known one.) Here is an example; let
(%i21) e : diff(f(x^2),x);
(%o21) 2*x*f[(1)](x^2)
Now, give f a formula
(%i22) f(x) := x^5$
and evaluate e
(%i23) ev(e);
(%o23) 10*x^9
This result is the same as
(%i24) diff(f(x^2),x);
In this calculation, Maxima rst evaluates f(x) to x
10
and then does the deriva-
tive. Additionally, we can substitute a value for x before evaluating
(%i25) ev(subst(2,x,e));
(%o25) 5120
We can duplicate this with
(%i26) subst(2,x,diff(f(x^2),x));
(%o26) 5120
(%i27) remfunction(f);
(%o27) [f]
We can also evaluate a positional derivative using a local function denition
(%i28) e : diff(g(x),x);
(%o28) g[(1)](x)
(%i29) e, g(x) := sqrt(x);
(%o29) 1/(2*sqrt(x))
(%i30) e, g = sqrt;
(%o30) 1/(2*sqrt(x))
(%i31) e, g = h;
(%o31) h[(1)](x)
(%i32) e, g = lambda([t],t^2);
(%o32) 2*x
64 CHAPTER 2. SYMBOLIC CALCULATION
2.6 Integral Calculus
Although the process of nding an integral can be viewed as the inverse of the
process of nding a derivative, in practice nding an integral is more dicult. It
turns out that the integral of fairly simple looking functions cannot be expressed
in terms of closed-form functions, and this has been one motivation for the
introduction of denitions for a variety of special functions, as well as ecient
methods for numerical integration.
In the following, we always assume we are dealing with a real function of
a real variable and that the function is single-valued and continuous over the
intervals of interest. The Maxima manual entry for integrate includes (we have
made some changes and additions):
Function: integrate(expr, var)
Function: integrate(expr, var, a, b)
Attempts to symbolically compute the integral of expr with respect to var.
integrate(expr, var)
is an indenite integral, while
integrate(expr, var, a, b)
is a denite integral, with limits of integration a and b. The integral is
returned if integrate succeeds. Otherwise the return value is the noun form of
the integral (the quoted operator integrate) or an expression containing one
or more noun forms. The noun form of integrate is displayed with an integral
sign if display2d is set to true (which is the default). In some circumstances it
is useful to construct a noun form by hand, by quoting integrate with a single
quote, e.g., integrate(expr, var). For example, the integral may depend on
some parameters which are not yet computed. The noun may be applied to its
arguments by ev(iexp, nouns) where iexp is the noun form of interest.
To integrate a Maxima function f(x), insert f(x) in the expr slot. integrate
does not respect implicit dependencies established by the depends function.
integrate may need to know some property of the parameters in the inte-
grand. integrate will rst consult the assume database, and, if the variable
of interest is not there, integrate will ask the user. Depending on the question,
suitable responses are yes; or no;, or pos;, zero;, or neg;. Thus, the user can use
the assume function to avoid all or some questions.
2.6.1 Integration Examples
Example 2.6.1. Our rst example is the indenite integral
_
sin
3
x dx:
integrate(sin(x), x);
( diff (%,x), trigsimp(%%) );
Notice that the indenite integral returned by integrate does not include the
arbitrary constant of integration which can always be added. If the returned
integral is correct (up to an arbitrary constant), then the rst derivative of the
returned indenite integral should be the original integrand, although we may
have to simplify the result manually by using the command trigsimp.
2.6. INTEGRAL CALCULUS 65
Example 2.6.2. Our second example is another indenite integral
_
x dx
b
2
x
2
:
integrate (x/ sqrt (b^2 - x^2), x);
diff(%,x);
The denite integral can be related to the area under a curve and is the
more accessible concept, while the integral is simply a function whose rst
derivative is the original integrand.
Example 2.6.3. Consider the denite integral
_

0
e
x
cos
2
x dx:
i3 : integrate (cos(x)^2 * exp(x), x, 0, %pi);
Instead of using integrate for a denite integral, you can try ldent (think
Limit denite integral), which may provide an alternative form of the answer
(if successful).
Function: ldefint(expr, x, a, b)
This function attempts to compute the denite integral of expr by using limit
to evaluate the indenite integral of expr with respect to x at the upper limit
b and at the lower limit a. If it fails to compute the denite integral, ldefint
returns an expression containing limits as noun forms. ldefint is not called
from integrate, so executing ldefint(expr, x, a, b) may yield a dierent
result than integrate(expr, x, a, b). ldefint always uses the same method
to evaluate the denite integral, while integrate may employ various heuristics
and may recognize some special cases.
Example 2.6.4. Use of ldefint, as well as the direct use of defint (which
bypasses integrate ):
ldefint (cos(x)^2 * exp(x), x, 0, %pi);
defint (cos(x)^2 * exp(x), x, 0, %pi);
Example 2.6.5. A denite integral over an innite range
_

x
2
e
x
2
dx
integrate (x^2 * exp(-x^2), x, minf, inf);
To check this integral, we rst ask for the indenite integral and then check it
by dierentiation.
i1 : integrate(x^2*exp(-x^2),x );
diff(i1,x);
Thus the indenite integral is correct. The second term, heavily damped by the
factor e
x
2
at , does not contribute to the denite integral. The rst term
is proportional to the (Gauss) error function, (x), in which x is real. For (in
general) complex w = u +iv,
erf(w) =
2

_
w
0
e
z
2
dz ,
in which we can integrate over any path connecting 0 and w in the complex
z = x +iy plane, since the integrand is an entire function of z (no singularities
66 CHAPTER 2. SYMBOLIC CALCULATION
-1
-0.8
-0.6
-0.4
-0.2
0
0.2
0.4
0.6
0.8
1
-4 -2 0 2 4
e
r
f
(
x
)
x
Figure 2.4: The Gauss error function.
in the nite z plane). We can plot this function by invoking the Plot/Plot 2d
GUI-box and get the graph in Figure 2.4. Maximas limit function conrms what
the plot indicates:
[limit(erf(x),x, inf), limit(erf(x),x, minf)];
[1, - 1]
These limits can be used in the result for the indenite integral above.
Example 2.6.6. Use of assume.
We would like to compute the denite integral for parameter a:
_

0
x
a
(x + 1)

5
2
dx , a > 1 .
We rst invoke the assumption and do the whole computation according to:
(%i1) (assume(a>1),facts());
(%o1) [a > 1]
(%i2) integrate (x^a/(x+1)^(5/2), x, 0, inf );
2 a + 2
Is ------- an integer?
5
no;
Is 2 a - 3 positive, negative, or zero?
neg;
3
(%o2) beta(- - a, a + 1)
2
2.6. INTEGRAL CALCULUS 67
The combination of a > 1 and 2a3 < 0 means that we are eectively assuming
1 < a < 3/2. These assumptions about a imply that
4
5
<
2a+2
5
< 1. To be
consistent, we must hence answer no to the rst question.
Let us tell Maxima to forget about the assume assignment and see what the
dierence is.
(%i3) ( forget(a>1), facts() );
(%o3) []
(%i4) is( a>1 );
(%o4) unknown
(%i5) integrate (x^a/(x+1)^(5/2), x, 0, inf );
Is a + 1 positive, negative, or zero?
pos;
Is a an integer?
no;
7
Is ------- an integer?
2 a + 4
no;
Is 2 a - 3 positive, negative, or zero?
neg;
3
(%o5) beta(- - a, a + 1)
2
(%i6) [is( a>1 ), facts() ];
(%o6) [unknown, []]
Thus we see that omitting the initial assume(a>1) statement causes integrate to
ask four questions instead of two. We also see that answering questions posed
by the integrate dialogue script does not result in population of the facts list.
The Maxima beta function has the manual entry beta (a, b) and is dened
in terms of the gamma function as
B(r, s) =
(r)(s)
(r +s)
,
where the gamma function can be dened for complex z and Re(z) > 0 by the
integral along the real t-axis
(z) =
_

0
t
z1
e
t
dt .
and for Im(z) = 0 and Re(z) = n and n an integer greater than zero we have
(n + 1) = n! .
Next, we take a look at changing the integration variable.
68 CHAPTER 2. SYMBOLIC CALCULATION
Example 2.6.7. We can make a change of variable to enable the return of an
indenite integral. The task is to evaluate the indenite integral
_
sin
_
r
2
_
dr(x)
dx
q(r)
dx
by telling Maxima that the sin
_
r
2
_
in the numerator is related to q(r) in the
denominator by the derivative:
dq(u)
du
= sin
_
u
2
_
Then, we would manually rewrite the integrand (using the chain rule) as
sin
_
r
2
_
dr(x)
dx
q(r)
=
1
q(r)
dq(r)
dr
dr(x)
dx
=
1
q(r)
dq
d
=
d ln q
dx
.
and hence obtain the indenite integral ln(q(r(x))).
In Maxima, we assign the derivative knowledge using gradef:
(%i1) gradef(q(u),sin(u^2) )$
(%i2) integrand : sin(r(x)^2) * diff(r(x),x) / q(r(x)) ;
d 2
(-- (r(x))) sin(r (x))
dx
(%o2) ----------------------
q(r(x))
(%i3) integrate(integrand,x);
(%o3) log(q(r(x)))
(%i4) diff(%,x);
d 2
(-- (r(x))) sin(r (x))
dx
(%o4) ----------------------
q(r(x))
Note that integrate pays no attention to depend assignments, so the briefer
type of notation which depend allows with dierentiation cannot be used with
integrate:
(%i5) depends(r,x,q,r);
(%o5) [r(x), q(r)]
(%i6) integrand : sin(r^2)* diff(r,x) / q;
dr 2
-- sin(r )
dx
(%o6) ----------
q
2.6. INTEGRAL CALCULUS 69
(%i7) integrate(integrand,x);
/
2 [ dr
sin(r ) I -- dx
] dx
/
(%o7) ---------------
q
which is fatally awed, since Maxima pulled both sin
_
r(x)
2
_
and
1
q(r(x))
outside
the integral. Of course, the above depends assignment will still allow Maxima
to rewrite the derivative of q with respect to x using the chain rule:
(%i8) diff(q,x);
dq dr
(%o8) -- --
dr dx
Example 2.6.8. Integration of Rational Algebraic Functions.
A rational algebraic function can be written as a quotient of two polynomials.
Consider the following function of x.
e1 : x^2 + 3*x -2/(3*x)+110/(3*(x-3)) + 12;
We can obviously nd the lowest common denominator and write this as the
ratio of two polynomials, using either function rat or ratsimp.
e11 : ratsimp(e1);
4 2
x + 3 x + 2
-------------
2
x - 3 x
Because the polynomial in the numerator is of higher degree than the polynomial
in the denominator, this is called an improper rational fraction. Any improper
rational fraction can be reduced by division to a mixed form, consisting of a sum
of some polynomial and a sum of proper fractions. We can recover the partial
fraction representation in terms of proper rational fractions (numerator degree
less than denominator degree) by using partfrac(expr, var).
e12 : partfrac(e11,x);
With this function of x expressed in partial fraction form, you are able to write
down the indenite integral immediately (e.g., by inspection, without using Max-
ima). But, of course, we want to practice using Maxima!
integrate(e11,x);
integrate(e12,x);
70 CHAPTER 2. SYMBOLIC CALCULATION
Maxima has to do less work if you have already provided the partial fraction form
as the integrand; otherwise, Maxima internally seeks a partial fraction form in
order to do the integral.
Remark 2.6.1. There is a global parameter logabs whose default value is false
and which aects what is returned with an indenite integral containing loga-
rithms.
(%i11) logabs;
(%o11) false
(%i12) integrate(1/x,x);
(%o12) log(x)
(%i13) diff(%,x);
1
(%o13) -
x
(%i14) logabs:true$
(%i15) integrate(1/x,x);
(%o15) log(abs(x))
(%i16) diff(%,x);
1
(%o16) -
x
(%i17) log(-1);
(%o17) log(- 1)
(%i18) float(%);
(%o18) 3.141592653589793 %i
When we override the default and set logabs to true, the argument of the log
function is wrapped with an absolute value.
2.6.2 Integration by Parts
Suppose f(x) and g(x) are two continuously dierentiable functions in the inter-
val of interest. Then the integration by parts rule states that given an interval
with endpoints (a, b), (and of course assuming the derivatives exist) one has
_
b
a
f(x)g

(x) dx =
b
_
a
f(x)g(x)
_
b
a
f

(x)g(x) dx .
This result follows from the product rule of dierentiation and can also be used
for indenite integrals. In practice, when integration by parts is applied, we are
confronted with an integral whose integrand can be viewed as the product of
two factors, which we will call f(x) and h(x):
_
f(x)h(x) dx
2.6. INTEGRAL CALCULUS 71
and we wish to use integration by parts to get an integral involving the derivative
of the rst factor, f

(x), which will hopefully result in a simpler integral. We


then identify h(x) = g

(x) and solve this equation for g(x) (by integrating; this
is also a choice based on the ease of integrating the second factor h(x) in the
given integral). Having g(x) in hand we can then write out the result using
the indenite integral integration by parts rule above. We can formalize this
process for an indenite integral with the Maxima code:
iparts(f,h,var):= block([g ],
g : integrate(h,var), f*g - integrate(g*diff(f,var),var ) );
Lets practice with the integral
_
x
2
sin (x) dx, in which f(x) = x
2
and h(x) =
sin(x), so we need to be able to integrate sin(x) and want to transfer a derivative
on to x
2
, which will reduce the rst factor to 2x. Notice that it is usually easier
to work with Maxima expressions rather than with Maxima functions in a
problem like this.
iparts(x^2,sin(x),x);
(ev(%,nouns),expand(%%) );
collectterms(%,cos(x) );
If we were not using Maxima, but doing everything by hand, we would use two
integrations by parts (in succession) to remove the factor x
2
entirely, reducing
the original problem to simply knowing the integrals of sin (x) and cos (x).
2.6.3 Change of Variable
Many integrals can be evaluated most easily by making a change of variable of
integration. A simple example is:
_
2x
_
x
2
+ 1
_
3
dx =
_
_
x
2
+ 1
_
3
d
_
x
2
+ 1
_
=
_
u
3
du
=
u
4
4
=
_
x
2
+ 1
_
4
4
.
There is a function in Maxima, called changevar which will help you change
variables in a one-dimensional integral (either indenite or denite).
Function: changevar(integral-expression, g(x,u), u, x)
Makes the change of variable in a given noun form integrate expression
such that the old variable of integration is x, the new variable of integration is
u, and x and u are related by the equation g(x, u) = 0.
Example 2.6.9. Here we use this Maxima function on the simple indenite
integral we have just done by hand:
72 CHAPTER 2. SYMBOLIC CALCULATION
expr : integrate(2*x*(x^2+1)^3,x);
changevar(expr,x^2+1-u,u,x);
ev(%, nouns);
ratsubst(x^2+1,u,%);
subst(x^2+1,u,%o3);
subst(u=(x^2+1),%o3);
The original indenite integral is a function of x, which we obtain by replacing
u by its equivalent as a function of x. We have shown three ways to make this
replacement to get a function of x, using subst and ratsubst.
Remark 2.6.2. It should be noted that changevar uses the solution of g(x, u) = 0
for x. Hence, if there are multiple such solutions, e.g., as in the case g(x, u) =
x
2
u 1, Maxima may use the wrong one. Maxima does not issue any warning
of this choice and the result of picking the wrong solution is in many cases a
sign error in the integral.
Example 2.6.10. Consider the integral
_

0
ln

1
1
w
2

dw ,
which should be negative, since the curve of the integrand is negative on the entire
integration interval. Maxima can do this integral both using the substitution u =
1
w
2
and directly. The endpoint contributions are evaluated as limits. We see that,
for the variable prior to the substitution, we have w =
1

u
and choosing the
negative root gives a positive nal result - which is clearly wrong.
kill(all);
logabs : true$
intg : integrate(log((1-w^(-2))),w);
changevar(intg, w = 1/sqrt(u), u, w);
ev(%, nouns);
logcontract(%);
define(F(u),%);
Fupper : limit(F(u), u, 0, plus);
Flower : limit(F(u), u, 1, minus);
Fupper - Flower;
float(%);
kill(all);
plot2d([log((1-w^(-2)))], [w,1,5], [y,-2,1],
[plot_format, gnuplot])$
intg : integrate(log(abs(1-w^(-2))),w);
ev(%, nouns);
logcontract(%);
define(F(w),%);
Fupper : limit(F(w), w, inf, minus);
Flower : limit(F(w), w, 1, plus);
2.7. MATRIX COMPUTATIONS 73
Fupper - Flower;
float(%);
2.7 Matrix Computations
Linear algebra and matrix computation are not the most powerful applications
for Maxima, however, with Maxima, we can compute the determinant, inverse
and eigenvalues and eigenvectors of matrices which have symbolic elements (i.e.,
elements which involve algebraic variables). We will take a brief look at the most
common operations
A matrix is entered in wxMaxima through the Algebra/Enter Matrix or
Generate Matrix GUI-menu box. Consider
Example 2.7.1. A simple 3 3-matrix with symbolic elements and some basic
matrix operations.
A : matrix(
[0,1,a],
[1,0,1],
[1,1,0]
);
We take the transpose, determinant and inverse of the matrix. When inverting,
we may also keep the determinant as a factor by specifying the option detout
At: transpose(A);
Adet : determinant(A);
Ainv : invert(A);
Ainv2 : invert(A), detout;
In Maxima, matrices are multiplied with the dot-operator (* produces the ele-
mentwise product), i.e., the product of A and its inverse is calculated according
to:
Ainv . A;
ratsimp(%);
A . Ainv;
expand(%);
factor(%);
In order to nd the eigenvalues and eigenvectors of A, we use the function
eigenvectors(A);, which yields a rather lengthy result. In the resulting output,
the rst triple (or number of rows of the matrix) gives the eigenvalues of A and
the next gives their respective multiplicities (here each is unrepeated). The next
three triples give the corresponding eigenvectors of A. In order to extract from
this expression one of these eigenvectors, we may use the part function:
part (%, 2, 1, 1);
74 CHAPTER 2. SYMBOLIC CALCULATION
2.8 Visualization
Visualization in wxMaxima can be done in various ways; inline with the GUI or
using the openmath and gnuplot packages. These oer an enormous amount
of options as to garphics appearance and features and their detailed description
falls out of scope of this treatment. In most cases, detailed descriptions and
examples can be googled from the internet. There are interactive menus for
both two-dimensional and three-dimensional graphs behind the GUI-box Plot.
Take a look at the examples:
Example 2.8.1. Plot the curve y = f(x) = xe
x
2
:
plot2d([x * exp(-x^2)], [x,-5,5],
[plot_format, gnuplot])$
Similarly, we can plot the surface z = g(x, y) = e

1
3
(x
2
+y
2
)
cos (xy) by invoking
the command:
plot3d(exp((-x^2-y^2)*0.3)*cos(x*y), [x,-3,3], [y,-3,3],
[plot_format,gnuplot])$
2.9 Numerical Data
Numerical data can be entered through assigning parameters and/or through
conversion of existing results. The GUI menu Numeric contains interactive
boxes for the most common conversion needs and precision settings. When
dealing with numerically sensitive tasks or topics from numerical analysis, care
should be taken so as to ensure that loss of accuracy can be avoided in com-
putations. Maxima is not a numerical mathematics software and many of its
algorithms are not optimized for numerical precision. We proceed with a quick
glance at the most important numerical functions:
The variable fpprec is the number of signicant digits (default equal to 16)
for arithmetic on bigfloat numbers. fpprec does not aect computations on
ordinary oating point numbers.
bigfloat(expr): Converts all numbers and functions of numbers in expr to
bigfloat numbers. The number of signicant digits in the resulting bigoats
is specied by the global variable fpprec. When float2bf is false a warning
message is printed when a oating point number is converted into a bigoat
number (since this may lead to loss of precision).
float(expr): Converts integers, rational numbers and bigoats in expr to
oating point numbers. It is also an evflag, float causes non-integral rational
numbers and bigoat numbers to be converted to oating point.
Chapter 3
An Overview of Octave
Figure 3.1: The surface z = g(x, y) = e

1
3
(x
2
+y
2
)
cos (xy) visualized with Oc-
tave/GNUplot.
3.1 Introduction
Octave is an interactive programming language specically suited for vectoriz-
able numerical calculations. It provides a high level interface to many standard
libraries of numerical mathematics, e.g. LAPACK or BLAS. The syntax of Oc-
tave resembles that of Matlab. An Octave program usually runs unmodied on
Matlab. Matlab, however, being commercial software, has a larger function set,
and so the reverse does not always work, especially when the program makes
use of specialized add-on toolboxes for Matlab.
75
76 CHAPTER 3. AN OVERVIEW OF OCTAVE
3.1.1 Help!
The function help lists the names of all built-in functions and internal variables,
whereas help name further explains the variable or function name.
Example 3.1.1. Consider a help call for the function that computes eigenvalues
for a matrix:
octave:1> help eig
3.1.2 Input Conventions
All commands can be typed in at the prompt or read from a script. Scripts
are plain text les with le sux .m. They are imported by calling the le
name without the sux and behave as if their content was typed in line by
line. ; separates several commands within a line. A command terminated by
; does not display its result on-screen. A comma , separates two commands
without suppressing on-screen output. ... at the end of the line denotes that an
expression continues into the next line. Comments are preceded by %. Octave
is case sensitive.
3.1.3 Variables and Standard Operations
varname = expression assigns the result of expression to varname. Octave
has all the usual mathematical functions +, -, *, /, ^, sin, cos, exp, acos, abs
etc. The operators of elementary logic are: < smaller, <= smaller or equal,
and, > greater, >= greater or equal, | or, == equal, = not equal and not.
When debugging user-dened objects, the following commands are useful:
whos shows all user-dened variables and functions. clear name clears name
from memory; if no name is given, all variables and functions will be cleared.
type name displays information about the variable or function name on the
screen.
Example 3.1.2. Various types of input and how to run a script le.
octave:1> x12 = 1/8, long_name = A String
x12 = 0.12500
long_name = A String
octave:2> sqrt(-1)-i
ans = 0
octave:3> x = sqrt(2); sin(x)/x
ans = 0.69846
And here is a script doless, saved in a le named doless.m:
one = 1;
two = 2;
three = one + two;
3.2. VECTOR AND MATRIX OPERATIONS 77
Calling the script:
octave:1> doless
octave:2> whos
*** local user variables:
prot type rows cols name
==== ==== ==== ==== ====
wd real scalar 1 1 three
wd real scalar 1 1 one
wd real scalar 1 1 two
3.2 Vector and Matrix Operations
Matrices and vectors are the most important building blocks for programming
in Octave.
3.2.1 Vectors
Example 3.2.1. Row and column vectors: u = (1, 2, 3), v = (1, 2, 3)
T
:
u = [ 1 2 3 ]
v = [ 1; 2; 3 ]
Vectors with constant increment can be generated with the command start(:increment):end.
octave:1> x = 3:6
x =
3 4 5 6
octave:2> y = 0:.15:.7
y =
0.00000 0.15000 0.30000 0.45000 0.60000
octave:3> z = pi:-pi/4:0
z =
3.14159 2.35619 1.57080 0.78540 0.00000
3.2.2 Matrices
A matrix A =
_
1 23 4
_
is generated like in the following example.
Example 3.2.2. octave:1> A = [ 1 2; 3 4]
A =
1 2
3 4
Matrices can also assembled from submatrices:
octave:2> b = [5; 6];
octave:3> M = [A b]
M =
78 CHAPTER 3. AN OVERVIEW OF OCTAVE
1 2 5
3 4 6
There are functions to create frequently used m n matrices. If m = n
, only one argument is necessary. The function eye(m,n) produces a matrix
with ones on the main diagonal and zeros elsewhere. When m = n, the identity
matrix is generated. An m n-matrix with only zeros is generated with the
function zeros(m,n), whereas ones(m,n) generates an m n matrix with all
entries equal to 1. The function rand(m,n) generates a random matrix whose
entries are uniformly distributed in the interval (0, 1) .
Basic Matrix Arithmetic +, -, and * denote matrix addition, subtraction,
and multiplication. A transposes and conjugates A and \A. transposes A.
Example 3.2.3. Matrix operations
octave:1> A = [1 2; 3 4]; B = 2*ones(2,2);
octave:2> A+B, A-B, A*B
ans =
3 4
5 6
ans =
-1 0
1 2
ans =
6 6
14 14
3.2.3 Element-wise Operations
While * refers to the usual matrix multiplication, .* denotes element-wise mul-
tiplication. Similarly, ./ and .^ denote the element-wise division and power
operators.
Example 3.2.4. Element-wise matrix operations
octave:1> A = [1 2; 3 4]; A.^2 % Element-wise power
ans =
1 4
9 16
octave:2> A^2 % Proper matrix power: A^2 = A*A
ans =
7 10
15 22
3.2. VECTOR AND MATRIX OPERATIONS 79
3.2.4 Indexing and Slicing
v(k) is the k-th element of the row or column vector v. A(k,l) is the matrix
element a
kl
. v(m:n) is the slice of the vector v from its m-th to its n-th
entry. A(k,:) is the k-th row of the matrix A. A(:,l) is the l-th column of
the matrix A. There are also functions for querying dimensions of vectors and
matrices; length(v) returns the number of elements of the vector v. The call
[Rows,Columns] = size(A) returns the number of rows and columns of the
matrix A. Matrices can also be reshaped; reshape(A,m,n) transforms A into
an m n -matrix. diag(A) creates a column vector containing the diagonal
elements a
jj
of the matrix A. diag(v) generates a matrix with the elements
from the vector v on the diagonal, whereas diag(v,k) generates a matrix with
the elements from the vector v on the k-th diagonal. Moreover,
A(k,:) = rv assigns to the k-th row of A the row vector rv.
A(k,:) = [] deletes the k-th row of A.
A(:,j) = cv assigns to the j-th column of A the column vector cv.
A(:,j) = [] deletes the j-th column of A.
Example 3.2.5. octave:1> A = [1 2 3; 4 5 6]; v = [7; 8];
octave:2> A(2,3) = v(2)
A =
1 2 3
4 5 8
octave:3> A(:,2) = v
A =
1 7 3
4 8 8
octave:4> A(1,1:2) = v
A =
7 8 3
4 8 8
3.2.5 Solving Linear Systems of Equations
The command A\b solves the equation Ax = b .
3.2.6 Inverses, Decompositions and Eigenvalues
B = inv(A) computes the inverse of A.
[L,U,P] = lu(A) computes the LU-decomposition LU = PA.
[Q,R] = qr(A) computes the QR-decomposition QR = A.
R = chol(A) computes the Cholesky-decomposition of A.
80 CHAPTER 3. AN OVERVIEW OF OCTAVE
S = svd(A) computes the singular values of A.
H = hess(A) brings A into Hessenberg form.
E = eig(A) computes the eigenvalues of A.
[V,D] = eig(A) computes a diagonal matrix D, containing the eigenvalues
of A and a matrix V containing the corresponding eigenvectors such that AV =
VD.
norm(X,p) calculates the p-norm of vector X. If X is a matrix, p can only
take the values 1, 2 or =inf= (= inf). The default is p = 2.
cond(A) computes the condition number of A with respect to the 2-norm.
A lot of these commands support further options. They can be listed by
typing help funcname.
3.2.7 Testing for Zero Elements
[i,j,v] = find(A) nds the indices of all nonzero elements of A. The resulting
vectors satisfy A
i(l),j(l)
= v
l
= 0. any(v) returns 1 if the vector v contains
nonzero elements. any(A) applies any to each of the columns of the matrix A.
3.3 Control Structures
3.3.1 Functions
Functions are called with arguments, whereas scripts consist of a list of con-
secutive commands. Both of these are stored in a text le with sux .m. All
variables within a function are local in contrast to those of a script, which are
global to the workspace.
Example 3.3.1. A function f, saved in the le named f.m.
function y = f (x)
y = cos(x/2)+x;
end
Remark 3.3.1. In Octave, several functions can be dened in a single script le.
Matlab on the other hand, strictly enforces one function per .m le, where the
name of the function must match the name of the le. If compatibility with
Matlab is important, this restriction should also be applied to programs written
in Octave.
Example 3.3.2. A case with two function values. Consider the function dolittle,
saved under the le named dolittle.m.
function [out1,out2] = dolittle (x)
out1 = x^2;
out2 = out1*x;
end
Let us call the function:
3.3. CONTROL STRUCTURES 81
octave:1> [x1,x2]=dolittle(2)
x1 = 4
x2 = 8
octave:2> whos
*** currently compiled functions:
prot type rows cols name
==== ==== ==== ==== ====
wd user function - - dolittle
*** local user variables:
prot type rows cols name
==== ==== ==== ==== ====
wd real scalar 1 1 x1
wd real scalar 1 1 x2
Obviously, the variables out1 and out2 are local to dolittle. Previously dened
variables out1 or out2 would not have been aected by the function call.
3.3.2 Global Variables
The declaration for a global variable is global name. Consider a function foo
in the le named foo.m:
global N % makes N a global variable; may be set in main file
function out = foo(arg1,arg2)
global N % makes local N refer to the global N
<Computation>
end
If you change N within the function, it changes in the value of N everywhere.
3.3.3 Loops
The syntax of for- and while-loops is obvious in the following:
Example 3.3.3. Loop syntax
for n = 1:10
[x(n),y(n)]=dolittle(n);
end
while t<T
t = t+h;
end
For-loop backward:
for n = 10:-1:1
...
82 CHAPTER 3. AN OVERVIEW OF OCTAVE
3.3.4 Branching
Example 3.3.4. Conditional branching works as follows.
if x==0
error(x is 0!);
else
y = 1/x;
end
switch pnorm
case 1
sum(abs(v))
case inf
max(abs(v))
otherwise
sqrt(v*v)
end
3.3.5 Functions of Functions
The function eval(string) evaluates string as Octave code. On the other
hand, feval(funcname,arg1,..) is equivalent to calling funcname with argu-
ments arg1,...
Example 3.3.5. Approximate an integral by the midpoint rule:
_
b
a
f(x) dx
b a
N
N1

j=0
f
_
a +
_
j +
1
2
_
b a
N
_
.
We dene two functions, gauss.m and mpr.m:
function y = gauss(x)
y = exp(-x.^2/2);
end
function S = mpr(fun,a,b,N)
h = (b-a)/N;
S = h*sum(feval(fun,[a+h/2:h:b]));
end
Now the function gauss can be integrated by calling:
octave:1> mpr(gauss,0,5,500)
3.4. INPUT AND OUTPUT 83
3.3.6 Eciency Considerations
It should be noted that loops and function calls, especially through feval,
have a very high computational overhead. Consequently, excessive use of these
results in slowly executable code. Therefore, if possible, all operations should
be vectorized.
Example 3.3.6. We are programming the midpoint rule from the previous sec-
tion with a for-loop (the le name is mpr_long.m):
function S = mpr_long(fun,a,b,N)
h = (b-a)/N; S = 0;
for k = 0:(N-1),
S = S + feval(fun,a+h*(k+1/2));
end
S = h*S;
end
We verify that mpr and mpr_long yield the same result, and compare the execu-
tion times.
octave:1> t = cputime;
> Int1=mpr(gauss,0,5,500); t1=cputime-t;
octave:2> t = cputime;
> Int2=mpr_long(gauss,0,5,500); t2=cputime-t;
octave:3> Int1-Int2, t2/t1
ans = 0
ans = 45.250
3.4 Input and Output
save data var1, var2 .. saves the values of variables var1 etc. into the le
data. load data reads the le data, restoring the values of the previously
saved variables. fprintf(string[,var1,.. ]) resembles C syntax for format-
ting output, see man fprintf under Unix. format [long|short] enlarges or
reduces the number of decimals displayed. Calling format without argument
restores the default. The comand pause suspends evaluation until a key is
pressed.
Example 3.4.1. Display formatting.
octave:1> for k = .1:.2:.5,
> fprintf(1/%g = %10.2e\n,k,1/k); end
1/0.1 = 1.00e+01
1/0.3 = 3.33e+00
1/0.5 = 2.00e+00
84 CHAPTER 3. AN OVERVIEW OF OCTAVE
3.5 Graphics
3.5.1 2D Graphics
plot(x,y[,fmt]) plots a line through the points (x
j
, y
j
). With the string fmt
you can select line style and color; see help plot for details. Furthermore,
semilogx(x,y[,fmt]) works like plot with a logarithmic scale for the x-axis
and semilogy(x,y[,fmt]) works like plot with a logarithmic scale for the y-
axis. A plot with logarithmic scales on both axes is produced with the command
loglog(x,y[,fmt]).
Method 3.5.1. Procedure for plotting a function y = f(x) :
Generate a vector with the x -coordinates of the points to be plotted.
x = x_min:step_size:x_max;
Generate a vector containing the corresponding y-values by letting f act on
the vector x in an element-wise fashion:
y = f(x);
Important: Since f operates element-wise, care must be taken to use the opera-
tors .+, .-, .^ etc., instead of the usual +, - and ^!
Finally, the plot command is called.
plot(x,y)
To generate a coordinate grid, invoke:
plot(x,y)
grid
Example 3.5.2. Plotting a simple function with a coordinate grid.
octave:1> x = -10:.1:10;
octave:2> y = sin(x).*exp(-abs(x));
octave:3> plot(x,y)
octave:4> grid
3.5.2 3D Graphics
The command [xx,yy] = meshgrid(x,y) generates the grid data for a 3D plot,
i.e., two matrices xx whose rows are copies of x and yy whose columns are copies
of y. Applying mesh(x,y,z) after this plots the surface z = f(x, y) in three
dimensions.
Example 3.5.3. A plot of the surface z = sin
_
x
2
y
2
_
.
octave:1> x = -2:0.1:2;
octave:2> [xx,yy] = meshgrid(x,x);
octave:3> z = sin(xx.^2-yy.^2);
octave:4> mesh(x,x,z);
3.5. GRAPHICS 85
-0.4
-0.3
-0.2
-0.1
0
0.1
0.2
0.3
0.4
-10 -5 0 5 10
Figure 3.2: The graph y = f(x) = e
|x|
sin x.
3.5.3 Commands for 2D and 3D Graphics
The command title(string) writes string as title for the graphics and
xlabel(string) labels the x-axis with string. Similarly for other axes with
the commands ylabel(string) and zlabel(string). To set axis limits for
the plot, the command axis(v) can be used. The vector v has the form
v = (xmin, xmax, ymin, ymax[, zmin zmax]) .
hold [on|off] controls whether the next graphics output should or not clear
the previous graphics, whereas clg clears the graphics window.
86 CHAPTER 3. AN OVERVIEW OF OCTAVE
-2
-1.5
-1
-0.5
0
0.5
1
1.5
2
-2
-1.5
-1
-0.5
0
0.5
1
1.5
2 -1
-0.5
0
0.5
1
Figure 3.3: The surface z = f(x, y) = sin
_
x
2
y
2
_
.
Chapter 4
Numerical Computation
4.1 Preliminaries
GNU Octave is a high-level language, primarily intended for numerical compu-
tations. It provides a convenient interactive command line interface for solving
linear and nonlinear problems numerically, and for performing other numeri-
cal experiments. It may also be used as a batch-oriented language for data
processing.
GNU Octave is freely redistributable software. You may redistribute it
and/or modify it under the terms of the GNU General Public License as pub-
lished by the Free Software Foundation.
4.1.1 Running Octave
On most systems, Octave is started with the shell command octave. Octave
displays an initial message and then a prompt indicating it is ready to accept
input. You can begin typing Octave commands immediately afterwards.
If you get into trouble, you can usually interrupt Octave by typing Control-
C (written C-c for short). C-c gets its name from the fact that you type it by
holding down CTRL and then pressing C. Doing this will normally return you
to Octaves prompt.
To exit Octave, type quit or exit at the Octave prompt.
4.1.2 Editing What You Have Typed
At the Octave prompt, you can recall, edit, and reissue previous commands
using Emacs- or vi-style editing commands. The default keybindings use Emacs-
style commands. For example, to recall the previous command, press Control-p
(written C-p for short). Doing this will normally bring back the previous line
of input. C-n will bring up the next line of input, C-b will move the cursor
backward on the line, C-f will move the cursor forward on the line, etc.
87
88 CHAPTER 4. NUMERICAL COMPUTATION
4.1.3 Startup Files
When Octave starts, it looks for commands to execute from the les in the
following list. These les may contain any valid Octave commands, including
function denitions.
octave-home /share/octave/site/m/startup/octaverc
where octave-home is the directory in which Octave is installed. This le is
provided so that changes to the default Octave environment can be made glob-
ally for all users at your site for all versions of Octave you have installed. Care
should be taken when making changes to this le since all users of Octave at
your site will be aected. The default le may be overridden by the environment
variable OCTAVE_SITE_INITFILE.
octave-home /share/octave/version /m/startup/octaverc
where version is the version number of Octave. This le is provided so that
changes to the default Octave environment can be made globally for all users of
a particular version of Octave. Care should be taken when making changes to
this le since all users of Octave at your site will be aected. The default le
may be overridden by the environment variable as above.
~/.octaverc
This le is used to make personal changes to the default Octave environment.
.octaverc
This le can be used to make changes to the default Octave environment for
a particular project. Octave searches for this le in the current directory after
it reads ~/.octaverc. Any use of the cd command in the le will aect
the directory where Octave searches for it. If you start Octave in your home
directory, commands from the le ~/.octaverc will only be executed once.
A message will be displayed as each of the startup les is read if you invoke
Octave with the --verbose option but without the --silent option.
4.1.4 Quitting Octave
Quitting is done with either of the commands:
exit (status )
quit (status )
Exit the current Octave session. If the optional integer value status is supplied,
pass that value to the operating system as the Octaves exit status. The default
value is zero. The commands
atexit (fcn )
atexit (fcn, flag )
4.2. FUNCTIONS AND SCRIPTS 89
register a function to be called when Octave exits. For example,
function last_words ()
disp ("Bye bye");
endfunction
atexit ("last_words");
will print the message Bye bye when Octave exits. The additional argument
ag will register or unregister fcn from the list of functions to be called when
Octave exits. If flag is true, the function is registered, and if flag is false, it
is unregistered. For example, after registering the function last_words above,
atexit ("last_words", false);
will remove the function from the list and Octave will not call last_words when
it exits. Note that atexit only removes the rst occurrence of a function from
the list, so if a function was placed in the list multiple times with atexit, it
must also be removed from the list multiple times.
4.1.5 Help and Documentation
Octave has an extensive help facility. The same documentation that is available
in printed form is also available from the Octave prompt, because both forms
of the documentation are created from the same input le.
In order to get good help you rst need to know the name of the command
that you want to use. This name of the function may not always be obvious, but
a good place to start is to just type help. This will show you all the operators,
reserved words, functions, built-in variables, and function les. An alternative
is to search the documentation using the lookfor function. Once you know the
name of the function you wish to use, you can get more help on the function
by simply including the name as an argument to help. For example, help plot
will display the help text for the plot function. Octave sends output that is
too long to t on one screen through a pager like less or more. Type a RET to
advance one line, a SPC to advance one page, and Q to exit the pager.
The part of Octaves help facility that allows you to read the complete text
of the printed manual from within Octave normally uses a separate program
called Info. When you invoke Info you will be put into a menu driven program
that contains the entire Octave manual.
4.2 Functions and Scripts
Complicated Octave programs can often be simplied by dening functions.
Functions can be dened directly on the command line during interactive Octave
sessions, or in external les, and can be called just like built-in functions.
90 CHAPTER 4. NUMERICAL COMPUTATION
4.2.1 Dening Functions
In its simplest form, the denition of a function named name looks like this:
function name
body
endfunction
A valid function name is like a valid variable name: a sequence of letters, digits
and under- scores, not starting with a digit. Functions share the same pool of
names as variables. The function body consists of Octave statements. It is the
most important part of the denition, because it says what the function should
actually do. For example, here is a function that, when executed, will ring the
bell on your terminal (assuming that it is possible to do so):
function wakeup
printf ("\a");
endfunction
The printf statement simply tells Octave to print the string \a. The special
character \a stands for the alert character (ASCII 7). Once this function is
dened, you can ask Octave to evaluate it by typing the name of the function.
Normally, you will want to pass some information to the functions you dene.
The syntax for passing parameters to a function in Octave is
function name (arg-list )
body
endfunction
where arg-list is a comma-separated list of the functions arguments. When
the function is called, the argument names are used to hold the argument values
given in the call. The list of arguments may be empty, in which case this form
is equivalent to the one shown above. To print a message along with ringing the
bell, you might modify the wakeup to look like this:
function wakeup (message)
printf ("\a%s\n", message);
endfunction
Calling this function using a statement like this
wakeup ("Rise and shine!");
will cause Octave to ring your terminals bell and print the message Rise and
shine!, followed by a newline character (the \n in the rst argument to the
printf statement). In most cases, you will also want to get some information
back from the functions you dene. Here is the syntax for writing a function
that returns a single value:
function ret-var = name (arg-list )
body
endfunction
4.2. FUNCTIONS AND SCRIPTS 91
The symbol ret-var is the name of the variable that will hold the value to be
returned by the function. This variable must be dened before the end of the
function body in order for the function to return a value. Variables used in the
body of a function are local to the function. Variables named in arg-list and
ret-var are also local to the function. For example, here is a function that
computes the average of the elements of a vector:
function retval = avg (v)
retval = sum (v) / length (v);
endfunction
If we had written avg like this instead,
function retval = avg (v)
if (isvector (v))
retval = sum (v) / length (v);
endif
endfunction
and then called the function with a matrix instead of a vector as the argument,
Octave would have printed an error message like this:
error: value on right hand side of assignment is undefined
because the body of the if statement was never executed, and retval was never
dened. To prevent obscure errors like this, it is a good idea to always make
sure that the return variables will always have values, and to produce meaningful
error messages when problems are encountered. For example, avg could have
been written like this:
function retval = avg (v)
retval = 0;
if (isvector (v))
retval = sum (v) / length (v);
else
error ("avg: expecting vector argument");
endif
endfunction
There is still one additional problem with this function. What if it is called
without an argument? Without additional error checking, Octave will probably
print an error message that wont really help you track down the source of the
error. To allow you to catch errors like this, Octave provides each function with
an automatic variable called nargin. Each time a function is called, nargin is
automatically initialized to the number of arguments that have actually been
passed to the function. For example, we might rewrite the avg function like
this:
92 CHAPTER 4. NUMERICAL COMPUTATION
function retval = avg (v)
retval = 0;
if (nargin != 1)
usage ("avg (vector)");
endif
if (isvector (v))
retval = sum (v) / length (v);
else
error ("avg: expecting vector argument");
endif
endfunction
Although Octave does not automatically report an error if you call a function
with more arguments than expected, doing so probably indicates that something
is wrong. Octave also does not automatically report an error if a function is
called with too few arguments, but any attempt to use a variable that has not
been given a value will result in an error. To avoid such problems and to provide
useful messages, we check for both possibilities and issue our own error message.
4.2.2 Multiple Return Values
Unlike many other computer languages, Octave allows you to dene functions
that return more than one value. The syntax for dening functions that return
multiple values is
function [ret-list ] = name (arg-list )
body
endfunction
where name, arg-list, and body have the same meaning as before, and ret-list
is a comma-separated list of variable names that will hold the values returned
from the function. The list of return values must have at least one element. If
ret-list has only one element, this form of the function statement is equivalent
to the form described in the previous section.
Here is an example of a function that returns two values, the maximum
element of a vector and the index of its rst occurrence in the vector.
function [max, idx] = vmax (v)
idx = 1;
max = v (idx);
for i = 2:length (v)
if (v (i) > max)
max = v (i);
idx = i;
endif
endfor
endfunction
4.2. FUNCTIONS AND SCRIPTS 93
In this particular case, the two values could have been returned as elements of
a single array, but that is not always possible or convenient. The values to be
returned may not have compatible dimensions, and it is often desirable to give
the individual return values distinct names.
In addition to setting nargin each time a function is called, Octave also
automatically initializes nargout to the number of values that are expected to be
returned. This allows you to write functions that behave dierently depending
on the number of values that the user of the function has requested. The implicit
assignment to the built-in variable ans does not gure in the count of output
arguments, so the value of nargout may be zero.
The svd and lu (singular value decomposition and LU-factorization for ma-
trices) functions are examples of built-in functions that behave dierently de-
pending on the value of nargout.
It is possible to write functions that only set some return values. For exam-
ple, calling the function
function [x, y, z] = f ()
x = 1;
z = 2;
endfunction
as
[a, b, c] = f ()
produces:
a = 1
b = [](0x0)
c = 2
along with a warning.
4.2.3 Variable-length Argument Lists
Sometimes the number of input arguments is not known when the function is
dened. As an example think of a function that returns the smallest of all its
input arguments. For example,
a = smallest (1, 2, 3);
b = smallest (1, 2, 3, 4);
In this example both a and b would be 1. One way to write the smallest function
is
function val = smallest (arg1, arg2, arg3, arg4, arg5)
body
endfunction
94 CHAPTER 4. NUMERICAL COMPUTATION
and then use the value of nargin to determine which of the input arguments
should be considered. The problem with this approach is that it can only handle
a limited number of input arguments. If the special parameter name varargin
appears at the end of a function parameter list it indicates that the function
takes a variable number of input arguments. Using varargin the function looks
like this
function val = smallest (varargin)
body
endfunction
In the function body the input arguments can be accessed through the variable
varargin. This variable is a cell array containing all the input arguments. The
smallest function can now be dened like this
function val = smallest (varargin)
val = min ([varargin{:}]);
endfunction
This implementation handles any number of input arguments, but its also a very
simple solution to the problem. A slightly more complex example of varargin is
a function print_arguments that prints all input arguments. Such a function
can be dened like this
function print_arguments (varargin)
for i = 1:length (varargin)
printf ("Input argument %d: ", i);
disp (varargin{i});
endfor
endfunction
4.2.4 Variable-length Return Lists
It is possible to return a variable number of output arguments from a function
using a syntax similar to the one used with the special varargin parameter name.
To let a function return a variable number of output arguments the special
output parameter name varargout is used. As with varargin, varargout is a
cell array that will contain the requested output arguments.
As an example the following function sets the rst output argument to 1,
the second to 2, and so on.
function varargout = one_to_n ()
for i = 1:nargout
varargout{i} = i;
endfor
endfunction
When called this function returns values like this
4.2. FUNCTIONS AND SCRIPTS 95
[a, b, c] = one_to_n ()
a = 1
b = 2
c = 3
If varargin (varargout) does not appear as the last element of the input (output)
parameter list, then it is not special, and is handled the same as any other
parameter name.
4.2.5 Returning From a Function
The body of a user-dened function can contain a return statement. This state-
ment returns control to the rest of the Octave program. It looks like this:
return. Unlike the return statement in C, Octaves return statement cannot
be used to return a value from a function. Instead, you must assign values to
the list of return variables that are part of the function statement. The return
statement simply makes it easier to exit a function from a deeply nested loop
or conditional statement. Here is an example of a function that checks to see if
any elements of a vector are nonzero.
function retval = any_nonzero (v)
retval = 0;
for i = 1:length (v)
if (v (i) != 0)
retval = 1;
return;
endif
endfor
printf ("no nonzero elements found\n");
endfunction
Note that this function could not have been written using the break statement
to exit the loop once a nonzero value is found without adding extra logic to
avoid printing the message if the vector does contain a nonzero element.
4.2.6 Function Files
Except for simple one-shot programs, it is not practical to have to dene all the
functions you need each time you need them. Instead, you will normally want
to save them in a le so that you can easily edit them, and save them for use
at a later time.
Octave does not require you to load function denitions from les before
using them. You simply need to put the function denitions in a place where
Octave can nd them.
When Octave encounters an identier that is undened, it rst looks for
variables or functions that are already compiled and currently listed in its symbol
table. If it fails to nd a denition there, it searches a list of directories (the
96 CHAPTER 4. NUMERICAL COMPUTATION
path) for les ending in .m that have the same base name as the undened
identier. Once Octave nds a le with a name that matches, the contents of
the le are read. If it denes a single function, it is compiled and executed.
When Octave denes a function from a function le, it saves the full name
of the le it read and the time stamp on the le. If the time stamp on the
le changes, Octave may reload the le. When Octave is running interactively,
time stamp checking normally happens at most once each time Octave prints
the prompt. Searching for new function denitions also occurs if the current
working directory changes.
Checking the time stamp allows you to edit the denition of a function while
Octave is running, and automatically use the new function denition without
having to restart your Octave session.
4.2.7 Subfunctions
A function le may contain secondary functions called subfunctions. These
secondary func- tions are only visible to the other functions in the same function
le. For example, a le f.m containing
function f ()
printf ("in f, calling g\n");
g ()
endfunction
function g ()
printf ("in g, calling h\n");
h ()
endfunction
function h ()
printf ("in h\n")
endfunction
denes a main function f and two subfunctions. The subfunctions g and h may
only be called from the main function f or from the other subfunctions, but not
from outside the le f.m.
4.2.8 Private Functions
In many cases one function needs to access one or more helper functions. If the
helper function is limited to the scope of a single function, then subfunctions as
discussed above might be used. However, if a single helper function is used by
more than one function, then this is no longer possible. In this case the helper
functions might be placed in a subdirectory, called private, of the directory in
which the functions needing access to this helper function are found.
As a simple example, consider a function func1, that calls a helper function
func2 to do much of the work. For example
function y = func1 (x)
4.2. FUNCTIONS AND SCRIPTS 97
y = func2 (x);
endfunction
Then if the path to func1 is <directory>/func1.m, and if func2 is found in
the directory <directory>/private/func2.m, then func2 is only available for
use of the functions, like func1, that are found in <directory>.
4.2.9 Script Files
A script le is a le containing (almost) any sequence of Octave commands. It
is read and evaluated just as if you had typed each command at the Octave
prompt, and provides a convenient way to perform a sequence of commands
that do not logically belong inside a function.
Unlike a function le, a script le must not begin with the keyword function.
If it does, Octave will assume that it is a function le, and that it denes a single
function that should be evaluated as soon as it is dened.
A script le also diers from a function le in that the variables named in a
script le are not local variables, but are in the same scope as the other variables
that are visible on the command line.
Even though a script le may not begin with the function keyword, it is
possible to dene more than one function in a single script le and load (but
not execute) all of them at once. To do this, the rst token in the le (ignoring
comments and other white space) must be something other than function. If
you have no other statements to evaluate, you can use a statement that has no
eect, like this:
# Prevent Octave from thinking that this
# is a function file:
1;
# Define function one:
function one ()
...
To have Octave read and compile these functions into an internal form, you
need to make sure that the le is in Octaves load path (accessible through the
path function), then simply type the base name of the le that contains the
commands. (Octave uses the same rules to search for script les as it does to
search for function les.)
If the rst token in a le (ignoring comments) is function, Octave will compile
the func- tion and try to execute it, printing a message warning about any non-
whitespace characters that appear after the function denition.
Note that Octave does not try to look up the denition of any identier
until it needs to evaluate it. This means that Octave will compile the following
statements if they appear in a script le, or are typed at the command line,
# not a function file:
1;
98 CHAPTER 4. NUMERICAL COMPUTATION
function foo ()
do_something ();
endfunction
function do_something ()
do_something_else ();
endfunction
even though the function do_something is not dened before it is referenced in
the function foo. This is not an error because Octave does not need to resolve all
symbols that are referenced by a function until the function is actually evaluated.
Since Octave doesnt look for denitions until they are needed, the following
code will always print bar = 3 whether it is typed directly on the command
line, read from a script le, or is part of a function body, even if there is a
function or script le called bar.m in Octaves path.
eval ("bar = 3");
bar
Code like this appearing within a function body could fool Octave if denitions
were resolved as the function was being compiled. It would be virtually impos-
sible to make Octave clever enough to evaluate this code in a consistent fashion.
The parser would have to be able to perform the call to eval at compile time, and
that would be impossible unless all the references in the string to be evaluated
could also be resolved, and requiring that would be too restrictive (the string
might come from user input, or depend on things that are not known until the
function is evaluated).
4.2.10 Function Handles, Inline Functions, and Anony-
mous Functions
It can be very convenient store a function in a variable so that it can be passed
to a dierent function. For example, a function that performs numerical mini-
mization needs access to the function that should be minimized.
Function Handles
A function handle is a pointer to another function and is dened with the syntax
@function-name. For example, f = @sin; Creates a function handle called f
that refers to the function sin.
Function handles are used to call other functions indirectly, or to pass a
function as an argument to another function like quad or fsolve. For example
f = @sin;
quad (f, 0, pi)
You may use feval to call a function using function handle, or simply write
the name of the function handle followed by an argument list. If there are no
arguments, you must use an empty argument list (). For example
4.3. EQUATIONS AND OPTIMIZATION 99
f = @sin;
feval (f, pi/4)
f (pi/4)
Anonymous Functions
Anonymous functions are dened using the syntax
@(argument-list ) expression
Any variables that are not found in the argument list are inherited from the
enclosing scope. Anonymous functions are useful for creating simple unnamed
functions from expressions or for wrapping calls to other functions to adapt
them for use by functions like quad. For example,
f = @(x) x.^2;
quad (f, 0, 10)
creates a simple unnamed function from the expression x.^2 and passes it to
quad,
quad (@(x) sin (x), 0, pi)
wraps another function, and
a = 1;
b = 2;
quad (@(x) betainc (x, a, b), 0, 0.4)
adapts a function with several parameters to the form required by quad. In this
example, the values of a and b that are passed to betainc are inherited from
the current environment.
Inline Functions
An inline function is created from a string containing the function body using
the inline function. The following code denes the function () = +2.
f = inline("x^2 + 2");
After this it is possible to evaluate f(x) at any x by writing f(x).
4.3 Equations and Optimization
4.3.1 Nonlinear Equations
Octave can solve sets of nonlinear equations of the form
f (x) = 0
100 CHAPTER 4. NUMERICAL COMPUTATION
using the function fsolve, which is based on the Minpack subroutine hybrd.
This is an iterative technique so a starting point will have to be provided. This
also has the consequence that convergence is not guaranteed even if a solution
exists.
Example 4.3.1. Consider the set of equations
2x
2
+ 3xy + 4 sin(y) 6 = 0 ,
3x
2
2xy
2
+ 3 cos (y) + 4 = 0 .
We rst need to write a function to compute the value of the given function.
Here:
function y = f (x)
y(1) = -2*x(1)^2 + 3*x(1)*x(2) + 4*sin(x(2)) - 6;
y(2) = 3*x(1)^2 - 2*x(1)*x(2)^2 + 3*cos(x(1)) + 4;
endfunction
Then, call fsolve with a specied initial condition to nd the roots of the system
of equations. For example, given the function f dened above,
[x, fval, info] = fsolve (@f, [1; 2])
results in the solution
x =
0.57983
2.54621
fval =
-5.7184e-10
5.5460e-10
info = 1
A value of info = 1 indicates that the solution has converged. The function
perror may be used to print English messages corresponding to the numeric
error codes. For example,
perror ("fsolve", 1)
solution converged to requested tolerance
When no Jacobian is supplied (as in the example above) it is approximated
numerically. This requires more function evaluations, and hence is less ecient.
In the example above we could compute the Jacobian analytically as
_
f1
x1
f1
x2
f2
x1
f2
x2
_
=
_
3x
2
4x
1
4 cos (x
2
) + 3x
1
2x
2
2
3 sin(x
1
) + 6x
1
4x
1
x
2
_
The Jacobian can then be used with the following script and call to fsolve:
4.3. EQUATIONS AND OPTIMIZATION 101
# fsolvetest.m
1;
function [y,J] = f(x)
y = zeros(size(x));
y(1) = -2*x(1)^2 + 3*x(1)*x(2) + 4*sin(x(2)) - 6;
y(2) = 3*x(1)^2 - 2*x(1)*x(2)^2 + 3*cos(x(1)) + 4;
if (nargout == 2)
J(1,1) = 3*x(2) - 4*x(1);
J(1,2) = 4*cos(x(2)) + 3*x(1);
J(2,1) = -2*x(2)^2 - 3*sin(x(1)) + 6*x(1);
J(2,2) = -4*x(1)*x(2);
end
endfunction
[x, fval, info] = fsolve (@f, [0; 0],optimset("Jacobian","on"))
# end of fsolvetest.m
which gives the same solution as before.
4.3.2 Optimization
Octave comes with support for solving various kinds of optimization problems.
Specically Octave can solve problems in Linear Programming, Quadratic Pro-
gramming, Nonlinear Programming, and Linear Least Squares Minimization.
Linear Programming
Octave can solve Linear Programming problems using the glpk function. That
is, Octave can solve
min
x
c
T
x ,
subject to the linear constraints Ax = b, x 0. The glpk function also supports
variations of this problem.
Quadratic Programming
Octave can also solve Quadratic Programming problems through the func-
tion qp, this is
min
x
1
2
x
T
Hx +x
T
q ,
subject to
Ax = b , lb x ub , A
lb
A A
ub
.
Nonlinear Programming
Octave can also perform general nonlinear minimization using the successive
quadratic programming solver sqp. The problem formulation is
min
x
(x) ,
102 CHAPTER 4. NUMERICAL COMPUTATION
subject to
g (x) = 0 , h(x) 0 , lb x ub ,
where g (x) is the gradient and h(x) is the hessian of , respectively.
Example 4.3.2. Consider the following:
function r = g (x)
r = [ sumsq(x)-10;
x(2)*x(3)-5*x(4)*x(5);
x(1)^3+x(2)^3+1 ];
endfunction
function obj = phi (x)
obj = exp(prod(x)) - 0.5*(x(1)^3+x(2)^3+1)^2;
endfunction
x0 = [-1.8; 1.7; 1.9; -0.8; -0.8];
[x, obj, info, iter, nf, lambda] = sqp (x0, @phi, @g, [])
x = -1.71714
1.59571
1.82725
-0.76364
-0.76364
obj = 0.053950
info = 101
iter = 8
nf = 10
lambda = -0.0401627
0.0379578
-0.0052227
Linear Least Squares Programming
Octave also supports linear least squares minimization. That is, Octave can nd
the parameter b such that the model y = xb ts data (x, y) as well as possible,
assuming zero-mean Gaussian noise. If the noise is assumed to be isotropic the
problem can be solved using the \ or / operators, or the ols function. In
the general case where the noise is assumed to be anisotropic the gls is needed.
4.4. BOUNDARY/INITIAL VALUE PROBLEMS 103
4.4 Boundary/Initial Value Problems
4.4.1 Integrating Dierential Equations
Octave has built-in functions for solving nonlinear dierential equations of the
form
dx
dt
= f(x, t) , x(t = t
0
) = x
0
.
For Octave to integrate equations of this form, you must rst provide a denition
of the function f(x, t). This is straightforward, and may be accomplished by
entering the function body directly on the command line. For example, the
following commands dene the right- hand side function for an interesting pair
of nonlinear dierential equations. Note that while you are entering a function,
Octave responds with a dierent prompt, to indicate that it is waiting for you
to complete your input.
Example 4.4.1. A system of ordiary dierential equations.
octave:1> function xdot = f (x, t)
>
> r = 0.25;
> k = 1.4;
> a = 1.5;
> b = 0.16;
> c = 0.9;
> d = 0.8;
>
> xdot(1) = r*x(1)*(1 - x(1)/k) - a*x(1)*x(2)/(1 + b*x(1));
> xdot(2) = c*a*x(1)*x(2)/(1 + b*x(1)) - d*x(2);
>
> endfunction
Given the initial condition
octave:2> x0 = [1; 2];
and the set of output times as a column vector (note that the rst output time
corresponds to the initial condition given above)
octave:3> t = linspace (0, 50, 200);
it is easy to integrate the set of dierential equations:
octave:4> x = lsode ("f", x0, t);
The function lsode uses the Livermore Solver for Ordinary Dierential Equa-
tions.
1
To display the solution graphically, use the command
1
Described in A. C. Hindmarsh, ODEPACK, a Systematized Collection of ODE Solvers,
Scientic Computing, R. S. Stepleman et al. (Eds.), North-Holland, Amsterdam, 1983, pages
55-64.
104 CHAPTER 4. NUMERICAL COMPUTATION
octave:1> plot (t, x)
If you are using a graphical user interface, Octave will automatically create a
separate window to display the plot.
To save a plot once it has been displayed on the screen, use the print com-
mand. For example,
print -deps foo.eps
will create a le called foo.eps that contains a rendering of the current plot
in Encapsulated PostScript format. The command
help print
explains more options for the print command and provides a list of additional
output le formats.
4.5 Partial Dierential Equations
To date (October 2011) there does not seem to be a stable implementation of
a program package for partial dierential equation in Octave. Some attempts
to port the routine pdepe from Matlab to Octave have been made, however,
these appear to be problematic since pdepe contains calls to routines in Matlab
not available in Octave. Hence, these have to be substituted with suitable
Octave alternatives. Perhaps the best approach in Octave for PDE is simply
to rewrite these by hand as systems of ODEs using some established method
(lines, nite dierence, nite element) and solve the resulting ODE-system with
code available in Octave.
4.6 Integration
Octave comes with several built-in functions for computing the integral of a func-
tion numerically. These functions all solve one-dimensional integration prob-
lems.
4.6.1 Functions of One Variable
Octave supports three dierent algorithms for computing the integral
_
b
a
f(x) dx
of a function f(x) over the interval for x from a to b. These are:
quad Numerical integration based on Gaussian quadrature.
quadl Numerical integration using an adaptive Lobatto rule.
quadgk Numerical integration using an adaptive Gauss-Konrod rule.
quadv Numerical integration using an adaptive vectorized Simpsons rule.
trapz Numerical integration using the trapezoidal method.
4.6. INTEGRATION 105
Besides these functions Octave also allows you to perform cumulative numerical
integration using the trapezoidal method through the cumtrapz function.
Example 4.6.1. We consider the integral
_
b
a
f(x) dx =
_
3
0
x
_
|1 x| sin
1
x
dx .
This is a fairly dicult integration (plot the function over the range of integra-
tion to see why). The rst step is to dene the function:
function y = f (x)
y = x .* sin (1 ./ x) .* sqrt (abs (1 - x));
endfunction
Note the use of the dot forms of the operators. This is not necessary for
the call to quad, but it makes it much easier to generate a set of points for
plotting (because it makes it possible to call the function with a vector argument
to produce a vector result). Then we simply call quad:
[v, ier, nfun, err] = quad ("f", 0, 3)
1.9819
1
5061
1.1522e-07
Although quad returns a nonzero value for ier, the result is reasonably accurate
(to see why, examine what happens to the result if you move the lower bound to
0.1, then 0.01, then 0.001, etc.).
Another method for integration is implemented in the routine
[r, amat, bmat, q ] = colloc (n, "left", "right")
colloc computes derivative and integral weight matrices for orthogonal collo-
cation using the subroutines given in J. Villadsen and M. L. Michelsen, Solution
of Dierential Equation Models by Polynomial Approximation.
Here is an example of using colloc to generate weight matrices for solving
a boundary value problem for the second order dierential equation
u

= 0 , u(0) = 0 , u(1) = 1 .
First, we can generate the weight matrices for n points (including the endpoints
of the interval), and incorporate the boundary conditions in the right hand side
(for a specic value of ).
n = 7;
alpha = 0.1;
[r, a, b] = colloc (n-2, "left", "right");
at = a(2:n-1,2:n-1);
bt = b(2:n-1,2:n-1);
rhs = alpha * b(2:n-1,n) - a(2:n-1,n);
106 CHAPTER 4. NUMERICAL COMPUTATION
Then the solution at the roots r is
u = [ 0; (at - alpha * bt) \ rhs; 1]
[ 0.00; 0.004; 0.01 0.00; 0.12; 0.62; 1.00 ]
4.6.2 Functions of Multiple Variables
Octave does not have built-in functions for computing the integral of functions
of multiple variables directly. It is however possible to compute the integral of a
function of multiple variables using the functions for one-dimensional integrals.
To illustrate how the integration can be performed, we will integrate the
function
f(x, y) =

xy sin (xy) .
for x and y between 0 and 1.
The rst approach creates a function that integrates f with respect to x,
and then integrates that function with respect to y. Since quad is written in
Fortran it cannot be called recursively. This means that quad cannot integrate
a function that calls quad, and hence cannot be used to perform the double
integration. It is however possible with quadl, which is what the following code
does.
function I = g(y)
I = ones(1, length(y));
for i = 1:length(y)
f = @(x) sin(pi.*x.*y(i)).*sqrt(x.*y(i));
I(i) = quadl(f, 0, 1);
endfor
endfunction
I = quadl("g", 0, 1)
0.30022
The above process can be simplied with the dblquad and triplequad functions
for integrals over two and three variables. For example
I = dblquad (@(x, y) sin(pi.*x.*y).*sqrt(x.*y), 0, 1, 0, 1)
0.30022
The above mentioned approach works but is fairly slow, and that problem
increases exponentially with the dimensionality the problem. Another possible
solution is to use Orthogonal Collocation as described in the previous section.
The integral of a function f(x, y) for x and y between 0 and 1 can be approxi-
mated using n points by
_
1
0
_
1
0
f(x, y) dxdy
n

i=1
n

j=1
q
i
q
j
f (r
i
, r
j
) ,
where (r
i
)
n
i=1
and (q
i
)
n
i=1
are returned in vectors from colloc(n). The gen-
eralization to more than two variables is straightforward. The following code
computes the studied integral using n = 7 points.
4.6. INTEGRATION 107
f = @(x,y) sin(pi*x*y).*sqrt(x*y);
n = 7;
[t, A, B, q] = colloc(n);
I = q*f(t,t)*q;
0.30022
It should be noted that the number of points determines the quality of the
approximation. If the integration needs to be performed between a and b instead
of 0 and 1, a change of variables is needed.
108 CHAPTER 4. NUMERICAL COMPUTATION
Chapter 5
Exercises
5.1 wxMaxima
5.1.1 Inverse Functions
Exercise 5.1.1. Consider the function f(x) =
x+2
3x1
, dened for x R \
_
1
3
_
.
Study the monotonicity of the function on its set of denition. Compute the
inverse function f
1
(x). Study the composition f(f(f(f(f(f (x)))))), i.e.,
the function composed n times with itself.
Solution: We nd f

and show that the derivative always is negative. We


solve the inverse function and observe that f
1
(x) = f(x). Therefore the com-
position is equal to the identity if n is even and f otherwise.
f(x) := (x+2)/(3*x-1);
fp(x) := diff(f(x),x);
factor(ratsimp(diff(f(x),x)));
f(f(f(f(x))));
ratsimp(%);
f(f(f(x)));
ratsimp(%);
Exercise 5.1.2. A study of the mass balance of water for a tank that is drained
at the rate y(t) as a function of time t resulted in the following dimensionless
relationship:
t = y
0
y + ln
1 y
0
1 y
,
where y(0) = y
0
is the outow of water at time t = 0. Unfortunately, this
equation is implicit for y(t), however, it can be considered an inverse function t =
f
1
(y). Discuss the existence of f and the possibility of deriving an explicit
equation y = f(t).
Solution: It turns out that t = g(y) has an inverse function, as g

is positive
for the physically feasible case 0 < y < 1 and negative otherwise. Hence,
109
110 CHAPTER 5. EXERCISES
f exists. However, an explicit relation y = f(t) cannot be obtained; Maxima
fails to implement the solution and we get a relation with y on both sides.
g(y) := y0 - y + log((1-y0)/(1-y));
gp(y) := diff(g(y),y);
5.1.2 Limits
Exercise 5.1.3. In the special theory of relativity, the kinetic energy of a
particle having mass m and velocity v is
T(v, c) =
mc
2
_
1
_
v
c
_
2
mc
2
,
where c is the speed of light. On the other hand, in classical mechanics, the
particle would have kinetic energy K(v) =
1
2
mv
2
. Compute the following limits
a) lim
v0
T(v,c)
K(v)
.
b) lim
c
T(v,c)
K(v)
.
Solution:
# case (a)
T(v,c) := (m*c^2) * ( 1/sqrt(1-(v/c)^2) - 1 );
K(v) := (1/2) * m * v^2;
limit(T(v,c) / K(v), v, 0);
# case (b)
limit(T(v,c) / K(v), c, inf);
5.1.3 Dierentiation
Exercise 5.1.4. An electrical current passing through a circular coil with ra-
dius r exerts a force
F(x) =
kx
(x
2
+r
2
)
5
2
on a small magnet at the distance x above the center of the coil. k is a constant
of proportionality. Show that F has a maximum for x =
r
2
.
Solution: F is continuous and dierentiable for every x R and lim
x
F(x) =
0. Thus, a maximum must be located in the critical points x

=
r
2
. One of
these is the location of a minimum and the other that of a maximum. This is
seen from the observation F

(x
+
) = F

(x

).
F(x) := k*x / (x^2 + r^2)^(5/2);
define(Fp(x), diff(F(x),x));
sol : solve([Fp(x) = 0], [x]);
Fpp(sol);
ratsimp(ratsimp(%));
5.2. OCTAVE 111
5.1.4 Integration
Exercise 5.1.5. Compute the integral
_
x
5
+x
4
8
x
3
4x
dx .
Solution:
f(x) := (x^5 + x^4 - 8)/(x^3 - 4*x);
integrate(f(x), x);
ratsimp(%);
diff(%,x);
ratsimp(%);
5.2 Octave
5.2.1 Linear Algebra
Exercise 5.2.1. Consider a matrix A and a vector b with
A =
_
1 2
3 4
_
and b =
_
36
88
_
.
Solve the system of equations Ax = b. Compute the LU- and QR-decompositions,
as well as the eigenvalues and eigenvectors of A. Compute the Cholesky decom-
position of A
T
A and verify that cond
_
A
T
A
_
= cond(A)
2
.
Solution:
A = reshape(1:4,2,2).; b = [36; 88];
A\b
[L,U,P] = lu(A)
[Q,R] = qr(A)
[V,D] = eig(A)
A2 = A.*A;
R = chol(A2)
cond(A)^2 - cond(A2)
5.2.2 Timing
Exercise 5.2.2. Compute the matrix-vector product of a 100 100 random
matrix and a random vector in two dierent ways. First, use the built-in matrix
multiplication *. Next, use for-loops. Compare the results and computing times.
Solution:
A = rand(100); b = rand(100,1);
t = cputime;
v = A*b; t1 = cputime-t;
112 CHAPTER 5. EXERCISES
w = zeros(100,1);
t = cputime;
for n = 1:100,
for m = 1:100
w(n) = w(n)+A(n,m)*b(m);
end
end
t2 = cputime-t;
norm(v-w), t2/t1
Running this script yields the following output.
ans = 0
ans = 577.00
5.2.3 Stability Functions of BDF-integrators
Exercise 5.2.3. Calculate all the roots of the polynomial
147
60

6
6
5
+
15
2

4

20
3

3
+
15
4

2

6
5
+
1
6
.
Hint: Use the command compan.
Plot these roots as points in the complex plane and draw a unit circle for
comparison. (Hint: Use hold, real and imag).
Solution:
bdf6 = [147/60 -6 15/2 -20/3 15/4 -6/5 1/6];
R = eig(compan(bdf6));
plot(R,+); hold on
plot(exp(pi*i*[0:.01:2]));
if any(find(abs(R)>1))
fprintf(BDF6 is unstable\n);
else
fprintf(BDF6 is stable\n);
end
5.2.4 3D Plotting
Exercise 5.2.4. Plot the graph of the function
f(x, y) = exp(x
2
y
2
) .
Solution:
x = -3:0.1:3;
[xx,yy] = meshgrid(x,x);
z = exp(-xx.^2-yy.^2);
5.2. OCTAVE 113
-1
-0.5
0
0.5
1
-1 -0.5 0 0.5 1 1.5
Figure 5.1: The roots of the polynomial for the BDF-integrator.
figure, mesh(x,x,z);
title(e^{-x^2-y^2});
print(3d-plot2.eps,-deps
5.2.5 Hilbert Matrix
Exercise 5.2.5. For each nn Hilbert matrix H, where n = 1, . . . , 15, compute
the solution to the linear system Hx = b, b = ones(n,1), and compare this
solution to the exact one obtained through the exact inverse Hilbert matrix.
Calculate the error and the condition number of the matrix and plot both in
semi-logarithmic coordinates. (Hint: Use hilb, invhilb.)
Solution:
err = zeros(15,1); co = zeros(15,1);
for k = 1:15
H = hilb(k);
b = ones(k,1);
err(k) = norm(H\b-invhilb(k)*b);
co(k) = cond(H);
end
semilogy(1:15,err,r,1:15,co,x);
114 CHAPTER 5. EXERCISES
-3
-2
-1
0
1
2
3
-3
-2
-1
0
1
2
3 0
0.2
0.4
0.6
0.8
1
e
-x
2
-y
2
Figure 5.2: The surface z = f(x, y) = e
x
2
y
2
.
5.2.6 Least Square Fit of a Straight Line
Exercise 5.2.6. Calculate the least square t of a straight line to the points
(x
j
, y
j
) , given as two vectors x and y. Plot the points and the line.
Solution:
function coeff = least_square (x,y)
n = length(x);
A = [x ones(n,1)];
coeff = A\y;
plot(x,y,x);
hold on
interv = [min(x) max(x)];
plot(interv,coeff(1)*interv+coeff(2));
end
5.2.7 Trapezoidal Rule
Exercise 5.2.7. Write a program to integrate an arbitrary function f in one
variable on an interval [a, b] numerically, i.e., estimate
_
b
a
f(x) dx
5.2. OCTAVE 115
using the trapezoidal rule with subinterval division h =
ba
N
:
_
b
a
f(x) dx h
_
_
f(a) +f(b)
2
+
N1

j=1
f(a +jh)
_
_
.
For a function f of choice, we will check by generating a doubly logarithmic
error plot that the trapezoidal rule is of order 2.
Solution:
function S = trapez(fun,a,b,N)
h = (b-a)/N;
% fy = feval(fun,[a:h:b]); better:
fy = feval(fun,linspace(a,b,N+1));
fy(1) = fy(1)/2;
fy(N+1) = fy(N+1)/2;
S = h*sum(fy);
end
function y = f(x)
y = exp(x);
end
for k=1:15;
err(k) = abs(exp(1)-1-trapez(f,0,1,2^k));
end
loglog(1./2.^[1:15],err);
hold on;
title(Trapezoidal rule, f(x) = exp(x));
xlabel(Increment);
ylabel(Error);
loglog(1./2.^[1:15],err,x);
116 CHAPTER 5. EXERCISES
Chapter 6
Course problems
In this nal chapter, we consider a set of problems for application of the software
tools treated above. Many of the problems are from various sectors of chemical
engineering, however, some more general topics from mathematical physics and
applied mathematics are also included. Although many of the exercises can be
done without software tools, the basic idea is to demonstrate the use of wxMax-
ima and Octave in their solution. Therefore, these packages should be applied
as extensively as possible and a self-contained report of the theory together with
documentation and program listings should be included in the solution.
6.1 Single Nonlinear Equation
We use the van der Waal equation of state to calculate molar volume and com-
pressibility factor for a gas.
The ideal gas law is known to describe the pressure-volume-temperature rela-
tionship for a gas only at relatively low (near atmospheric) pressures. At higher
pressures, a more complex pressure-volume-temperature model is required. The
van der Waal equation of state is given by
_
p +
a
V
2
_
(V b) = RT ,
where
a =
27
64
_
R
2
T
2
c
p
c
_
and
b =
RT
c
8p
c
.
117
118 CHAPTER 6. COURSE PROBLEMS
The variables and constants are dened as follows:
p = pressure in atm.
V = molar volume in
liters
mol
.
T = temperature in K.
R = gas constant
_
0.08206
atm liter
mol K
_
.
T
c
= critical temperature (405.5 K for ammonia) .
p
c
= critical pressure (111.3 atm for ammonia) .
The reduced pressure, p
r
, and compressibility factor are dened as:
p
r
=
p
p
c
, Z =
pV
RT
.
Exercise 6.1.1. Based on the above theory, do the following:
(a) Compute the molar volume and compressibility for gaseous ammonia at
pressure p = 56 atm and temperature T = 450 K using the van der Waal
equation of state.
(b) Repeat the computation for the following reduced pressures p
r
= 1, 2, 4,
10 and 20.
(c) Depict the variation Z (p
r
).
6.2 Another Single Nonlinear Equation
Here, an application from uid dynamics will be studied. We calculate the
terminal velocity for solid particles falling in a uid under the force of gravity.
A simple force balance applied to a spherical particle reaching terminal ve-
locity in a uid leads to the equation
v
t
=

4g (
p
) D
p
3C
D

,
where v
t
is the terminal velocity in
m
s
, g = 9.81
m
s
2
is the acceleration of gravity,
and
p
are the densities in
kg
m
3
of the uid and of the particle, respectively, D
p
is the diameter of the spherical particle in m and C
D
is a dimensionless drag
coecient.
The drag coecient on a spherical particle at terminal velocity varies with
6.3. A SET OF LINEAR EQUATIONS 119
the Reynolds number Re as follows:
C
D
=
_

_
24
Re
, Re < 0.1 ,
24
Re
_
1 + 0.14Re
0.7
_
, 0.1 Re 1000 ,
0.44 , 1000 < Re 350000 ,
0.19
80000
Re
, Re > 350000 ,
where the Reynolds number is dened as
Re =
D
p
v
t

,
with the dynamic viscosity in Pa s or
kg
ms
.
Exercise 6.2.1. Calculate the terminal velocity for
(a) coal particles with
p
= 1800
kg
m
3
, D
p
= 208 10
6
m falling in water
at T = 298.15 K with = 994.6
kg
m
3
and = 8.931 10
4 kg
ms
.
(b) coal particles in water separated in a centrifugal device with an accelera-
tion of 30g.
6.3 A Set of Linear Equations
We consider material balance equations applied to a steady-state process with-
out recycling.
The four solvents xylene, styrene, toluene and benzene are separated from
a composite inow by use of the array of distillation towers shown in the gure
below, where F, B, B
1
, B
2
, D, D
1
and D
2
are the molar ow rates measured
in
mol
min
.
Applying material balances for the four individual components yields the set
of linear equations:
Xylene: 0.07D
1
+ 0.18B
1
+ 0.15D
2
+ 0.24B
2
= 0.15 70
Styrene: 0.04D
1
+ 0.24B
1
+ 0.10D
2
+ 0.65B
2
= 0.25 70
Toluene: 0.54D
1
+ 0.42B
1
+ 0.54D
2
+ 0.10B
2
= 0.40 70
Benzene: 0.35D
1
+ 0.16B
1
+ 0.21D
2
+ 0.01B
2
= 0.20 70
Moreover, we can formulate overall balances as well as component material
120 CHAPTER 6. COURSE PROBLEMS
Figure 6.1: An array of distillation towers used for separation of solvents.
balances for the two distillation towers; for column # 2 we obtain:
Molar ow rates: D = D
1
+B
1
Xylene: X
Dx
D = 0.07D
1
+ 0.18B
1
Styrene: X
Ds
D = 0.04D
1
+ 0.24B
1
Toluene: X
Dt
D = 0.54D
1
+ 0.42B
1
Benzene: X
Db
D = 0.35D
1
+ 0.16B
1
.
Here, X
Dx
, X
Ds
, X
Dt
and X
Db
denote the mole fractions of xylene, styrene,
toluene and benzene, respectively. Similarly, for the distillation column # 3, we
have
Molar ow rates: B = D
2
+B
2
Xylene: X
Dx
B = 0.15D
2
+ 0.24B
2
Styrene: X
Ds
B = 0.10D
2
+ 0.65B
2
Toluene: X
Dt
B = 0.54D
2
+ 0.10B
2
Benzene: X
Db
B = 0.21D
2
+ 0.01B
2
.
Exercise 6.3.1. Compute the molar ow rates for
(a) streams B
1
, B
2
, D
1
and D
2
.
(b) streams B and D and their composition.
6.4. NONLINEAR REGRESSION 121
6.4 Nonlinear Regression
We use polynomials, a modied Clausius-Clapeyron equation and the Antoine
equation to model vapor pressure versus temperature data in thermodynamics.
Consider the vapor pressure data for benzene in the table below:
We now wish to model the relationship p(T) based on a set of regression
models and the data given in the table. Initially, we consider a polynomial
p(T) =
n

i=0
a
i
T
n
= a
0
+a
1
T +a
2
T
2
+ +a
n
T
n
,
where a
0
, a
1
, a
2
, .., a
n
are the parameters (coecients) to be determined by
regression and n is the degree of the polynomial. Beside the coecients, also
the choice of the degree n is customarily optimized so as to give the best rep-
resentation of the tabulated data by the polynomial. Our criterion for best
representation is attainment of a minimum of the least-squares objective func-
tion:

data points
(p
data
p (T
data
))
2
.
An alternative to polynomial regression is the equation of Clausius-Clapeyron,
which for our data units take the form
log (p(T)) = A
B
T + 273.15
.
Note that the denominator is just the temperature on the absolute scale. Pa-
rameters A and B are parameters to be determined by the regression.
122 CHAPTER 6. COURSE PROBLEMS
A similar form of mathematical model is the Antoine equation, with the
modication of one added parameter in comparison with Clausius-Clapeyrons
equation:
log (p(T)) = A
B
T +C
.
In this case, however, the regression analysis is trickier, as the Antoine equation
cannot be linearized. Therefore, nonlinear regression must be utilized.
Exercise 6.4.1. Perform regression analysis on the above tabulated data with
mathematical model according to
(a) an n:th degree polynomial with optimal choice of n.
(b) the Clausius-Clapeyrons equation.
(c) the Antoine equation.
6.5 A Set of Nonlinear Equations
We consider a system of nonlinear algebraic equations describing chemical equi-
librium for multiple reactions. The following chemical reactions are taking place
in a constant-volume, gas-phase batch reactor:
A + B C + D
B + C X + Y
A + X Z
A system of algebraic equations describes the equilibrium of these reactions.
From thermodynamics and stoichiometry we can derive the following relation-
ships.
K
C1
=
c
C
c
D
c
A
c
B
, K
C2
=
c
X
c
Y
c
B
c
C
, K
C3
=
c
Z
c
A
c
X
.
c
A
= c
A0
c
D
c
Z
, c
B
= c
B0
c
D
c
Y
,
c
C
= c
D
c
Y
, c
Y
= c
X
+c
Z
.
Here, the variables c
A
, c
B
, c
C
, c
D
, c
X
, c
Y
and c
Z
denote the equilibrium con-
centrations of the various species, resulting from the initial concentrations c
A0
and c
B0
. The equilibrium constants K
C1
, K
C2
and K
C3
are known.
Exercise 6.5.1. Compute the equilibrium concentrations c
A
, c
B
, c
C
, c
D
, c
X
,
c
Y
and c
Z
from the above equations both algebraically and numerically, based
on the parameter values K
C1
= 1.06, K
C2
= 2.63, K
C3
= 5 and c
A0
= 1.5 = c
B0
.
For the numerical solution, use the starting points
(a) c
D
= c
X
= c
Z
= 0
(b) c
D
= c
X
= c
Z
= 1
(c) c
D
= c
X
= c
Z
= 10
6.6. A SET OF ORDINARY DIFFERENTIAL EQUATIONS 123
6.6 A Set of Ordinary Dierential Equations
In this problem, a set of rst order ordinary dierential equations is used to
model unsteady heat transfer in a series of perfectly mixed tanks. Three tanks
in series are used for preheating a multicomponent oil mixture before it is fed
to a distillation column, see the gure below. Each tank is initially lled with
1000 kg of oil at 20

C. Saturated steam at 250

C condenses within coils
immersed in the tanks. Oil is fed into the rst tank at a rate of 100
kg
min
and it
oveows into the subsequent tanks at the same ow rate. The temperature of
the feed into the rst tank is 20

C. The tanks are perfectly mixed, so that the
temperature inside the tanks is uniform and the steam outlet temperature agrees
with this interior temperature. The heat capacity of the oil is C
p
= 2.0
kJ
kg
. For
a particular tank, the rate at which heat is transferred from the steam to the
oil is given by
Q = K (T
steam
T) ,
where K = 10
kJ
min

C
is the eective heat transfer coecient of the coil in
the tanks, T is the temperature of the steam in

C and Q is the rate of heat
transferred in
kJ
min
. We now proceed to formulate energy balances for each of
the three tanks. Note that the mass ow rate into each tank is the same, i.e.,
W = W
1
= W
2
= W
3
. Moreover, the mass in each tank is constant, as the
volume and density of the oil mixture is constant. Hence, M = M
1
= M
2
= M
3
and we see that for the rst tank:
accumulation = input output
MC
p
dT
1
dt
= WC
p
T
0
+K (T
steam
T
1
) WC
p
T
1
.
It should be noted that we do not need mass balances for any of the tanks, since
the masses do not change at steady state. For the second and third tanks, we
derive similar equations:
MC
p
dT
2
dt
= WC
p
(T
1
T
2
) + K (T
steam
T
2
) ,
MC
p
dT
3
dt
= WC
p
(T
2
T
3
) + K (T
steam
T
3
) .
Exercise 6.6.1. Determine the steady-state temperature in each of the three
tanks. What time will be required for T
3
to reach 99 % of its steady-state
temperature after startup?
124 CHAPTER 6. COURSE PROBLEMS
6.7 Another Set of Ordinary Dierential Equa-
tions
We study a set of ordinary dierential equations with known boundary condi-
tions, with the objective of aiding the design of a gas phase catalytic reactor with
pressure drop. In the packed-bed reactor depicted below, a rst-order reversible
gas phase reaction is taking place according to
2A C .
The reactor is surrounded by a heat exchanger and it works in plug ow mode
without radial gradients (dierences) in temperature, pressure and concentra-
tion at any location within the packed bed made up of the solid catalyst.
The most important variables for reactor design is the conversion X and
temperature T as functions of the location within the catalyst bed, specied
by the catalyst weight W. A material balance for reactant A then leads to the
dierential equation
F
A0
dX
dW
= r
A
,
where the catalytic reaction rate is given by
r
A
= k
r
_
c
2
A

c
C
K
r
C
_
.
The rate constant k is based on the Arrhenius expression for reactant A
k
r
= ke
E
A
R
(
1
450 K

1
T
)
and the equilibrium constant at each temperature can be calculated from the
similar vant Ho-expression
K
r
C
= K
C
e
Hr
R
(
1
450 K

1
T
)
.
With the help of stoichiometry, we can obtain expressions for the concentra-
6.7. ANOTHER SET OF ORDINARY DIFFERENTIAL EQUATIONS 125
tions c
A
and c
C
according to
c
A
= c
A0
_
1 X
1 0.5X
_
T
0
T
y ,
c
C
= c
A0
_
0.5X
1 0.5X
_
T
0
T
y ,
y =
p
p
0
.
The pressure drop along the packed bed reactor is governed by the dierential
equation for partial pressure
dy
dW
=
1 0.5X
2y
T
T
0
.
Applying an energy balance yields a dierential equation for temperature
dT
dW
=
U
a
(T
a
T) +r
A
H
r
F
A0
C
A
p
.
Exercise 6.7.1. Solve the coupled dierential equations for the conversion X,
reduced pressure y and temperature T along the reactor bed, i.e., for the inter-
val W [0, 20] kg. Use parameter values from the table below
C
A
p
= 40.0
kJ
molK
R = 8.314
J
molK
C
C
p
= 80.0
kJ
molK
F
A0
= 5.0
mol
min
H
r
= 40
kJ
mol
U
a
= 0.8
J
kgminK
E
A
= 41.8
kJ
molK
T
a
= 500 K
k = 0.5
dm
6
kmolmin
= 0.015 kg
1
K
C
= 25000
dm
3
mol
p
0
= 10 atm
c
A0
= 0.271
mol
dm
3
y
A0
= 1.0 (feed is pure A)
T
0
= 450 K
(a) Plot the results in a representative graph.
(b) At approximately W = 16 kg, a special feature should appear in the results
of (a). Investigate which parameters aect this and the reasons behind it.
(c) Plot the concentration proles c
A
(W) and c
C
(W).
126 CHAPTER 6. COURSE PROBLEMS
6.8 A Second-Order Ordinary Dierential Equa-
tion
We consider an application from transport phenomena and reaction kinetics,
modeled by a two-point boundary value problem for a second-order ordinary
dierential equation. Diusion with simultaneous rst-order irreversible chemi-
cal reaction in a single phase containing only reactant A and product B can be
described by the dierential equation
d
2
c
A
dz
2
=
k
D
AB
c
A
,
where c
A
is the concentration of reactant A in
kmol
m
3
, z is the spatial variable in m,
k is the homogeneous reaction rate constant in s
1
and D
AB
is the binary diu-
sion coecient in
m
2
s
. A typical geometry for this problem is a one-dimensional
layer with one end exposed to a known concentration c
A0
and the other end
without diusion, i.e., no ux of material across that boundary. Hence, the
boundary conditions would be
c
A
= c
A0
, z = 0 ,
dc
A
dz
= 0 , z = L .
Exercise 6.8.1. Apply the numerical data
c
A0
= 0.2
kmol
m
3
,
k = 10
3
s
1
,
D
AB
= 1.2 10
9
m
2
s
,
L = 10
3
m
and compute
(a) an analytical solution of c
A
(z), z [0, L].
(b) a numerical solution of c
A
(z), z [0, L].
(c) depict the the concentration proles obtained in (a) and (b) in the same
graph.
6.9 Ordinary Dierential Equations and Algebraic
Equations
We consider batch distillation of an ideal binary mixture of the two components
designated 1 and 2. Then, the moles of liquid remaining to be distilled L
6.10. A CONTROL LOOP 127
as a function of the mole fraction x
2
of component 2 can be described by the
ordinary dierential equation
dL
dx
2
=
L
x
2
(k
2
1)
,
where k
2
is the vapor-liquid equilibrium rate for component 2. For this ideal
system, we have k
i
=
pi
ptot
where p
i
is the vapor pressure of component i and
p
tot
is the total pressure. The pressures are measured in mmHg.
A common model for vapor pressure of component i is the Antoine equation
p
i
= 10

Ai
B
i
T+C
i

,
where A
i
, B
i
and C
i
are parameters and T is temperature measured in

C.
The temperature inside the distillation pot follows something called the bubble
point curve and is governed by the implicit algebraic equation
k
1
x
1
+k
2
x
2
= 1 .
Exercise 6.9.1. An ideal mixture of benzene (component 1) and toluene (com-
ponent 2) obeys the Antoine equation with the parameters
A
1
= 6.90565 , A
2
= 6.95464
B
1
= 1211.033 , B
2
= 1344.8
C
1
= 220.79 , C
2
= 219.482
The total pressure is p
tot
= 912 mmHg. Given that L = 100 mol for x
2
= 40 %,
compute L for x
2
= 80 %.
6.10 A Control Loop
We study dynamics of the continuous rst-order process with delay depicted
below. The system consists of a well-stirred tank, heater and PI-temperature
controller. A stream of liquid with density , specic heat c
p
and tempera-
ture T
i
is fed into the heated tank at a constant rate of W. The volume and
temperature in the well-stirred tank is V and T, respectively. The temperature
of the discharge (at rate W and temperature T
o
) from the tank is controlled by
heating the water in the tank at rate q, based on the measurement T
m
with a
set point temperature T
r
. The objective is to maintain T
o
= T
r
although the
inlet temperature T
i
may dier from the steady-state design temperature T
is
.
In order to model this system, governing model and control equations must
be formulated. An energy balance for the tank yields the dierential equation:
dT
dt
=
Wc
p
(T
i
T) +q
V c
p
,
with initial condition T = T
r
at t = 0, corresponding to steady-state operation
at the set point temperature T
r
.
128 CHAPTER 6. COURSE PROBLEMS
The thermocouple for measuring T
m
is described by a rst-order system with
delay
d
for the discharge liquid from the tank to reach the measurement point.
Thus, we have
T
o
(t) = T (t
d
) .
The eect of this delay may be taken into account by a Pad approximation
giving a rst-order linear dierential equation for the discharge temperature
dT
o
dt
=
2

d
(T T
o
)
dT
dt
, T
o
(t = 0) = T
r
.
The above equation gives the input temperature for the thermocouple. However,
its shielding and electronics are modeled by a rst-order system for the dynamics
of the measured temperature T
m
:
dT
m
dt
=
T
o
T
m

m
,
where the time constant
m
is known. The heat input to the tank, as governed
by the controller is described by
q = q
s
+K
c
(T
r
T
m
) +
K
c

I
_
t
0
(T
r
T
m
(s)) ds ,
where K
c
is the proportional gain of the controller,
I
is the integration time
constant or reset time. The heat input q
s
is that required at steady state for
the design conditions:
q
s
= Wc
p
(T
r
T
is
) .
For convenience, we can note that the integral in the controller equation above
satises the fundamental theorem of calculus, i.e., we have another dierential
equation for the integral according to:
d
dt
_
t
0
(T
r
T
m
(s)) ds = T
r
T
m
(t) .
Exercise 6.10.1. Solve the coupled dierential equations for the tempera-
tures T, T
o
and T
m
in
6.11. STIFF DIFFERENTIAL EQUATIONS 129
(a) a situation where the system initially operates at design steady state for
the temperature 80

C when the inlet temperature T
i
is suddenly changed
to 40

C at t = 10 min. Let the control loop be open (K
c
= 0).
(b) a situation similar to case (a) with the parameter values in the table below.
V c
p
= 4000
kJ
K
Wc
p
= 500
kJ
minK
T
is
= 333.15 K T
r
= 353.15 K

d
= 1 min
m
= 5 min
K
c
= 50
kJ
minK

I
= 2 min
6.11 Sti Dierential Equations
A dierential equation is considered sti if the solution sought is varying
slowly, while other, nearby solutions vary rapidly. This means that stiness is
a issue connected with computational eciency when one solves the dierential
equation numerically. If computation time would be irrelevant, we would not be
concerned about stiness. We could then use standard numerical methods for
the solution and wait for a sucient amount of steps for the computation to be
executed. However, since the decrease in computational speed may be orders of
magnitude in pathological cases, it is desired to apply special methods to solve
this type of equations.
Example 6.11.1. A simple sti ordinary dierential equation can be found in
a model of ame propagation. When a match is lit, the ball of ame grows very
rapidly until reaching a critical size. It then remains at this size because the
amount of oxygen consumed in this combustion process balances the amount of
oxygen sucked into the ball through its surface. The model can be formulated
dimensionlessly as
dy
dt
= y
2
y
3
, 0 < t <
2

,
y(0) = ,
where the scalar variable y(t) represents the radius of the ame ball. The terms
y
2
and y
3
come from the surface area and volume, respectively, of this ball. A
critical parameter in this case is , describing the small initial radius of the
ame ball.
Exercise 6.11.1. Solve the ame propagation problem above
(a) analytically. Apply the Lambert W-function.
(b) numerically, by use of standard nonsti methods as well as special sti
methods. Consider dierences in computation time and compare the re-
sults to that of case (a).
130 CHAPTER 6. COURSE PROBLEMS
6.12 Partial Dierential Equations
Partial dierential equations (PDE) have more than one independent variable,
in contrast to ordinary dierential equations (ODE). Most computational meth-
ods for PDE are based on some sort of reformulation into ODE and subsequent
use of ecient solution methods for these. There is an extensive theory, with
continuous and vigorous development over recent years, for PDE solution prop-
erties and existence. Nevertheless, some of the most popular solution methods
are classical and we will take a look at one here.
Example 6.12.1. Consider the PDE describing the (normalized) temperature
in the earth at depth x and time t, when the temperature at the surface is h(t).

2
u(x, t)
x
2
=
u(x, t)
t
, x ]0, [ , t ]0, [ ,
u(0, t) = h(t) ,
lim
x
u(x, t) = 0 ,
u(x, 0) = 0 .
This problem can be solved using numerous strategies, to which we will return
shortly. First, we will take a look at how the time variation in the boundary
condition is handled. Consider a similar problem for a constant boundary con-
dition:

2
v(x, t)
x
2
=
v(x, t)
t
, x ]0, [ , t ]0, [ ,
v(0, t) = H ,
lim
x
v(x, t) = 0 ,
v(x, 0) = 0 .
Now, according to Duhamels principle we have the following convolution-like
relationship between the two solutions u(x, t) and v(x, t):
u(x, t) = h
v(x, )
t
=
_
t
0
h()
v(x, t )
t
d .
Exercise 6.12.1. Consider the initial-boundary value problem for v(x, t). Solve
it using the approach:
(a) Introduce the new independent variable =
x

4t
and convert the problem
to a boundary value problem for an ordinary dierential equation. Solve
the ODE with the new boundary conditions.
(b) Use the Laplace-transform to convert the problem to a boundary value
problem for an ordinary dierential equation. Solve the ODE with the
new boundary conditions.
Furthermore, try to verify the relationship between u(x, t) and v(x, t) by using
the Laplace-transform. Finally, solve the complete problem for u(x, t) numeri-
cally and compare the result to the one given above by Duhamels principle.
6.13. INTEGRAL EQUATIONS 131
6.13 Integral Equations
An equation where the unknown function/solution is part of an denite (con-
stant integration bounds) or indenite (variable bounds) integral is customarily
termed an integral equation. The former type is called a Fredholm equation and
the latter a Volterra equation. If the unknown solution appears only in the
integrand, the equation is designated type I and otherwise type II.
Denition 6.13.1. A type II Volterra integral equation
y(t) = f(t) +
_
t
a
K(x, t)y(x) dx
Denition 6.13.2. A type I Fredholm integral equation
f(t) =
_
b
a
K(x, t)y(x) dx
Whereas a dierential equation describes the solution y(t) locally through
its derivatives, an integral equation describes the global variation over the entire
denition set of the solution including the boundary conditions. For a dieren-
tial equation, the boundary conditions have to be specied separately whereas
they are condensed into the properties of the kernel K(x, t) in the integral
equation.
Integral equations provide an alternative to modeling processes by dieren-
tial equations in engineering. In many respects an integral equation description
is more compact and more suited to investigations of, e.g., solution existence
and uniqueness. There are also physical phenomena, such as heat radiation in
energy balance formulations, which cannot be modeled by dierential equations
but readily with integral equations.
Frequently, in modeling and simulation, an objective is to analyze sensitivity
to input disturbances. Here, integral equations come in handy, as the integral
_
K(x, t)y(x)dx often has the nice property of mollifying rapid variation in y(x)
whereas the eect of y

(x) is the opposite. In many cases, though, dierential


equations are more suited to practical computations, since closed-form solutions
do not exist for integral equations nearly as frequently.
Integral equations may be solved by a great variety of methods, based on
the type of the equation and its particular form of the kernel K(x, t). We will
briey consider a few simple methods for the Volterra equation of type II
y(t) = f(t) +
_
t
a
K(x, t)y(x) dx
and the Fredholm equation of type II
y(t) = f(t) +
_
b
a
K(x, t)y(x) dx .
132 CHAPTER 6. COURSE PROBLEMS
Dierentiating the integral equation leads to an initial value problem for a dif-
ferentialequation. This approach works for, e.g., a type II Volterra and in a
case where the kernel only depends on x, i.e., K = K(x), we obtain a linear
dierentialequation
y

(t) K(t)y(t) = f

(t) , y(a) = f(a) ,


Exercise 6.13.1. Verify the above dierential equation and obtain a formal
solution together with an example for the kernel K(x) = 3x
2
.
In addition to dierentiation, iteration can be applied for solution of Volterra
equations of the type II. We start with the initial guess y
0
(t) and solve for
y
1
(t), y
2
(t), . . . , from the original integral equation according to
y
j+1
(t) = f(t) +
_
t
a
K(x, t)y
j
(x) dx
It can be proved that the sequence of solution always converges for continuous
kernels K(x, t) and f(t).
Exercise 6.13.2. Consider a Volterra equation of type II with the kernel
K(x, t) = 3x
2
and f(t) = 1, a = 0. Solve this equation by iteration based
on the initial guess y
0
(t) = 1.
The Fredholm equation of type II can also be solved in closed form, if the
kernel can be separated similarly to the approach of separating variables in
solution of partial dierential equations:
K(x, t) =
N

n=1

n
(x)
n
(t) .
In many cases this separation can be achieved approximately, by using linearly
independent basis functions
n
(x). Considering this in the integral equation
under the assumption that the order of summation and integration can be in-
terchanged (the sum is nite and convergence of the integral is rapid enough),
leads to the equation
y(t) = f(t) +
N

n=1

n
(t)
_
b
a

n
(x)y(x) dx .
Noting that the integral is a constant depending on the particular value of the
summation index n allows us to introduce
c
n
=
_
b
a

n
(x)y(x) dx .
If we now multiply the integral equation in the previous step above by
m
(t)
and integrate, we obtain
c
m
=
_
b
a

m
(t)f(t) dt +
N

n=1
c
n
_
b
a

n
(t)
m
(t) dt .
6.14. SPECIAL TOPICS 133
Considering this for m = 1, . . . , N yields a system of simultaneous linear equa-
tions, which can be expressed in matrix form as
(I A) c = b ,
where I is the identity matrix, c the vector consisting of the coecients c
k
and b
the vector of the known constants b
m
=
_
b
a

m
(t)f(t) dt. The matrix A consists
of the constants
_
b
a

n
(t)
m
(t) dt. Hence, the integral equation has been reduced
to a linear algebra problem of an equation system with the solution
c = (I A)
1
b .
With the above solution the Fredholm equation of type II can be solved using
the formula
y(t) = f(t) +
N

n=1
c
n

n
(t) .
Exercise 6.13.3. Consider the equation
y(t) = 1 +
_
1
0
3x
2
(e
t
2
1)
e 1
y(x) dx .
Solve this equation using the above described separation strategy.
6.14 Special Topics
6.14.1 Perturbation Theory
Consider the equation satised by y(x):
y +
1
50
ln (1 +y) = x
2
.
Unfortunately, this equation cannot be solved exactly, however, we can apply
a perturbation method amounting to the following: We replace the factor
1
50
in front of the logarithm by a parameter, , and seek an approximate solution
y(x, ) to the modied equation
y + ln (1 +y) = x
2
.
We may assume that this solution can be expressed as a MacLaurin-series for
the parameter :
y(x, ) = y(x, 0) +y

(x, 0) +

2
2!
y

(x, 0) + ,
where y

(x, 0) =
y(x,)

=0
, y

(x, 0) =

2
y(x,)

=0
etc. These derivatives can
now be computed through dierentiating the modied equation and substituting
= 0. This, e.g., immediately yields y(x, 0) = x
2
. Determine the ve rst terms
of the above MacLaurin-series and put =
1
50
to obtain an approximation of
the initial equation.
134 CHAPTER 6. COURSE PROBLEMS
6.14.2 Calculus of Variations
We will take a look at a method of solving variational problems with constraints
by use of constraints. In general form, we are interested in optimizing an integral
of a functional F(x, y, y

) (a function of our function y(x), which we adjust in


order to reach the optimum)
I [y(x)] =
_
x1
x0
F(x, y, y

) dx .
We thus wish to nd a function y(x) such that the above integral is minimized
or maximized subject to the constraint
G(x, y, y

) = 0 .
Here, this is done by forming the Lagrangian function
L(x, y, y

, ) = F(x, y, y

) +(x)G(x, y, y

)
and solving the Euler-Lagrange equation:
d
dx
_
L
y

L
y
= 0
together with the constraint G(x, y, y

) = 0 gives an optimum for the func-


tional I [y(x)] under the given constraint. Consider the following brief
Example 6.14.1. An agitated tank contains a mass m of water at tempera-
ture 0

C. It is desired to raise the temperature of the water to 40

C over a
time T =

2.0 h by feeding hot water into the tank at a rate of m per hour, at the
same time draining the tank continuously at the same rate of m per hour. The
inlet and outlet temperatures, as functions of time, are T
1
(t) and T
2
(t), respec-
tively. The inlet temperature is controlled by an adjustable electric heater inside
the feed pipe and an optimal strategy for the heating is achieved by minimizing
the functional
I [T
1
(t), T
2
(t)] =
_

2
0
_
[T
1
(t) 0]
2
+ [T
2
(t) 0]
2
_
dt .
By applying an energy balance over the tank, we can derive the constraint
dT
2
(t)
dt
= T
2
(t) T
1
(t) .
The initial- and end-conditions for the outlet temperature are T
2
(0) = 0

C
and T
2
(

2) = 40

C, respectively.
We note that the general form G(x, y, y

) = 0 of the constraint is G =
dT2(t)
dt
T
2
(t) +T
1
(t) and the Lagrangian can be formulated as
L[T
1
(t), T
2
(t), (t)] = [T
1
(t)]
2
+ [T
2
(t)]
2
+(t)
_
dT
2
(t)
dt
T
2
(t) +T
1
(t)
_
.
6.14. SPECIAL TOPICS 135
Based on this function, we have the Euler-Lagrange equations:
d
dt
_
L
T

1
_

L
T
1
= 0 ,
d
dt
_
L
T

2
_

L
T
2
= 0 .
Exercise 6.14.1. Combine the Euler-Lagrange equations and constraint equa-
tion in the example above to derive a linear ordinary dierential equation for
the outlet temperature T
2
(t). Using the conditions T
2
(0) = 0

C and T
2
(

2) =
40

C, formulate a boundary value problem and solve it. Use the solution to
obtain the inlet temperature T
1
(t).
6.14.3 JWKB-approximation
Many applications of mathematical physics can be modeled by the general wave
equation
(x)

2
y
t
2
=

x
_
T(x)
y
x
_
,
where y is a spatial variable, t is time and (x) and T(x) are called the density
and transfer coecient, respectively. A classical approach to solving this type
of partial dierential equation (PDE) is the method of separation of variables,
which amounts to seeking special solutions of the form
y(x, t) = f(x)g(t) .
Substituting this into the PDE yields the equality
1
g(t)
d
2
g(t)
dt
2
=
1
(x)f(x)
d
dx
_
T(x)
df(x)
dx
_
.
Now, we note that the left-hand side of this equation is a function of time t only,
whereas the right-hand side is a function of x only. As the equality nevertheless
must be valid for all values of x and t, it must be concluded that the expressions
on both sides must be constant. Setting this constant equal to the negative
number
2
leads, for the right-hand side, to the equation
d
dx
_
T(x)
df(x)
dx
_
+
2
(x)f(x) = 0 .
If T and are constant, we have a solution of the form
f(x) = Ae
i

c
x
,
where all the new names denote constant parameters. Keeping this in mind, for
constant T and slow variation in (x), we try a solution of the form
f(x) = A(x)e
iS(x)
.
136 CHAPTER 6. COURSE PROBLEMS
Substituting this into our dierential equation for f(x) and cancelling the ex-
ponential gives the equation
A

+ 2iS

+ iS

AS
2
A +
_

2
u
2
_
A = 0 ,
where u
2
=
T
(x)
. Taking real and imaginary parts of the above equation leads
to the two equations
2S

+S

A = 0 ,
A

+

2
u
2
AS
2
A = 0 .
If u(x) is slowly varying, the derivatives of S as well as A will be small compared
with the functions themselves. In particular, in the second equation above,
A



2
u
2
, which means that it can be neglected. Integrating the remaining
equation yields
S(x) =
_
x

u(p)
dp .
The lower integration limit is arbitrary, but is sometimes for convenience taken
to be zero. There remains to compute the factor A(x). This can be done from
the rst equation if we note that multiplication by A gives
2AA

+S

A
2
= 0
d
dx
_
A
2
S

_
= 0
A
2
S

=
2
,
where
2
is a positive constant. Thus, A(x) = constant
_
u(x). The real part
of our solution to the dierential equation is hence
f(x) = constant
_
u(x) sin
__
x

u(p)
dp
_
.
Exercise 6.14.2. Consider a vibrating string stretching from x = 0 to x = L,
with the density
(x) =
0
+ sin
x
L
,
where
0
and are constant parameters with the property . Use a Taylor-
series expansion for the root

1 +z in order to compute the frequencies
S(L) =
_
L
0

u(p)
dp =
_

0
T
_
L
0
_
1 +

0
sin
x
L
dp .
6.14. SPECIAL TOPICS 137
6.14.4 Monte Carlo Methods
Monte Carlo methods can be considered statistical simulation methods based
on generating sequences of random numbers. The term Monte Carlo was
coined by Nicholas Constantine Metropolis (1915-1999) and inspired by Stanis-
lawUlam (1909-1986), because of the similarity of statistical simulation to games
of chance, the city of Monte Carlo being a worldwide center for gambling. As
may be anticipated, the eciency of these methods is heavily dependent on
the eciency and quality of producing machine-generated random number se-
quences. Hence, a substantial part of the research in the eld is focused on these
objectives. A popular application for the Monte Carlo method is computation
of multidimensional integrals, for which standard methods of discretization can
become computationally expensive. For example, in d dimensions the error of
the composite trapezoidal rule for numerical calculation of an integral converges
as O
_
1
n
2
d
_
when the number of discretization points is n. The corresponding
error for the Monte Carlo method can be shown to be O
_
1

n
_
. Thus, the
inequality
O
_
1

n
_
< O
_
1
n
2
d
_
, d > 4 .
This tells us that Monte Carlo integration pays o for ve dimensional (and
higher) integrals
_
V
f(w) dw
1
dw
2
dw
3
dw
d
.
Method 6.14.2. Multidimensional integration.
(i) Generate n randomly distributed points, x
1
, x
2
, . . ., x
n
in the hypervol-
ume V = [a
1
, b
1
] [a
2
, b
2
] [a
d
, b
d
]. That is, these points are n-tuples
of coordinates within the volume.
(ii) Determine the average
f =
1
n
n

i=1
f (x
i
) .
(iii) Compute an approximation to the desired integral
_
V
f(x) dV = (b
1
a
1
) (b
2
a
2
) (b
d
a
d
) f .
(iv) An error estimate is given by
error = (b
1
a
1
) (b
2
a
2
) (b
d
a
d
)

f
2

_
f
_
2
n
.
138 CHAPTER 6. COURSE PROBLEMS
Exercise 6.14.3. Compute the multidimensional integral
_ 7
10
0
_
_ 4
5
0
_
_ 9
10
0
_
_
1
0
_
_ 11
10
0
_
6 x
2
y
2
z
2
u
2
w
2
_
dw
_
du
_
dz
_
dy
_
dx
(a) by Monte Carlo approximation.
(b) analytically.
Moreover, compare the results in (a) and (b) and obtain an error estimate for
the result in (a).
6.14.5 Coding Theory
Every book published has a so called ISBN-code, consisting of a string a
1
a
2
. . . a
10
of integers with the property 0 a
i
9 if 1 i 9 and 0 a
10
10. However,
instead of the number 10, the greek number X is used. The element a
10
is a
checksum calculated by the formula
a
10
=
9

i=1
ia
i
, (mod 11).
Show, e.g., by direct calculation that if two digits a
j
och a
k
are interchanged or
if one digit a
j
is changed, the checksum will be disrupted and become erroneous.

You might also like