``Learning Macsyma'' shows you how to type commands into the macsyma interactive algebraic manipulation system.You will learn a number of the basic commands, how to correct simple errors, and enough details for you to understand the kinds of operations which can be done by an algebraic manipulation ystem.macsyma (pronounced ``maxima'') is a large computer program designed for the manipulation of algebraic expressions involving indeterminates, constants, and functions.macsyma can differentiate, integrate, take limits, solve equations, factor polynomials, expand functions in power series, and perform many other operations.You can use a programming language to extend macsyma's capabilities to new domains.``Learning Macsyma'' is divided into twelve short sections.A complete outline of the material they cover follows.In chapter 1 you will learn
O How to type expressions into macsyma
O Some simple commands: expand, diff, ev, substitute
O Defining functions
O Fill this in
1.1 Typing Expressions
The section Getting started explained what to do to get to the first command prompt on your computer.We assume you are now faced with a display something like this:
% macsyma (this is what you typed)
Ésome textÉ
(c1)
Suppose you wanted to work with the expression (x+1)3.You could type it in by using Fortran-style syntax as follows:
(c1) (x+1)**3;
The ``;'' and the (invisible) ``carriage return'' terminates your command, and prompts macsyma to evaluate your expression and display the result.Your command can be several lines long, in which case you can format it any way you wish with extra spaces, tabs, or returns before the ``;''.In this case of command c1 above, and every other command you type in, your expression is simplified and then evaluated.As it happens here, tthese processes the expression unchanged, and macsyma responds with the display below
3
(d1) (x + 1)
(c2)
Note that expressions are normally printed in a two-dimensional format with raised superscripts.This usually makes the expression easier to understand than a linear format, although as you will see in later displays, it sometimes requires some effort.The result is assigned a label d1 which may be used in subsequent commands.You can also use a ``$'' to end a command, in which case the result will be computed but not displayed.An important observation: the system is assigning values to the names c1, d1, etc.You should avoid using these same names for other purposes in your computations.ÑÑÑÑÑÑÑÑÑÑÑÑÑÑNoteÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
If you choose to leave macsyma at this point, or any time a c-line prompt appears, type quit();.If you wish to stop in the midst of a computation and quit in a less orderly fashion, type -z (that's one character), to get back to the UNIX shell, and then type kill % .ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
After the display, macsyma prompts you with the next line label, c2.Çset name=Your Next CommandÈÇset section=2ÈÇinclude chapter-headÈ
One of the many commands available in macsyma is expand, which converts an expression to a mathematically equivalent one, but with certain changes in the form.Most macsyma commands have the form of a ``function'' being applied to some arguments.In this case, the expression labelled d1 above is the single argument to expand.(c2) expand(d1);
3 2
(d2) x + 3 x + 3 x + 1
1.2 Typing Errors
Before getting too involved, you should realize that if you make a mistake in typing, you can delete erroneous characters by using your standard UNIX erase, kill, word-kill, etc.characters.(Typically these are backspace, control-U, control-W, respectively).Some workstations provide various on-screen editing facilities, and these may also be used.macsyma provides one extra facility: If you wish to delete all lines of a multi-line command, type ?? to get a freshly re-displayed line label.If you make a mistake but type the semi-colon and return key before you notice, the system will print a message:
(c2) expand((d1);
expand (( d1) ***$***
syntax error
please rephrase or edit.(c2)
You should probably just retype the expression, if it is short.To use the editor, you would type the escape key and you would then enter the vi editor.This is described in further detail in ``Using Macsyma.''
Since only a small selection of commands will be covered in ``Learning Macsyma,'' you should be aware that additional information is available on almost any command in macsyma on-line.To see a blurb on, for example, the command expand, type
describe(expand);(return)
to the system.For some commands, an example is also available, and can be viewed by typing, for instance,
example(expand);
The on-line documentation may include local commands and other information that has not yet been incorporated into printed material.More Commands
Let us consider a few additional commands and facilities.To compute the derivative of an expression, you use the diff command.Diff(expr,var) differentiates an expression with respect to the variable var.(c3) sin(x)*cos(x);
(d3) cos(x) sin(x)
(c4) diff(%,x);
2 2
(d4) cos (x) - sin (x)
In line c4 we used the special symbol %.This symbol is a shorthand for the previous expression computed, which in this case is labelled d3.To differentiate an expression twice, use diff(expr,var,2).(c5) diff(d3,x,2);
(d5) - 4 cos(x) sin(x)
The concept of differentiation in macsyma is actually a good deal more general than is illustrated by this example.Application of the chain rule is generally supported, and a
large repertoire of built-in functions and operations are provided.1.3 Substitution and Evaluation
There are a number of ways of producing a new expression from an old one.One technique is to evaluate an expression with (temporary) asssociation of values with some of the indeterminates or variables in it.For example, to substitute x2 for every occurrence of z in the expression z exp(z) you could type
(c6) z*exp(z);
z
(d6) z %e
(c7) ev(d6,z=x**2);
2
2 x
(d7) x %e
In macsyma, the base of the natural logarithms is written %e, to distinguish it from a simple variable named e.Ö-1 is written as %i and p is written %pi.An alternative syntax for exactly the same command as the explicit command ev (for evaluation in a context where z = x 2 ) on line c7 is to implicitly invoke the command.(c8) d6,z=x**2;
2
2 x
(d8) x %e
The ev command has more elaborate options and uses.Ev ``evaluates'' the first expression (leftmost argument) in an environment specified by the additional expressions which are either equations as shown above, or built-in ``switches'' which control macsyma.An equivalent command in this particular case, is substitute.You can abbreviate the command as subst:
(c9) subst(x**2,z,d6);
2
2 x
(d9) x %e
Observe that if you substitute a for b in c you write subst(a,b,c);.Note that the commands ev and subst do not change the value of z itself.The next section explains how you can assign values to variables.1.5 Assignment
Although some very sophisticated linguistic facilities are available in macsyma, we will describe only the most basic features here.Assignment is very familiar to programmers, and it is used to associate a ``value'' with a name.macsyma implicitly assigns values to the d-labels we have been using.You can, however, make up your own labels for using single-letter or multiple-letter names.To assign a value to a variable a, used a colon (:) as follows:
(c10) a:%;
2
2 x
(d10) x %e
(c11) a+1;
2
2 x
(d11) x %e + 1
Sometimes users unintentionally re-use a variable such as a above as a symbols or an ``indeterminate'': as though they had no value.Differentiating with respect to x is not very meaningful when x is (say) a number.If you are surprised when such values appear and wish to reuse the same name again, you can refer to the symbol a regardless of any value associated with it, you can use the expression 'a.This is pronounced ``quote a''.To permanently ``unassign'' a value from a, say:
(c12) a:'a;
(d12) a
Now if you ask for the value of a, you get:
(c13) a;
(d13) a
Another command which is sometimes used for the same purpose is kill(a); It also removes other possible information you might have about a, too.1.6 Defining Functions
Function definition in macsyma is a way of storing computational routines to be used repeatedly.Functions in macsyma always return values and can therefore be used in expressions.Sometimes it is convenient to think of functions in macsyma or other programming languages as similar to mathematical functions.Although we can also ask macsyma to compute a number approximating sin(0.5), that is not where it ends.When you use macsyma there is a real possibility that you might really mean a mathematical function rather than merely the ``computing rule associating a number with some input.'' For example, in macsyma you can find solutions to equations involving the sine function (named sin), or you might expect sin in the answer to a differentiation problem, etc.Nevertheless, we will abuse the term function to describe these computational routines.In the jargon of programming language descriptions, these function definiitions associate a name with some number of ``formal parameters'' and a computational rule or expression or ``body''.The value which is produced by ``applying'' the function is basically the result of substituting ``actual parameters'' or values for the formal parameters in the``body''.For example to define a function f (z) which will be, essentially, a short-hand for sin2z + 1 you use the following command.Note the use of ``:=''.(c14) f(z) := sin(z)**2+1;
2
(d14) f(z) := sin (z) + 1
(c15) f(x+1);
2
(d15) sin (x + 1) + 1
It is possible to define functions which use any of the built-in macsyma commands, or use other user-defined functions which may be defined with other function definition commands.macsyma allows you to define self-referential or recursive functions, and allows you to use ``undefined'' functions as well.An undefined function merely returns ``itself'' as its value.macsyma has many more commands than we have illustrated here.Even so, it is unlikely that everything you might want to do has been anticipated, and therefore macsyma provides you with a complete programming language.This may not be a comfort to you if you are totally unfamiliar with programming, but if you want to use macsyma for elaborate processing of mathematical equations or data, you may have to learn some of this.If you have some familiarity with some conventional programming languages, you may be pleasantly surprised by the additional generality afforded by ``symbolic'' computation.Further on in ``Learning Macsyma'' we give some lessons in this language.1.7 Equations, Part, and Solve
Sometimes it is convenient to compute with equations in macsyma .An equation is not the same as an assignment, a function definition, or a test for equality.Some programming languages overuse the symbol ``='' for some of these, but macsyma does not.In macsyma, an equation is just an expression containing two subexpressions separated by an ``=''.Certain simplification and evaluation operations are defined to work in (usually) conventional ways on equations, as illustrated below.Line c16 shows how to type in an equation.(c16) x**2+2*x=y**2;
2 2
(d16) x + 2 x = y
(c17) d16+1;
2 2
(d17) x + 2 x + 1 = y + 1
The left-hand-side of an equation can be selected with the lhs command, or by the more general part command which can be used to pick apart expressions such as sums, products, etc.(c18) lhs(%);
2
(d18) x + 2 x + 1
(c19) part(d17,2);
2
(d19) y + 1
(c20) part(%,1);
2
(d20) y
To save typing, the same result as d20 could have been obtained from part(part (d17,2),1) or even more simply, part(d17,2,1).Equations are used by some commands, such as solve.Solve returns a list of equations, that is, a sequence separated by commas and enclosed in square brackets:
(c21) x**2-1;
2
(d21) x - 1
(c22) solve(%,x);
(d22) [x = - 1, x = 1]
Notice the way the list of the two solutions is displayed.We can substitute the first of the two answers in d21, and evaluate:
(c23) d21,part(%,1);
(d23) 0
1.8 Sums, Programs, Ev Revisited
You can compute the sum of the first five positive integers, squaredby:
(c24) sum(i**2,i,1,5);
(d24) 55
Another way of providing a similar result by writing a small program, is to use a for statement.(c25) for i:1 step 1 thru 5 do s:s+i**2 ;
(d25) done
The result is stored as the value of the variable s.If s had been 0 previously, the current value of s would be 55.Actually,
(c26) s;
(d26) s + 55
This reflects the fact that the value of s initially was just s.You can, of course, substitute 0 for the original value:
(c27) subst(0,'s,%);
(d27) 55
Note that this substitution does not affect the value of s.It just sets d27 to 55.A more mysterious case occurs if you type
(c28) ev(s+55);
(d28) s + 165
explanation: if we had typed merely s+55, it would evaluate to (s+55)+55, or s+110.But ev evaluates ``once more'' to get (s+55)+110.Ev is sometimes a puzzle if you do not separate those symbols that you use for programming purposes and therefore have values, and those symbols you use only for indeterminates.In spite of the previous example, summations are not really the same as the programming languages' ``for loops''.Sometimes summations are merely placeholders for computations which for one reason or another cannot be done.This is an example:
(c29) 'sum(g(i),i,0,n);
n
====
\
(d29) > g(i)
/
====
i = 0
There are three reasons for this summation to be returned ``unsummed''.We have not provided a ``function definition'' for g; the variable n is not some fixed integer value; and finally the ``quote'' symbol or apostrophe (') to the left of the sum on line c29 inhibits evaluation.The effect of the quote is, in most circumstances the prevention of evaluation.Sometimes macsyma can deduce the value of a summation in closed form even though it cannot be evaluated, because of built-in simplification capabilities.Some summations can, for example, be solved by a fairly general procedure analogous to symbolic integration.In macsyma a distinction is sometimes drawn between ``noun'' and ``verb'' forms of commands.Most functions are ``verbs'' in that they will be evaluated ``away'' in an effort to eliminate them from expressions.To prevent such evaluation, the ``quote'' illustrated above can generally be used.Some functions are nouns or verbs depending upon context such as the nature of their arguments.The trigonometric functions are this way, being nouns if they are given integer arguments, but verbs if they are given floating-point arguments, or ev'd with the numer option set:
(c30) sin(1);
(d30) sin(1)
(c31) sin(1),numer;
(d31) 0.8414709848078965
Floating-point numbers are carried to double precision.There is also an implementation of higher (arbitrarily higher!) precision ``bigfloats'' available and described in ``Using Macsyma.''
More Expansion
Let us return to our very first example of a command, and provide some more details and techniques for expansion, or application of the distributive law of multiplication.In some computations where an indeterminate represents a quantity of small magnitude, you might wish to automatically drop higher-degree terms from an expansion.In some cases you might wish to drop terms in several variables, e.g.all terms in q with exponent greater than 7, and terms in p with exponent greater than 4, or terms of pn and qm combined so that their ``weight'' 2n + m exceeds 7.This sequence of commands does that:
(c32) ratwtlvl:7$
(c33) ratweight(q,1,p,2);
(d33) [q, 1, p, 2]
(c34) ratexpand((p+q+1)^8);
7 6 5 5 4 4 2 3 3
(d34) 8 q + 28 q + 168 p q + 56 q + 280 p q + 70 q + 560 p q + 280 p q
3 2 2 2 2 3 2
+ 56 q + 420 p q + 168 p q + 28 q + 280 p q + 168 p q + 56 p q + 8 q
3 2
+ 56 p + 28 p + 8 p + 1
The ``rats'' appearing in the command names here are an indication that the commands use something called ``canonical RATional expression form,'' or CRE form, an efficient data representation used for dealing with polynomials and ratios of polynomials.We have also used ``^'' instead of ``**'' (the two notations are interchangeable in macsyma.) We will return to representation issues shortly.1.9 Integration
One of macsyma 's flashiest features is its ability to compute symbolic indefinite integrals:
(c35) x/(x^3+1);
x
(d35) ------
3
x + 1
(c36) integrate(%,x);
2 x - 1
2 atan(-------)
log(x - x + 1) sqrt(3) log(x + 1)
(d36) --------------- + ------------- - ----------
6 sqrt(3) 3
To check the solution, we can differentiate.(c37) diff(%,x);
2 2 x - 1 1
(d37) ------------------ + -------------- - ---------
2 2 3 (x + 1)
(2 x - 1) 6 (x - x + 1)
3 (---------- + 1)
3
A more satisfactory form would result if the terms were expanded and the sum put over a common denominator.By converting this result to a CRE form (the same form used for the previous RAT commands) the expression is simplified.The ratsimp command does this:
(c38) ratsimp(%);
x
(d38) ------
3
x + 1
2 Representation and Simplification
The acronym stands for Project MAC's SYmbolic MAnipulation System.MAC itself is an acronym, usually cited as meaning Man and Computer or Machine Aided Cognition.The Laboratory for Computer Science at the Massachusetts Institute of Technology was known as Project MAC during the initial development of macsyma .There are more readable (but slower) typesetting display facilities which requires more a elaborate computer terminal than the usual character-display type.
2 Representation and Simplification
The multiplicity of representations illustrated by lines d38 and d37 constitute an important feature of macsyma .It is not always so clear which command will produce the most appealing form of an expression.Ratsimp, which did such a fine job above, would produce a huge expression if applied to (x + 5) sup 100 , since it multiplies through all those terms.The correct choice of representation is often the key to solving challenging problems.The factor command is another way of changing representation, illustrated below.(c39) factor(x^12+1);
4 8 4
(d39) (x + 1) (x - x + 1)
Factor finds exact integral factors, not approximate zeros, and is thus qualitatively different from numerical root-finders.It is generally much slower than numerical routines, but gives a different type of answer, as illustrated above.Numerical zero-finding for polynomials or other functions can be found in an extensive library of routines from the Numerical Algorithms Group (NAG), which has been linked to macsyma in a package called NAGLINK.This is described in reference.(ref) If your system does not have NAGlink , but has another numerical library program for zero-finding, it can probably be connected to macsyma.Details on linking macsyma to such libraries is described in (ref: section ?).Factor and integrate are probably two of the more surprising commands in macsyma because most people who understand the problems involved are not familiar with general algorithms for solving them.There are general algorithms for these problems, although the algorithm for integration sometimes indicates that the answer does not exist in terms of elementary functions.When a general solution to a problem is not available, or even when it is known but inefficient, it is sometimes possible to simulate a good solution method by ``pattern recognition'': that is, by recognizing those cases that can be solved, and providing the answers, without dealing with the complete problem.Many user programs, and a few built-in macsyma facilities use this approach.Factor, and indeed many of the commands illustrated above, are used internally by macsyma for its own more complicated algorithms.For example, solve uses factor and other routines on polynomial problems.2 Limitations
You should realize that an algebraic manipulation system like macsyma cannot solve all symbolic problems.There are times when solve or integrate or other commands will determine that there are no closed-form solutions to the problem posed (in which case they will generally inform you of the situation).There are other instances in which the solution method may be known in principal, but because the calculations are so onerous, the computer seems unlikely to finish in a reasonable time.Algebraic computations are often subject to ``intermediate expression swell'' where (even though the final answer may be small -- perhaps 0), the route to the answer is difficult.Occasionally you may run out of memory space.A clever computer system administrator may change the program and operating system parameters to your benefit, but it is more likely that you should try to rearrange your computations.Just because it is possible to type a command in a syntactically satisfactory manner does not mean that the required computation is easy or even feasible.Once a computation has started, you may have second thoughts about allowing it to finish.Hence you might be concerned with the information in the next section:
2 Stopping
You may, from time to time, get your system running on a fool's errand.How do
you bring it to its senses?
There are several related notions of running uncontrollably.If the output is streaming past you
at too high a speed to read, (this is unlikely to happen on a slow
printing terminal, but might happen on a display terminal) you
can make the system pause by typing -S (that's done by holding
the control key down and typing S.We usually write this as ^S),
which is the default
``X-off'' character.Normally, no output gets lost, but transmission is
temporarily
halted.You can resume the display by typing -Q (or ``X-on'').Sometimes you want to halt computation, not just
printing.You have an interrupt character,
usually or ^C,
which you have chosen as your standard in your UNIX operating system shell.If you wish to halt a computation,
you can type this interrupt character one, two, or three times.The first character will cause an interrupt at the next available clean place in your computation.(Technically, this would be at the interface between some compiled and some interpreted code).If the interrupt does not happen promptly enough for you, you may type the interrupt character a second time.(Technically speaking, this will snap ``transfer links'' which are used when compiled code calls compiled code, and then cause an interrupt at the next such function-call.) It is possible to be caught in a very tight loop in which there are no function calls, in which case the third typing of the interrupt character will stop the computation cold.Even using this drastic interrupt, you will generally be able to avail yourself of any of several alternatives.When the system stops, it will type
Interrupt (type h for help):
You can then type one of several characters:
q Just quit out of the interrupt and continue the computation (after displaying the time if showtime was set to true or all.);
r Reset the computation to the top-level of macsyma ,
exit Exit from macsyma ,
l Enter a LISP break, (something a LISP expert might want to do: LISP, an acronym for LISt Processing Language, is the computer language
in which
macsyma
is implemented.),
m
Enter a
macsyma -break.This gives you a kind of
macsyma -subprocess
within your running program, which you can use to inquire about variables,
resetting things, etc.You exit by typing exit; which returns you
to your previous computation.h
Type a menu of options.Basically what you see above.It is also possible to quit temporarily out of your job by typing ^Z.See your UNIX manual for details on job control, background jobs, and
similar issues.Some people, in desperation, hang up their telephone.This might work, assuming you are connected to the computer that way.Turning the
power off on a hard-wired terminal usually does not work.2 Out of Core?
In the 4BSD UNIX system, the message 'killed' or 'out of core' immediately
after the starting of a vaxima means that there is currently insufficient free space on
the swapping device to run
macsyma .This can happen with any job, but is perhaps more likely to happen
with
macsyma
because of its size.This situation is
system-load dependent and swap-space dependent: when the load decreases, try again.2 Quitting
If you wish to exit from
macsyma ,
in an orderly fashion, removing the quiescent job,
returning control to the shell (or whatever invoked
macsyma ),
you can do this by typing the command exit();
2 Storage Allocation and Timing
If you run
macsyma
for long enough, and especially if you set up a
long computation, you will see strange messages like the
two below:
[*list:634{22%}; fixnum:43{2%}; ut:0%]
[*list:634{23%}; fixnum:43{2%}; ut:69%]
This is caused by a phenomenon known as a ``garbage collection''
(really) which is part of the underlying LISP language system.This is an activity started up when the computation needs more
free storage.The system then stops doing ``useful'' work, and identifies
objects in memory which are no longer needed.This takes a few
seconds of computer time (maybe 2),
which under heavy load may take a half-minute of real time.A message occurs after each garbage collection.You cannot really stop
the garbage collector,
but you can stop
the message from printing out by setting gcprint : false .You may think you don't want to see this information, but it is actually
reassuring to know that your program is running sometimes, even
though it is printing nothing but ``gc'' messages.Programs which may have run out of storage on other version of
macsyma
may run successfully on the VAX.However, the address space
available to a user is in practice restricted by operating
system constraints, some of which have been incorporated as
parameters in the LISP system.An error message which declares
``Attempt to allocate beyond static structures'' indicates that
you will have to have a reconfigured LISP system to grow larger.You should save
your computation and ask your system administration or
manager to make a larger LISP system and
macsyma .This
takes about 3 or 4 minutes of computation, but requires
familiarity with the instructions for generating a system.Since the current allocation is
really fairly large, you should also take this opportunity
to see if you really want to continue with the computation.Large
jobs in most time-sharing systems,
tend to be more burdensome than small ones, even those running for longer
periods of time.It is possible to fiddle with various allocations to attempt to
decrease the number of garbage collections in a system which you
suspect will require large amounts of a particular kind of
space.The command
alloc(,) allocates
some number of pages.Spacetypes include list, bignum, fixnum, flonum, array and
a few others.Most
macsyma
computations use
list
cells predominantly.See the Franz LISP manual for more details.The message ``[fasl hole filled up]'' which you may provoke by using
the fasl or load program, is merely informative, and is not an indication
of trouble.If the
macsyma
variable
gcprint
is set to a non-false value then
after each garbage collection a summary of current memory allocation
will be printed out in this form: [*list:634{87%}; fixnum:23{27%}; ut:87%].The meaning of this is that after garbage collection and subsequent
allocation of new data space, there are 634 (512 byte) pages of list data and
23 pages of fixnum data.87% of the list space is used and 27% of the fixnum
space is used.The * before list indicates that it was list space which ran
out and caused the garbage collection.The ut indicates the percentage
of time utilized in non-garbage collection mode.The first time the
message is printed, this item will be 0% because
various counters must be initialized.The allocation of storage is
automatic; you will never be asked to make a decision about which data
space to allocate, although a low utilization measure is an indication
that automatic allocation is not working appropriately for your problem,
and various parameters can be fiddled with via alloc.You
can also get brief information about the time taken by each command
by setting showtime : all.The ``garbage collection'' or ``gc'' time is indicated separately,
because it happens asynchronously and it seems unfair to penalize a
particular (perhaps millisecond) operation for the fact that it
was the unlucky one to trigger a ``gc''.Intermission.Take a break.In the next two sections
of the primer we introduce a number of facilities in
macsyma
useful in dealing with trigonometric functions.A section on rule-directed
transformations follows, since our favorite examples are
trigonometry simplifications.2 Operations with Trigonometric Forms
Consider the expression cos sup 2 x - sin sup 2 x .(c40) cos(x)^2-sin(x)^2;
2 2
(d40) cos (x) - sin (x)
To evaluate the last expression at a point, say
pi / 3 , you can use the ev command:
(c41)ev(%,x=%pi/3)
1
(d41) - -
2
The value of 1 / 2 was obtained not by computing pi / 3
numerically and approximating the value of sin at that point, but
by a routine which provides simplification of special values of
trigonometric functions at points n pi / m , where
m = 1,2,3,4,6 and n is an integer.To obtain a
real approximation, we could use numer,
as illustrated previously.Of course
macsyma
is able to differentiate expressions
involving trigonometric functions, also as illustrated previously.(c42) diff(d40,x);
(d42) - 4 cos(x) sin(x)
and knows how to integrate them.(c43) integrate(d40,x);
sin(2 x) sin(2 x)
-------- + x x - --------
2 2
(d43) ------------ - ------------
2 2
This result is less than satisfactory.See what we can do:
(c44) expand(%);
sin(2 x)
(d44) --------
2
2 Trigonometric Re-representations and Identities
There are a number of identity transformations specifically oriented
to trigonometric forms.Whether these produce simpler or more
complex expressions depends on the expressions they are used upon,
and sometimes is a matter of opinion.macsyma
can convert trigonometric functions with
argument nx, n an integer, to trigonometric functions in x.You use trigexpand
for this transformation:
(c45) trigexpand(%);
(d45) cos(x) sin(x)
Another operation named
trigreduce
performs a related, almost ``inverse'' transformation,
that of converting products of
powers of trigonometric functions to functions with multiple
angles.(c46) trigreduce(%);
sin(2 x)
(d46) --------
2
Sometimes you wish to convert all trigonometric
functions to exponentials with complex arguments.With the
flag
exponentialize set to true you can perform
this transformation:
(c47) exponentialize:true$
(c48) sin(x);
%i x - %i x
%i (%e - %e )
(d48) - ----------------------
2
In order to convert back to trigonometric functions you can use
realpart.First we must turn off the exponentialize flag.(c49) exponentialize:false$
(c50) realpart(d48);
(d50) sin(x)
Exponentials with complex arguments of the form
n i pi / m , ~~~m = 1,2,3,4,6, n an integer, will be transformed
to algebraic numbers if the flag %emode is set to
true.(c51) %emode:true$
(c52) d50,x=%pi;
(d52) 0
Before continuing, let's reset that flag.(c53) %emode:false$
A very powerful technique for approximation of analytic functions
is the use of
truncated Taylor series (more generally, Laurent
series).macsyma
provides a command for the computation of these approximations, as
illustrated below:
(c54) taylor(sin(x)/x,x,0,4);
2 4
x x
(d54)/t/ 1 - -- + --- + ...6 120
This is a Taylor series in x about
x=0 up to the 4th power.Observe that the display
has
some unusual features: the terms are ordered in reverse of
the conventional (non-series) display, there is a /t/ mark near the
label, and the ellipsis (...) is printed to the right to indicate
truncation of other terms.Taylor series are a separate representation of expressions in
macsyma .Recall that we have
encountered the ``rational'' representation
used internally by commands like ratsimp, factor, and sometimes in
integrate.This form can also be directly provided in answers from
some commands.All along we have been seeing
a ``usual'' or ``general'' representation in our interactions.Thus we have already seen evidence of three representations.Many of
macsyma 's
most powerful commands for simplification
are essentially switching between representations.There are a few more representations in the system directly
accessible by the user such as
``Poisson'' series, used in celestial mechanics; there are a
number of additional alternative representations used, but
away from the user's sight.2 Rules
It is handy to have a facility
for applying identities or side relations.The prototypical one is
sin sup 2 x ~+~ cos sup 2 x ~ -> ~ 1 .There are a number of ways of
achieving the effect of such a rule.The simplest is
substitution.Let us recall expression d40.(c55) d40;
2 2
(d55) cos (x) - sin (x)
(c56) %,sin(x)^2=1-cos(x)^2;
2
(d56) 2 cos (x) - 1
The same effect could have been achieved by using
substitute(1-cos(x)^2,sin(x)^2,%).To continue with the same prototypical rule,
often one wishes to recognize that sin sup 4 x can be
transformed using the same rule.For this one needs the
added power of
ratsubst.(c57) ratsubst(1-cos(x)^2,sin(x)^2,sin(x)^4);
4 2
(d57) cos (x) - 2 cos (x) + 1
In general ratsubst will perform a ratsimp
(and thus an expansion) as well as apply the substitution.When performing calculations repeatedly, you may wish
to apply a substitution rule whenever possible.You can have an
``automatic'' facility, although not the full power of a
ratsubst command by using a tellsimp rule.(c58) tellsimp(sin(x)^2,1-cos(x)^2)$
(c59) (sin(x)+1)^2;
2
(d59) (sin(x) + 1)
(c60) expand(%);
2
(d60) 2 sin(x) - cos (x) + 2
(c61) sin(x)^2;
2
(c61) 1 - cos (x)
You can ``tell the simplifier''
a more general rule which will convert sin sup 2 a to
1 - cos sup 2 a for any a using a
declaration:
(c62) matchdeclare(a,true)$
(c63) tellsimp(sin(a)^2,1-cos(a)^2)$
(c64) sin(y)^2;
2
(d64) 1 - cos (y)
You should understand that the existence of such
rules generally slows down the simplification of expressions with the same
``main operator'' as the
tellsimp
rules.In this
case the main operator is ``^''.Another rule-defining mechanism,
let
has much of the power
of a
ratsubst,
although it will be applied only when using
letsimp.First let us remove the
tellsimp
rule.(c65) kill(rules)$
(c66) let(sin(a)^2,1-cos(a)^2);
2 2
(d66) (sin (a) --> 1 - cos (a))
Note that a is still declared
true
for matching
purposes.To effect a transformation using the
let rules, whatever their number, you use the letsimp
command.(c67) sin(x)^4;
4
(d67) sin (x)
(c68) letsimp(%);
4 2
(d68) cos (x) - 2 cos (x) + 1
We have not exhausted
macsyma
facilities for
dealing with trigonometric functions, or for that matter, its
facilities for defining and applying rules.Poisson series, mentioned earlier, deals with a special class of
trigonometric expressions frequently used in celestial
mechanics have a special representation.A program called
trigsimp
may provide appropriate simplifications in a goal-driven fashion
(to make the smallest expression).Other ways of defining rules and ``advising'' the simplifier are described
in the
macsyma
manual.Introduction to MACSYMA\'s Programming Language 2
2 Introduction 2 1
This second chapter of the primer on
macsyma
is intended for readers who are familiar with the basic ideas of
algebraic manipulation from chapter 1,
who know at least one programming language, and who wish to use
macsyma
for more ambitious tasks than can be handled in a few sequential
commands.If you are familiar with Pascal or Algol 60, you will probably
find this adequate as a programming background.Familiarity with Fortran
or Basic is less useful.macsyma 's
user-programming language\**
\** The system-programming language used for implementing
macsyma ,
namely LISP, is quite different.If you wish to see how
macsyma
was constructed, you need to know LISP to understand the source code.is designed to allow you
to define program modules or ``functions'' for algebraic manipulation.Each module uses zero or more arguments, and returns an
algebraic expression.Since numbers are special cases
of algebraic expressions,
macsyma 's
user-language
can be used as a numeric language too.Because the language
is implemented as an interpreter it is usually
more general than compiler-based languages, and also
tends to be rather slow in tight inner loops of simple operations,
by comparison.It has novel linguistic features, some of which are illustrated below.2 Some Examples
f1
and
f2
defined below, are versions of the ``factorial'' function.Observe the punctuation
carefully.Assignment is ``:'', function definition is ``:='', statements
are separated from one another by ``,'' [not
terminated
by commas].The label ``loop'' is set off by a comma as though it
were a statement too.We have added indentation to make the programs
conform to what you might expect, but extra spaces and tabs are optional.There is a conditional execution statement (the if) which has
an optional else clause.(c1) f1(x):=if x<1 then 1 else x*f1(x-1)$
(c2) f1(5);
(d2) 120
(c3) f2(x) := block ([temp],
temp:1,
while n > 1 do (
temp:n*temp,
n:n-1), /*end while*/
temp)$
(c4) f2(5);
(d4) 120
Observe the simplicity of using
macsyma
compared to, say, Pascal.There is no
need to write a ``driver'' or main program
with input or output commands.The input is provide through
function application on an argument, and the output is the displayed value.Every command or function in
macsyma
has a value, and may, in addition, have some side-effects, such as the
setting of variables, or the printing of messages.The block construction illustrated above
is analogous to a procedure declaration.The first part of it is a list of local variables, and following
that, expressions which are evaluated in order.Certain expressions or commands make sense only within a block, not
at
macsyma 's command level:
these are labels, returns and gos.The semantics of each
of these
commands conforms to the usual intuitive meaning.If the last statement
in a block does not cause a transfer of control, and ``execution
falls through the bottom'', the value returned from the
block
is the value of the last expression evaluated.2 Unconventional Conditionals
The next example shows a function with a side-effect, but the major
point is to illustrate some subtleties which you may not have thought
about in
conditional statements (if-then-else).If you were asked, ``Is A greater than B'', it would seem you could respond
either ``yes'' or ``no''.In your conventional programming language, certainly,
that would be a reasonable assumption.But really, wouldn't it
be appropriate in some circumstances for you to answer, ``How should I know?''?
That option is preserved in
macsyma .If the flag prederror is set to true, the default, and if
macsyma
is unable to evaluate a predicate, it signals an error, and unless
directed otherwise, returns control to the top-level
macsyma
command monitor.However, if the prederror flag is false, execution continues
to the next statement, ignoring both
then and else clauses!
This is illustrated below:
(c5) test(x,y):=block([],
if x > y then print(x, '' is greater than '', y)
else print(x, '' is not greater than'', y),
return(alldone))$
(c6) test(4,3);
4 is greater than 3
(d6) alldone
(c7) test(3,4);
3 is not greater than 4
(d7) alldone
(c8) test(y^2+1,-y);
2
MACSYMA was unable to evaluate the predicate: y + 1 > - y
(c9) prederror:false$
(c10) test(y^2+1,-y);
(d10) alldone
Note that no message was printed for line
d10,
but the return value, ``alldone''
was displayed.2 Assumptions
What do YOU think? Is y sup 2 + 1 ~>~ - y? For this question to make sense,
both sides of the inequality must be in the same ordered domain.We
do not know, offhand, whether y can assume values which are matrices,
complex numbers, sets, or even programs!
If y were known to be real, or more specifically, positive real, a program
could try some deduction.macsyma
has some features of this nature, as illustrated below.(c11) assume(y>0);
(d11) [y > 0]
(c12) test(y^2+1,-y);
2
y + 1 is greater than - y
(d12) alldone
If we wish
macsyma
to forget that assumption,
(c13) forget(y>0);
(d13) [y > 0]
2 Arbitrary Numbers of Parameters
Ambitious packages of programs have been written by many
macsyma
users.Sometimes the requirement that a command has a fixed number of arguments
causes discomfort.\**
\** The language Pascal does not allow you to define
a function f which can
be used with a variable number of actual parameters, although
the Pascal design includes built-in procedures with variable numbers of
arguments (write for example).It is possible to write a
macsyma
program which counts the
number of arguments it is given, sets default values for others, and
does any number of clever things.A simple example is shown below.Note
the way the ``left-hand-side'' of the ``:='' is set up.(c14) prog3([l]) := block( [],
print (''l is bound to'', l, '' and l[1] is '',l[1]),
return(length(l)))$
(c15) prog3(a,b,c,d);
l is bound to [a, b, c, d] and l[1] is a
(d15) 4
(c16) prog3(a,b);
l is bound to [a, b] and l[1] is a
(d16) 2
2 Arrays
Arrays are a useful data structure, and are provided in most
programming languages.macsyma
provides arrays, but does not require that they be declared, or that
they have numeric (integer) index-sets.Rather than writing a program to fill up an array and then iterating
through all elements, sometimes it is easier to describe a program
to generate elements as they are called for.Such array-associated
functions are often quite convenient.The usual
way you set them up is to provide specific values for certain
index values, and then let others be assigned as needed.Note carefully
the use of ``:='' and ``:''.(c17) a[4]:4*u;
(d17) 4 u
(c18) a[22/7]:%pi;
(d18) %pi
(c19) a[x]:mystery;
(d19) mystery
(c20) a[h]:=cos(h);
(d20) a := cos(h)
h
(c21) a[3];
(d21) cos(3)
(c22) a[x+1];
(d22) cos(x + 1)
You might wonder what the value of a is, after all this.Most
disappointing:
(c23) a;
(d23) a
The information that you are after is available this way:
(c24) arrayinfo(a);
22
(d24) [hashed, 1, [3], [--], [4], [x], [x + 1]]
7
The list of information supplied indicates several aspects
of the array.It is
``hashed'': uses the data-structure of a hash-table for storage
(this is a common encoding trick discussed in data structure texts).The number of subscripts is 1.The specific indexes for which it has
recorded values are listed.The array-associated function defined
on line
c20
can be displayed
by dispfun.2 Iteration
``For'' loops provide the major iteration facility in
macsyma .Three examples which illustrate variants of this are the factorial
functions below:
(c25) f3(n) := block([temp],
temp:1,
for i:1 thru n do temp : temp*i,
return(temp))$
(c26) f4(n) := block([temp],
temp:1,
for i:n step -1 thru 1 do temp : temp*i,
return(temp))$
(c27) f5(n) := block([temp],
temp:1,
for i:n unless i <= 1 do (temp : temp*i , i:i-2),
return(temp))$
Decrementing i by 2 in the previous program was needed because the default
step size of 1 is added to i each time through.F5 is certainly
a perverse program.Incidentally, returns from within a for exit from the loop, and not from
the enclosing
block.It is important to
note that one can group a collection of statement to be ``done'' together
with parentheses, as illustrated in
f5.2 Serious Business
Most serious users of
macsyma
find that they are repeatedly using the same programs, and need to
save them for another day.Some users also find they rarely get
the programs or the data quite right the first time, and would rather
type these things in to a text editor, and have
macsyma
gobble the text up from a file rather than the keyboard.Publication quality programs require comments and other features you
are unlikely to want to type into
macsyma
interactively.Some people perfect a function or get an algebraic
expression correct by typing definitions and commands into a file,
say, newstuff, using an editor such as ed, ex, vi, or emacs
and then within
macsyma
type batch(newstuff);.If your file-name has funny characters
like periods or slashes, you must use quotes.For example, batch("/usr/mac/demo.begin").macsyma
then reads the statements the file, assigning labels etc., and if there are syntax
or other errors, prompts for help from the keyboard.If you want it
to continue on to the next line after an error, type batcon(true); .Reading very large text files of programs and data can be slow using
batch, and if
you are not changing the text, you might prefer saving your environment
in another way.You can use save(savedstuff,all); to save every named or labelled
object in a
macsyma
system, on the file
savedstuff
in your working directory.(You had
better have write-permission or you'll get an error message.) Another
time you can start up from where you left off by typing
loadfile(savedstuff);
into a fresh
macsyma .You can load several saved files into a single system.Naturally if the
files contain items with identical names, there is a potential for
conflict.These will be resolved in favor of the last item read in.If you want to save only some material you have produced, say only the
functions defined and the values of variables x, y, and z, you can type
save(savfunxyz,functions,x,y,z);
A neat way to save a useful section of your environment is
to (carefully) use kill to remove useless
items first, and
then save all that is left.Doing kill(labels,...)
after first making sure that any useful result also has a name
other than a c or d-label is sometimes a good start.You generally
should not save every computation, since disk space is not
infinite.2 Hardcopy
If you print out the files produced by save to show to your
colleagues who are as yet unconvinced of the merits of
macsyma ,
you will be disappointed.While such files are ``ASCII'' character
text, they do not make easy reading for persons uninitiated in various
arcane matters.What you might want to do, then, is store human-readable versions of
your output on a file.This is especially useful if you have a
display terminal, or a slow hardcopy printer.macsyma
provides a way of opening a file for echoing both input and output of
the system.The command
writefile(fn);
where fn is a filename, starts the echoing, and
closefile();
stops the echoing.If you want the output to be human-readable after being run through
a typesetting program (eqn + troff in UNIX), you can experiment with
the output produced by setting typeset : true .(Suggestion: gcprint : false is a good idea.)
2 Return to Arrays and Functions
macsyma
provides a fascinating trick: arrays of functions.Imagine an array, each
of whose elements is a function.For example, Legendre polynomials have
an index, and an argument.Thus we can refer to P sub 4 ( z sup 2 ).Just as arrays can
have an associated function, function-arrays can have such an associated
function.Because we like to show off occasionally, and typesetting
can be done by the VAX
macsyma
system, we illustrate
this feature here.This was produced by saving output in a file
and running it through ``troff'' ( T\dE\uX may be an alternative
at some time).(c28) p[n](x):=ratsimp(1/(2^n*n!)*diff((x^2-1)^n,x,n));
I (d28)
p sub n [ x ] ~:=~ "ratsimp" ( 1 over { 2 sup n \^ n !
} \^ { d sup n } over { d x sup n } ( x sup 2 ^-^ 1
) sup n )
(c29) p[4];
I (d29)
lambda ( [ x ] , { "35" \^ x sup 4 ^-^ "30" \^ x sup 2
^+^ 3 } over 8 )
(c30) p[4](y+1);
I (d30)
{ "35" \^ ( y ^+^ 1 ) sup 4 ^-^ "30" \^ ( y ^+^ 1 ) sup
2 ^+^ 3 } over 8
The ``lambda'' (lambda) notation for a raw function of one
variable appears on line c29.This notation comes from the ``lambda-calculus''
used to describe the programming language LISP, and illustrates the fact
that
macsyma
can talk about such structures.You can generally ignore this fact, however.2 More Useful Examples
As has been indicated earlier, procedures in
macsyma
can be used for almost any classical
programming purposes (e.g.numerical techniques, combinatorial search).We have already indicated some differences from a purely numerical
language, such as FORTRAN.We have seen that in
macsyma
there are no required
type declarations, and floating-point numbers, while ``contagious''
in the sense that mixed-mode (floating-point + integer) is converted
to floating-point, do not
necessarily arise from certain calculations.For example,
sin(3) normally results in
sin(3)
in
macsyma ,
rather than its floating-point equivalent.sin(3.0)
will, however, return a floating-point number.The numerical subroutine below, a Newton's method zero-finder
sets the flag
numer to true to force
macsyma
to convert most expressions free of indeterminates
to numbers.This program uses Newton's method to
find a zero of the expression exp
which depends on the variable
var.The iteration starts with var=x0
and terminates when the expression, evaluated at the trial-point,
has absolute value less than
eps.The derivative of
exp
is computed algebraically, and its value is computed at various
points as the search is being conducted:
0
(c1) newton(exp,var,x0,eps):= /* 1 */
block([xn,s,numer], /* 2 */
numer:true, /* 3 */
s:diff(exp,var), /* 4 */
xn:x0, /* 5 */
while abs(subst(xn,var,exp))> eps do
xn:xn-subst(xn,var,exp)/subst(xn,var,s),
return(xn) ) /* 8 */$
This procedure for Newton's method uses an explicit expression
for the first argument
exp
(e.g.sin(x)*erf(2*x)-%e^x
).It is not a function name, e.g.f
as we used before.The use of such an expression is straightforward and
probably the best way for a beginner.The resulting program is
somewhat verbose, because, as illustrated in lines 6 and 7 above,
it is necessary to substitute values for variables in the expression
and its derivative, s,
to get numbers.Note the setting
of numer
on line 3 to assure that the if statement on line
6 would get numerical values for its test.The rest of the procedure
is the classical Newton iteration.The advantage of this procedure
over a purely numerical one is that it takes advantage
of the ability to compute the derivative
of exp algebraically and automatically, once, before evaluating it at any
point.Another item to observe here is the use of comments in the text of
programs which are
batched in to the system./* This is a comment */ .There are often many different ways of expressing the same computation,
and some of them may be substantially more convenient or efficient
than others.While it may not make much of a difference in
efficiency in this case, the following revision of the
newton
procedure illustrates some techniques you may find useful
in
macsyma .0
(c2) newton(exp,var,x0,eps):= /* 1 */
block([ xn:x0, s:diff(exp,var), numer:true], /* 2 */
define(f(var), exp), /* 3 */
define(fprime(var),s), /* 4 */
loop, if abs(f(xn)) < eps then return(xn), /* 5 */
xn: xn - f(xn)/fprime(xn), /* 6 */
go (loop) ) /* 7 */ $
Observe the list of local names at the beginning of the
block,
which are initialized at the same time they are declared on line 2.Lines 3 and 4 are interesting because they define two new functions,
f
and
fprime
each to have as their bodies, the values of
exp
and s.The Newton iteration is more easily observed in functional
rather than ``substitution'' notation.An even smaller version of newton could be defined by
using a single function for exp/diff(exp,var).Let us try this last function:
(c3) h:expand((x-1)*(x-3)*(x-5));
3 2
(d3) x - 9 x + 23 x - 15
(c4) newton(h,x,3.5,1.0e-10);
(d4) 2.999999999994027
You might wonder how many iterations that took.One way is to use
the very convenient debugging feature provided by
macsyma
which allows you to watch the assignment of values to variables.You set the variable
setcheck to a list of the variables you wish to watch.(or
all
to watch all the variables.)
(c5) setcheck:[xn]$
(c6) newton(h,x,3.5,1.0e-10);
xn set to 3.5
xn set to 2.923076923076923
xn set to 3.000228597554006
[*flonum:20{5%}; list:634{17%}; fixnum:43{2%}; ut:0%]
xn set to 2.999999999994027
(d6) 2.999999999994027
(That message ``[*flonum: ...]'' is a message from the
garbage collector, mentioned in the first section of the primer.)
That tells us that only three iterations were needed in this case.We claimed that two functions were defined in running this
program.To display a function using the same syntax that
you would use to type it in, you use the grind\** command.\** When computers were
slow and programs were large, reformatting programs
took a long time.The name of a program at MIT
to ``grind out'' LISP function definitions was grindef.The name
was carried over to
macsyma .Now, most LISP systems call this reformatting ``prettyprinting''.(c7) grind(fprime);
fprime(x):=3*x^2-18*x+23$
(d7) done
2 Part Hacking
An important tool for applications programs in
macsyma
the ability to extract and test parts of expressions.These are
used for the
definition or extension of algorithms which do
various conditional manipulation of formulas.For example, you can write
a symbolic differentiation algorithm for expressions
by applying the rules below:
I (1)
d over dx~ x ~=~ 1 ~~~~~~~d over dx~ y ~=~ 0 ~~(y != x)
I (2)
d over dx~ ( u + v) ~=~ d over dx~ u ~+~ d over dx~ v
I (3)
d over dx~ ( u cdot v) ~=~ v d over dx~ u ~+~ u d over dx~ v
The technique we shall consider for implementing a version of the
differentiation program is to take the expression apart using the
part
command, and use the rules above to guide the manipulation.First, we check to see if the expression is an
atom (e.g.number, variable).Thus we begin our differentiation program as follows:
0
newdiff(expr,var):=
if atom(expr)=true then
(if expr=var then 1
else 0)
This fragment implements both parts of
rule 1.If the
if
statement falls through to the
else
clause,
then we have a composite expression.We then check what its leading
operator is by selecting its zeroth ``part'' via
part(expr,0).Based on its value we apply the appropriate rule.else if part(expr,0)=''+'' then
newdiff(part(expr,1),var)
+ newdiff(part(expr,2),var)
else if part(expr,0)=''*'' then
part(expr,2)*newdiff(part(expr,1),var)
+ part(expr,1)*newdiff(part(expr,2),var)
else 'newdiff(expr,var)$
Note the last clause which returns a 'newdiff form, that is, quoted,
as a result when
the program doesn't know how to handle the leading operator.With some thought, you
should now be able to extend newdiff to accommodate expressions including
sin
and
cos
as well as
sums and products with more than two terms.(The
macsyma
language does not at the moment have a
case
statement, which would make this particular program look better.)
2 User Representation of Data
There is no ``record'' or ``structure'' data-type ``constructor'' in
macsyma ,
but there is a way of doing something similar.If you have used a
language like Pascal which has such a feature, you may appreciate
its usefulness.Modern dialects of LISP use such structures, but when
macsyma
was first designed and initially implemented (in 1967), this was not
in widespread use.It also influenced the user-level programming language.It
is natural to have to deal with collections of information in writing
programs.For example, you might wish to provide as input or output
data, a pair of expressions representing a lower and an upper bound on
a formula.One way of handling this is by making up a new ``function''
name, say bounds and using it as though it were a record designator or
constructor,
but never associating it with an algorithm.Thus bounds(1,x) could
be an expression representing the ordered pair <1,x>.Another example would be the use of integer_vector(1,3,5,7)
to designate a sequence (presumably of arbitrary length, in general),
of integers.There is a built-in form in
macsyma ,
namely a ``list'', which can be used to deal with such collections.It is part of the LISP heritage indicated earlier that there was initially
only one type of structure: lists of any length or element type in
macsyma .A list, when printed, looks like square-brackets
enclosing a sequence of items.Thus you could express the bounds above
as [1,x].However, if you used lists for all collections, you
would not know, on the face of it, whether [1,2] was an instance of
bounds
or
integer_vector.macsyma
allows you to designate functions you intend to treat as lists, although
you can use a different ``header'' like
bounds
with each different type.macsyma
makes available certain built-in
functions which can then be used on such list-like constructions
such as integer_vector.These are declared by, for example,
declare(integer_vector,list).The built-in operations include
cons, append, member, endcons, map, rest.list2:cons(element,list1)
returns a (new)
list2
which has the given
element inserted at the beginning of
list1;
List1 and list2
have a common ``shared'' tail.list3:append(list1,list2)
returns a (new)
list3 which is a
combination of the two lists, sharing a common tail with list2.Member(element,list)
returns true or false depending on a test
for membership.Endcons(element,list)
returns an (unshared) list where the given element has been
attached to the end of
given list
Map(fn,list)
returns a new list where each element
has had the function fn applied to it in turn.Rest(list,n)
returns the part of the list beginning n items from
the front.These functions are parts of the fundamental repertoire of
the programming language LISP.The use of list-like objects should be considered whenever you are
dealing with a collection of elements: a set of coordinates, a series
of coefficients, a system of equations, a set of solutions, etc.Independent of the ``whole list'' operations above,
macsyma
has some selection and alteration operations which are available on
the same collections of data by the use of a numeric index.If you wish to use these indexing facilities, as we will illustrate for the
notion of
complex below, you declare(complex,list).Then, if you define a complex
number by x:complex(3,4) meaning that
x has real part 3, and imaginary
part 4, the notation x[1]:10;
is supported, and changes the value of
x
to
complex(10,4).The declaration explains to the
macsyma
system that the data structure for
complex
will be implemented (in effect) as a list of items, and should be decomposable
using the semantics of the
macsyma
list-handling commands.In fact, both selection and alteration is supported, and if you set the
notation up by
(real:1,imag:2)$
you can use the following command:
x[imag]:-x[imag]
to change
x
to its complex conjugate.An important caution must be observed.When
macsyma
deals with compound structures, they are usually not recopied, and if
there are two names for the same object and the object is changed, then
both names refer to the changed object.If
x
and
y
refer to the same
complex
number, then changes to
x[real]
are also made to the corresponding component of
y.If these items are to be kept separate,
x:copylist(y);
will give
x
a different representation, but whose value is the same as
y's.You can then change their components separately.macsyma 's
built-in lists mentioned earlier, which use square-brackets,
can be altered and selected by indexing.There are two other compound structures in
macsyma
which we mention here, which may be useful for
collections of data: arrays and matrices.The matrix form is useful for two-dimensional rectangular tables of
data.The matrix data format is supported by a number of special
commands oriented toward the conventional interpretation of
matrices in mathematics: inverses, determinants, etc.Matrices can be used for other kinds of data, but you should be
cautious about using them in a manner that is too far distant from
the conventional: arithmetic operations in
macsyma ,
in particular, have already been defined.Arrays are unusual in their flexibility in
macsyma .They are usually treated as global tables, although they can be
declared to be
local
to a function; they cannot
be passed around as parameters
as is the case with matrices.The
names of arrays may be passed from program to program, but the data
itself is not recopied, nor is it convenient to even make a copy
of the data into another array.``Hashed'' arrays are particularly
ingenious, and have been illustrated earlier.Functions can be associated
with arrays to provide new values for entries as they are required.At this point you should be able to make use of the
macsyma
manual to learn more details for representation of
new data types as you develop your application.1 More learning
The true programming buff may also be interested in the macro-expansion
capabilities of
macsyma
and its extensible syntax.At this point we would discourage the use of
these facilities by novices, but encourage their use by persons willing
to experiment in providing the most versatile user-oriented packages within
the
macsyma
framework.There is a ``compilation'' facility which allows users to translate
macsyma
code into potentially faster running code.Since most of the time in
most programs is used by calls to LISP programs, this is usually ineffective.In general, this should be avoided by novices and most experienced users, since
time spent on this is more wisely spent on mathematical restructuring of
the solution method, or (in the case of primarily numerical computation),
using a numerical library routine written in a suitable language.1 Maxims for the MACSYMA User
Some beginning users of algebraic manipulation systems
find that their
previous experiences with traditional programming systems do
not translate easily into algebraic programming; others find
macsyma
descriptions inadequate because the emphasis is on
the mixture of mathematical notations and algorithms, and not on
``efficient'' use of machine or human resources (no one likes to wait
longer than necessary for an answer!).While we cannot provide a complete education in efficient and effective
programming,
we have collected a few
``maxims'' in an attempt to help you with some of these ``start-up'' problems.Algebraic manipulation is a new and different
computational approach for which prior experience with
computational methods may be misleading.You should attempt to learn the ways in which algebraic
manipulation differs from other approaches.For
example, consider the problem of inverting an n times n
matrix.In numerical analysis we learn that the problem
requires on the order of n sup 3 operations.Theoreticians
will point out that for n sufficiently large, one can
reduce the number of multiplications below n sup 3 to n sup 2.8.This analysis is unfortunately not relevant in dealing with matrices
with symbolic entries.Consider the number of terms in
the determinant of the general n times n matrix whose elements
are the symbols a sub i,j .When the inverse is written out
in a fully expanded form, just the
determinant (a necessary part of representing
the inverse) has n !
terms.It is impossible to compute this determinant in less than ``time
proportional to n !'' In fact,
for large n, it is just not feasible
to compute this form explicitly on existing computers.The combinatorial
or exponential character that some algebraic manipulation
problems have when they are approached with an inefficient algorithm, makes for a vastly
different game from, say, numerical computation, where the size of objects
is generally known at the onset of the calculation, and does not increase.Needlessly
generalizing a problem usually results in unnecessary expense.For example, if you wish to obtain determinants
for a collection of matrices whose general
pattern of entries is represented by parametric formulas,
you might consider obtaining the determinant
of the general matrix and substituting various values for the parameters
into the
result.This may work for matrices of low order, but
is probably a poor plan for dealing with the exponential
growth inherent in computing symbolic determinants.It would probably
be better to substitute the parameters first, since this would
drastically reduce the cost of the determinant calculation.Sometimes, when humans are dealing with formulas, it is
preferable to use an indeterminate, say G in a formula
which is really known to be, say, 3/5.On the other
hand, it is likely (although not certain!) that the calculation
using 3/5 will take less time than the calculation with G.Since the cost inherent in some computations is usually
a function
of the number of variables in the expression, it pays to reduce the
number of variables in a problem as much as possible.You should be aware of the types of calculations which in the general
case have exponential growth
(e.g.many matrix calculations with symbolic
entries, repeated differentiation of products or quotients, solution of systems
of polynomial equations).Your should anticipate a certain amount of trial-and-error in calculations.Just as in other problem-solving activities,
often the first technique that comes to mind is not the best.While it
occasionally happens that brute force carries the day, cleverness in computing
can be as important as cleverness in hand calculations.It is natural, during hand calculations, to apply critical simplificiations
or substitutions in computations.These simplifications include
collecting terms selectively or striking out terms which do not ultimately
contribute to the final answer because of physical interpretations.Computer algorithms which do not incorporate these same tricks may bog down
surprisingly soon.Thinking about these shortcuts may be important.In fact,
it is one of the more
rewarding aspects of computer algebra systems that they give the problem solver
an opportunity to organize, encapsulate and distribute
a particularly clever piece of mathematical manipulation.Try to reduce your problem so that it can be performed in a simpler domain.For example, if your problem appears to involve trigonometric functions, logs,
exponentials, etc.see if you can reduce it to a rational function (ratio of
polynomials) problem.If it appears to be a rational function, see if you can, by substitutions,
make it into a polynomial problem, or a truncated power-series problem.If it appears to be a problem involving rational numbers, consider the use of
floating-point numbers as an alternative, if the growth in the size of numbers
presents difficulties.There are other special forms that are especially efficient.In a number
of areas of investigation it pays to convert all expressions to the internal rational form
(using rat) or into Poisson-series form (using intopois) to
avoid the overhead the the general representation.The price you may
pay here is thtat the structure of the formulas may be significantly different
from those you began with: The canonical transformations used by these
representations drastically re-order, expand, and modify the original expressions.Sometimes someone else has already started on your problem.You should look through the ``share'' directory programs available to see
if there are contributed packages that might be of use either as subroutines or as
models for programming.You should also consider writing programs that
you develop in solving your problems in a form suitable for sharing with
others.Pattern matching allows you to ``tune'' the system simplifier to your
application, and develop rule-replacement programs.Learning to use
the pattern-matching facilities effectively is a nontrivial task.Nevertheless
if you have a fairly complex problem involvilng the recognition and application
of identities, you should consider making an effort to use these facilities.In recent years, advocates of ``rule-based expert systems'' have claimed
that this type of formalism can or should be used to incorporate varied types of
knowledge.Algebraic manipulation programs have depended on pattern matching
since at least 1961, for some of their power.Finally, we would like to point out that algebraic manipulation systems,
in spite of their pitfalls, can be of major assistance in solving difficult
problems.If you are willing to invest some time in learning, there may be
enormous benefits in using such a system.We think it is unfortunate that
some users reserve
macsyma
for difficult problems.Those of us who have grown up with
macsyma
near at hand find it of great use in routine computations as well.We have enjoyed constructing
macsyma ,
and we hope that you will enjoy using it.We hope you will consider
contributing to program libraries at your local installation and at
other sites.Naturally, any comments or additions to this primer are welcome.Richard Fateman
University of California, Berkeley
(Last revision 12/85)