Several computer algebra systems are available to Linux users. Ieven have looked at a few of them in this column, but for this issue, I discussOpenAxiom. OpenAxiom actually is a fork of Axiom. Axiom originallywas developed at IBM under the name ScratchPad. Development started in 1971,so Axiom is as old as I am, and almost as smart. In the 1990s, it wassold off to the Numerical Algorithms Group (NAG). In 2001, NAG removed itfrom commercial sale and released it as free software. Since then, it hasforked into OpenAxiom and FriCAS. Axiom still is available. Thesystem is specified in the bookAXIOM: the Scientific ComputationSystem by Richard Jenks and Robert Sutor. This book is available on-lineathttp://wiki.axiom-developer.org/axiom-website/hyperdoc/axbook/book-contents.xhtml,and it makes up the core documentation forOpenAxiom.
Most Linux distributions should have a package for OpenAxiom.For example, with Debian-based distributions, you can installOpenAxiom with:
sudo apt-get install openaxiomIf you want to build OpenAxiom from source, you need to have aLisp engine installed. There are several to choose from on Linux, such asCLisp or GNU Common Lisp. Building is a straightforward:
./configure; make; make installTo use OpenAxiom, simply executeopen-axiom on the command line. Thiswill give you an interactive OpenAxiom session. If you have a script ofcommands you want to run as a complete unit, you can do so with:
open-axiom --script myfile.inputwhere the file "myfile.input" contains the OpenAxiom commands to beexecuted.
So, what can you actually do with OpenAxiom? OpenAxiom has many differentdata types. There are algebraic ones (like polynomials, matrices and powerseries) and data structures (like lists and dictionaries). You can combinethem into any reasonable combinations, like polynomials of matricesor matrices of polynomials. These data types are defined by programs inOpenAxiom. These data type programs also include the operations that canbe applied to the particular data type. The entire system is polymorphicby design. You also can extend the entire data type system by writingyour own data type programs. There are a large number of differentnumeric types to handle almost any type of operation as well.
The simplest use of OpenAxiom is as a calculator. For example, you canfind the cosine of 1.2 with:
cos(1.2)This will give you the result with 20 digits, by default. You can changethe number of digits being used with thedigits()function. OpenAxiomalso will give you the type of this answer. This is useful when you aredoing more experimental calculations in order to check your work. Inthe above example, the type would beFloat. If you trythis:
4/6the result is2/3, and you will see a new type,Fraction Integer. Ifyou have used a commercial system like Maple before, this shouldbe familiar.
OpenAxiom has data types to try to keep results as exactvalues. If you have a reason to use a particular type, you can do aconversion with the:: operator. So, you could redo the above divisionand get the answer as a float with:
(4/6)::FloatIt even can go backward and calculate the closest fraction that matchesa given float with the command:
%::Fraction IntegerThe% character refers to the most recent result that youcalculated. The answer you get from this command may not match theoriginal fraction, due to various rounding errors.
There are functionsthat allow you to work with various parts of numbers. You canround() ortruncate() floating-point numbers. You even can get just the fractionalpart withfractionPart().
One slightly unique thing in OpenAxiom is aset of test functions. You can check for oddness and evenness with thefunctionsodd?() andeven?(). Youeven can check whether a number isprime withprime?(). And, of course, you still have all of the standardfunctions, like the trigonometric ones, and the standard operators,like addition and multiplication.
OpenAxiom handles general expressions too. In order to use them, youneed to assign them to a variable name. The assignment operatoris:=. One thing to keep in mind is that this operator will executewhatever is on the right-hand side and assign the result to the name onthe left-hand side. This may not be what you want to have happen. If so,you can use the delayed assignment operator==. Let's say you want tocalculate the square of some numbers. You can create an expression with:
xSquared := x**2In order to use this expression, you need to use theeval function:
eval(xSquared, x=4)You also can have multiple parameters in your expression. Say you wantedto calculate area. You could use something like this:
xyArea := x * y eval(xyArea, [x=2, y=10])The last feature I want to look at in this article is how OpenAxiomhandles data structures. The most basic data structure is a list. Listsin OpenAxiom are homogeneous, so all of the elements need to be the samedata type. You define a list directly by putting a comma-separated groupin square brackets—for example:
[1,2,3,4]This can be done equivalently with thelistfunction:
list(1,2,3,4)You can put two lists together with theappend function:
append([1,2],[3,4])If you want to add a single element to the front of a list, you can usethecons function:
cons(1, [2,3,4])List addressing is borrowed from the concepts in Lisp. So the mostbasic addressing functions to get elements are the functionsfirstandrest. Using the basic list from above, the function:
first([1,2,3,4])will return the number 1, and the function:
rest([1,2,3,4])will return the list [2,3,4]. Using these functions and creative useof loops, you can get any element in a given list. But, this is veryinconvenient, so OpenAxiom provides a simpler interface. If you hadassigned the above list to the variablemylist, you could get the thirdelement with:
mylist.3or, equivalently:
mylist(3)These index values are 1-based, as opposed to 0-based indexing inlanguages like C.
A really unique type of list available is the infinitelist. Say you want to have a list of all integers. You can do that with:
myints := [i for i in 1..]This list will contain all possible integers, and they are calculatedonly when you need the value in question. You can have more complicatedexamples, like a list of prime numbers:
myprimes := [i for i in 1.. | prime?(i)]One issue with lists is that access times depend on how big the listis. Accessing the last element of a list varies, depending on how bigsaid list is. This is because lists can vary in length. If you have apiece of code that deals with lists that won't change in length, youcan improve performance by using an array. You can create a one-dimensional arraywith the function:
oneDimensionalArray([2,3,4,5])This assigns a fixed area of memory to store the data, and access timenow becomes uniform, regardless of the size of the list. Arrays also are used as the base data structure for strings and vectors. You even can create a bits data structure. You could create a group of eight1-bits with:
bits(8,true)In this way, you can begin to do some rather abstract computational work.
As you have seen, OpenAxiom, and its variants, are very powerful systemsfor doing scientific computations. I covered onlythe very basic functionality available here, but it should give you a feelingfor what you can do. In the near future, I plan to take another lookat OpenAxiom and see what more advanced techniques are possible,including writing your own functions and programs.






