*Maxima* is a free software package.
It can be freely downloaded for various different systems and
there is extensive documentation that can also be freely
copied. Maxima's website is at
http://maxima.sourceforge.net

*Maxima* is one of the oldest
Computer Algebra Systems (CAS). It was created by MIT's MAC
group in the 1960s and it was initially
called *Macsyma*
(*project MAC's SYmbolic
MAnipulator*). *Macsyma* was
originally developed for the DEC-PDP-10 large-scale computers
that were used in various academic institutions at that
time.

In the 1980s, its code was ported to several new platforms
and one of those derived versions was
called *Maxima*. In 1982 the MIT
decided to sell *Macsyma* as
proprietary software and simultaneously Professor William
Schelter of the University of Texas continued to develop the
*Maxima* version. In the late 1980s
other proprietary CAS systems similar to
*Macsyma* appeared, such as
*Maple* and
*Mathematica*. In 1998, Professor
Schelter obtained authorization from the DOE (Department of
Energy), which held the copyright for the original version
of *Macsyma*, to distribute the source code
of *Maxima* as free software. When
Professor Schelter passed away in 2001, a group of volunteers
was formed to continue to develop and
distribute *Maxima* as free
software.

In the case of CAS software, the advantages of free software are very important. When a method fails or gives very complicated answers it is quite useful to have access to the details of the underlying implementation of the methods used. On the other hand, as one's research and teaching becomes dependent on the results of a CAS, it is desirable to have good documentation of the methods involved and its implementation and to be assured that there are no legal barriers forbidding the examination and modification of that code.

There are several different interfaces to work with
Maxima. It can be run from a command shell, or from one of the
graphical interfaces as *wxMaxima*, *imaxima*
or *Xmaxima*. Figure A.1
shows the main window of Xmaxima, which is a graphical
interface originally developed by Professor William
Schelter.

Xmaxima establishes a connection with the Maxima program (using a socket), sends the commands that the user types to Maxima and shows the results it returns.

Xmaxima usually opens two windows
(Figure A.1). One of them, called
the **browser**, shows a tutorial and allows the user to
read the manual or other Web pages. The second window is
the **console**, where Maxima commands should be written
and their output will appear.

In the "Edit" menu there are options to navigate the list of previous commands ("previous input") or to copy and paste text; some options in the menus can also be accessed with the shortcut keys shown next to them.

Different colors are used to distinguish commands that have already been processed (in blue) from the command that is being written and has not yet been sent to Maxima (in green); the results are shown in black (see Figure A.1). When changing a command already executed or when starting a new command, care must be taken that what is being written appears in green or blue, to ensure that it will be sent to Maxima. Sometimes it may be necessary to use the options "Interrupt" or "Input prompt", in the "File" menu to recover the state in which Xmaxima is accepting commands.

It is also possible to move the prompt symbol to some older entry in the screen (in blue), change it, and press enter to repeat the same command with the modifications.

When a Maxima session starts, the tag
(%i1) will appear, which
means *input* 1. A valid command
should be written next to that tag, ended with a semi-colon
and when the enter key is pressed, that input will be parsed,
simplified, linked to an internal variable
%i1 and its result
will be shown following a tag (%o1), that means
*output* 1. That result will also be
linked to an internal variable %o1. Another tag (%i2) will appear next, to mark the place
where a second command should be written and so on. The most
basic usage of Maxima is as a calculator, as in the following
examples.

(%i1) 2.5*3.1;

(%o1) 7.75

(%i2) 5.2*log(2);

(%o2) 5.2 log 2

(%o1) 7.75

(%i2) 5.2*log(2);

(%o2) 5.2 log 2

The result (%o2) shows two important aspects of Maxima. First, the natural logarithm of 2 was not computed, because its result is an irrational number which cannot be represented exactly with a finite number of numerical digits. The second important aspect is that the symbol * which is always required when a product is entered and the parenthesis, which have to be used to specify the argument of a function, were not included in the output. That happened because, by default, the output is shown in a mode called display2d, in which the output tries to resemble the way mathematical expressions are usually shown in books. The expression "5.2 log 2" most probably will be interpreted correctly by a reader, as the product of 5.2 times the logarithm of 2; however, if that same ambiguous expression was given as input to Maxima it would trigger an error, because Maxima syntax requires an operator between 5.2 and the logarithm function, and the argument of the logarithm must be inside parenthesis. In spite of the form of the output, variable %o2 has been linked to an expression with correct syntax, so it can be reused in later Maxima commands without syntax errors.

To look up the documentation of a function or special variable in the manual, for instance the function log that was just used, the describe function is used, which can be abbreviated with a question mark followed by space and the name of the function:

(%i3) ? log

– Function: log (<x>)

Represents the natural (base e) logarithm of <x>.

Maxima does not have a built-in function for the base 10 logarithm or other bases. 'log10(x) := log(x) / log(10)' is a useful definition.

…

– Function: log (<x>)

Represents the natural (base e) logarithm of <x>.

Maxima does not have a built-in function for the base 10 logarithm or other bases. 'log10(x) := log(x) / log(10)' is a useful definition.

…

Maxima accepts real and complex numbers. Real numbers in
Maxima can be integers, rationals, such as 3/5, or
floating-point numbers, for instance, 2.56 and 25.6e-1, which
is a short notation for
25.6×10^{−1}. Irrational numbers, such
as sqrt
(2)
(square root of 2) or log
(2)
(natural logarithm of 2) are left in that form, without being
approximated by floating-point numbers, and later
calculations, such as sqrt(2)^2 or exp(log(2)) will lead to the exact result
2.

Floating-point numbers are "contagious"; namely, the operations in which they enter will be carried out in that format. For example, if instead of writing log (2) one would write log (2.0), the logarithm would be computed approximately in floating-point. Another way to force an expression to be computed as a floating-point number consists on using the function float. For example, since the result (%o2) obtained above was linked to the variable %o2, to get a floating-point approximation of that result one would write:

(%i4) float (%o2);

(%o4) 3.604365338911716

(%o4) 3.604365338911716

The function float
computed the product 5.2 log(2) approximately, using 16
significant digits in floating-point format. The
floating-point format used in Maxima stores each number in 64
binary bits, which leads to between 15 and 17 significant
digits when expressed in decimal base. That format is known
as *double precision*.

A frequent source of confusion arises from the fact that those numbers are being represented internally in binary base and not in decimal base; thus, certain numbers that can be represented in decimal with a few digits, for instance 0.1, would need an infinite number of binary digits to be represented accurately in binary base. It is the same thing that happens with the fraction 1/3 in decimal base, which in floating-point form has an infinite number of digits: 0.333… (in the base 3 system that fraction can be easily represented). The fractions that lead to an infinite number of digits are not the same in the decimal and binary base systems. Consider the following results, which are perfectly correct and would appear in any system that uses binary digits and double-precision format, but might look puzzling to someone used to work with the decimal system:

(%i5) 2*0.1;

(%o5) 0.2

(%i6) 6*0.1;

(%o6) 0.6000000000000001

(%o5) 0.2

(%i6) 6*0.1;

(%o6) 0.6000000000000001

The explanation for this last result is that the number 0.1 cannot be written exactly using 64 binary bits. Thus, multiplying 0.1 by 2 does not give exactly 0.2, but the decimal number with 16 significant digits which is closer to the result obtained is 0.2000000000000000, giving the impression that the result of the product is exactly that, when it is not. In the case of 6*0.1, using double precision format, the closest number with 16 decimal significant digits is 0.6000000000000001. Some computing systems ignore the last digits in the results obtained from double-precision calculations, showing the result as 0.6, but whenever binary double-precision is used, the result of 6*0.1 will never be exactly 0.6.

If the number 1/3 had to be represented in decimal system,
using only 3 significant digits, the most approximate
representation of the number would be 333/10^{3},
namely, 0.333. In binary system with double precision 52
significant binary digits are used, which means that the
numerator has to be less than 2^{52} and the
denominator must be a number of the form
. Maxima's
function rationalize
shows the approximate representation being used for a number,
in the form of a fraction. For instance,

(%i7) rationalize (0.1);

(%o7)

(%o7)

the numerator is less than 2^{52} (and bigger than
2^{51}), while the denominator is exactly equal to
2^{55}. In order for that fraction to represent
exactly 0.1, the denominator should be ten times bigger than
the numerator, namely, it should end in 70 rather than 68, but
the power of 2 closer to that number had to be used.

To avoid the numerical errors inherent to the floating-point
representation, fractions can be used; for example, 1/10
instead of 0.1. There is also another Maxima specific format
which accepts any arbitrary number of significant digits to
represent floating-point numbers. That format is
called **big float** and it is used by writing
"b", instead of
"e" for the
exponents; for example, 2.56×10^{20}, written as
2.56e20 would be represented internally in double-precision
format, with 16 significant digits and any calculations made
with it would result in other double-precision numbers; but if
the same number is written as 2.56b20, it will be represented
internally in *big-float* format and
when it makes part of numerical calculations, the result will
be another number in the same format, which can have many
significant digits up to a maximum number determined by the
value of the internal variable fpprec
(*floating-point precision*).

The function
bfloat
converts a number into *big-float*
format and the default value
of fpprec is 16. For example, in
order to get a numerical approximation for the
result (%o2), with 60
significant digits, the following commands are used:

(%i8) fpprec: 60;

(%o8) 60

(%i9) bfloat (%o2);

(%o9) 3.60436533891171573209728052144843624984298344312084369367127b0

(%o8) 60

(%i9) bfloat (%o2);

(%o9) 3.60436533891171573209728052144843624984298344312084369367127b0

The letter b, followed by zero, at the end of the result
(%o9) means that the
number is in the *big-float* format
and it should be multiplied by a factor of
10^{0} = 1.

In the rest of this appendix and in all the chapters in this book, all floating-point numerical results will be automatically rounded to only 4 significant digits. That is achieved by changing the value of the system variable fpprintprec from its default value of 0 to 4:

(%i10) fpprintprec: 4;

(%o10) 4

(%o10) 4

internally, all floating-point numbers will continue to have
16 significant digits and *big-float*
numbers will have the number of significant digits set by
fpprec; however, whenever a number
has to be printed in the screen, it will be rounded to 4
significant digits. If at any moment one wants to see all the
significant digits stored internally, it will be necessary to
set fpprintprec back to its default
value of 0.

To link a value or other objects to a variable, the symbol
":" is used, and not the equal sign
"=", which will be used to define
mathematical equations. The name of the variables can be any
combination of letters, numbers and one of the symbols % or
_, but the first character cannot be a number.
*Maxima* is case sensitive. Here are
some examples:

(%i11) a: 2$

(%i12) [b, c]: [-2, -4];

(%o12)

(%i13) c;

(%o13) −4

(%i14) Root1: (-b + sqrt(b^2 - 4*a*c))/(2*a);

(%o14) 2

(%i15) d: sqrt(z^2 + a*c);

(%o15)

(%i12) [b, c]: [-2, -4];

(%o12)

(%i13) c;

(%o13) −4

(%i14) Root1: (-b + sqrt(b^2 - 4*a*c))/(2*a);

(%o14) 2

(%i15) d: sqrt(z^2 + a*c);

(%o15)

variables a, b, c and Root1 were linked to the numerical values 2, −2, −4 and 2, while variable d was linked to an expression.

Notice that input (%i11) was ended with a dollar sign $, rather than a semi-colon. That will make the command to be executed without showing its result on the screen. In any case, variable %o11 became linked to the result of input (%i11) and can be referred to later, even though its value was not shown. Input (%i12) shows how to link several variables with a single command. When the name of a variable is written, as in input (%i13), the output will be the value linked to that variable or the name of the variable itself if it has not been linked to any value. In the expression given to be linked to Root1, variables a, b and c were replaced by the values linked to them, and the result was then simplified and linked to the variable, while variable d was linked to an expression that depends on z, because that variable was not linked to any value.

In order to remove the value linked to a variable, the function remvalue can be used; in the next example the value linked to a is removed and an expression that depends on a is then linked to Root1:

(%i16) remvalue (a)$

(%i17) Root1: (-b + sqrt(b^2 - 4*a*c))/(2*a);

(%o17)

(%i17) Root1: (-b + sqrt(b^2 - 4*a*c))/(2*a);

(%o17)

To remove all values linked to variables, the command remvalue (all ) is used. Notice that a variable can be linked to a numerical value, to an algebraic expression or to any other Maxima object.

To substitute a variable in an expression by a given value, the command subst is used; for instance, to get the expression linked to Root1 in the case when a equals 1 and to approximate the result to a floating-point number, the following commands are used:

(%i18) subst (a=1, Root1);

(%o18)

(%i19) float(%o18);

(%o19) 3.236

(%o18)

(%i19) float(%o18);

(%o19) 3.236

these two last commands did not modify the expression linked to Root1, which remains unchanged.

Maxima sets up several internal variables, with names starting by %. Some examples are the variables %i2 and %o2, linked to an input command and its result. The symbol % by itself represents the last result obtained; for instance, in input %i19 it would have been enough to write down % instead of %o18.

It is safer not to use variable names that are already being used by Maxima, even though it is possible to use the same name for a variable, a function and objects of different kinds.

A variable can also be linked to a mathematical equation; for example:

(%i20) secondlaw: F = m*a;

(%o20)

(%o20)

Maxima simplifies most of the input commands before executing them. In this last example, as the result of that simplification the variables in the product m *a were reordered alphabetically. If any of the 3 variables in the equation, F, m and a were linked to a value, that value would have been replaced, and variable secondlaw would be linked to the equation obtained after that replacement and simplification is done. In this case, none of the variables were linked to any values; if later on one of the variables in the equation is linked to value, the equation linked to secondlaw remains the same, as shown by the following commands:

(%i21) a: 3;

(%o21) 3

(%i22) secondlaw;

(%o22)

(%o21) 3

(%i22) secondlaw;

(%o22)

In order to give values to the variables in the equation linked to secondlaw, the command subst can be used; for example,

(%i23) subst([m=2, 'a=5], secondlaw);

(%o23)

(%o23)

Notice that when several variables are replaced by values, the variables and the values must be place within square brackets and separated by commas. The single quote before a was used to prevent that a were replaced by the value linked to it; had the single quote not been used, the expression "a=5" would have become "3=5" and variable a would not have been replaced in secondlaw by any value:

(%i24) subst([m=2, 3=5], secondlaw);

(%o24)

(%o24)

A variable can also be linked to a list of values, which are placed inside square brackets and separated by commas. For instance, the following command links variable squares to a list with the squares of the first 5 positive integer numbers:

(%i25) squares: [1, 4, 9, 16, 25]$

Many of the operations done by Maxima among numbers can also be done among lists. For example, to get another list in which each element is the square root of the corresponding element in the previous list, multiplied by 3, it is enough to write:

(%i26) 3*sqrt(squares);

(%o26)

(%o26)

The elements in a list are numbered by integer numbers
starting with 1. To refer to an element in the list, the
corresponding index is written within square brackets; for
instance the third element in the list linked
to `squares` is 9, which can be
extracted this way:

(%i27) squares[3];

(%o27) 9

(%o27) 9

A very useful function to create lists is makelist, which expands an expression, replacing various different values for a given variable. The first argument given to makelist must be the expression to be expanded and the second argument is the name of the variable that will be replaced by a sequence of values from an initial value and up to a maximum value defined by the third and fourth arguments. If a fifth argument is given, it will be used as the increment in the sequence of values that will be replaced; otherwise, the default increment of 1 will be used. Two examples of the use of this function are the following

(%i28) cubes1: makelist ( i^3, i, 1, 5 );

(%o28)

(%i29) cubes2: makelist ( i^3, i, 2, 6, 0.6);

(%o29)

(%o28)

(%i29) cubes2: makelist ( i^3, i, 2, 6, 0.6);

(%o29)

In the first list, the cubes of 1, 2, 3, 4 e 5 were computed. In the second one, the cubes of 2, 2.6, 3.2, 3.8, 4.4, 5.0 and 5.6 were computed. Notice that the cubes of floating-point numbers resulted in floating-point numbers, which were shown with only 4 significant digits due to the value that was previously given to variable fpprintprec in (%i10), while the cube of the integer number 2 resulted in another integer number.

The third argument given to function makelist can also be a list with the sequence of values that should be replaced for the variable in the second argument. For instance, the following command creates a list with the cubes of 5, -3.2b0 and :

(%i30) makelist ( i^3, i, [5, -3.2b0, x^2]);

(%o30)

(%o30)

There are some predefined mathematical constants in Maxima. The variable names linked to those constants usually start with the % symbol. Three important constants are the number , linked to %pi, Euler's number , base of the natural logarithms, linked to %e and the imaginary number , linked to %i.

Both %pi and %e are irrational numbers which cannot be represented exactly with a finite number of digits, but a floating-point approximation, with 16 significant digits, can be obtained using function float; a numerical representation with more significant digits can also be found using function bfloat and variable fpprec.

The imaginary number %i is used to work with complex numbers. For instance, the following input command computes the product between two complex numbers:

(%i31) (3 + %i*4)*(2 + %i*5);

(%o31)

(%o31)

Function
rectform (which stands
for *rectangular form*) can be used
to get the previous result written in the form of a real part
plus an imaginary part:

(%i32) rectform(%);

(%o32)

(%o32)

To save all the commands that have been entered during a work
session in Xmaxima, there is an option
"*Save Maxima Input to
File*" in the
"*File*" menu. The file
created with that option can be loaded later on into Maxima,
making all the commands in the file to be executed as if they
had been entered sequentially, by using option
"*Batch File*" in the
"*File*" menu. Maxima's
functions
stringout and batch can also be used
to do the same tasks, without using Xmaxima menu
options.

The file created contains simple plain-text, which can be edited with a text editor. The commands entered will appear without the tags (%i1), (%i2), etc; therefore, care must be taken with commands that refer to previous results %o1, %o2, etc, since the sequence of numbers assigned to those outputs might be different. Comments can be included into that file, starting them with the symbols /* and ending with */, which can come several lines below the start of the comment. The commands entered directly into Maxima or written into that file can also contain blank spaces between numbers, operators, variables and other objects, in order to make them more readable, and each command can also expand several lines.

An efficient way to work with Maxima consists on starting by
writing a text file, called a
"*batch*" file, with the
commands that are going to be used, which would then be loaded
with the "*Batch File*"
option. That way, if an error appears making it necessary to
reenter the same commands, it will be enough to correct the
wrong command in the file and to load it again. The commands
in that file should be written without any
tags (%i1),
(%i2),… which will be
assigned automatically when the file is run.

Xmaxima's option "*Save Console to
File*", in the "*Edit*"
menu, saves all the information shown in the screen, including
the tags (%i1),
(%o1),
(%i2),
(%o2), etc.
That file can be useful for documenting, but it cannot be reused as
*batch* file.

Some commands that are used repeatedly in different working sessions, for instance, the definition a frequently used function, can be placed inside a file that would then be loaded using batch("file"), where "file" is the complete name and path of the file used. If the name of the file does not include a path to the directory where it is located, it will be searched first in the current directory and then in a directory where Maxima expects to find user's batch files. The default location of that directory can be seen examining the contents of the system variable maxima_userdir.

A *batch* file can also be loaded
automatically every time Maxima is started, if it is given the
name maxima-init.mac and it is placed in the
directory where Maxima expects to find user's batch files. For
example, the Maxima sessions shown in the chapters of this
book are run in a system where there is a
file maxima-init.mac in
the directory
"/home/username/.maxima",
with the following contents:

ratprint: false$

fpprintprec: 4$

fpprintprec: 4$

thus, each time Maxima is started, the system variable ratprint will get the logical value false, which will turn off the warnings about floating-point numbers being automatically replaced by rational numbers and the system variable fpprintprec gets the value 4, which makes floating-point numbers to be shown in the screen with only 4 significant digits. Any other valid Maxima commands can be placed into that file, but care must be taken not to include commands that lead to errors, which could block Maxima preventing it to start.

Expressions can include mathematical operations with abstract variables. For example:

(%i33) 3*x^2 + 2*cos(t)$

Those expressions can then be manipulated producing new expressions. Here is an example:

(%i34) %^2 + x^3;

(%o34)

(%o34)

The equal sign is used to define mathematical equations; for instance:

(%i35) 3*x^3 + 5*x^2 = x - 6;

(%o35)

(%o35)

To find the roots of a polynomial function allroots can be used; for instance:

(%i36) allroots(%);

(%o36) ,

(%o36) ,

There are two complex roots and a real one. The three roots
were placed inside a list. To extract, for instance, the
right-hand-side of the third root in the list, the
command rhs (short for
*right-hand side*) is used:

(%i37) rhs(%[3]);

(%o37) −2.222

(%o37) −2.222

Variable x remains undefined, since the equal sign does not link the variable to the value on the other side. The results given in (%o36) are numerical approximations and not the exact roots. In some cases, the exact algebraic expressions for the roots can be found using the command solve, which can also solve other types of equations, not only polynomials. For example, the roots found above could also have been obtained with the following commands:

(%i38) solve ( 3*x^3 + 5*x^2 = x - 6, x )$

(%i39) float ( rectform (%));

(%o39) ,

(%i39) float ( rectform (%));

(%o39) ,

The exact result given by function solve takes several lines and it was not shown in the screen; only the approximation of those roots as floating-point numbers was shown in this case.

Remember that when a variable name has already been linked to a value, it will be necessary to type a single quote before the variable name, to be able to use it as an abstract algebraic variable. One can also remove the value linked to that variable using function remvalue.

To solve a system of equations, which can be linear or non-linear, the first argument given to solve must be a list with the equations and the second argument must be another list with the names of the variables; the list of equations or each equation in it can be previously linked to some variable. For example:

(%i40) eqA: (4 + 8)*x1 - 8* x2 = 6 + 4$

(%i41) eqB: (2 + 8 + 5 + 1)*x2 - 8*x1 = -4$

(%i42) solve ( [eqA, eqB], [x1, x2] );

(%o42)

(%i41) eqB: (2 + 8 + 5 + 1)*x2 - 8*x1 = -4$

(%i42) solve ( [eqA, eqB], [x1, x2] );

(%o42)

The result was a list within another list, because the first list encloses the values of the variables and the second list encloses the various possible solutions to the system, which in this case was only one. The previous system could have also been solved with the command linsolve, instead of solve, because the equations are linear.

Maxima includes many other functions to work with algebraic expressions. For instance, function expand to expand products and powers of expressions.

(%i43) expand ((x + 4*x^2*y + 2*y^2)^3);

(%o43)

(%o43)

Function factor is used to factor expressions. Other functions used to simplify expressions are ratsimp, radcan and xthru. Among various equivalent expressions, the concept of simplicity is a relative one and it is more a matter of taste; thus, different simplifying functions might give different expressions, even though they should be equivalent. It is convenient to try out various simplifying functions in each case and then choose a preferred form of an expression. Also, in some cases, as it happens with ratsimp, the results might be different when the same function is applied again.

Function subst, which has been used above to substitute numerical values, can also be used to substitute other expressions. For example, to substitute by , and by 2 in output (%o43), one would write:

(%i44) subst([x=1/z, y=2], %o43);

(%o44)

(%o44)

and to put everything over a common denominator and save the
result into a varaible `res` one possibility would
be:

(%i45) res: ratsimp(%);

(%o45)

(%o45)

Algebraic expressions are represented internally as lists; hence, some Maxima functions for lists can also be used with expressions. For instance, function length gives the length of a list and it can also be used to compute the number of terms in an expression; for instance

(%i46) length(res);

(%o46) 2

(%o46) 2

Since the expression res was combined into a common denominator, the two terms accounted for by length are the numerator and denominator of the expression; therefore, function first, which extracts the first element in a list, will show only the numerator of the expression linked to res

(%i47) first(res);

(%o47)

(%o47)

and the length of that new expression is:

(%i48) length(%);

(%o48) 7

(%o48) 7

The 7 elements counted are the seven sub-expressions that are
being added in (%o47). An expression that cannot be
further separated into other sub-expressions, for instance,
, is called an **atom**; functions that expect a list as
its argument will usually trigger an error when they are given
an atom as the argument. Function atom tells whether the
argument given is an atom or not.

Another function which is very useful to deal with lists is map, which will apply a given function to each element in a list. In the case of a rational expression, it can be used to apply a function to the numerator and denominator of the expression. For example, notice the different results obtained by expanding an expression and expanding its numerator and denominator separately:

(%i49) frac1: (x+y)^2 / (x-y)^2;

(%o49)

(%i50) expand(frac1);

(%o50)

(%i51) map ( expand, frac1 );

(%o51)

(%o49)

(%i50) expand(frac1);

(%o50)

(%i51) map ( expand, frac1 );

(%o51)

Table A.1 shows the names of the main trigonometric functions in Maxima. The functions that expect an angle as their input argument interpret that angle in radians and not in degrees, since Maxima also knows some properties of those functions, including their power series, which are only valid when the angle is given in radians. The results given by the inverse functions are angles in radians.

Function | Description |
---|---|

sin(x) | Sin |

cos(x) | Cosine |

tan(x) | Tangent |

sec(x) | Secant |

csc(x) | Cosecant |

cot(x) | Cotangent |

asin(x) | Arc sine |

acos(x) | Arc cosine |

atan(x) | Arc tangent |

atan2(y,x) | Arc tangent |

asec(x) | Arc secant |

acsc(x) | Arc cosecant |

acot(x) | Inverse cotangent |

All inverse functions with only one input argument give angles between 0 and . For instance:

(%i52) acos(-0.5);

(%o52)

(%i53) acos(-1/2);

(%o53)

(%o52)

(%i53) acos(-1/2);

(%o53)

Notice that the result was exact when the argument given to the function was written in exact form, using a rational number. Function atan2 takes two input arguments, which are the Cartesian coordinates and of a point and returns an angle that can be in any of the 4 quadrants (between and ), and corresponds to the angle between the segment from the origin to that point and the positive semi-axis. To convert an angle from radians to degrees, it is multiplied by 180 and divided by , as in the following example:

(%i54) 180*atan2(-1,-sqrt(3))/%pi;

(%o54) −150

(%o54) −150

To convert an angle from degrees into radians, it is multiplied by and divided by 180. For example, the sine of 60° is:

(%i55) sin(60*%pi/180);

(%o55)

(%o55)

There are also some functions to simplify trigonometric expressions. Function trigexpand expands sines and cosines of sums of angles:

(%i56) trigexpand(sin(u+v)*cos(u)^3);

(%o56)

(%o56)

Function trigreduce tries to convert an expression into a sum of terms that only have a single trigonometric function.

(%i57) trigreduce(%);

(%o57)

(%o57)

Function trigsimp applies the trigonometric identity and the relations among trigonometric functions, trying to write the expression using only sines and cosines. For instance:

(%i58) tan(x)*sec(x)^2 + cos(x)*(1 - sin(x)^2);

(%o58)

(%i59) trigsimp(%);

(%o59)

(%o58)

(%i59) trigsimp(%);

(%o59)

The simplest way to represent mathematical functions in Maxima is by using expressions. For example, to represent function , the expression on the right-hand-side is linked to variable

(%i60) f: 3*x^2 - 5*x;

(%o60)

(%o60)

The derivative of with respect to is computed using function diff

(%i61) diff (f, x);

(%o61)

(%o61)

and the antiderivative with respect to is obtained with integrate

(%i62) integrate (f, x);

(%o62)

(%o62)

The value of the function at a point, for instance , can be obtained substituting by 1 using subst, or with function at

(%i63) at (f, x=1);

(%o63) −2

(%o63) −2

Maxima also has its own syntax to define general functions, which is the subject of the next section, and which can be used in the case of mathematical functions. For example, the same function could have also be defined as follows:

(%i64) f(x) := 3*x^2 - 5*x;

(%o64)

(%o64)

The value of the function at a point would then be obtained directly, but to compute the derivative and antiderivative it is now necessary to write the function and the variable in its argument:

(%i65) f(1);

(%o65) −2

(%i66) diff (f(x), x);

(%o66)

(%i67) integrate (f(x), x);

(%o67)

(%o65) −2

(%i66) diff (f(x), x);

(%o66)

(%i67) integrate (f(x), x);

(%o67)

Notice that the commands in (%i66) and (%67) are really differentiating or integrating an expression for and not the Maxima function. What happened was that when f( x) is written and x is not linked to any value, the Maxima function will give as result an expression that is then differentiated by diff or integrated by integrate. But some Maxima functions will not give a mathematical expression as their result; for instance:

(%i68) h(x) := if x < 0 then x/2 else x^2;

(%o68)

(%o68)

The values at different points, such as , are obtained without any problem, but functions diff and integrate cannot compute the derivative and antiderivative, because the result of h( x) is not a mathematical expression (it includes Maxima specific commands: if, then and else):

(%i69) diff (h(x), x);

(%o69)

(%o69)

Whenever diff doesn't know how to compute a derivative, as in the previous case, it will echo the same input that was given, which in this case was just shown in a different form in the screen, but internally variable %o69 became linked to diff(if x < 0 then x/2 else x^2,x).

When an expression depends on several variables, diff computes the partial derivative:

(%i70) diff (x^2*y-y^3, x);

(%o70)

(%o70)

A definite integral is computed also with function integrate, giving the integral limits after the integration variable; for example:

(%i71) integrate (1/(1 + x^2), x, 0, 1);

(%o71)

(%o71)

A Maxima function is a program with some input variables and an output. Maxima has a simple programming language that is used to define those functions and it is also possible to use Lisp, which is the language in which Maxima is written, to define functions. It is even possible to redefine any of the functions that have been referred; for instance, if in the Maxima version being use some function has a bug that has already been fixed in a more recent version, it is possible to load the new version of the function and, unless it introduces conflicts with other older functions, it should work correctly.

A first example of a function is a fact to compute the factorial of an integer number (to get the factorial of a number in Maxima one just has to type an exclamation sign ! after it, but another version of the same program will be defined here):

(%i72) fact(n) := if n <= 1 then 1 else n*fact(n-1);

(%o72)

(%i73) fact(6);

(%o73) 720

(%o72)

(%i73) fact(6);

(%o73) 720

It is not necessary to use any command to return the output, since the output of the last command in the function will become the output of the function. A function can call itself recursively as it has been done in this example.

Several Maxima commands can be grouped together by typing them inside parenthesis and separated by commas. Those commands are run sequentially and the result of the last command will be the result of the whole group. Each command can be indented and can expand more than one line. The following example defines a function that adds all the arguments given to it:

(%i74) add([v]) := block([s: 0],

for i:1 thru length(v) do

(s : s + v[i]),

s)$

(%i75) add (45,2^3);

(%o75) 53

(%i76) add (3,log(x),5+x);

(%o76)

for i:1 thru length(v) do

(s : s + v[i]),

s)$

(%i75) add (45,2^3);

(%o75) 53

(%i76) add (3,log(x),5+x);

(%o76)

A list was used as the argument for the function, which makes the function accept any number of input variables (or none) and all the input variables will be placed in a list linked to the local variable v. Function block was used to define another local variable s, with an initial value of 0, which by the end of the function will have the sum of the input variables. The first element given to block must be a list, with any number of local variables, each one with or without an initial value and after that list follows the remaining part of the function definition. The command for iterates the local variable i —in this case from 1 up to the length of the list v— with increments, by default, equal to 1 (option step can be given to modify the default value of that increment). When the iterations are done, the value of the variable is shown to make it become the output of the function.

When an unknown function is used no errors are triggered; instead, the unknown function is echoed in the output; for example:

(%i77) 2*4*maximum(3,5,2);

(%o77)

(%o77)

Most of Maxima functions behave the same way when they fail to give a result. For instance:

(%i78) log(x^2+3+x);

(%o78)

(%o78)

That behavior is very useful, because it makes it possible to change the value of the arguments later on and to reevaluate the function. For example, substituting variable x by the floating-point number 2.0 in this last result, the logarithm would then be computed:

(%i79) subst(x=2.0, %);

(%o79) 2.197

(%o79) 2.197

plot2d is used to show the plot of one or several functions of one variable. For example, the plot of the polynomial , for values of between −3 and 1, is shown by the following command:

(%i80) plot2d(3*x^3 + 5*x^2 - x + 6, [x, -3, 1]);

the result of command (%o80) (which was not shown here) is the
name of an auxiliary file that was created and then passed
to an external program (*Gnuplot*)
that will interpret the commands in it and will show the
plot in a separate window
(Figure A.2). Moving the mouse
over the plot, the coordinates of the point where the cursor
is are shown.

To plot several functions in the same window, those functions are placed inside a list. For instance:

(%i81) plot2d ( [sin(x), cos(x)], [x, -2*%pi, 2*%pi] );

The results is shown in Figure A.3.

Since version 5.32, there are three options pdf_file, png_file and ps_file that can be used to save a plot into a file in PDF, PNG or PostScript format.

For instance, the following command saves the plot produced by command (%i80) into a PNG file:

(%i82) plot2d(3*x^3+5*x^2-x+6,[x,-3,1],[png_file,"function1.png"]);

(%o82) [/home/username/maxout.gnuplot, /home/username/function1.png]

(%o82) [/home/username/maxout.gnuplot, /home/username/function1.png]

The result shows that two files were created; the first
one, named `maxout.gnuplot`
contains the Gnuplot commands that will generate the plot
and save the result into the second file name
shown, `function1.png`. Since no path was given for
the name of the file in the
png_file option,
the file is created in the user directory. File
`maxout.gnuplot` contains plain
text which can be edited with a text editor and run,
independently of Maxima, using
program `gnuplot`:

gnuplot /home/username/maxout.gnuplot

The following command saves Figure A.2 into a PDF file:

(%i83) plot2d(3*x^3+5*x^2-x+6,[x,-3,1],[pdf_file,"function1.pdf"]);

It is also possible to create plots with lists of points in a two-coordinate system. The two coordinates of each point can be given as a list, inside another list with all the points. For example, to show the three points (1.1, 5), (1.9, 7) and (3.2,9) in a plot, the points coordinates can be placed inside a list linked to p:

(%i84) p: [[1.1, 5], [1.9, 7], [3.2, 9]]$

To create the plot, it is necessary to give plot2d a list that starts with the keyword discrete, followed by the list of points. In this case it is not mandatory to specify an interval of values for the variable in the horizontal axis:

(%i85) plot2d ( [discrete, p] );

The plot is shown in Figure A.4.

By default, the points are linked by line segments; to show only the points, without line segments, option style should be used with a value equal to the keyword points.

Several sets of points and several functions can also be shown in a single plot. In that case, each set of points should be represented by a list that starts with the keyword discrete, as in the previous section, and each function should be represented by an expression (or function name). All the lists of points and expressions should also be enclosed within another list and it will be necessary to specify a range of values for the independent variable (the one in the horizontal axis); a range of values for the variable in the vertical axis is not mandatory, but can be given using option y.

Plot the experimental results in the following table,
together with the expected theoretical curve:
, where
cm/s^{2}

(cm) | (s) |

10 | 0.6 |

20 | 0.9 |

30 | 1.1 |

40 | 1.3 |

50 | 1.4 |

**Solution**. The plot of the results and the expected curve is
obtained with the following commands:

(%i86) table: [[10,0.6],[20,0.9],[30,1.1],[40,1.3],[50,1.4]]$

(%i87) plot2d([[discrete, table], 2*%pi*sqrt(L/980)], [L,0,60],

[style, points, lines], [color, red, blue],

[point_type, asterisk], [legend, "results", "theory"],

[xlabel, "L (cm)"], [ylabel, "T (s)"], [y,0,2]);

(%i87) plot2d([[discrete, table], 2*%pi*sqrt(L/980)], [L,0,60],

[style, points, lines], [color, red, blue],

[point_type, asterisk], [legend, "results", "theory"],

[xlabel, "L (cm)"], [ylabel, "T (s)"], [y,0,2]);

Option style in (%i87) makes the first object, which is the list of points in the table, to be represented as isolated points and the second object, which is the expression for the expected curve, to be represented by small line segments, which is the default behavior. The plot is shown in Figure A.5. Option y was used in order to leave some space above for the legend; that option is also very useful in the case of functions with vertical asymptotes, to limit the values on the vertical axis thus preventing the vertical axis to extend up to very large values.

Command plot3d is used to plot functions of two variables. For example, the following command creates the plot shown in Figure A.6:

(%i88) plot3d ( sin(x)*sin(y), [x, 0, 2*%pi], [y, 0, 2*%pi] );

Moving the mouse over the plot, while its left-side button is pressed, the surface will be rotated showing how it looks from different sides. The command plot3d also accepts a list of several functions to be plotted in the same window. It is also possible to give a list o 3 functions of 2 parameters, that define the 3 components of a position vector that describes a surface (parametric plot).

There are many other options for plot2d and plot3d and there are other graphic functions. Those options and functions are describe in the section titled "Plotting" of the Maxima Reference Manual: http://maxima.sourceforge.net/docs/manual

The most elaborate plot in this book is Figure 7.13, which was produced with the following commands:

(%i89) Ft: -s^4/2 + 4*s^3 - 3*s^2/2 - 32*s + 25$

(%i90) V: -integrate (Ft,s,0,s)/0.3$

(%i91) se: map (lambda([x],rhs(x)), float (realroots (Ft)))$

(%i92) He: makelist (subst (s = v, V), v, se)$

(%i93) p: makelist(map(lambda([x],rhs(x)),float(realroots(V=H))),

H,[He[1],250,He[3],70])$

(%i94) l1: [discrete, [[-4,He[1]], [p[1][1],He[1]]]]$

(%i95) l2: [discrete, [[-4,250], [p[2][1],250]]]$

(%i96) l3: [discrete, [[p[2][2],250], [p[2][3],250]]]$

(%i97) l4: [discrete, [[p[3][2],He[3]], [p[3][5],He[3]]]]$

(%i98) l5: [discrete, [[p[4][2],70], [p[4][3],70]]]$

(%i99) l6: [discrete, [[p[4][4],70], [p[4][5],70]]]$

(%i100) rep: [discrete,[l1[2][2],l2[2][2],l3[2][1],l3[2][2],

l4[2][1],l4[2][2],l5[2][1],l5[2][2],l6[2][1],l6[2][2]]]$

(%i101) max: [discrete,[[se[1],He[1]],[se[3],He[3]]]]$

(%i102) min: [discrete,[[se[2],He[2]],[se[4],He[4]]]]$

(%i103) plot2d ([V,l1,l2,l3,l4,l5,l6,rep,max,min], [s,-4,7.5],

[ylabel,"V(s)"], [legend,false],

[color,blue,red,red,red,red,red,red,red,black,black],

[style,lines,lines,lines,lines,lines,lines,lines, points,points,points],

[point_type,bullet,asterisk,circle],[label,["-32.9",0.3,-65],

["51.1",5.5,20], ["70",0.8,85], ["70",5.6,85],

["114.7",0.6,132], ["114.7",5.4,132], ["250",-3.99,270],

["250",3.5,270], ["356.4",-3.9,375], ["356.4",3.4,375]])$

(%i90) V: -integrate (Ft,s,0,s)/0.3$

(%i91) se: map (lambda([x],rhs(x)), float (realroots (Ft)))$

(%i92) He: makelist (subst (s = v, V), v, se)$

(%i93) p: makelist(map(lambda([x],rhs(x)),float(realroots(V=H))),

H,[He[1],250,He[3],70])$

(%i94) l1: [discrete, [[-4,He[1]], [p[1][1],He[1]]]]$

(%i95) l2: [discrete, [[-4,250], [p[2][1],250]]]$

(%i96) l3: [discrete, [[p[2][2],250], [p[2][3],250]]]$

(%i97) l4: [discrete, [[p[3][2],He[3]], [p[3][5],He[3]]]]$

(%i98) l5: [discrete, [[p[4][2],70], [p[4][3],70]]]$

(%i99) l6: [discrete, [[p[4][4],70], [p[4][5],70]]]$

(%i100) rep: [discrete,[l1[2][2],l2[2][2],l3[2][1],l3[2][2],

l4[2][1],l4[2][2],l5[2][1],l5[2][2],l6[2][1],l6[2][2]]]$

(%i101) max: [discrete,[[se[1],He[1]],[se[3],He[3]]]]$

(%i102) min: [discrete,[[se[2],He[2]],[se[4],He[4]]]]$

(%i103) plot2d ([V,l1,l2,l3,l4,l5,l6,rep,max,min], [s,-4,7.5],

[ylabel,"V(s)"], [legend,false],

[color,blue,red,red,red,red,red,red,red,black,black],

[style,lines,lines,lines,lines,lines,lines,lines, points,points,points],

[point_type,bullet,asterisk,circle],[label,["-32.9",0.3,-65],

["51.1",5.5,20], ["70",0.8,85], ["70",5.6,85],

["114.7",0.6,132], ["114.7",5.4,132], ["250",-3.99,270],

["250",3.5,270], ["356.4",-3.9,375], ["356.4",3.4,375]])$

The function to be plotted is equal to minus the antiderivative of the force , divided by the mass, 0.3. The values of where equals zero were extracted into the list se, namely, that list contains the points where has critical points. The list p has the coordinates of those critical points and where equals 70 and 250. Six horizontal lines l1…l6 were created using the coordinates of those points and the three sets of points rep, max and min hold the coordinates of the points where is equal to 70 or 250, where it has local maxima and where it has local minima. The plot was then created showing the function, the horizontal lines and the three sets of points, using different objects for each group. Finally option label was used to write down some information on some places of the plot.

- Plot each of the following functions, using
ranges that will show well the form of the function and its
important features (roots and critical points).
- The function has two critical points (a local minimum and a local maximum). Plot the function. Keeping in mind that the local minimum and maximum are located where the derivative of the function equals zero, find the and coordinates of those two points.
- Find the equation of the circumference that
includes the three points (−2, 7), (−4, 1) and
(4, −5).
**Hint**: the general form of the equation should be . To find the three constants , and , substitute the coordinates of the 3 points in that general equation and solve the resulting system of 3 equations. - Define a Maxima function
`fib(n)`that will compute any number in Fibonacci's sequence, = {1, 1, 2, 3, 5, 8,…}, defined by the recurrence relation: - Write a Maxima function "maximum" that will return the maximum value from all the arguments given as input.

2. the local maximum is at (0.709, 4.30) and the local minimum at (3.29, -4.30).

3.