Norm Matloff's Introduction to the Yacas Symbolic Math Package
Contents:
Yacas is a public-domain package for doing symbolic
math, similar in function (if not necessarily in scope) to Mathematica.
Its best features are that it is easy to install and use, has a good
online help feature, and is free! It should compile easily on any kind
of UNIX platform, and there is a Windows version.
Yacas can be used either in interactive or batch mode.
Typically in the latter case you will use it to program with, i.e. with
loops, if-then-else etc.
Download it from the
Yacas Web page.
Follow the usual "configure; make; make install" sequence, as stated in the
INSTALL file.
The introduction, in the file manualmaker/intro.html
of the source code package, is quite good. Further
documentation is in manualmaker/ref.html. You can get
these
online as well.
Both files are accessible from within Yacas , by typing
"??". Yacas invokes lynx for this
(or another browser, if you specify one). Use the arrow keys to move
between items, `u' to go up a level, and `q' to return to
Yacas. Also, typing `?' will give you documentation on
a particular function; e.g. "?Limit" will give you information on the
Limit function.
In interactive ("console") mode, the user prompt is
In>, and the result of the command is prefaced by
Out>. You can do editing within the command line by
using the left/right arrow keys, ctrl-d and Delete, and can move back through
previous commands using the up/down arrow keys. Command completion can
be done via the TAB key. You should end each command with a semicolon.
(Currently Yacas will supply the semicolon in
interactive mode if you don't, but the documentation seems to say that
this will change in the future.)
To get a 5-second introduction, find the limit of sin(x)/x as x goes
to 0 as follows:
% yacas
[sign-on greeting deleted here]
In> Limit(x,0) Sin(x)/x;
Out> 1;
In> quit
Quitting...
%
Here's another quick example, in which we integrate x from x
= 0 to x = 1:
In> Integrate(x,0,1) x^2;
Out> 1/3;
The symbol % represents the output
(Out>) from the previous command. For example:
In> x+x^2;
Out> x+x^2;
In> Factor(%);
Out> (1+x)*x;
Yacas is mainly a symbolic math package, and thus
attempts to keep everything as expressions rather than numbers. Use can
use the N() ("numeric") function to convert to
numbers, e.g.:
In> Integrate(t,0,0.25) Cos(2*Pi()*t);
Out> 0.1591549431*Sin(1.5707963267);
In> N(%);
Out> 0.1591549431;
Or, in one step:
In> N(Integrate(t,0,0.25) Cos(2*Pi()*t));
Out> 0.1591549431;
Note that the sine and cosine functions use capital S and C; all the
Yacas reserved words begin with capitals, and if you
forget, Yacas will just refuse to do anything.
The expression Pi() means 3.14... The expression
Pi, without the parentheses, means the same thing,
expect that it is not evaluated to a number. The second form is usually
better, because it allows for cancellation in symbolic expressions.
Here are a few other things to get you started (and in some cases also to
fill in gaps in the documentation):
To get better readability for exponents and fractions, use
PrettyForm() , e.g.
In> x+x^2
Out> x+x^2;
In> PrettyForm(%)
2
x + x
Out> True;
To simplify an expression, use Simplify(). Note,
however, that you should not expect miracles from this.
Yacas does allow you to add your own simplification
rules which it will use for guidelines, but in general, expect to do
your own simplifying.
You can define variables and functions by using :=.
For example:
In> f(x):=x^2;
Out> True;
In> f(3);
Out> 9;
In> a:=5;
Out> 5;
In> f(a);
Out> 25;
As in many other languages, an array in Yacas is
called a list. List subscripts are specified using
brackets (indices start at 1, not 0), and a list can be referred to
en masse by using braces. Perl/Python-style operations on
lists are provided, such as slicing, i.e. extracting
subsets of a list. For example:
In> x:={4,5,12,200};
Out> {4,5,12,200};
In> x[2];
Out> 5;
In> x[2 .. 4];
Out> {5,12,200};
In> z:=2 .. 4;
Out> {2,3,4};
In> x[z];
Out> {5,12,200};
In> x[2]:=-5;
Out> True;
In> x;
Out> {4,-5,12,200};
In> x:=Append(x,8);
Out> {4,-5,12,200,8};
In> x
Out> {4,-5,12,200,8};
Note the blank spaces enclosing the ".." Also, as you can see, in
interactive mode, simply typing in the name of a variable results in its
value being printed out (including the case in which the variable is a
list).
Lists must be initialized (even if only to the empty list, {}). They
can grow dynamically, using the Append() function as
seen above. (Note that Append() itself does not change
its list argument; in order to achieve such a change, the result of the
function call must be assigned to the argument.) Subsets can be
extracted not only by slicing but also via the function
Select(), which does an on-the-fly if-then extraction.
The length of a list can be obtained by calling the function
Length() on it.
Yacas also features Perl/Python-style hashes.
Vectors are represented as lists, and matrices (in row-major order, a
fact not explicitly mentioned in the documentation) as lists of lists,
each individual list comprising one row of the matrix.
One writes a row vector as a one-row matrix. The row vector (1,2,3),
for instance, would be written as {{1,2,3}}. Be sure to note the extra
set of braces. The inner set of braces is enclosing the one row of the
matrix, and then the outer set makes it a one-row matrix.
One can write a column vector as a multi-row, one-column matrix, or more
simply as a list. For example, let's define the matrix m
1 2
3 4
and multiply it with row and column vectors:
In> m:={{1,2},{3,4}}
Out> {{1,2},{3,4}};
In> a:={{5,6}}
Out> {{5,6}};
In> b:={1,1}
Out> {1,1};
In> m*b
Out> {3,7};
In> a*m
Out> {{23,34}};
In> c:={{2},{2}}
Out> {{2},{2}};
In> m*c
Out> {{6},{14}};
Since a matrix is a list of lists, individual matrix elements are
referred to using double-brackets notation:
In> m[1][2];
Out> 2;
Again since a matrix is a list of lists, you can use the
Length() function to find its number of rows and columns, e.g.:
In> y:={{1,2,3},{4,5,6}};
Out> {{1,2,3},{4,5,6}};
In> Length(y);
Out> 2;
In> Length(y[1]);
Out> 3;
You can solve systems of linear equations using SolveMatrix(). For
example:
n> m:={{1,a},{0,1}}
Out> {{1,a},{0,1}};
In> t:={5,1}
Out> {5,1};
In> SolveMatrix(m,t)
Out> {5-a,1};
(I've put in the `a' here to illustrate the fact that SolveMatrix()
works even with variable elements in the matrix.)
The ZeroMatrix() and ZeroVector()
functions are good for initializing large matrices. The main usefulness
gained through them is dimensioning. Say for instance we wish to create
a 5x5 matrix z. We could start with z = {}, then build it up by using
Append() to add rows and thus establish that it is of
dimension 5x5. But using ZeroMatrix() does this more
more conveniently:
In> z:=ZeroMatrix(5,5);
Out> {{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}};
Yacas is a full-blown programming language, allowing
not only C-style loops, if-then-else, functions and the like, but also
some LISP-like features.
Loops, etc. typically have a body, akin to the group of
statements enclosed in braces after, say, a while
in C. In Yacas a body can be a single statement, or a
series of statements enclosed in brackets. For example:
In> i:=2;
Out> 2;
In> ForEach(j,1 .. 5) i:=i+1;
Out> True;
In> i;
Out> 7;
In> k:=3;
Out> 3;
In> ForEach(j,1 .. 5) [i:=i+1; k:=k+i;]
Out> True;
In> i;
Out> 12;
In> k;
Out> 53;
If a body contains more than two statements, you will typically want
to place them on separate lines for clarity. Do so using the
\ (line-continuation symbol):
In> i:=7;
Out> 7;
In> k:=3;
Out> 3;
In> ForEach(j,1 .. 5) \
In> [i:=i+1; \
In> k:=k+i; \
In> ];
Out> True;
In> i;
Out> 12;
In> k;
Out> 53;
Functions can be defined in a variety of ways, one of which is
Function(function_name,formal_parameter_list) [body]
where function_name is quoted and formal_parameter_list must be
enclosed in braces. For example, here is a function to find the
hypotenuse of a right triangle:
In> Function("hyp",{a,b}) [c:=a^2+b^2; c:=Sqrt(c);];
Out> True;
In> hyp(3,4);
Out> 5;
A function will return the last value computed. In the example
above, the last computation done by the function was
c:=Sqrt(c);
and thus it is this value which the function returns, which is
what we want. In fact,
In> Function("hyp",{a,b}) [Sqrt(a^2+b^2);];
would work too.
Functions can return list values, etc. Here for example is a function
that swaps two numbers, creating a new pair which is the swapped version
of the input:
In> Function("swap",{a,b}) [bb:=a; aa:=b; {aa,bb};];
Out> True;
In> {u,v}:=swap(5,8);
Out> {8,5};
Note by the way that in that example above aa and bb will be global, not local
to swap(). We could make them local by using the function
Local():
Local(aa,bb);
Two of the other major Yacas functions used in
programming constructs are While() and
If(). While() is similar to
ForEach(), but If() requires some
comment. It works in a way similar to
a = u < v ? 0 : 1;
in C. The format for if-then-else is
If(boolean_condition, [if_block], [else_block]);
Here boolean_condition ("predicate," in Yacas terminology) is as in C,
though = is used instead of == for equality, and And
and Or are used.
The following shows what to do in Yacas for what in C would be
if (x < y) {
x = 2;
y = 3;
}
else {
x = 12;
y = 13;
}
In> {x,y}:={15,3};
Out> {15,3};
In> If(x < y, [x:=2; y:=3;], [x:=12; y:=13;]);
Out> 13;
In> {x,y};
Out> {12,13};
In> {x,y}:={1,200};
Out> {1,200};
In> If(x < y, [x:=2; y:=3;], [x:=12; y:=13;]);
Out> 3;
In> {x,y};
Out> {2,3};
Note how we have, for instance in the first line above, used a list
to conveniently set x and y within the same statement (which we could
have done this within the If() too), and also to print
x and y within one statement.
Yacas can also be run in batch mode. Say for instance
we had a file x.ys with contents
i:=5;
Print(i);
Then we could type
yacas -pc x.ys
at the shell command line, with the output being
5
By the way that we did need to call Print() here,
even though in interactive mode we could have simply printed via the
statement
i;
On the other hand, we must not use the \ line-continuation symbol in
batch mode.
Functions, etc. can be stored in library files, and then loaded using
Load() (other functions exist for this too).
Use Print() to print to the console (or current output
device) without a newline character, and Echo() if
you need a newline character. For example:
In> x:=12;
Out> 12
In> Echo(x,1,2,3);
12 1 2 3
Out> True
Some plotting operations are available, in Plot2D()
and Plot3DS().
I will add some example Yacas scripts from time to time in my
Yacas Web directory. Here is what I have so far (sorry, not very
much):
- DiscreteMC.ys. Illustrates
functions; matrices and vectors; ForEach();
Length(); Transpose().
- UseDiscreteMC.ys. Illustrates
use of Load(); ZeroMatrix();
Echo(); Simplify().
- ContinMC.ys. Illustrates
same features as DiscreteMC.ys above.
Nice feature! For example,
In> TexForm(Exp(-t^2));
$\exp \left( - t ^{2}\right) $
Out> True;
Clearly this tutorial has just barely scratched the surface.
Yacas offers much, much more. See the documentation
to learn more.