Maxima/Printable version
This is the print version of Maxima You won't see this message or any elements not part of the book's content when you print or preview this page. |
The current, editable version of this book is available in Wikibooks, the open-content textbooks collection, at
https://en.wikibooks.org/wiki/Maxima
What is Maxima and what is it useful for
What is Maxima and What is it Useful or?
[edit | edit source]Introduction
[edit | edit source]"Experienced Lisp programmers may say that there are built-in Lisp procedures that will achieve far more succinctly and efficiently what I have achieved in some of the example programs here.
My defence is that the point of these tutorials is not to teach Common Lisp in its entirety, but to help the reader understand the general principles of programming in Lisp. I believe that it is daunting for a beginner to be confronted with a catalogue of Lisp procedures to learn by rote. It is far more important to understand how to approach a problem, and break it down into simpler problems with the help of recursion."
Readers might find it curious for a book about Maxima to lead off with a quote about the Lisp programming language. It is true that Maxima is a software application based on Lisp, so it that sense a reference to Lisp is not completely unusual.
However, it is the point that is made by this quote that is quite relevant to those that find themselves using Maxima for some specific purposes or simply as a matter of personal interest. This book is not intended to be a "Maxima in Small Parts" version of the topic. It is neither a tutorial or a comprehensive and thoroughgoing technical guide for Maxima. Neither is it a "How-to-Do" recipe document for this or that with Maxima This book is intended to be a sort of middle ground between a tutorial and a technical reference manual.
Maxima as a computer algebra system (CAS) application is technically both wide and deep in terms of its scope. The intent of this book is to "help the reader understand the general principles of" using Maxima. If the reader is new to Maxima then all of what follows may be too much with which to start. Beginning with the many tutorials available may better serve users new to Maxima. On the other hand, if the reader is an experienced user of Maxima then the effort to consider all of what follows may not meet subjective technical standards, and possibly not be particularly instructive.
Maxima, as well as Lisp, are not "new kids on the block" so to speak. To some readers and users with a more modern perspective and exposure to such matters, Maxima and its "out-of-the-box" command line interface (CLI) may seem crude and out of date. Don't be swayed by this. There is a much capability at hand in using Maxima. Readers and users are highly encouraged to use the wxMaxima user interface application for the best experience. wxMaxima with its interactive workbook environment positions Maxima on a completely different level of user experience. The details of installing Maxima and wxMaxima follow in a subsequent section.
About Maxima and its Uses
[edit | edit source]Maxima belongs to the category of computer software applications known as computer algebra systems - or CAS. Within this category of applications, it is "general purpose" in that it is not dedicated to any specific mathematical topic of study or application. However, within that general-purpose category there is a sense in which it is a special-purpose application in that, while significant numerical computational capabilities are possible, the primary emphasis is on processing "symbolic" mathematical expressions using syntax for expression composition for input that conforms to that which Maxima can parse, interpret, and process.
So, to state it briefly, Maxima is primarily an application for processing symbolic mathematical expressions according to the purpose of the user using syntax Maxima can parse and interpret.
In general, Maxima expressions fall into three categories:
- Mathematical expressions
- Object expressions
- Programming expressions
Mathematical expressions are for doing things that simply are essentially of a mathematical nature. Object expressions are used to create data structures for storage. Programming expressions provide the capability for some types of imperative or functional programming instructions.
Thus, Maxima is not strictly a programming language like Python, Julia, Java, C, and so forth. The differences between Maxima as a CAS, and other programming languages should become evident from the contents of this document and, even better, with the actual experience of using Maxima to accomplish specific mathematical tasks.
Getting started using Maxima will be much easier if the user begins with a particular frame of mind. Almost every user input to Maxima is an expression of some type. Expressions are what Maxima is all about - especially mathematical symbolic expressions. If numbers can be considered as represented symbolically by numeration (integers, fractions, decimal or floating point literals) then it is not an exaggeration to characterize everything Maxima can do as symbolic processing.
The following is a list of a few examples (certainly not all) of what Maxima can be used for:
- Solve algebraic equations symbolically or numerically
- Solve ordinary differential equations
- Matrix creation and operations
- Calculus - limits, differentiation, integration
- Expansion, factoring, and simplification of expressions
- Rational numbers as fractions, and "big" floating point numbers to specified precision
- Complex numbers
- Trigonometric expressions
Plotting - 2D and 3D with some animation
Maxima also includes packages that may be loaded into the current working environment that provide for some specialized tasks, including the study of specific mathematical subjects or applications.
Methods of use
Users have choices as to the kind of interface used to interact with Maxima. These choices inevitably have an influence on the installation source and process used to install Maxima on a computer with a particular operating system - notably MS Windows, Linux, or Mac OS.
The following is a concise list of the various interactive interface options:
- Online by way of a web browser interface , without installation[1]
- Offline after installation on a computer system
- Using a graphical user interface (with a GUI)
- From a terminal console (without a GUI)
The online web browser interface may be useful for beginners that want to try Maxima for the first time, or for occasions when a local installation is not available for some reason. This web browser interface includes a link to the Maxima Documentation, which is best characterized as a reference manual with some examples, and not as a user guide.
After installation of Maxima alone without a GUI, the user can interface with the Maxima CLI by way of a terminal console by entering:
$> maxima
This should start Maxima as follows:

The (%i1) prompt is where the first Maxima expression is entered by the user. For example:
(%i1) 'integrate(%e^(2*t+a)*sin(t)*t,t);
⌠
⎮ 2 t + a
(%o1) ⎮ %e t sin(t) dt
⎮
⌡
(%i2)
It is likely that most users will find that interacting with Maxima from a terminal console (without a GUI) is somewhat crude, and furthermore all input expressions and output expressions are not persistent between sessions. Hence, the GUI option is generally recommended, but at the cost of having to become familiar with the GUI of choice.
There are two commonly used GUIs for Maxima:
- Xmaxima -- https://maxima.sourceforge.io/docs/xmaxima/xmaxima.pdf
- wxMaxima -- https://wxmaxima-developers.github.io/wxmaxima/index.html
Xmaxima is typically included with the Maxima installation. It is very similar to the terminal console GUI.

wxMaxima is unquestionably the more comprehensive, complete, and useful GUI presently available for Maxima.

Maxima is typically more useful as an interactive tool. However, it can be used to execute a file containing Maxima expressions. To execute Maxima expressions saved in a file named c.mac for example, and save output to a text file named c.txt use a command from a terminal shell session such as:
$> maxima -b c.mac >c.txt
References
[edit | edit source]- ↑ "Maxima Online - WASM". maxima-on-wasm.pages.dev. Retrieved 2026-04-19.
Installation
Installation
[edit | edit source]If there can be a frustration for both new users of Maxima and current users it is installation. For typical users, this does not need to be the case. This section is devoted to providing the simplest installation path possible for computers with three operating systems (MS Windows, Mac OS, and Linux) without getting bogged down by technical details or atypical requirements.
There are in general two installation options that will be of interest to most users of Maxima:
- Installation of Maxima alone
- Installation of the wxMaxima GUI including Maxima
Installation of Maxima Alone for Linux, MS Windows, and Mac OS
[edit | edit source]For Linux users, there are several options for installing Maxima:
- Maxima may be installed using the software package management system for a Linux distribution. Most distributions provide packages for Maxima in their repositories. These usually are the version which was current, when the distribution was released. So they likely are not the latest version of Maxima. Also, these binaries may not have been compiled with support for Unicode which is something that users may find useful. However, having a more current version of Maxima may not be necessary, and the same applies to Unicode support. So if following the Maxima installation instructions of the links below for Linux are too technical, then the simplest path is to install Maxima may be by using the software package management system for a specific Linux distribution.
- Maxima can be installed by following the instructions for Linux at the following: Maxima Linux Manual Installation Instructions. Keep in mind that installation using this method, while providing a recent release of Maxima, does not provide for a built-in means of updating when a newer release becomes available. Instructions for updating to a newer release can be found by referring to the information at the end of this section.
For MS Windows and Mac OS, follow the instructions of the following:
- MS Windows: MS Windows Maxima Installation Instructions
- Mac OS: Mac OS Maxima Installation Instructions
Installation of wxMaxima GUI including Maxima for MS Windows and Mac OS
[edit | edit source]For MS Windows and Mac OS, follow the instructions for the relevant operating system provided using the following link to the wxMaxima website installation instruction page: wxMaxima Installation Instructions.
Installing wxMaxima by following these instructions will include the installation of Maxima.
Installation of wxMaxima GUI including Maxima for Linux (recommended)
[edit | edit source]For Linux there are several options:
- As noted for Linux, above there is the option of installing wxMaxima including Maxima using the software package management system for your Linux distribution. Most distributions provide binaries for wxMaxima and Maxima in their repositories. These usually are the version which was current, when the distribution was released. So they likely are not the latest version of wxMaxima and Maxima. Also, these Maxima binaries may not have been compiled with support for Unicode which is something that users may find useful. However, having a more current version of wxMaxima and Maxima may not be necessary, and the same applies to Unicode support. So the simplest path may be to install wxMaxima and Maxima using the software package management system for your Linux distribution.
- The other option which may be the best for most Linux users is to install wxMaxima from FlatHub using flatpak. FlatHub packages generally speaking will be more recent releases of wxMaxima. Some Linux distributions include support for FlatHub flatpak packages. Refer to the following link for specific Linux distributions: FlatHub Linux Distribution Support and Setup. The wxMaxima FlatHub source is available using the following link: wxMaxima FlatHub Installation. Under Add-ons (Adds Maxima) select the Install button to include Maxima with the wxMaxima installation.
- The second option is to install Maxima using the Installation of Maxima Alone for Linux instructions of the link above, and then install wxMaxima using the software package management system for your Linux distribution. wxMaxima will either autodetect the installed version of Maxima, or the user can provide the path to the desired Maxima executable file using the Configure settings of wxMaxima. This option provides a relatively recent version of Maxima with Unicode support.
Instructions for compiling and installing Maxima and wxMaxima from source code can be found by referring to the links above for Maxima and wxMaxima respectively. This option is technically complex requiring specialized know-how.
Steps to Upgrade or Remove a Manually Installed Version of Maxima
[edit | edit source]To Upgrade a Manually Installed Version of Maxima
[edit | edit source]Important! Read the following in its entirety before attempting a Maxima version upgrade.
If Maxima was manually installed on a Linux system by following the instructions for Linux at the following link:
Maxima Linux Manual Installation Instructions
then to upgrade a manually installed Maxima version from a binary "tarball" (like maxima-5.49.0-sbcl-glibc2.31.tar.gz for example), to a newer version it is necessary to repeat the same installation instructions of this link using the downloaded tarball for the newer version, as there is no built-in upgrade mechanism for this sort of binary tarball manual installation.
Note: Since the installation is manual, always ensure compatibility with the system glibc version (by checking with ldd --version) according to the installation instructions.
By repeating the the installation steps as published using the tarball of the newer Maxima version, files that are common to both versions will be replaced by the same or newer files. Additionally, a new directory will be created for the new Maxima version in the directory /usr/local/share/maxima. A similarly named directory will be created in the directory /usr/local/lib/maxima.
For example, if the tarball is named maxima-5.49.0-sbcl-glibc2.31.tar.gz, then the directories for that version will be /usr/local/share/maxima/5.49.0 and /usr/local/lib/maxima/5.49.0. These two directories contain all the files unique to the 5.49.0 version of Maxima. The /usr/local/share/maxima and /usr/local/lib/maxima directories may contain other directories from previously installed versions.
For example, a previous installation may have created a directory named /usr/local/share/maxima/5.48.1 for the 5.48.1 version of Maxima. Any previous such directories may be removed or retained according to user preferences. It may be best to remove any directories of previous versions before the installation of a newer version.
WARNING! Use caution to prevent deleting unrelated files.
The directories for previous version named 5.48.1 for example can be removed as follows:
sudo rm -rf /usr/local/share/maxima/5.48.1
sudo rm -rf /usr/local/lib/maxima/5.48.1
The version of the new installation can be checked using:
maxima --version
from a terminal shell session.
To Remove Manually All Installed Versions of Maxima
[edit | edit source]To remove all manually installed versions of Maxima, delete all files related to Maxima installed in the following directories:
/usr/local/bin//usr/local/share/maxima//usr/local/lib/maxima/
WARNING! Use caution to prevent deleting unrelated files.
sudo rm /usr/local/bin/maxima
sudo rm /usr/local/bin/rmaxima
sudo rm /usr/local/bin/xmaxima
sudo rm -rf /usr/local/share/maxima
sudo rm -rf /usr/local/lib/maxima
Introduction By Example
Getting Used to Maxima By Way of an Example of Use
[edit | edit source]The examples that follows are presented for the purpose of providing some beginning perspective, and hopefully some motivation to make the effort to get familiar with how Maxima works.
The task at hand is relevant in the context of aerodynamics and aviation. The specific goal is to find the dynamic pressure at a true airspeed (VTAS) of 200 ft/s at sea level.
Dynamic pressure is calculated using the expression:Where:
- = dynamic pressure lbf/ft² (pounds of force per square foot)
- = air density (at sea level is 0.0023769) slugs/ft³
- = true airspeed in feet per second (ft/s).
British Engineering units are used in this context to avoid multiple conversions due to the units used. It is better to convert in the end if necessary in this case.
Note: The appearance of the following Maxima examples may vary depending on Unicode support in the version of Maxima being used and the Maxima user interface -- UI. The Maxima examples used in this book are from the wxMaxima GUI unless noted otherwise, and a version of Maxima with Unicode support.
First, enter the Maxima expression for dynamic pressure q:
(%i1) q : 1/2*\ρ*V^2;
(q) (V^2*ρ)/2
This Maxima expression uses the colon character to assign the expression for dynamic pressure to the identifier q. The identifier q is now simply a name for an expression. The equal sign ( = ) is not used for this operation in Maxima as is the case with some programming languages. This Maxima line of a input expression ends with a semicolon ( ; ) character. Each line of input must end with a semicolon or the dollar sign character ( $ ), the use of which will be described later. Next, enter an assignment expression for the numerical value of the air density at sea level:
(%i2) ρ : 0.0023769;
(ρ) 0.0023769
Density ρ is in the units of slugs per cubic foot - slugs/ft³. With this next input expression, Maxima is asked to evaluate q. This is accomplished by two single quotation marks placed before q as shown next:
(%i3) ''q;
(%o3) 0.0033855446120918224*VTAS^2
The output indicates that q depends on VTAS -- true airspeed. The goal is to evaluate q, if VTAS = 200 ft/s is true. One way to do that is with the following Maxima expression:
(%i4) ''q, VTAS = 200;
(%o4) 135.42178448367287
The result is about 135 pounds of force per square foot.
There is another way to accomplish this that may be somewhat more convenient for determining sea level dynamic pressure given true airspeed. First, assign the Maxima floating point literal value of 0.0033855446120918224 to an identifier named c as follows:
(%i5) c : 0.0033855446120918224;
(c) 0.0033855446120918224
Next, enter
(%i6) q(VTAS) := c*VTAS^2;
(%o6) q(VTAS):=c*VTAS^2
(%i7) q(200);
(%o7) 135.4217844836729
This result is limited to sea level density. That does not make the result of no practical use. This relationship, or something similar is, used to calibrate aircraft airspeed indicators to display indicated airspeed (IAS) in the cockpit. However, it might be the case that it is necessary to determine the dynamic pressure at other altitudes besides sea level.
In the standard atmosphere model, air density is a function of altitude (h), and is defined piece-wise based on the atmospheric layer.
The density is derived from the Ideal Gas Law: where in British Engineering units:
- ‒ is density in slugs/ft³
- ‒ is pressure in lbf/ft²
- ‒ is temperature in °R (Rankine)
- ‒ is the specific gas constant (for dry air) approximately 1716.56 (ft·lbf)/(slug·°R)
(%i8) P = \ρ*R*T;
(%o8) P=RTρ
The backslash character ( \ ) in front of the character for in the input expression allows an identifier to use Unicode. This makes for some nicer looking output. This is a Maxima mathematical equation expression. This equation can be solved for as follows:
(%i9) solve(%,ρ);
(%o58) [ρ=P/(R*T)]
The Maxima built-in identifier % names the last output expression.The output of this expression is a Maxima list object with the only instance being the equation expression solved for . Depending on the expression, the solve() operation may result in more than one solution expression. Maxima creates a list object for one or more solution expressions. This solution equation expression can be accessed as follows:
(%i10) %[1];
(%o10) ρ=P/(R*T)
The value of this expression is obtained by referencing the first (and only) solution of the Maxima list object of solutions ‒ [ρ=P*R*T]. The reference is obtained by use of the [1] index syntax as shown. There are other ways Maxima can be used to accomplish the same result:
(%i11) igl : P = ρ*R*T;
(igl) P=R*T*ρ
In this case the expression for the ideal gas law was assigned an identifier igl. The advantage to this sort of assignment is that the equation can be referred to using the identifier as follows for example:
(%i12) solve(igl,ρ);
(%o12) [ρ=P/(R*T)]
The identifier igl can be used at any point to refer to the equation expression: P = \ρ*R*T). An assignment operator can also be used to assign the identifier solution to an expression. For example:
(%i13) solve(igl,ρ);
(%o13) [ρ=P/(R*T)]
(%i14) solution : solve(igl,ρ);
(solution) [ρ=P/(R*T)]
(%i15) solve(solution,P)[1];
(%o15) P=R*T*ρ
The last input and output expression might be somewhat of a "head-scratcher" at first glance, but it is worthwhile to understand how Maxima works in this case. The identifier solution names an expression that uses the solve() operator on the identifier igl as an argument. This expression is evaluated first by Maxima. Then the solve() operator is applied to the result solving for P. The result is a list object with one solution expression. This expression is then referred to using the [1] index, and the output is the equation expression P=R*T*ρ .
The expression for ρ (density) as a function of pressure (p) and temperature (°F) can be checked against known values using the following expressions:
(%i16) \°R(°F) := °F + 459.67;
(%o16) °R(°F):=°F+459.67
(%i17) P(p) := p*144.0;
(%o17) P(p):=p*144.0
(%i18) R:1716.56;
(R) 1716.56
(%i19) ρ(p,°F) := P(p)/(''R*\°R(°F));
(%o19) ρ(p,°F):=P(p)/(1716.56*°R(°F))
The above Maxima expressions are examples of Maxima function expressions.
For standard sea level conditions of pressure and temperature as follows,
- p is 14.696 lbf/ft²
- °F is 59.0°
the calculated value for density is:
(%i20) ρ(14.696,59.0);
(%20) 0.0023769033250291326
Compare this resulting value of density with the the value of the table below for 0 altitude and temperature of 59.0 °F:
| Altitude above Sea Level
- h - (ft) |
Temperature
- T - (oF) |
Acceleration of Gravity
- g - (ft/s2) |
Pressure
- p - (lb/in2) |
Density
- ρ - (10-4 slugs/ft3) |
|---|---|---|---|---|
| 0 | 59.0 | 32.174 | 14.696 | 23.77 |
| 5000 | 41.17 | 32.159 | 12.228 | 20.48 |
| 10000 | 23.36 | 32.143 | 10.108 | 17.56 |
| 15000 | 5.55 | 32.128 | 8.297 | 14.96 |
| 20000 | -12.26 | 32.112 | 6.759 | 12.67 |
| 25000 | -30.05 | 32.097 | 5.461 | 10.66 |
| 30000 | -47.83 | 32.082 | 4.373 | 8.91 |
| 35000 | -65.61 | 32.066 | 3.468 | 7.38 |
It would be useful to have the means to round result values to a desired number of decimal places. Maxima does not have a built-in operator for rounding decimal fraction values. Also, there is no package that is included as part of the Maxima distribution that provides for this capability. However, Robert Dodier has created a Maxima package that includes a function for this purpose ‒ named excel_round.mac[1].
However, to be able access the excel_round() function of this package, it must first be downloaded or copied into a location accessible to Maxima using the load() operator. The built-in Maxima load() operator is used to access specialized functions that are not built-in to Maxima. In order to use the load() operator, the location of the downloaded excel_round.mac file has to be part of the argument to the load() operator unless the file happens to be in the Maxima current working directory. The built-in operatingsystem package can provide some functions to help with determining the current working directory. This package is loaded as follows:
(%i21) load(operatingsystem);
(%o21) "/usr/local/share/maxima/5.49.0/share/contrib/operatingsystem/operatingsystem.mac"
(%i22) getcurrentdirectory();
(%o22) "/home/username/"
In this example username is the name of the home directory of the user. so if the downloaded excel_round.mac file is not located in the current working directory, then the directory can be changed to the location where the file is located:
(%i22) chdir("/home/username/local/maxima/packages");
(%o22) "#P"/home/username/local/maxima/packages""
Now the excel_round.mac file can be loaded assuming it is within the directory
/home/username/local/maxima/packages
as follows:
(%i23) load("excel_round.mac");
(%o23) "excel_round.mac"
Alternatively, if the location of the file is known it can be loaded using the full path name as follows for example:
(%i24) load("/home/username/local/maxima/packages/excel_round.mac");
(%o24) "/home/username/local/maxima/packages/excel_round.mac"
This method obviates the need for loading the operatingsystem package.
Note: The wxMaxima GUI makes loading packages simply a matter of a menu selection.
The density value above can be rounded to six decimal places as follows:
(%i25) excel_round(ρ(14.696,59.0),6);
(%o25) 0.002377
This rounded value agrees with the sea level value of slugs/ft³ taken from the table of Standard Atmosphere values. For Standard Atmosphere values of pressure ( 6.758 lbf/in² ) and temperature ( -12.26 °F ) at 20,000 ft the density value is:
(%i26) excel_round(ρ(6.759,-12.26),6);
(%o26) 0.001267
This rounded value agrees with the sea level value of slugs/ft³ taken from the table of Standard Atmosphere values.
Pressure
[edit | edit source]However, what is needed for the task at hand is density as a function of altitude. Both the pressure P and the temperature T can be expressed as a function of altitude h:
Where in British Engineering units, the constants are:
- is Pressure in pounds per square foot lbf/ft²
- is (Sea Level Pressure): 2116.224 lbf/ft² or 14.696 lbf/in²
- is the specific gas constant (for dry air) approximately 1716.56 (ft·lbf)/(slug·°R)
- is (Sea Level Temperature): 518.67 °R (15 °C or 59 °F)
- is (Lapse Rate): 0.003563 °R/ft
- is 32.174 ft/s²
- is altitude in feet above sea level
The exponent evaluates to approximately 5.26054:
(%i27) 32.174/(0.003563*1716.56);
(%o27) 5.260539027391964
(%i28) excel_round(%,5);
(%o28) 5.26054
evaluates to approximately
(%i29) 0.003563/518.67;
(%o29) 6.869493126650858*10^-6
(%i30) excel_round(6.869493126650858*10^-6,11);
(%o30) 6.86949*10^-6
Temperature
[edit | edit source]
- is Temperature in °R
- is altitude in feet.
Practical Formulas for Pressure and Temperature
[edit | edit source]Thus, the practical formula for pressure and temperatures in terms of British Engineering units are:
lbf/ft²
°R
Pressure
[edit | edit source](%i31) P(h) := 2116.224*(1-6.8649*10^-6*h)^5.26054;
(%o31) P(h):=2116.224*(1-6.8649*10^(-6)*h)^5.26054
(%i32) p(P) := P/144.0;
(%o32) p(P):=P/144.0
(%i33) P(20000);
(%o33) 973.0940875140712
(%i34) p(%);
(%o34) 6.757597829958828
(%i35) excel_round(%,3);
(%o35) 6.758
Temperature
[edit | edit source](%i36) T(h) := 518.67 - 0.003563*h;
(%o36) T(h):=518.67-0.003563*h
(%i37) T(20000);
(%o37) 447.40999999999997
(%i38) excel_round(%,2);
(%o38) 447.41
(%i39) declare("°", alphabetic);
(%o39) done
(%i39) °F(°R) := °R -459.67;
(%o39) °F(°R):=°R-459.67
(%i40) °F(447.41);
(%o40) -12.259999999999991
(%i41) excel_round(%,2);
(%o41) -12.26
Density
[edit | edit source]The expressions for pressure and temperature as functions of altitude can be used with the expression for the ideal gas law for an expression of density as a function of altitude as follows:
(%i42) ρ(h) := P(h)/(R*T(h));
(%o42) ρ(h):=P(h)/(R*T(h))
(%i42) excel_round(ρ(20000)*10^4,2);
(%o42) 12.67
This result agrees with the density value of the standard atmosphere at 20,000 ft. Using the expression for the air density as a function of altitude, an expression for dynamic pressure is as follows:
(%i43) q(h,VTAS) := ((ρ(h)*VTAS^2))/2;
(%o43) q(h,VTAS):=(ρ(h)*VTAS^2)/2
Using the expression above, values of dynamic pressure can be calculated as a function of altitude and true airspeed as follows for 20,000 feet and 15,000 feet at 200 ft/s:
(%i44) q(20000,200);
(%o44) 25.34079027107967
(%i45) q(15000,200);
(%o45) 29.922636037412556
This value can be checked using the value for density from the Standard Atmosphere table at 15,000 ft and the expression for dynamic pressure as follows:
(%i46) excel_round(%,2);
(%o46) 29.92
(%i47) (200.0^2)*0.001496/2.0;
(%o47) 29.919999999999998
(%i48) excel_round(%,2);
(%o48) 29.92
In the context of aviation and aircraft performance, airspeeds are commonly referenced to knots (nautical miles per hour) instead of ft/s. To determine dynamic pressure as a function of altitude and true airspeed in knots, the following expressions are used:
(%i49) VTAS(knots) := 1.687811*knots;
(%o49) VTAS(knots):=1.687811*knots
(%i50) excel_round(VTAS(118.49676),2);
(%o50) 200.0
(%i51) q(h,knots) := ((ρ(h)*VTAS(knots)^2))/2;
(%o51) q(h,knots):=(ρ(h)*VTAS(knots)^2)/2
(%i52) excel_round(q(15000,118.49676),2);
(%o52) 29.92
So approximately 118 knots true airspeed is equivalent to 200 ft/s, and the above expression for dynamic pressure is in terms of a function of altitude in feet and true airspeed in knots.
Plotting
[edit | edit source]
Maxima has several ways to do plotting. The image that follows is a simple plot of density as a function of altitude produced using the plotting operator wxplot2d():
(%i53) T(h) := 518.688 - 0.0035616*h;
(%o53) T(h):=518.688-0.0035616*h
(%i54) P(h) := 2116.224*(1-6.8649*10^-6*h)^5.26054;
(%o54) P(h):=2116.224*(1-6.8649*10^(-6)*h)^5.26054
(%i55) R : 1716.56;
(R) 1716.56
(%i56) ρ(h) := P(h)/(R*T(h));
(%o56) ρ(h):=P(h)/(R*T(h))
(%i57) wxplot2d([ρ(h)], [h,-100,35000])$

A Practical Application - True Airspeed (TAS)
[edit | edit source]Having the display of TAS during actual flight conditions is very useful information. With the necessary sensors and electronics, TAS can be displayed continuously to pilots during changing flight conditions. One way to accomplish this is to have aircraft sensors that measure values of dynamic pressure, air pressure, and air temperature. These measured values can be used by electronic devices designed to calculate TAS for display and use by other equipment. The essentials of how this could be implemented can be demonstrated using Maxima by way of the expressions that follow:
(%i1) dpe : q = 1/2*ρ*V^2;
(dpe) q=(V^2*ρ)/2
(%i2) solutions:solve(dpe,V);
(solutions) [V=-(sqrt(2)*sqrt(q/ρ)),V=sqrt(2)*sqrt(q/ρ)]
The above expressions result in a list of two solution expressions. The second of these two is the one that is useful in this context.
(%i3) solutions[2];
(%o3) V=sqrt(2)*sqrt(q/ρ)
(%i4) igl : ρ = P/(R*T);
(igl) ρ=P/(R*T)
(%i5) eq : subst(rhs(igl),ρ,solutions[2]);
(%o5) V=sqrt(2)*sqrt((R*T*q)/P)
In the last of the above expressions the subst() operator is used to substitute an expression for density ρ in the expression for speed V.
(%i6) R :1716.56;
(R) 1716.56
(%i7) V(q,P,T) := ''(rhs(eq));
(%o7) V(q,P,T):=sqrt(2)*sqrt((R*T*q)/P)
The value for R determines the units:
- dynamic pressure q is in lbf/ft²
- pressure P is in lbf/ft²
- T is in °R
- V is in ft/s
The second of the two expressions above define a Maxima function for V in terms of values of dynamic pressure q, air pressure P, and temperature T.
This expression for speed can be checked using known values. At 15,000 ft if:
q is 29.92 lbf/ft²
P is 1194.79 lbf/ft²
T is 465.24 °R
then:
(%i8) load("excel_round.mac");
(%o8) "/home/davidmiller/Downloads/excel_round.mac"
(%i9) excel_round(float(V(29.92,1194.79,465.24)),1);
(%o9) 200.0
This resulting value of 200 ft/s for the TAS agrees with previous calculations under the given conditions. However, this is TAS in ft/s. Displaying TAS in terms of knots is much more relevant. The conversion factor for this purpose is 1.687811. So TAS in terms of knots can be expressed as follows:
(%i10) TAS(q,P,T) := V(q,P,T)/1.687811;
(%o10) TAS(q,P,T):=V(q,P,T)/1.687811
(%i11) excel_round(float(TAS(29.92,1194.79,465.24)),1);
(%o11) 118.5
The result is 118.5 knots for TAS which agrees with previous calculated values. The expression for TAS could have been more general by using an identifier (cf, for example) for the conversion factor as follows:
(%i12) TAS(q,P,T) := V(q,P,T)/cf;
(%o12) TAS(q,P,T):=V(q,P,T)/cf
(%i13) cf : 1.687811;
(cf) 1.687811
(%i14) excel_round(float(TAS(29.92,1194.79,465.24)),1);
(%o14) 118.5
The conversion factor for meters per second (m/s) is: 3.28084
(%i15) cf:3.28084;
(cf) 3.28084
(%i16) excel_round(float(TAS(29.92,1194.79,465.24)),1);
(%o16) 61.0
This is TAS in meters per second. Thus, by changing the value of only the conversion factor, TAS could be determined for various units of measure.
Summary
[edit | edit source]This section provided examples of the use of Maxima expressions in an applied context. It was demonstrated that Maxima can be used effectively for numerical computations. However, unlike typical general-purpose programming languages, it was also demonstrated that Maxima is capable of providing much more capability than merely "number crunching" by way of symbolic operations. The symbolic expression capabilities of Maxima extend way beyond what was demonstrated in this section.
The purpose of this section is not to provide a comprehensive survey of the symbolic expression capabilities of Maxima. Rather, it is intended to be an introduction to Maxima for the sake of familiarity with the sort of expressions that are typical for using Maxima in an applied context, with the syntax that is used for Maxima expressions, and generally the important role expressions have in interacting with the Maxima interface.
Three Maxima operators that should be recognized as used frequently as evidenced by the expressions of this section are:
=the equality operator (equation expressions):=the Maxima function definition operator:the assignment operator
No matter the task at hand for which Maxima is being used, these three operators are likely to be essential, so having a clear understanding of the nature of each is important.
Equations and Functions
[edit | edit source]Here is what a wxMaxima "Tip of the Day" remarks about the first two:
"Equations have several advantages over functions. For example they can be manipulated with factor(), expand() and similar functions. They can easily be introduced one into another."
It is essential to recognize that Maxima function expressions defined using the := operator (and likewise for the define() operator, not discussed here) is not synonymous with the mathematical concept of a function, and this is also the case with typical general-purpose programming languages, and not only Maxima.
The Maxima function (in the programming sense) operator can be used to define a function (in the mathematical sense), but this is not generally the case for all Maxima function expressions. Maxima function expressions can be entered that cannot be used to define a mathematical function in the technical sense.
To define a mathematical function using Maxima, to be precise, would require something similar to the first two of the following expressions:
(%i1) y = f(x);
(%o1) y=f(x)
(%i2) f(x) := x^3;
(%o2) f(x):=x^3
(%i3) y = f(x), x=3;
(%o3) y=27
(%i4) y = f(3);
(%o4) y=27
(%i5) is(equalp(y,f(3)));
(%o5) unknown
(%i6) is(y = f(3));
(%o6) false
(%i7) is(y = f(3)), y = 27;
(%o7) true
(%i8) f(3);
(%o8) 27
The first of the above expressions, if evaluated, will have a value of true or false, depending on the values of x and y. The second of these two expressions will have a numerical value that depends only on the numerical value of x. This difference is essential to understand.
For a function, in the mathematical sense, it is necessary for values of x and y as applied to the expression
y = f(x),
to evaluate to true, that is the values of the ordered pairs of numbers (x,y) evaluate the expression y = f(x) to true if they are instances of the function, and false otherwise.
The function f(x), in the programming sense, can be defined in all sorts of ways as a Maxima expressions, including for the purpose of the definition of a mathematical function, but not necessarily so.
The following expressions from those above, provides some insight into the way Maxima as a CAS differs in an essential way from typical general-purpose programming languages:
(%i5) is(equalp(y,f(3)));
(%o5) unknown
(%i6) is(y = f(3));
(%o6) false
The value of the identifier y in these expressions is itself. because of this, y as an identifier represents the essence of a variable quantity, and not as merely as a name for another expression. The first of these two expressions has the value of unknown, because it simply is not possible to say if y and f(3) are equal. The second has a value of false simply because the value of y is itself and unless the value of f(3) is y, then this expression is obviously false.
(%i1) g(x) := y;
(%o1) g(x):=y
(%i2) y = g(y);
(%o2) y=y
This is trivially obvious, but also clearly logical, and if Maxima is anything, it is logical. This is as it should be.
Technically the := operator is a type of assignment. The other frequently used assignment operator is :, and a brief discussion of this operator follows.
Assignment
[edit | edit source]
The : assignment operator is most typical used to name another value or expression. The word "identifier" in this case is understood to be a name that is in a sense identical to a value or expression. some examples follow:
(%i08) x : 2;
(x) 2
(%i09) x;
(%o09) 2
(%i10) y : 3.14159;
(y) 3.14159
(%i11) y;
(%o11) 3.14159
(%i12) r : rationalize(0.1);
(r) 3602879701896397/36028797018963968
(%i13) r;
(%o13) 3602879701896397/36028797018963968
(%i14) s : "a string";
(s) "a string"
(%i15) s;
(%o15) "a string"
(%i16) \9ofHearts : true;
(\9ofHearts) true
(%i17) \9ofHearts;
(%o17) true
Assignment is not limited however to simple expressions such as these. Entire expressions from simple to more complex can be assigned to identifiers. For example:
(%i18) z : m + n +3;
(z) n+m+3
(%i19) z;
(%o19) n+m+3
(%i20) ex1 : a*x^2 +b*x + c;
(ex1) c+2*b+4*a
(%i21) ex1;
(%o21) c+2*b+4*a
(%i22) ex2 : 'integrate( %e^(2*t+a)*sin(t)*t,t);
(ex2) integrate(%e^(2*t+a)*t*sin(t),t)
(%i23) ex2;
(%o23) integrate(%e^(2*t+a)*t*sin(t),t)
(%i24) solution : ex2, integrate;
(solution) ((10*%e^(2*t+a)*t-3*%e^(2*t+a))*sin(t)+(4*%e^(2*t+a)-5*%e^(2*t+a)*t)*cos(t))/25
(%i25) solution;
(%o25) ((10*%e^(2*t+a)*t-3*%e^(2*t+a))*sin(t)+(4*%e^(2*t+a)-5*%e^(2*t+a)*t)*cos(t))/25
This sort of assignment is not possible using typical general-purpose programming languages, and will result in undefined variable error messages. For example in the case of Julia:
julia> z = m + n + 3
ERROR: UndefVarError: `m` not defined in `Main`
Suggestion: check for spelling errors or missing imports.
Stacktrace:
[1] top-level scope
@ REPL[1]:1
Julia is a very capable and useful programming language, especially for numerical computations, but symbolic expressions are not what Julia was intended to be used for. Maxima on the other hand, is quite at home with symbolic expressions.
Some of the output expressions in these examples are rendered in a much more readable and conventional manner by the wxMaxima GUI using typical mathematical notation. The output for ex2 for example is rendered as:
The output for the solution identifier is rendered as:
The wxMaxima GUI can be configured to suppress the % character displayed before the special constant %e in the above output expressions if desired.
The reader is referred to Sections 9.6 (Assignment operators) and 22 (Equations) of the Maxima Help document for more information related to these three operators and more.
Getting Started Using Maxima
Getting Started Using Maxima - Some Essentials
[edit | edit source]This section is intended for those that are new to Maxima. It may or may not be of value or interest to those having prior experience.
The Maxima Way of doing Mathematics
[edit | edit source]Imagine that you want to create a computer application to perform some general mathematical tasks - not merely numerical calculations or "number crunching" as it is sometimes referred to somewhat pejoratively. It seems likely that it would be realized early on that, unlike humans that can interpret concepts and notation using context, computers and programming software generally are intolerant of any sort of ambiguity. Progress is being made in providing programming software with the ability to interpret based on context, but not here in Maxima. The Maxima expression syntax was created to be logical as well as unambiguous and precise in meaning and intention.
Another realization likely would be that mathematical expressions are the essential object on which mathematical concepts hinge, and that these concepts are conveyed using a conventional (if not entirely standard) system of notation. So, the means to compose mathematical expressions using some syntax for interpreting mathematical notation that your program could read and process as input would be essential. So Maxima is not a programming language in the conventional sense.
With the foregoing in mind, before starting to see examples of Maxima in action, keep the following in mind while learning and using Maxima:
- Expressions of various types (especially mathematical expressions) are the input to Maxima
- Every expression returns a value which is displayed as output unless the display is suppressed by some means
- Expressions as input are entered using an expression syntax that Maxima can read and process
Maxima expressions are of three types:
[edit | edit source]- Mathematical expressions
- Programming expressions
- Object expressions
Maxima expressions are comprised of two "ingredients" so to speak:
[edit | edit source]- Atoms
- Operators
Atoms:
[edit | edit source]These are one type of the built-in basic expression ingredients of Maxima. They are:
- Identifiers - names used alone or to identify other expressions by name
- Literal numerals for numbers - integer, fraction, and floating point literals
- Strings - quoted strings of one or more characters
Operators:
[edit | edit source]These are the second type of the built-in expression ingredients of Maxima. Including:
- Mathematical operators such as + , - , * , /, ^ , ! for addition, subtraction, negation, multiplication, division, exponentiation, factorial and the like. Internally to Maxima these are short-hand symbols for operators. Maxima operators also include "functions" such as sin(x), log(x), etc.
- Operators that are used to accomplish something other than for mathematical purposes
Note: It is important to point out that there is a difference between operators, functions as used in the context of programming, and the mathematical concept of functions. In this book all Maxima functions in the programming sense of the word that are built-in to Maxima (that is "out-of-the-box" so to speak) will be referred to as operators, including those from loaded packages that are included with the Maxima distribution. Maxima functions in the programming sense of the word created by the user will be referred to as functions. The context should make it clear when the mathematical concept of a function is being referred to. It is unfortunately the case that the Maxima documentation refers to operators as functions. Like so much else, the word "function" has become overloaded.
A Brief Introduction to Expressions - Atoms, Identifiers and Operators
[edit | edit source]Below follows a brief introduction to Maxima expressions. All Maxima expressions are composed of atoms (including identifiers) and operators, and every expression has a value.
With the foregoing information in mind, Maxima itself can be used to provide some examples of these various aspects of working with Maxima. This will be accomplished in the spirit of providing some insight and clarity for how to interact with Maxima, and how to compose expressions for input and how to interpret the values of expressions as output. What follows is not a "how-to" doe this or that mathematical task or application. It is more like an owner's manual for a vehicle. It describes the equipment and the features, but does not tell you how to drive the vehicle.
Atoms
[edit | edit source]There are three types of atoms used as "ingredients" for composing Maxima expressions for input:
- Identifiers
- Numerical literals for representing numbers
- Strings
An elaboration of the technical details of each of these three types will follow in subsequent sections. In this section is a brief introduction, and examples of each of these types presented to gain a basic level of familiarity with each type of atom.
Identifiers
[edit | edit source]Identifiers are one type of what are termed atoms as used in the context of Maxima expressions, but they are unique in that they are the only type of atom that can be assigned an expression other than their literal value.
Identifiers as atoms are used in Maxima expressions for two main purposes:
- To be unassigned an expression, and serve as a named variable
- To name an expression by way of an assignment operator
Try the following using Python:
m + n
>>> m + n
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'm' is not defined
>>>
or using R:
> m + n
Error: object 'm' not found
>
or using Octave:
octave:1> m + n
error: 'm' undefined near line 1, column 1
octave:2>
Now, try this using Maxima:
Maxima 5.49.0 https://maxima.sourceforge.io
using Lisp SBCL 2.0.1.debian
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) m + n;
(%o1) n + m
Take it on faith that the identifiers m and n are in the Maxima namespace as a consequence of this expression, and that each has a value assigned by Maxima merely as a consequence of being used in the m + n input expression – m is m and n is n in this case.
(%i2) m;
(%o2) m
(%i3) n;
(%o3) n
A value for any identifier (other than itself) may never be assigned while using Maxima no matter how many times it is referenced. That is perfectly okay. Maxima doesn't care. But sometimes a value is assigned to an identifier – either the first time it is referenced or after it is first referenced:
(%i4) m : n;
(m) n
(%i5) m;
(%o5) n
(%i6) remvalue(m);
(%o6) [m]
(%i7) m;
(%o7) m
In the above expressions, the identifier m is assigned, using the : assignment operator, the value of identifier n (which is in this case n), and then the value of m is removed using the remvalue() operator. Thus, the value of m reverts to itself – m.
These expressions, while trivial in a sense, provide some insight into an important way Maxima behaves. When identifiers are first referenced as input, they have a value – either a value through some sort of assignment, or merely the identifier name itself. Identifiers can be assigned values by different means as part of expressions as input.
Below follows some examples of Maxima identifiers as a very brief introduction:
(%i1) x; /* An unassigned identifier x */
(%o1) x
(%i2) mass; /* An unassigned identifier name of mass */
(%o2) mass
(%i3) f(x); /* An identifier f(x) for unassigned Maxima user-defined function */
(%o3) f(x)
(%i4) is(x = X); /* Identifiers are case-sensitive - x is not X */
(%o4) false
(%i6) y = x^2; /* Identifiers x and y used in an expression */
(%o6) y=x^2
(%i7) x : sqrt(2); /* Idenifier x assigned a value */
(x) sqrt(2)
/* An identifier w(x,y,z) for a Maxima user-defined function */
(%i8) w(x,w,z) := a*x^2 + b*y^2 + c*z^2;
(%o8) w(x,w,z):=a*x^2+b*y^2+c*z^2
Maxima identifiers serve to name expressions as a value by means on some type of assignment, or they can be simply a name with a value of the name itself, in which case these unassigned identifiers may be considered to be variables. The technical details of Identifiers, assignment types, and expressions are elaborated upon in other book sections for each of these topics.
Numerical literals for representing numbers
[edit | edit source]There are four types of numerical literals used to compose Maxima expressions:
- Integers
- Fractions (for rational numbers)
- Floating Point
- Bigfloat (variable-precision floating point)
(%i8) 1234; /* This is an integer type. An atom */
(%o8) 1234
(%i9) 5/9; /* This is a fraction for a rational number type. Not an atom. */
(%o9) 5/9
(%i10) 3.14159; /* This is a floating point type. An atom. */
(%o10) 3.14159
(%i11) 5.532051841609784b-1; /* This is a bigfloat type. An atom */
(%o11) 5.532051841609784b-1
Strings
[edit | edit source]Strings are simply a quoted sequence of characters:
(%i12) "a string atom"; /* This is a string atom. */
(%o12) "a string atom"
(%i13) "Hello World!"; /* This is another string atom. */
(%o13) "Hello World!"
(%i14) "Supercalifagilisticexpialidocious"; /* This is a longer string atom. */
(%o14) "Supercalifagilisticexpialidocious"
(%i15) "C"; /* There is no Maxima character type. */
(%o15) "C"
Mathematical Operators
[edit | edit source]Along with atoms, Maxima operators are the second ingredient used to form expressions used as input. There are many Maxima operators. Some are used frequently as a consequence of their utility for forming mathematical expressions. Many others are used infrequently as these operators are used for specialized purposes.
| Operator | Operation | Notes | Type |
|---|---|---|---|
| Arithmetic | |||
| + | addition | also unary addition prefix | n-ary
infix commutative |
| - | subtaction | also unary negation prefix | binary
infix noncommutative |
| * | multiplication | n-ary infix
commutative | |
| / | division | or fraction | binary infix
noncommutative |
| ^ | exponentiation | binary postfix | |
| Relational | |||
| < | less than | binary infix | |
| <= | less than or equal | binary infix | |
| > | greater than | binary infix | |
| >= | greater thanor equal | binary infix | |
| Logical | |||
| and | and | Operands are Boolean expressions
Result is a Boolean value |
n-ary infix
noncommutative |
| not | not | Operand is a Boolean expression
Result is a Boolean value |
unary prefix |
| or | or | Operands are Boolean expressions
Result is a Boolean value |
n-ary infix
noncommutative |
| Equations | |||
| = | equality | Unevaluated equation | Syntactically equal |
| # | negation of syntactic equality = | Unevaluated negation of an equation | Syntactically not equal |
| Assignment | |||
| : | assignment to left hand side | evaluates right hand side | |
| :: | assignment to left hand side | evaluates both sides | |
| := | function definition | does not evaluate right hand side | |
| ::= | macro function definition | ||
| define () | function definition | does evaluate right hand side | |
| Operators (Functions)
or Option Variables |
Description | Notes | |
|---|---|---|---|
| Numbers | |||
| abs (z) | mathematical absolute value | works for both numerical and symbolic values | |
| ceiling (x) | returns the least integer that is greater than or equal to x | ||
| entier (x) | returns the largest integer less than or equal to x where x is numeric | ||
| floor (x) | returns the largest integer that is less than or equal to x | ||
| fix (x) | a synonym for entier (x) | ||
| hstep (x) | the Heaviside unit step function | ||
| lmax (L) | when L is a list or a set, return
|
||
| lmin (L) | When L is a list or a set, return
|
||
| max (x_1, …, x_n) | returns a simplified value for the numerical maximum of the expressions x_1 through x_n | ||
| min (x_1, …, x_n) | returns a simplified value for the numerical minimum of the expressions x_1 through x_n. | ||
| round (x) | when x is a real number, returns the closest integer to x | ||
| signum (x) | for either real or complex numbers x, the signum function returns 0 if x is zero; for a nonzero numeric input x, the signum function returns x/abs(x)
|
||
| truncate (x) | when x is a real number, return the closest integer to x not greater in absolute value than x | ||
| Complex
Numbers |
|||
| cabs (expr) | returns the absolute value of an expression representing a complex number | ||
| carg (z) | returns the complex argument of z | ||
| conjugate (x) | returns the complex conjugate of x | ||
| imagpart (expr) | returns the imaginary part of the expression expr | ||
| polarform (expr) | returns an expression r %e^(%i theta) equivalent to expr, such that r and theta are purely real
|
||
| realpart (expr) | returns the real part of expr | ||
| rectform (expr) | returns an expression a + b %i equivalent to expr, such that a and b are purely real
|
||
| Combinatorial | |||
| !! | the double factorial operator | ||
| binomial (x, y) | returns the binomial coefficient x!/(y! (x - y)!).
|
||
| factcomb (expr) | tries to combine the coefficients of factorials in expr with the factorials themselves | by converting for example, (n + 1)*n! into (n + 1)!.
|
|
| factorial (x)
! |
returns the factorial of x | factorial (x) the same as x!
|
|
| factlim | specifies the highest factorial which is automatically expanded | option variable
default: 100000 |
|
| factorial_expand | controls the simplification of expressions like (x+n)!, where n is an integer
|
option variable
default: false |
|
| genfact (x, y, z) | returns the generalized factorial, defined as x (x-z) (x - 2 z) ... (x - (y - 1) z)
|
when x is an integer, genfact (x, x, 1) = x! and genfact (x, x/2, 2) = x!!
|
|
| minfactorial (expr) | examines expr for occurrences of two factorials which differ by an integer | minfactorialthen turns one into a polynomial times the other
|
|
| sumsplitfact | when sumsplitfact is false, minfactorial is applied after a factcomb
|
option variable
default: true |
|
| Root
Exponential Logarithmic |
|||
| %e_to_numlog | when true, r some rational number, and x some expression, %e^(r*log(x)) will be simplified into x^r
|
option variable
default: false |
|
| %emode | when %emode is true, %e^(%pi %i x) is simplified
|
option variable
default: true |
|
| %enumer | when %enumer is true, %e is replaced by its numeric value 2.718… whenever numer is true.
|
option variable
default: false |
|
| exp (x) | represents the exponential function | ||
| li [s] (z) | represents the polylogarithm function of order s and argument z, defined by an infinite series | ||
| log (x) | represents the natural (base ) logarithm of x. | Maxima does not have a built-in function for the base 10 logarithm or other bases | |
| logabs | when doing indefinite integration where logs are generated, e.g. integrate(1/x,x), the answer is given in terms of log(abs(...)) if logabs is true, but in terms of log(...)if logabs is false
for definite integration, the |
option variable
default: false |
|
| logarc (expr) | carries out the replacement of inverse circular and hyperbolic functions with equivalent logarithmic functions for an expression expr without setting the global variable logarc
|
||
| logarc | when the global variable logarc is true, inverse circular and hyperbolic functions are replaced by equivalent logarithmic functions.
|
option variable
default: false |
|
| logconcoeffp | controls which coefficients are contracted when using logcontract
|
option variable
default: false |
|
| logcontract (expr) | recursively scans the expression expr, transforming subexpressions of the form a1*log(b1) + a2*log(b2) + c into log(ratsimp(b1^a1 * b2^a2)) + c
|
||
| logexpand | if true, that is the default value, causes log(a^b) to become b*log(a)
If it is set to if it is set to |
option variable
default: true |
|
| lognegint | implements the rule log(-n) -> log(n)+%i*%pi for n a positive integer if true
|
option variable
default: false |
|
| logsimp | if false then no simplification of %e to a power containing log is done
|
option variable
default: true |
|
| plog (x) | represents the principal branch of the complex-valued natural logarithm with -%pi < carg(x) <= +%pi
|
||
| sqrt (x) | the square root of x. It is represented internally by x^(1/2)
|
||
| Trigonometric
Hyperbolic |
|||
| acos (x) | arc cosine | ||
| acosh (x) | hyperbolic arc cosine | ||
| acot (x) | arc cotangent | ||
| acoth (x) | hyperbolic arc cotangent. | ||
| acsc (x) | arc cosecant | ||
| acsch (x) | hyperbolic arc cosecant | ||
| asec (x) | arc secant. | ||
| asech (x) | hyperbolic arc secant | ||
| asin (x) | arc sine | ||
| asinh (x) | hyperbolic arc sine | ||
| atan (x) | arc tangent | ||
| atan2 (y, x) | returns the value of in the interval taking into consideration the quadrant of the point (x,y) | ||
| atanh (x) | hyperbolic arc tangent | ||
| cos (x) | cosine | ||
| cosh (x) | hyperbolic cosine | ||
| cot (x) | cotangent | ||
| coth (x) | hyperbolic cotangent | ||
| csc (x) | cosecant | ||
| csch (x) | hyperbolic cosecant | ||
| sec (x) | secant | ||
| sech (x) | hyperbolic secant | ||
| sin (x) | sine | ||
| sinh (x | O | ||
| tan (x) | tangent | ||
| tanh (x) | hyperbolic tangent | ||
| Random
Numbers |
|||
| make_random_state () | a random state object represents the state of the random number generator | ||
| set_random_state (s) | copies s to the random number generator state | ||
| random (x) | returns a pseudorandom number | ||
Maxima Expressions
[edit | edit source]For the purpose of review, Maxima expressions are of three types:
- Mathematical expressions
- Object expressions
- Programming expressions
Object expressions and programming expressions are for use in support of the intended purpose of Maxima – a computer algebra system. Mathematical expressions are those that are the essential type for doing mathematics using Maxima.
Mathematical Expressions
[edit | edit source]Mathematical expressions consist of atoms and operators that are of a mathematical nature. Mathematical expressions can be simple to relatively complex. It is helpful to understand the anatomy of Maxima expressions in terms of atoms and operators. Some expressions can consist of a single atom, but more likely it will be the case that expressions will be comprised of atoms and operators.
The simplest expressions can consists of a single atom:
(%i1) 5; /* an integer atom */
(%o1) 5
(%i2) 3.14159; /* a floating point atom */
(%o2) 3.14159
(%i3) 77.3987483627298298277627928389828329382983b0; /* a bigfloat atom */
(%o3) 7.739874836272983b1
(%i4) x; /* an unassigned identifier atom */
(%o4) x
Atoms are "self-evaluating" in the sense that they return themselves as values. Expressions such as these are not very useful, but they are the simplest example of mathematical expressions. Fractions for literal rational numbers are simple expressions entered as follows, but are not atoms:
(%i5) 12/33; /* A fraction expression. Maxima simplfies the expression as output */
(%o5) 4/11
(%i6) atom(12/33); /* The fraction expression is not an atom */
(%o6) false
(%i8) op(12/33); /* The overall operation of this expression is / */
(%o8) /
In cases where Maxima returns an error message or the returned results are unexpected or perplexing, the atom () and op () operators may provide some insight into the nature of the error message or returned value.
Maxima evaluates the division of integers as rational numbers, and simplifies the return value if possible:
(%i09) 12/33 * 3/4; /* multiplication of fractions */
(%o09) 3/11
(%i10) (12/33) / (4/3); /* division of fractions */
(%o10) 3/11
(%i11) 3/8 + 13/4; /* addition of fractions */
(%o11) 29/8
Maxima will resolve mixed numerical types in expressions as returned values in a manner which might be expected :
(%i12) 3/2 * 5; /* fraction and an integer */
(%o12) 15/2
(%i13) 3/2 * 5.0; /* fraction and floating point */
(%o13) 7.5
(%i14) 12.0/33; /* floating point and an integer */
(%o14) 0.36363636363636365
(%i15) 0.36363636363636365*0.36363636363636365b0; /* floating point and bigfloat */
(%o15) 1.322314049586777b-1
Some expressions remain "symbolic" numerically, and are not simplified or returned as a number type:
(%i16) sqrt(2); /* an algebraic irrational */
(%o16) sqrt(2)
(%i17) 3*5^(1/3); /* another algebraic irratioanl */
(%o17) 3*5^(1/3)
Built-in numerical constants are atoms. Numerical expressions involving one or more operators are not, unless the expression evaluates to an atom:
(%i18) %pi; /* a trancendental built-in constant */
(%o18) %pi
(%i20) atom(%pi); /* a trancendental built-in constant */
(%o20) true
(%i20) atom(%e); /* a trancendental built-in constant */
(%o20) true
(%i21) atom(%i); /* i is a built-in constant */
(%o21) true
(%i22) atom(sqrt(2)); /* sqrt(2) in not an atom */
(%o22) false
(%i23) atom(3*5^(1/3)); /* 3*5^(1/3) is not an atom */
(%o23) false
(%i24) atom(3+5); /* 3+5 evaluates to 8 which is an atom*/
(%o24) true
(%i25) atom((5^2)*3.14159); /* (5^2)*3.14159) evaluates to 78.53975 which is an atom */
(%o25) true
An important point to understand is that expressions when evaluated may have a return value that is an atom or is not an atom:
(%i26) atom(3+5); /* the value of 3+5 is an atom */
(%o26) true
(%i27) atom(5^2)*3.14159 /* the value of this expression is an atom */
(%o27) true
(%i28) (5^2)*3.14159; /* it is a floating point numeral */
(%o28) 78.53975
(%i29) op(3+5); /* an error as the value is an atom */
part: argument must be a non-atomic expression; found 8
-- an error. To debug this try: debugmode(true);
More useful and interesting expressions involve identifiers, However, expressions involving identifiers and operators may or may not have a value that is atomic:
(%i30) atom(z); /* the value of z is z - an atom */
(%o30) true
(%i31) atom(3); /* 3 is an atom */
(%o31) true
(%i32) atom(z+3); /* the value of z+3 is z+3 - not an atom */
(%o32) false
(%i33) op(z+3); /* the overall operator of z+3 is + */
(%o33) +
(%i34) z:5; /* assign 5 to z */
(z) 5
(%i35) atom(z+3); /* the value of z+5 is 8 - an atom */
(%o35) true
These examples may seem simple, but what is exemplified by these simple expressions applies no matter how complex the expression may be:
(%i36) expr1:(1/(15^2 + 20^2 -2*15*20*cos(%pi/3))^(1/2)); /* an expression */
(expr1) 1/(5*sqrt(13))
(%i37) atom(expr1); /* the value of expr1 is not an atom */
(%o37) false
(%i38) float(expr1); /* the value of expr1 as a floating point numeral is an atom */
(%o38) 0.05547001962252292
(%i39) atom(float(expr1)); /* an atom */
(%o39) true
(%i40) expr2:integrate(w^2, w, 0, 4); /* the value of this integration is an not an atom */
(expr2) 64/3
(%i41) atom(expr2); /* not an atom */
(%o41) false
(%i42) op(expr2); /* teh overall operator of 64/3 is / */
(%o42) /
(%i43) atom('integrate(w^2, w, 0, 4)); /* the value of this integration is an not an atom */
(%o43) false
(%i44) op('integrate(w^2, w, 0, 4)); /* the overall operation is integrate */
(%o44) integrate
(%i45) 2*s^2+5*s+1; /* a quadratic expression */
(%o45) 2*s^2+5*s+1
(%i46) solve(2*s^2+5*s+1,s); /* solve for s */
(%o46) [s=-((sqrt(17)+5)/4),s=(sqrt(17)-5)/4]
(%i47) rhs(solve(2*s^2+5*s+1,s)[1]); /* reference the right hand side */
(%o47) -((sqrt(17)+5)/4)
(%i48) atom(rhs(solve(2*s^2+5*s+1,s)[1])); /* teh value of the RHS is not an atom */
(%o48) false
(%i49) ans:float(rhs(solve(2*s^2+5*s+1,s)[1])); /* the floating point value is an atom */
(ans) -2.2807764064044154
(%i50) atom(ans);
(%o50) true
The Maxima REPL
[edit | edit source]Maxima is most useful as an interactive computer algebra system program. The means of interaction is primarily by using the Maxima REPL – which is an abbreviation for Read, Evaluate, Print, Loop. But "REPL" doesn't encapsulate all that is happening to Maxima expressions while using the user interface. The Maxima REPL is more of a "RCESDL" process:
- R – read
- C – construct
- E – evaluate
- S – simplify
- D – display
- L – loop
Maxima reads, constructs, evaluates, and simplifies expressions, and then displays return values and "loops" by displaying the next input prompt. Each of these (except looping) may be viewed as a layer of manipulation Maxima applies to expressions.
The next subsection describes expression reading and construction. Evaluation and simplification of expressions are described in subsections that follow. For now, consider evaluation to be the substitution of the value of an expression for the expression. Simplification is the application of a set of criteria defining what "simpler" means as a relation between expressions so that an equivalent "simplified" expression is substituted for an evaluated expression.
Expression Reading and Construction
[edit | edit source]Maxima will read lines of input and parse each one in order to determine if it is an expression that can be constructed for evaluation.
Maxima allows a sequence of expressions to be entered into an single expression by separating them by commas and putting parentheses around them:
/* An example of a sequence of expressions enclosed in parentheses.
Only the value of the last expression (y) in the sequence is returned and displayed.
*/
/* The expression below is composed of three nested expression groupings in parentheses.
This expression as a whole is mathematical in that its value is an integer literal
*/
(%i51) (y : (x : 1, for i from 1 thru 10 do (x : x*i), x),y);
(%o51) 3628800
/* The value of this expression is an atom */
(%i52) atom((y : (x : 1, for i from 1 thru 9 do (x : x*i), x),y));
(%o52) true
/* The constructed expression is not a atom as evaluation is suppressed */
(%i53) atom('(y : (x : 1, for i from 1 thru 9 do (x : x*i), x),y));
(%o53) false
/* The overall operation of this expression is ( */
(%i53) op('(y : (x : 1, for i from 1 thru 9 do (x : x*i), x),y));
(%o53) (
Let's take a look at some constructed expressions:
(%i54) 'for i from 1 thru 9 do (x: x*i); /* a constructed expression */
(%o54) mdo(i,1,false,false,9,false,i)
(%i55) if p > q then p else q$ /* an expression */
(%i56) 'if p > q then p else q; /* the same expression as constructed */
(%o56) mcond(p>q,p,true,q)
An expression as input is first read and parsed before being constructed. If the parser can construct an expression from the input, the constructed expression may then be evaluated, may be in turn simplified and may be finally displayed. However, the parser may or may not be able to construct an expression for various reasons, without displaying a warning or error message:
/* the Maxima parser does not like this expression */
(%i57) ([a], a: 42, a^2 - 1600);
warning: parser: I'll let it stand, but (...) doesn't recognize local variables.
warning: parser: did you mean to say: block([a], ...) ?
(%o57) 164
The parser let this expression go through to complete the process and display a return value, but not without a warning, and a suggestion. In other cases however the parser will display an error message:
/* this is a syntax error - missing closing parenthesis */
(%i58) (y: (x: 1, for i from 1 thru 9 do (x: x*i), x),y;
incorrect syntax: Missing )
9 do (x: x*i), x),y;
^
The parser can't construct an expression in cases where there is a syntax error. Nothing is evaluated. There is no returned value. In cases where an input expression can read and an expression can be constructed by the parser, the constructed expression may then be evaluated.
Expression Evaluation
[edit | edit source]The reading, parsing, evaluation,, simplification, and display of values are all steps in a process that, from the point of view of users, typically happens "under the hood" so to speak. It is helpful in using Maxima to have at least a familiarity with this process, while it is true that most often not much thought is given to these steps – until something unexpected results or there is an error.
However, the familiarity with the steps of this process can be put to use intentionally for practical purposes while using Maxima. For the purposes of this section of the book, it suffices to here provide a descriptive familiarity with the evaluation of expressions here, leaving the technical details for a subsequent section of this book.
All or parts of a constructed expression may or may not be evaluated for various reasons, upon which the technical details are not elaborated here. When evaluation does occur, it is essentially the composition of an expression from the constructed expression wherein the values of the atoms and operators along with their arguments are used.
Expression Simplification
[edit | edit source]To whatever extent evaluation of a constructed expression may occur, the resulting expression may or may not be simplified, again for reasons upon which the technical details are not elaborated here. A section of this book is provided to elaborate on the technical details of simplification.
There is a sense in which simplification implies a relation between expressions – " A is simpler than B" or something like that. In any case, simplification implies a set of criteria that is necessary to determine expressions which are simpler. Maxima provides a set of criteria for the purpose of simplifying expressions insofar as is possible. Whenever possible, constructed or evaluated expressions will be simplified, and the resulting simplified expression may be displayed as output.
Return Value Display
[edit | edit source]Typically, Maxima input expressions end with a semicolon ( ; ) character. In these cases, Maxima will display a return value as output unless an error occurs. The display of the output value can be suppressed by ending the input expression with a dollar sign character ( $ ) instead of a semicolon:
/* the value of this expression is done */
(%i59) (x : 1, for i from 10 thru 2 step -2 do (x : x/i));
(%o59) done
(%i60) x; /* a value for x was calculated by the above expression */
(%o60) 1/3840
/* the dollar sign ( $ ) suppresses the display of done */
(%i61) (x : 1, for i from 20 thru 2 step -2 do (x : x/i))$
/* the output of done was returned, but the display was suppressed */
(%i62) %;
(%o62) done
(%i63) x; /* a different value for x was calculated by the above expression */
(%o63) 1/3715891200
Programming Expressions
[edit | edit source]Maxima was created as a CAS application using the Lisp programming language. It is evident given the perspective experienced using Maxima, that there is some "Lispiness" evident in its use. But, while Lisp is a programming language, the programming expressions that are provided by Maxima are intended to be used in support of the purpose of Maxima as a CAS. There is much that can be accomplished using Maxima programming expressions, but it should be recognized that there are limitations in this context.
A savvy and adept programmer type of person may likely be able to be somewhat creative using Maxima programming expressions, but for the typical user, these expressions are essentially used to support mathematical tasks. Some may find that Maxima programming expressions provide a reasonably complete programming language for their purposes. Other users may find that for their purposes Maxima programming expressions impose some inconvenient or awkward limitations.
There are tools available to convert or translate Maxima expressions to the code of other programming languages – FORTRAN, RATFOR, C, Python 3, and Julia as examples. But these tools may require specialized knowledge and resources to use, and using them can be tedious for some users. For those users that wish to do more in terms of programming within (or outside of for that matter) the Maxima interactive environment, and are willing to use or learn Lisp, using Lisp itself can be a useful option. Lisp is a complete general programming language. A subsequent section of this book (Maxima and Lisp) is provided for those that have an interest in this option.
Some of the foregoing examples have included programming expressions used to return a mathematical result. This book presumes that Maxima programming expressions are intended to be used in support of mathematical tasks. A subsequent section of this book provides the technical details of Maxima programming expressions for this purpose.
Object Expressions
[edit | edit source]Maxima provides several object types. These objects are created by object expressions. The value of an object may be the name of the object or refer to the data the object encapsulates depending on the type of object. Like other expressions, object expression are comprised of an operator and its arguments. The most important built-in object types are:
- lists
- arrays (of which there are three types)
- structures
- matrices
- sets
Maxima list objects will likely be the most frequently encountered type of object while using Maxima expressions in general both during expression composition for input and as displayed expression results. Matrices and sets are likely to be mostly associated directly with mathematical expressions. Arrays and structures are relatively specialized object types that are most likely to be used in support of mathematical tasks and applications. This book presumes that Maxima object expressions are intended to be used in support of mathematical tasks. A subsequent section of this book provides the technical details of Maxima object expressions for this purpose.
"Maxima's current array/matrix semantics are a mess, I must say, with at least four different kinds of objects (hasharrays, explicit lists, explicit matrices, Lisp arrays) supporting subscripting with varying semantics." [1]
"Maxima's concept of arrays, lists, and matrices is pretty confused, since various ideas have accreted in the many years of the project... Yes, this is a mess. Sorry about that. These are all interesting ideas, but there is no unifying framework. " [2]
[1] Maxima: Syntax improvements by Stavros Macrakis
[2] Maxima: what does Maxima call an “array”? - answer by Robert Dodier
Identifiers
The Maxima Namespace
[edit | edit source]The topic of the namespace system used by Maxima is in a sense more relevant to programming expressions. However, since the nature of the Maxima namespace system is also relevant to Maxima identifiers as used in this book, and also as used routinely in the composition of Maxima expressions in general, and particularly mathematical expressions, some of the technical detail is provided here for the purpose of describing the role of identifiers. It is worth repeating here that in this book, for reasons of simplicity, the use of the term identifier is meant to encapsulate names used for various purposes as described below. The Maxima CAS namespace system is best characterized as case-sensitive for user-defined entities but case-insensitive (normalized to lowercase) for built-in operators (functions) and constants, with a flat global namespace for identifiers:
- Case Sensitivity: Maxima provides a case-sensitive namespace system where variables, functions, and operators are distinct entities based on their spelling. Maxima distinguishes between upper and lower case for user-defined variables and functions; for example,
foo,Foo, andFOOare treated as distinct identifiers. - Built-in Normalization: All built-in operators (e.g.,
sin,cos) and constants (e.g.,%e,%pi) have lowercase names only. TypingSIN(x)orSin(x)causes Maxima to assume the user is referring to a user-defined function rather than the built-in sine function. - Namespace Structure: The system uses a single global namespace where variables and functions persist until the session ends or are explicitly removed (e.g., via the
kill()command). There is no modular scoping for standard variables.
However, Maxima maintains specific exceptions for predefined mathematical operators (functions) and constants:
- Built-in (predefined) operators (functions) (e.g.,
sin,cos,log) are mapped to uppercase versions internally (e.g.,SIN,COS), allowing users to call them with either case, though lowercase is recommended for clarity. - Built-in constants (e.g.,
%e,%pi,%i,%gamma) are strictly lowercase and must be entered exactly as such. - System names related to session history (input or output labels) also use the
%prefix and are case-sensitive.
Users are advised to use lowercase for user-defined names and functions to ensure readability and avoid conflicts with the internal uppercase mapping of standard mathematical operators.
The namespace system in Maxima is fundamentally built upon its underlying Lisp implementation, creating a unique environment where case sensitivity, symbol translation rules, and special prefixes dictate how variables and functions are stored and accessed. The namespace utilizes dynamic scoping rather than lexical scoping for most operations, which impacts variable visibility and modification:
Dynamic Scope: Identifiers defined outside a function are global in scope and can be inadvertently modified by functions if the identifiers are the same, unless explicitly made local.
For instance, a loop variable i in a global context might be overwritten by a function using i if not properly scoped. A reference to a defined Maxima function accesses the values of identifiers based on the environment of the function that exists at the point of reference. If an identifier local to the function exists, the value of that identifier is used.
Otherwise, Maxima will attempt to find the value of the referenced identifier outside of the the local scope of the function in the global namespace. This means that identifiers are by default global in scope, and that users must account for this contingency when defining and referencing functions. Refer to the Maxima documentation for the descriptions of the block ( ) and local ( ) operators for information related to the scope of identifiers.
Global Persistence: By default, all user definitions reside in a single global namespace. They persist until the session ends or are explicitly removed.
Identifier Removal Mechanisms:
kill(symbol): Completely removes the value, function definition, array, and properties of an identifier.remvalue(symbol): Removes only the assigned value of the identifier, leaving function definitions or array properties intact.kill(all): Clears all user-defined identifiers from the namespace. The operatorresetis used to reset internal Maxima built-in global "flags" or option variables to their defaults.
Identifiers
[edit | edit source]Names, symbols, words, variables, constants, literals, labels, flags, options, and identifiers are all technical terms the meaning of which may depend on the context in which these terms are used. The term identifier is used for names in the broadest practical sense as follows:
- A name that has a value of itself ( a is a ), or
- A name that has a value of an expression other than itself ( a is b and a is not a are true)
(%i1) y; /* The value of y is y, y is a name for itself. */
(%o1) y
(%i2) y : f(x); /* y is assigned an expression */
(y) f(x)
(%i3) y; /* The value of y is f(x), y is a name for f(x). */
(%o3) f(x)
This means that identifiers refer to names for: symbols, words, variables, constants, literals, labels, flags, options, and so forth. In this book, if distinctions are necessary, it should be provided by the context in which the term identifier is used.
Reserved Words
[edit | edit source]The Maxima documentation provides the following caveat regarding reserved words:
"There are a number of reserved words which should not be used as variable names. Their use would cause a possibly cryptic syntax error."
integrate next from diff in at limit sum for and elseif then else do or if unless product while thru step
Apart from these Maxima reserved words, there is relative freedom in the choice of identifiers.
Identifier Composition Rules:
[edit | edit source]Maxima identifiers follow specific lexical rules:
- Allowed Characters: Alphabetic characters (
A-Z,a-z), digits (0-9), and the underscore (_). - Special Characters: Any special character can be included if preceded by a backslash (
\). For example,a\+bis a valid single identifier. - Starting with Digits: An identifier can start with a digit if escaped (e.g.,
\1st_var). - Unicode Support: Modern versions of Maxima (and specifically interfaces like wxMaxima) support Unicode characters in identifiers, treating them as alphabetic characters without needing escape sequences, provided the underlying Lisp and font support them.
- Characters Declared Alphabetic: The
declare (character, alphabetic)operator can be used to in order to use a character in composing an identifier that otherwise would not be considered as alphabetic.
It seems to be the case that, unless otherwise noted, there are no naming conventions or a style guide for Maxima. So in general, it is up to the user to decide on the composition of identifiers.
Note that identifiers may be used that are one or more characters that comprise the alphabetic characters, plus the digits 0 through 9, plus any other character preceded by the backslash ( \ ) escape character including the space character. Note however, that the \ must be entered for each reference to the identifier.
A numeral may be the first character of an identifier if it is preceded by a backslash. Numerals which are the second or later characters need not be preceded by a backslash.
The alphabetic characters are initially %, _, and the lower and upper case letters of the alphabet - that is, all characters for which the Lisp function ALPHA-CHAR-P returns true.
Characters may be declared alphabetic by the declare (character, alphabetic) operator. If so declared, they need not be preceded by a backslash in an identifier. However, the use of the declare (character, alphabetic) operator may cause unintended and unwanted side effects depending on the character, so this operator for this purpose should be used with that in mind if at all.
Atoms and Symbols
[edit | edit source]The term symbol and identifier are frequently used in the context of names. The use of the term symbol can be attributed, as much else in Maxima, to its Lisp orientation. In Maxima, atom() and symbolp() serve different purposes regarding object classification, though their outputs often overlap for names.
atom(v)returns true ifvis an atom and false otherwise. In Maxima, atoms include numbers, strings, names (symbols), andnil. Expressions (which have an operator and arguments) are not atoms. For example,atom(5)istrue,atom(x)istrue, butatom(x+1)isfalsebecause it is an expression with the operator+.symbolp(v)returns true only ifvis a symbol (a name). It returns false for numbers, strings, or any other atomic type that is not a name. For example,symbolp(x)istrue, butsymbolp(5)isfalse.
The key difference is that atom() is a broader predicate that includes symbols, numbers, and strings, while symbolp() is specific to symbolic names.
Examples:
[edit | edit source]/* Atom checks */
(%i4) atom(7); /* true: 7 is an atomic number */
(%o4) true
(%i5) atom(x); /* true: x is an atomic symbol */
(%o5) true
(%i6) atom("hello there"); /* true: "hello there" is an atomic string */
(%o6) true
(%i7) atom(x+1); /* false: x+1 is an expression */
(%o7) false
(%i8) symbolp(7); /* false: 7 is not a symbol */
(%o8) false
(%i9) symbolp(\7); /* true: 7 is now a symbol */
(%o9) true
(%i10) symbolp(x); /* true: x is a symbol */
(%o10) true
(%i11) symbolp(x+1); /* false: x+1 is a not a symbol */
(%o11) false
(%i12) symbolp(x\+1); /* true: x\+1 is a symbol */
(%o12) true
(%i13) symbolp("hello there"); /* false: "hello there" is not a symbol */
(%o13) false
(%i14) symbolp(hello\ there); /* true: hello\ there is now a symbol */
(%o14) true
Summary Table:
[edit | edit source]| Operator | Returns true for...
|
Returns false for...
|
atom()
|
Numbers, Identifiers, Strings, nil
|
Expressions (e.g., x+1, sin(x))
|
symbolp()
|
Symbols (Identifiers, Names) | Numbers, Strings, Expressions, nil
|
Atoms are further categorized into integers, floats, strings, or identifiers (symbols). Use atom() to distinguish between atomic data and composite expressions, and symbolp() to specifically identify symbolic names.
In attempting to be technically precise in the use of these various terms, it is often the case that the user becomes immersed in a confusing sea of technical jargon. On the other hand, in attempting to be clear and simple, there is the risk that some subjective or objective technical standards fail to be met. In this book, for the sake of clarity and simplicity, the term identifier is used for names and symbols in the broadest practical sense.
Unicode Support:
[edit | edit source]As was mentioned previously, versions of Maxima, and specifically the wxMaxima GUI, support Unicode characters in identifiers, treating them as alphabetic characters without the need to be escaped, provided the underlying Lisp implementation and font support them. This support extends the set of characters available for use in composing identifiers. This support can be useful in using Greek letters and other mathematical symbols. For example:
(%i5) Θ(s,r):= s/r;
(%o5) Θ(s,r):=s/r
(%i6) Θ(%pi/2,4); /* radians as a function of arc length and radius */
(%o6) %pi/8
Unicode can also be used in other ways in expressions:
(%i7) declare(ℝ, feature); /* make ℝ a feature */
(%o7) done
/* define a function to test identifiers for feature ℝ */
(%i8) ℝ(x):= block( [q],
if not symbolp(x)
then
q:sconcat(x," is not an indentifier")
elseif featurep(x, ℝ)
then
q:concat(x, " ∈ ℝ")
else
q:concat(x, " ∉ ℝ"),
return (q) )$
(%i9) declare(x,ℝ); /* make ℝ a feature of identifier x */
(%o9) done
(%i10) ℝ(x); /* check x for feature ℝ */
(%o10) x ∈ ℝ
(%i11) ℝ(w); /* check w for feature ℝ */
(%o11) w ∉ ℝ
(%i12) ℝ(3); /* check 3 for feature ℝ */
(%o12) 3 is not an indentifier
Users should be aware of some aspects of using Unicode in the context of Maxima. First, apart from the wxMaxima GUI, using Unicode characters is likely to be a "cut-and-paste" operation using a character map of some kind. wxMaxima has built-in Unicode support which makes using these characters simple. Second, there can be some anomalous behavior. For example:
(%i14) ℃; /* This Unicode character ℃ (2103) is an acceptable symbol */
(%o14) ℃
(%i15) symbolp(℃); /* Maxima likes ℃ */
(%o15) true
/* This Unicode character ℉ (2109) is an acceptable symbol */
(%i16) symbolp(℉);
(%o16) true
/* This Unicode character ° (00B0) is an acceptable symbol */
(%i17) symbolp(°)
(%o17) true
/* Maxima does not like this ° (00B0) character with another one */
(%i18) symbolp(°R);
incorrect syntax: R is not an infix operator
symbolp(°R)
^
/* Maxima likes this ° (00B0) character if escaped */
(%i19) symbolp(\°R);
(%o19) true
Features:
[edit | edit source]The foregoing example demonstrates that features can be associated with identifiers.
(%i10) features;
(%o10) [integer,noninteger,even,odd,rational,irrational,real,
imaginary,complex,analytic,increasing,decreasing,oddfun
evenfun,posfun,constant,commutative,lassociative,
rassociative,symmetric,antisymmetric,integervalued,ℝ]
All of these features are built-in to Maxima except the last one – ℝ. ℝ is a user-defined feature.
Maxima recognizes certain mathematical properties of functions and identifiers. These properties are called "features". The operator declare(x,foo) associates the feature foo with the function or identifier x. The operator declare(foo, feature) declares a new feature foo.
For example, declare(ℝ, feature) declares ℝ as a user-defined feature.
The predicate operator featurep(x, ℝ returns true if x has the ℝ feature, and false otherwise.
Properties:
[edit | edit source]
In addition to features, properties can be attributed to identifiers using the put (atom, value, indicator) operator or the qput (atom, value, indicator) operator. The terminology used with these operators can be confusing. These operators attribute a property using the argument named indicator and assign a value to the indicator using the argument named value to that indicator. The difference between these two operators is that put evaluates arguments and qput does not. The Maxima documentation explains as follows:
- put (atom, value, indicator)
Assigns value to the property (specified by indicator) of atom. indicator may be the name of any property, not just a system-defined property.
remreverses the effect ofput.
putevaluates its arguments.putreturns value.
- qput (atom, value, indicator)
- Assigns value to the property (specified by indicator) of atom. This is the same as
put, except that the arguments are quoted.
What "quoted" means in this context is that the evaluation of the arguments is suppressed.
The operator get(atom, indicator) returns the property indicated by indicator associated with the identifier (atom) or returns false if atom doesn’t have the property indicator. The operator get evaluates its arguments.
The fog of this word salad can be lifted by way of an example. The following from the Maxima documentation exemplifies the use of the put and get operators:
(%i11) put (%e, 'transcendental, 'type);
(%o11) transcendental
(%12) put (%pi, 'transcendental, 'type);
(%o12) transcendental
(%i13) put (%i, 'algebraic, 'type);
(%o13) algebraic
(%i14) typeof (expr) := block ([q],
if numberp (expr)
then return ('algebraic),
if not atom (expr)
then return (maplist ('typeof, expr)),
q: get (expr, 'type),
if q=false
then errcatch (error(expr,"is not numeric.")) else q)$
(%i15) typeof (2*%e + x*%pi);
x is not numeric.
(%o15) [[transcendental,[]],[algebraic,transcendental]]
(%i16) typeof (2*%e + %pi);
(%o16) [transcendental,[algebraic,transcendental]]
These expressions provide examples of the use of put and get operators. The indicator for the property used is quoted ( 'type ) presumably to prevent its evaluation in order to prevent a possible clash with a Maxima system identifier with the same name.
An identifier can have multiple attributed properties. The same property can be attributed to different identifiers with different values.
This example also demonstrates the recursive use of the user-defined function typeof.
Maxima System Constants:
[edit | edit source]Maxima provides built-in identifiers used to reference some frequently used constants. Among these are %e, %i, %gamma, and %phi, as well as others. Refer to the Maxima documentation for the full list of built-in constants and the related technical details.
Maxima System Labels:
[edit | edit source]The following table summarizes the built-in identifier labels for input and output expressions:
| Label | Value | ||
|---|---|---|---|
| % | last output expression | ||
| %in | input expression as labeled | ||
| %on | output expression as labeled |
The value of n within these labels is generated automatically and sequentially by Maxima. The values of n are numerals for the natural numbers starting at 1. These labels can serve as a sort of handy shorthand as identifiers for referencing expressions. However, users should be aware that reliance on these labels in certain cases can result in unexpected and unwanted side-effects, as well as a negative effect on the readability of saved expressions.
The system labels %z7 and %z9 represent any arbitrary integer value. These labels also are automatically generated by Maxima, and typically appear in the output of equation-solving functions (such as solve) when the solution involves periodic or multi-valued mathematical expressions, such as complex logarithms or roots. They serve as integer parameters to indicate that the solution is valid for any integer value assigned to them.
Maxima System Flags:
[edit | edit source]There are built-in Maxima system identifiers that serve special purposes. These identifiers may be referred to as flags. Frequently, these flags have the value of true or false , with one or the other as the default value. These flags are relatively many in number, and too numerous to exemplify here.
One flag that can serve as an example is simp:
(%i17) simp; /* The default value of simp is true */
(%o17) true
(%i18) 3+4; /* simplification is active */
(%o18) 7
(%i19) 21/7; /* simplification is active */
(%o19) 3
(%i20) simp:false; /* the value of simp is assigned false */
(simp) false
(%i21 3+4; /* simplification is not active */
(%o21) 3+4
(%i22) 21/7; /* simplification is not active */
(%o22) 21/7
It may be a counter-intuitive recognition that calculations like these simple examples are a matter of simplification and not evaluation, but that is the case even if more complex expressions are involved.
(%i23) x:3; /* identifier x is assigned the value of 3 */
(x) 3
(%i24) x; /* the value of x is 3 by evaluation */
(%o24) 3
(%i25) x+4; /* this expression is evaluated but not simplified */
(%o25) 3+4
Assigning the simp flag to true allows simplification to occur:
(%i26) simp:true; /* the simp flag is assigned true */
(simp) true
(%i27) x+4; /* this expression is evaluated and now simplified */
(%o27) 7
Operators
Maxima Operators
[edit | edit source]"Standards are great! That's why there are so many of them, and they change so often."
"What once was forbidden is now required."
– Unknown
Mathematical Notation and Operators
[edit | edit source]Mathematical notation was conceived of by different contributors and adopted over a period of time until the present . Standards are important. They help ensure that efforts are consistent and predictable. But if there are standards for notation, then these tend to be de facto in the absence of some imposed or adopted contextual guidance. Notation is important as this is the means by which mathematical expressions are composed.
Much of what is now considered "standard" notation was in use before the advent of computers and programming software. Software such as Maxima that has as its purpose "doing" at least some of what is meant by "mathematics," must provide the means by which mathematical expressions can be composed. Standard or conventional mathematical notation in general is not well-suited for this purpose.
Hence, there has been the effort to "shoe horn" expressions into a form that is better suited for composing expressions that conforms to software programming syntax, instead of developing software systems that can compose and interpret the full spectrum of existing mathematical expressions, presumably because the former is technically simpler. There has been more success in the form of output expressions in terms of conforming to standard mathematical notation.
Maxima is mostly about mathematical expressions, and these expressions are composed of operators and atoms. Atoms are relatively the simpler ingredient for use in composing expressions – numerical and string data types, but also identifiers, especially those that are not assigned a value, and hence may be considered variables.
Operators are the ingredient where much of the "heavy lifting" occurs with respect to expression composition, and operators need some means to be expressed. Maxima operators are all some sort of "function" (or in Lisp, a procedure) in the programming language sense of the word. This is important to understand. Even something as simple as the expression of a sum is a based on a function.
For example, consider the Maxima expressions:
(%i1) e+3;
(%o1) e+3
(%i2) :lisp #$[e+3]$
((MLIST SIMP) ((MPLUS SIMP) 3 $E))
Notice that a sum is simply the Lisp procedure MPLUS. What is true here for the + operator is true in general – operators are either implicitly or explicitly a function in the programming sense of the word. For those used to conventional mathematical notation, this fact can take some getting used to.
What this means in practice when composing Maxima expressions is that the form of the input may often not resemble what looks like conventional mathematical notation regardless of how well the output or value of the expressions represents the form of conventional mathematical notation. Maxima user interfaces such as wxMaxima and GNU TeXmacs are capable of rendering the output of Maxima expressions in a way that repreosents conventional mathematical notation quite well.
However, once again, the input expressions in these and similar user interfaces always are explicitly and literally composed of Maxima atoms and operators. There is a sense in which then, Maxima imposes an alternative form of mathematical notation for input purposes. This quite simply put is the current state of affairs with respect to doing what Maxima does using a language and syntax that is compatible with computers.
There is a last subsection of this section that provides some insight into the issue of conventional mathematical notation and mathematical computer software systems such as Maxima. This subsection is included for those that have an interest.
Maxima Operators
[edit | edit source].++.
Some Information Related to Mathematical Notation
[edit | edit source]There is no single, universally enforced standard that dictates mathematical notation across all branches of math. Instead, notation is decentralized, evolving organically and varying by discipline, publisher, and subfield. [1, 2, 3]
However, there are widely accepted conventions and formal frameworks that serve as references:
1. The ISO Standard
The closest thing to a universal style guide is the ISO 31-11 (now succeeded by ISO 80000-2).
- Who uses it: Primarily applied scientists, physicists, and engineering bodies. Pure mathematicians largely ignore it in favor of their own sub-field traditions.
- Core Rule: It mandates the use of italic fonts for variables (e.g., ) and upright (roman) fonts for mathematical constants (e.g., e or π). [7, 8]
2. Disciplinary Conventions
Mathematical notation broadly divides into four categories depending on the context:
- Operational Symbols: e.g.,
- Set & Logic Symbols: e.g.,
- Functional Notation: e.g.,
- Structural/Relational Notation: e.g., [2]
Within these categories, sub-fields develop distinct dialects. For example, a partial derivative might be written as in calculus, in differential equations, or in differential geometry.
3. Practical Usage
Because notation evolves so quickly, papers and textbooks typically rely on context and explicit definitions rather than a rigid central authority. For typesetting, the international default for mathematical texts is LaTeX, which establishes formatting norms but not the mathematical meaning itself. [1, 2, 9, 10]
To explore this topic further, the Wikipedia Mathematical Notation page provides a solid overview of common symbols and their regional variants. [7]
[1] https://mathoverflow.net/questions/33152/is-there-a-reference-containing-standard-mathematical-notations
[2] https://mathematicsauthority.com/mathematical-notation-guide/
[3] https://math.stackexchange.com/questions/4738809/is-there-one-universal-standard-for-mathematical-notation
[4] https://en.wikipedia.org/wiki/ISO_31-11
[5] https://mathoverflow.net/questions/33152/is-there-a-reference-containing-standard-mathematical-notations
[6] https://hsm.stackexchange.com/questions/19089/why-does-mathematical-notation-and-terminology-stop-being-standard-after-calculu
[7] https://en.wikipedia.org/wiki/Mathematical_notation
[8] https://nhigham.com/2016/01/28/typesetting-mathematics-according-to-the-iso-standard/
[9] https://www2.cde.ca.gov/cacs/math?c0=14,8&c1=5
[10] https://math.stackexchange.com/questions/1202594/there-is-a-logical-or-mathematical-symbol-for-compatibility-incompatibility
The definitive, encyclopedic reference for the history of mathematical symbols is Florian Cajori's A History of Mathematical Notations. This foundational text details the origin, evolution, and dissemination of virtually every mathematical symbol. You can access the full A History Of Mathematical Notations Vol I text online via the Internet Archive. [1, 2, 3]
For a quick, scannable breakdown of specific symbols, turn to the Wikipedia History of mathematical notation. This resource highlights major eras and the mathematicians who standardized our modern system. [1, 2, 3]
Key Resources by Topic
- Textbook Classic: Read or borrow Florian Cajori's unabridged work via Internet Archive for a deep dive into specific symbols. [1, 2]
- General Summary: Use the Wikipedia History of mathematical notation for a curated list of who invented specific operators. [1]
- Functions & Operations: Visit the MacTutor History of Mathematics archive, maintained by the University of St Andrews, to track individual symbols (e.g., \(+\), \(-\), \(\times \), \(\div \), and \(f(x)\)). [1, 2, 3]
- The Future of Notation: Read Stephen Wolfram's Mathematical Notation: Past and Future to learn how the history of notation shapes modern computation. [1]
"Now I have to tell you that I had always assumed that mathematical notation was too haphazard to be used as any kind of thing that a computer could reasonably interpret in a rigorous way. But at the beginning of the 1990s we got interested in making Mathematica be able to interact with mathematical notation. And so we realized that we really had to figure out what was going on with mathematical notation.
Neil Soiffer had spent quite a number of years working on editing and interpreting mathematical notation, and when he joined our company in 1991, he started trying to convince me that one really could work with mathematical notation in a reasonable way, for both output and input.
The output side was pretty straightforward: after all, TROFF and TeX already did a moderately good job with that.
The issue was input.
Well, actually, one already learned something from output. One learned that at least at some level, a lot of mathematical notation could be represented in some kind of context-free form. Because one knew that in TeX, for instance, one could set things up in a tree of nested boxes.
But how about input? Well, one of the biggest things was something that always comes up in parsing: if you have a string of text, with operands and operators, how do you tell what groups with what?"
– Stephen Wolfram
Names
"One quick way to check on name conflicts is to keep the html Maxima help manual up in a separate window, and have the Index panel available to type in a name you want to use. The painful way to check on name conflicts is to wait for Maxima to give you a strange error message as to why what you are trying to do won’t work. If you get strange results, try changing the names of your variables and or functions. An important fact is that Maxima is case sensitive, so you can avoid name conflicts by capitalizing the names of your user defined Maxima functions. Your Solve will not conflict with Maxima’s solve." Edwin L. Woollett[2]
References
[edit | edit source]
Objects
- atom
- number
- name
- string
- list of atoms
Variables
- global
- local
Data types
- Numbers
- Strings
- Constants
- Lists
- Arrays
- Structures
Features
Maxima recognizes certain mathematical properties of:
- functions and variables
- system. There is a list of non-mathematical, system-dependent features. See status.
which called features.
declare (x, foo) /* gives the property foo to the function or variable x */
declare (foo, feature) /* declares a new feature foo. */
declare ([red, green, blue], feature) /* declares three new features, red, green, and blue. */
The predicate
featurep (x, foo)
returns true if x has the foo property, and false otherwise.
The infolist features is a list of known features. These are
integer noninteger even odd rational irrational real imaginary complex analytic increasing decreasing oddfun evenfun posfun constant commutative lassociative rassociative symmetric antisymmetric integervalued
plus any user-defined features.
features is a list of mathematical features.
Example:
(%i1) declare (FOO, feature); (%o1) done (%i2) declare (x, FOO); (%o2) done (%i3) featurep (x, FOO); (%o3) true
Declare
[edit | edit source]declare recognizes the following properties:
- additive : Tells Maxima to simplify a_i expressions by the substitution a_i(x + y + z + ...) --> a_i(x) + a_i(y) + a_i(z) + .... The substitution is carried out on the first argument only.
- alphabetic : Tells Maxima to recognize all characters in a_i (which must be a string) as alphabetic characters.
- antisymmetric, commutative, symmetric : Tells Maxima to recognize a_i as a symmetric or antisymmetric function. commutative is the same as symmetric.
- bindtest : Tells Maxima to trigger an error when a_i is evaluated unbound.
- constant : Tells Maxima to consider a_i a symbolic constant.
- even, odd : Tells Maxima to recognize a_i as an even or odd integer variable.
- evenfun, oddfun : Tells Maxima to recognize a_i as an odd or even function.
- evflag : Makes a_i known to the ev function so that a_i is bound to true during the execution of ev when a_i appears as a flag argument of ev. See evflag.
- evfun : Makes a_i known to ev so that the function named by a_i is applied when a_i appears as a flag argument of ev. See evfun.
- feature : Tells Maxima to recognize a_i as the name of a feature. Other atoms may then be declared to have the a_i property.
- increasing, decreasing : Tells Maxima to recognize a_i as an increasing or decreasing function.
- integer, noninteger : Tells Maxima to recognize a_i as an integer or noninteger variable.
- integervalued : Tells Maxima to recognize a_i as an integer-valued function.
- lassociative, rassociative : Tells Maxima to recognize a_i as a right-associative or left-associative function.
- linear : Equivalent to declaring a_i both outative and additive.
- mainvar : Tells Maxima to consider a_i a "main variable". A main variable succeeds all other constants and variables in the canonical ordering of Maxima expressions, as determined by ordergreatp.
- multiplicative : Tells Maxima to simplify a_i expressions by the substitution a_i(x * y * z * ...) --> a_i(x) * a_i(y) * a_i(z) * .... The substitution is carried out on the first argument only.
- nary : Tells Maxima to recognize a_i as an n-ary function. The nary declaration is not the same as calling the nary function. The sole effect of declare(foo, nary) is to instruct the Maxima simplifier to flatten nested expressions, for example, to simplify foo(x, foo(y, z)) to foo(x, y, z).
- nonarray : Tells Maxima to consider a_i not an array. This declaration prevents multiple evaluation of a subscripted variable name.
- nonscalar : Tells Maxima to consider a_i a nonscalar variable. The usual application is to declare a variable as a symbolic vector or matrix.
- noun : Tells Maxima to parse a_i as a noun. The effect of this is to replace instances of a_i with 'a_i or nounify(a_i), depending on the context.
- outative : Tells Maxima to simplify a_i expressions by pulling constant factors out of the first argument. When a_i has one argument, a factor is considered constant if it is a literal or declared constant. When a_i has two or more arguments, a factor is considered constant if the second argument is a symbol and the factor is free of the second argument.
- posfun : Tells Maxima to recognize a_i as a positive function.
- rational, irrational : Tells Maxima to recognize a_i as a rational or irrational real variable.
- real, imaginary, complex : Tells Maxima to recognize a_i as a real, pure imaginary, or complex variable.
- scalar : Tells Maxima to consider a_i a scalar variable.
Declare tells:
- evenp()
- oddp()
- integerp()
- and so on
what to return.
Compare with:
- mode_decalre
Numbers
Check
[edit | edit source](%i1) load(to_poly); (%o1) home/a/maxima/share/to_poly_solve/to_poly.lisp (%i2) r; (%o2) r (%i3) isreal_p(r); (%o3) true /* When I use unspecified variables, Maxima seems to assume that they are real */ (%i4) z:x+y*%i; (%o4) %i y + x (%i5) isreal_p(z); (%o5) isreal_p(%i y) /* maxima can't check if it is real or not */ (%i6) isreal_p(x); (%o6) true (%i7) isreal_p(y); (%o7) true (%i8) complex_number_p(z); (%o8) false (%i9) declare(z, complex); (%o9) done (%i10) complex_number_p(z); (%o10) false /* still not complex */ true
Random numbers
[edit | edit source]bfloat(random(10^fpprec) / 10^fpprec); /* random bfloat with fpprec decimal digits in the range 0 to 1 */
Number types
[edit | edit source]Binary numbers
[edit | edit source](%i1) ibase; (%o1) 10 (%i2) obase; (%o2) 10 (%i3) ibase:2; (%o3) 2 (%i4) x=1001110; (%o4) x=78
Complex numbers
[edit | edit source]Argument
[edit | edit source]Principial value of argument of complex number in turns carg produces results in the range (-pi, pi] . It can be mapped to [0, 2*pi) by adding 2*pi to the negative values
carg_t(z):= block( [t], t:carg(z)/(2*%pi), /* now in turns */ if t<0 then t:t+1, /* map from (-1/2,1/2] to [0, 1) */ return(t) )$
On can order list of complex points according to it's argument :
l2_ordered: sort(l2, lambda([z1,z2], is(carg(z1) < carg(z2))))$
rational numbers
[edit | edit source]- rat
- ratp
Rationalize with limit denominator:[1]
limit_denominator(x, max_denominator):=
block([p0, q0, p1, q1, n, d, a, q2, k, bound1, bound2, ratprint: false],
[p0, q0, p1, q1]: [0, 1, 1, 0],
[n, d]: ratexpand([ratnum(x), ratdenom(x)], 0),
if d <= max_denominator then x else
(catch(
do block(
a: quotient(n, d),
q2: q0+a*q1,
if q2 > max_denominator then throw('done),
[p0, q0, p1, q1]: [p1, q1, p0+a*p1, q2],
[n, d]: [d, n-a*d])),
k: quotient(max_denominator-q0, q1),
bound1: (p0+k*p1)/(q0+k*q1),
bound2: p1/q1,
if abs(bound2 - x) <= abs(bound1 - x) then bound2 else bound1))$
Predicate functions
[edit | edit source](%i1) is(0=0.0); (%o1) false
Compare :
(%i1) a:0.0$ (%i2)is(equal(a,0)); (%o2) true
List of predicate functions ( see p at the end ) :
- abasep
- alphacharp
- alphanumericp
- atom
- bfloatp
- blockmatrixp
- cequal
- cequalignore
- cgreaterp
- cgreaterpignore
- charp
- clessp
- clesspignore
- complex_number_p from to_poly package
- constantp
- constituent
- diagmatrixp
- digitcharp
- disjointp
- elementp
- emptyp
- evenp
- featurep
- floatnump ( compare : isreal_p)
- if
- integerp
- intervalp
- is
- isreal_p from to_poly package
- lcharp
- listp
- listp
- lowercasep
- mapatom
- matrixp
- matrixp
- maybe
- member
- nonnegintegerp
- nonscalarp
- numberp
- oddp
- operatorp
- ordergreatp
- orderlessp
- picture_equalp
- picturep
- poly_depends_p
- poly_grobner_subsetp
- polynomialp
- prederror
- primep
- ratnump
- ratp
- scalarp
- sequal
- sequalignore
- setequalp
- setp
- stringp
- subsetp
- subvarp
- symbolp
- symmetricp
- taylorp
- unknown
- uppercasep
- zeroequiv
- zeromatrixp
- zn_primroot_p
See also :
- declare[2]
- property:
- rational, irrational, real, imaginary, complex,
- even, odd,
- decreasing, increasing
- evenfun, oddfun
- property:
Number Theory
[edit | edit source]There are functions and operators useful with integer numbers
Elementary number theory
[edit | edit source]In Maxima there are some elementary functions like the factorial n! and the double factorial n!! defined as where is the greatest integer less than or equal to
Divisibility
[edit | edit source]Some of the most important functions for integer numbers have to do with divisibility:
gcd, ifactor, mod, divisors...
all of them well documented in help. you can view it with the '?' command.
Function ifactors takes positive integer and returns a list of pairs : prime factor and its exponent. For example :
a:ifactors(8); [[2,3]]
It means that :
Other Functions
[edit | edit source]Continuus fractions :
(%i6) cfdisrep([1,1,1,1]); (%o6) 1+1/(1+1/(1+1/1)) (%i7) float(%), numer; (%o7) 1.666666666666667
Functions
Definition
[edit | edit source]For mathematical functions use always
define()
instead of
:=
There is only one small difference between them:
"The function definition operator. f(x_1, ..., x_n) := expr defines a function named f with arguments x_1, …, x_n and function body expr. := never evaluates the function body (unless explicitly evaluated by quote-quote '')."
"Defines a function named f with arguments x_1, …, x_n and function body expr. define always evaluates its second argument (unless explicitly quoted). "[3]
return
[edit | edit source]"return doesn't mean the same thing in Maxima as it does in other programming languages. It means only to return a value from a block; that's not enough for what you need here." Robert Dodier[4]
If you wish to make a return from some expression inside the function then you must use block and return.
block ([], expr1, ..., if (a > 10) then return(a), ..., exprn)
is itself an expression, and so could take the place of the right hand side of a function definition. Here it may happen that the return happens earlier than the last expression.
Local variables
[edit | edit source]block ([x], expr1, ..., exprn)
The first [] in the block, may contain a list of variables and variable assignments, such as [a: 3, b, c: []], which would cause the three variables a,b,and c to not refer to their global values, but rather have these special values for as long as the code executes inside the block, or inside functions called from inside the block. This is called dynamic binding, since the variables last from the start of the block to the time it exits. Once you return from the block, or throw out of it, the old values (if any) of the variables will be restored. It is certainly a good idea to protect your variables in this way. Note that the assignments in the block variables, are done in parallel. This means, that if you had used c: a in the above, the value of c would have been the value of a at the time you just entered the block, but before a was bound. Thus doing something like:
block ([a: a], expr1, ... a: a+3, ..., exprn)
will protect the external value of a from being altered, but would let you access what that value was. Thus the right hand side of the assignments, is evaluated in the entering context, before any binding occurs. Using just block ([x], ...) would cause the x to have itself as value, just as if it would have if you entered a fresh Maxima session.
See also description by Darren Irvine[5]
compile
[edit | edit source]- "The modedeclare statement is important for compiled code
- Compiling can greatly speed numerical code; for mostly symbolic code, the speed up is not great.
- There are some differences between compiled and uncompiled code -- be careful." Barton Willis[6]
mode_declare
[edit | edit source]"mode_declare tells the compiler that the compiled code needs not to be generic enough to be able to deal with all kind of objects. If your function only takes floats, but no symbolic arguments the compiled code might run much faster." Gunter Königsmann
diff
[edit | edit source]explicit
[edit | edit source]implicit
[edit | edit source]
Debugging
Directories
[edit | edit source]Start Maxima and type the command:[7]
maxima_userdir;
this will tell you the directory that is being used as your user directory.
infolists
[edit | edit source]- is a system variable
- Default value: []
- is a list of the names of all of the information lists in Maxima. These are
- labels : All bound %i, %o, and %t labels.
- values : All bound atoms which are user variables, not Maxima options or switches, created by : or :: or functional binding.
- functions : All user-defined functions, created by := or define.
- arrays : All declared and undeclared arrays, created by :, ::, or :=.
- macros : All user-defined macro functions, created by ::=.
- myoptions : All options ever reset by the user (whether or not they are later reset to their default values).
- rules : All user-defined pattern matching and simplification rules, created by tellsimp, tellsimpafter, defmatch, or defrule.
- aliases : All atoms which have a user-defined alias, created by the alias, ordergreat, orderless functions or by declaring the atom as a noun with declare.
- dependencies : All atoms which have functional dependencies, created by the depends, dependencies, or gradef functions.
- gradefs : All functions which have user-defined derivatives, created by the gradef function.
- props : All atoms which have any property other than those mentioned above, such as properties established by atvalue or matchdeclare, etc., as well as properties established in the declare function.
- let_rule_packages : All user-defined let rule packages plus the special package default_let_rule_package. (default_let_rule_package is the name of the rule package used when one is not explicitly set by the user.)
reset
[edit | edit source]reset : resets many (global) system variables
Use:
reset()
example output :
(%o1) [_, __, load_pathname, labels, %, linenum, ratprint, tr-unique,
lispdisp, multiplicities]
trace
[edit | edit source]In Maxima :
:lisp (setf *debugger-hook* nil)
manual debugging
[edit | edit source]print partial results using :
- playback
values
[edit | edit source]values:
- is a system variable
- is a list ... which contains the names of currently assigned scalar values which have been set by:
- the user interactively
- by packages which have been loaded"[8]
- initial value is []
dependencies
[edit | edit source]dependencies :
- is a system variable
- is the list of atoms which have functional dependencies, assigned by:
- depends
- the function dependencies
- gradef
status
[edit | edit source]status (feature);
example output:
(%o34) [sb-bsd-sockets-addrinfo, cl, mk-defsystem, cltl2, 64-bit, 64-bit-registers, alien-callbacks, ansi-cl, ash-right-vops, c-stack-is-control-stack, common-lisp, compare-and-swap-vops, complex-float-vops, cycle-counter, elf, float-eql-vops, fp-and-pc-standard-save, gencgc, ieee-floating-point, inline-constants, integer-eql-vop, interleaved-raw-slots, largefile, linkage-table, linux, little-endian, memory-barrier-vops, multiply-high-vops, os-provides-blksize-t, os-provides-dladdr, os-provides-dlopen, os-provides-getprotoby-r, os-provides-poll, os-provides-putwc, os-provides-suseconds-t, package-local-nicknames, precise-arg-count-error, raw-instance-init-vops, sb-after-xc-core, sb-core-compression, sb-doc, sb-eval, sb-futex, sb-ldb, sb-package-locks, sb-simd-pack, sb-source-locations, sb-test, sb-thread, sb-unicode, sb-xref-for-internals, sbcl, stack-allocatable-closures, stack-allocatable-fixed-objects, stack-allocatable-lists, stack-allocatable-vectors, stack-grows-downward-not-upward, symbol-info-vops, unix, unwind-to-frame-and-call-vop, x86-64]
Data structures
"Maxima's current array/matrix semantics are a mess, I must say, with at least four different kinds of object (hasharrays, explicit lists, explicit matrices, Lisp arrays) supporting subscripting with varying semantics. " [9]
"Maxima's concept of arrays, lists, and matrices is pretty confused, since various ideas have accreted in the many years of the project... Yes, this is a mess. Sorry about that. These are all interesting ideas, but there is no unifying framework. " [10]
Array
[edit | edit source]Maxima has two array types :[11]
- Undeclared arrays ( implemented as Lisp hash tables )
- Declared arrays ( implemented as Lisp arrays )
- created by the array function
- created by the make_array function.
Category: Arrays :
- array
- arrayapply
- arrayinfo
- arraymake
- arrays - global variable
- fillarray
- listarray
- make_array
- rearray
- remarray
- subvar
- use_fast_arrays
See also :
- array functions defined by := and define.
Undeclared array
[edit | edit source]Assignment creates an undeclared array.
(%i1) c[99] : 789; (%o1) 789 (%i2) c[99]; (%o2) 789 (%i3) c; (%o3) c (%i4) arrayinfo (c); (%o4) [hashed, 1, [99]] (%i5) listarray (c); (%o5) [789]
"If the user assigns to a subscripted variable before declaring the corresponding array, an undeclared array is created. Undeclared arrays, otherwise known as hashed arrays (because hash coding is done on the subscripts), are more general than declared arrays. The user does not declare their maximum size, and they grow dynamically by hashing as more elements are assigned values. The subscripts of undeclared arrays need not even be numbers. However, unless an array is rather sparse, it is probably more efficient to declare it when possible than to leave it undeclared. " ( from Maxima CAS doc)
"created if one does :
b[x+1]:y^2
(and b is not already an array, a list, or a matrix - if it were one of these an error would be caused since x+1 would not be a valid subscript for an art-q array, a list or a matrix).
Its indices (also known as keys) may be any object. It only takes one key at a time (b[x+1,u]:y would ignore the u). Referencing is done by b[x+1] ==> y^2. Of course the key may be a list, e.g.
b[[x+1,u]]:y
would be valid. "( from Maxima CAS doc)
Declared array
[edit | edit source]- declare array ( give a name and allocate memmory)
- fill array
- process array
array function
[edit | edit source]Function: array (name, type, dim_1, …, dim_n)
Creates an n-dimensional array. Here :
- type can be fixnum for integers of limited size or flonum for floating-point numbers
- n may be less than or equal to 5. The subscripts for the i'th dimension are the integers running from 0 to dim_i.
(%i5) array(A,2,2); (%o5) A (%i8) arrayinfo(A); (%o8) [declared, 2, [2,2]]
Because subscripts of array A elements are goes from 0 to dim so array A has :
( dim_1 + 1) * (dim_2 + 1) = 3*3 = 9
elements.
The array function can be used to transform an undeclared array into a declared array.
arraymake function
[edit | edit source]Function: arraymake (A, [i_1, …, i_n])
The result is an unevaluated array reference.
(%i12) arraymake(A,[3,3,3]);
(%o12) array_make(3, 3, 3)
3, 3, 3
(%i13) arrayinfo(A);
arrayinfo: A is not an array.
Function: make_array
[edit | edit source]Function: make_array (type, dim_1, …, dim_n)
Creates and returns a Lisp array.
Type may be :
- any
- flonum
- fixnum
- hashed
- functional.
There are n indices, and the i'th index runs from 0 to dim_i - 1.
The advantage of make_array over array is that the return value doesn't have a name, and once a pointer to it goes away, it will also go away. For example, if y: make_array (...) then y points to an object which takes up space, but after y: false, y no longer points to that object, so the object can be garbage collected.
Examples:
(%i9) A : array_make(3,3,3); (%o9) array_make(3, 3, 3) (%i10) arrayinfo(A); (%o10) [declared, 3, [3, 3, 3]]
List
[edit | edit source]Assignment to an element of a list.
(%i1) b : [1, 2, 3]; (%o1) [1, 2, 3] (%i2) b[3] : 456; (%o2) 456 (%i3) b; (%o3) [1, 2, 456]
(%i1) mylist : [[a,b],[c,d]]; (%o1) [[a, b], [c, d]]
Interesting examples by Burkhard Bunk : [12]
lst: [el1, el2, ...]; contruct list explicitly lst[2]; reference to element by index starting from 1 cons(expr, alist); prepend expr to alist endcons(expr, alist); append expr to alist append(list1, list2, ..); merge lists makelist(expr, i, i1, i2); create list with control variable i makelist(expr, x, xlist); create list with x from another list length(alist); returns #elements map(fct, list); evaluate a function of one argument map(fct, list1, list2); evaluate a function of two arguments
Category: Lists :
- [
- ]
- append
- assoc
- cons
- copylist
- create_list
- delete
- eighth
- endcons
- fifth
- first
- flatten
- fourth
- fullsetify
- join
- last
- length
- listarith
- listp
- lmax
- lmin
- lreduce
- makelist
- member
- ninth
- permut
- permutations
- pop
- push
- random_permutation
- rest
- reverse
- rreduce
- second
- setify
- seventh
- sixth
- some
- sort
- sublist
- sublist_indices
- tenth
- third
- tree_reduce
- xreduce
product
[edit | edit source]/* example by Burton Willis */ (%i28) P1(s) := rectform(product(s[i],i, 1, length(s)))$ (%i29) P2(s) := xreduce(lambda([a,b], rectform(a*b)),s)$ (%i30) s : makelist(random(1.0)+%i*random(1.0),10^4)$ (%i31) P1(s); Evaluation took 32.3080 seconds (32.3860 elapsed) using 17944.301 MB. (%o31) 0.0 (%i32) P2(s); Evaluation took 0.0620 seconds (0.0620 elapsed) using 8.343 MB. (%o32) 0.0
Matrix
[edit | edit source]"In Maxima, a matrix is implemented as a nested list (namely a list of rows of the matrix)". E.g. :[13]
(($MATRIX) ((MLIST) 1 2 3) ((MLIST) 4 5 6))
Construction of matrices from nested lists :
(%i3) M:matrix([1,2,3],[4,5,6],[0,-1,-2]);
[ 1 2 3 ]
[ ]
(%o3) [ 4 5 6 ]
[ ]
[ 0 - 1 - 2 ]
Interesting examples by Burkhard Bunk : [14]
A: matrix([a, b, c], [d, e, f], [g, h, i]); /* (3x3) matrix */ u: matrix([x, y, z]); /* row vector */ v: transpose(matrix([r, s, t])); /* column vector */
Reference to elements etc:
u[1,2]; /* second element of u */ v[2,1]; /* second element of v */ A[2,3]; or A[2][3]; /* (2,3) element */ A[2]; /* second row of A */ transpose(transpose(A)[2]); /* second column of A */
Element by element operations:
A + B; A - B; A * B; A / B; A ^ s; s ^ A;
Matrix operations :
A . B; /* matrix multiplication */ A ^^ s; /* matrix exponentiation (including inverse) */ transpose(A); determinant(A); invert(A);
Category: Matrices :[15]
- addcol
- addrow
- adjoint
- augcoefmatrix
- cauchy_matrix
- charpoly
- coefmatrix
- col
- columnvector
- covect
- copymatrix
- determinant
- detout
- diag
- diagmatrix
- doallmxops
- domxexpt
- domxmxops
- domxnctimes
- doscmxops
- doscmxplus
- echelon
- eigen
- ematrix
- entermatrix
- genmatrix
- ident
- invert
- list_matrix_entries
- lmxchar
- matrix
- matrix_element_add
- matrix_element_mult
- matrix_element_transpose
- matrixmap
- matrixp
- mattrace
- minor
- ncharpoly
- newdet
- nonscalar
- nonscalarp
- permanent
- rank
- ratmx
- row
- scalarmatrixp
- scalarp
- setelmx
- sparse
- submatrix
- tracematrix
- transpose
- triangularize
- zeromatrix
Function: matrix
[edit | edit source]Function: matrix (row_1, …, row_n)
Returns a rectangular matrix which has the rows row_1, …, row_n. Each row is a list of expressions. All rows must be the same length.
. operator
[edit | edit source]"The dot operator, for matrix (non-commutative) multiplication. When "." is used in this way, spaces should be left on both sides of it, e.g.
A . B
This distinguishes it plainly from a decimal point in a floating point number.
The operator . represents noncommutative multiplication and scalar product. When the operands are 1-column or 1-row matrices a and b, the expression a.b is equivalent to sum (a[i]*b[i], i, 1, length(a)). If a and b are not complex, this is the scalar product, also called the inner product or dot product, of a and b. The scalar product is defined as conjugate(a).b when a and b are complex; innerproduct in the eigen package provides the complex scalar product.
When the operands are more general matrices, the product is the matrix product a and b. The number of rows of b must equal the number of columns of a, and the result has number of rows equal to the number of rows of a and number of columns equal to the number of columns of b.
To distinguish . as an arithmetic operator from the decimal point in a floating point number, it may be necessary to leave spaces on either side. For example, 5.e3 is 5000.0 but 5 . e3 is 5 times e3.
There are several flags which govern the simplification of expressions involving ., namely dot0nscsimp, dot0simp, dot1simp, dotassoc, dotconstrules, dotdistrib, dotexptsimp, dotident, and dotscrules." ( from Maxima CAS doc)
Vectors
[edit | edit source]Category: Vectors :
- Vectors
- eigen
- express
- nonscalar
- nonscalarp
- scalarp
Category: Package vect[16]
- vect
- scalefactors
- vect_cross
- vectorpotential
- vectorsimp
Numerical methods
"If you are doing purely numerical computation and are concerned about speed, use a compiled numerical programming language. Maxima is intended for use if you have symbolic mathematical symbols, too, and while it works for numbers, most components of the system are on the lookout for non-numeric inputs, and this checking takes time. It is possible to speed up certain kinds of numeric computations in Maxima by using compile() and mode_declare() together. " RJF
Newton method
[edit | edit source]Functions
- newton for equation with function of one variable
- mnewton is an implementation of Newton's method for solving nonlinear equations in one or more variables.
newton
[edit | edit source]load :
load("newton");
(%o1) /home/a/maxima/share/numeric/newton.mac
(%i2) load("newton1");
(%o2) /home/a/maxima/share/numeric/newton1.mac
Code :
/*
Maxima CAS code
from /maxima/share/numeric/newton1.mac
input :
exp = function of one variable, x
var = variable
x0 = initial value of variable
eps =
The search begins with x = x_0 and proceeds until abs(expr) < eps (with expr evaluated at the current value of x).
output : xn = an approximate solution of expr = 0 by Newton's method
*/
newton(exp,var,x0,eps):=
block(
[xn,s,numer],
numer:true,
s:diff(exp,var),
xn:x0,
loop,
if abs(subst(xn,var,exp))<eps
then return(xn),
xn:xn-subst(xn,var,exp)/subst(xn,var,s),
go(loop)
)$
mnewton
[edit | edit source]
One can use Newton method for solving systems of multiple nonlinear functions. It is implemented in mnewton function. See directory :
/Maxima..../share/contrib/mnewton.mac
which uses linsolve_by_lu defined in :
/share/linearalgebra/lu.lisp
See this image for more code.
(%i1) load("mnewton")$
(%i2) mnewton([x1+3*log(x1)-x2^2, 2*x1^2-x1*x2-5*x1+1],
[x1, x2], [5, 5]);
(%o2) [[x1 = 3.756834008012769, x2 = 2.779849592817897]]
(%i3) mnewton([2*a^a-5],[a],[1]);
(%o3) [[a = 1.70927556786144]]
(%i4) mnewton([2*3^u-v/u-5, u+2^v-4], [u, v], [2, 2]);
(%o4) [[u = 1.066618389595407, v = 1.552564766841786]]
Algorithms

Stack implementation using list:
/* create stack */ stack:[1]; /* push on stack */ stack:endcons(2,stack); stack:endcons(3,stack); block ( loop, stack:delete(last(stack),stack), /* pop from stack */ disp(stack), /* display */ if is(not emptyp(stack)) then go(loop) ); stack;
Plots
Complex Functions
[edit | edit source]- Visualizing Complex Functions with Conformal Mapping ( themaximalist ) [17]
Topologist's sine curve
[edit | edit source]plot2d (sin(1/x), [x, 0, 1])$
Topologist's comb :

load(draw); /* by Mario Rodríguez Riotorto http://riotorto.users.sourceforge.net/gnuplot/index.html */ draw2d( title = "Topologist\\47s comb", /* Syntax for postscript enhanced option; character 47 = ' */ xrange = [0.0,1.2], yrange = [0,1.2], file_name = "comb2", terminal = svg, points_joined = impulses, /* vertical segments are drawn from points to the x-axis */ color = "blue", points(makelist(1/x,x,1,1000),makelist(1,y,1,1000)) )$
Outputs and warnings
- ratprint : false; /* remove "rat :replaced " */
- using $ instead of ; at the end of the line ( not inside function where , ends the line )
- return from the function
- "warning: encountered undefined variable ... in translation." This is warning from compile when function uses global variable without using in in tha arguments list. You have to include the variables in the function's list
Example programs
- Iteration of complex numbers, stack and drawing a list of points

- Iteration of complex numbers, comparing complex numbers, finding period of cycle

- Drawing Julia set and critical orbit. Computing period

- drawing curves in 2D plane

- drawing points

Weaknesses of math software
While Maxima is a very useful software, it suffers from the same issues faced by many other math programs.
- The limit of a discontinuous function at the point of discontinuity[18]
- Branch cuts[19]
- Zero-recognition
- Keeping track of domains of validity
References
[edit | edit source]- ↑ stackoverflow question : rationalize-number-with-limit-denominator
- ↑ maxima manual : Category Declarations-and-inferences
- ↑ Discussion at Maxima interest list
- ↑ stackoverflow question : difference-between-throw-return-and-break-in-maxima
- ↑ Darren Irvine : local-variables-function-parameters
- ↑ maxima-discuss : compiling-files-written-in-maxima
- ↑ [Maxima] Phantastic Program! One bug - discussion
- ↑ Maxima by Example: Ch. 1, Introduction to Maxima ∗ Edwin L. Woollett August 11, 2009
- ↑ Maxima: Syntax improvements by Stavros Macrakis
- ↑ Maxima: what does Maxima call an “array”? - answer by Robert Dodier
- ↑ the Maxima mailing list : [Maxima] array and matrix? - answer by Robert Dodier
- ↑ Maxima Overview by Burkhard Bunk
- ↑ the Maxima mailing list : [Maxima] array and matrix? - answer by Robert Dodier
- ↑ Maxima Overview by Burkhard Bunk
- ↑ maxima manual : Category Matrices
- ↑ maxima manual : Package vect
- ↑ themaximalist visualizing-complex-functions-by-their-images-over-concentric-circles
- ↑ Stackexchange : What are well-known weaknesses of CAS/math software?
- ↑ R Fateman : Branch Cuts in Computer Algebra,
Help
bash
[edit | edit source]- info maxima
Maxima commands
[edit | edit source]- dependencies
- infolists
- describe
- ??