\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename jacal.info
@settitle jacal
@include version.txi
@setchapternewpage on
@c Choices for setchapternewpage are {on,off,odd}.
@paragraphindent 2
@syncodeindex tp fn
@syncodeindex cp fn
@syncodeindex vr fn
@c %**end of header

@copying
@noindent
This manual is for JACAL (version @value{JACALVERSION}, @value{JACALDATE}),
an interactive symbolic mathematics system.

Copyright @copyright{} 1993-2000, 2002-2011, 2013, 2015, 2016, 2019, 2020, 2023-2026
Free Software Foundation, Inc.

@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.  A
copy of the license is included in the section entitled ``GNU Free
Documentation License.''
@end quotation
@end copying


@dircategory Mathematics
@direntry
* Jacal: (jacal).       Interactive Symbolic Mathematics.
@end direntry

@iftex
@finalout
@c DL: lose the egregious vertical whitespace, esp. around examples
@c but paras in @defun-like things don't have parindent
@parskip 4pt plus 1pt
@end iftex

@titlepage
@title JACAL
@subtitle Symbolic Mathematics System
@subtitle Version @value{JACALVERSION}, @value{JACALDATE}
@author Aubrey Jaffer
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage

@contents

@ifnottex
@node Top, Overview, (dir), (dir)
@top JACAL

@insertcopying

@menu
* Overview::                    Installing and Starting JACAL
* Introduction::
* Algebra::                     Operators and Commands
* Transcendental Functions::
* Calculus::                    Operators and Commands
* Matrices and Tensors::
* Lambda Calculus::             Functions
* Miscellaneous::
* Flags::
* Index::
@end menu
@end ifnottex

@node Overview, Introduction, Top, Top
@chapter Overview
@cindex Overview

JACAL is an interactive symbolic mathematics program.  JACAL can
manipulate and simplify equations, scalars, vectors, matrices, and
tensors of (single and multiple valued) algebraic expressions
containing numbers, variables, radicals, and algebraic and
transcendental functions.

JACAL @value{JACALVERSION} was released @value{JACALDATE}.  Current
information about JACAL can be found on JACAL's @dfn{WWW} home page:

@center @url{https://www.gnu.org/software/jacal/}

JACAL, part of the GNU project, is free software, and you are welcome
to redistribute it under certain conditions; See the file COPYING with
this program or type @code{(terms)();} to JACAL for details.

For a list of the features that have changed since the last JACAL
release, see the file @file{ANNOUNCE}.  For a list of the features that
have changed over time, see the file @file{ChangeLog}.

@menu
* Authors and Bibliography::
* Installation::                How to install JACAL on your system.
* GNU Free Documentation License::
@end menu

@node Authors and Bibliography, Installation, Overview, Overview
@section Authors and Bibliography
@cindex Authors
@cindex Bibliography

@table @b
@item Michael Thomas
Polynomial Factoring.
@item Jerry D. Hedden
Tensors.
@item Aubrey Jaffer
Most of JACAL
@end table

The maintainer can be reached as @samp{agj@@alum.mit.edu}.

@subheading Project History
@cindex History

In December of 1987, in order to facilitate the design of constant
impedance electrical filters (diplexers), I (Aubrey Jaffer) wrote a
symbolic circuit analysis program.  It was written in LISP and
implemented canonical rational expressions (ratio of multivariate
polynomials) as its representation of the (small signal) Laplace
Transform of currents, voltages, and impedances.  After doing some
reading about symbolic manipulation, I became fascinated with the
problem of canonical forms.  That interest produced JACAL, an
interactive symbolic mathematics program similar to Maxima.

I initially used JACAL for electronics modeling, handling equations
complicated enough that error-free pencil and paper manipulations were
difficult.  As JACAL's capabilities grew, more applications were
found.

Around 1993-1995 Mike Thomas added univariate and multivariate
polynomial factorization.
In 1993-1997, Jerry D. Hedden added tensor manipulations to JACAL.

Having retired, in 2024 I finally implemented indefinite integration
(actually anti-differentiation) of rational functions incorporating
radicals.

Spurred by my mathematical physics work in fluid-mechanics, I
implemented logarithms, exponentials, Lambert-W (the inverse of
@code{x*exp(x)}), and trigonometric functions as the solutions to
ordinary differential equations (ODE).

@subheading Bibliography
@cindex Bibliography

@table @asis

@item [Richardson]
Daniel Richardson.@*
@cite{Some undecidable problems involving elementary functions of a real variable.}@*
The Journal of Symbolic Logic, 33(4):514–520, 1968.

@item [Caviness]
B. F. Caviness.@*
@cite{On canonical forms and simplification.}@*
J. ACM, 17(2):385–396, April 1970.

@item [Wang]
Paul S. Wang.@*
@cite{The undecidability of the existence of zeros of real elementary functions.}@*
J. ACM, 21(4):586589, October 1974.

@item [Ritt]
J.F. Ritt.@*
@cite{Differential Algebra. American Mathematical Society: Colloquium publications.}@*
Dover Publications, 1966.

@item [Cox]
David Cox.@*
@cite{Ideals, Varieties, and Algorithms An Introduction to Computational Algebraic Geometry and Commutative Algebra.}@*
Undergraduate Texts in Mathematics.@*
Springer New York, New York, NY, 2nd ed. 1997. edition, 1997.

@item [SRE]
B. F. Caviness and R. J. Fateman.@*
@cite{Simplification of radical expressions.}@*
In @cite{Proceedings of the Third ACM Symposium on Symbolic and Algebraic Computation, SYMSAC ’76}@*
pages 329–338, New York, NY, USA, 1976. ACM.

@item [ACP]
@pindex ACP
Donald Ervin Knuth.@*
@cite{The Art of Computer Programming : Seminumerical Algorithms (Vol 2).}@*
2nd Ed (1981) Addison-Wesley Pub Co; ISBN: 0-201-03822-6

@item [GCL]
@pindex GCL
Keith O. Geddes, Stephen R. Czapor, George Labahn.@*
@cite{Algorithms for Computer Algebra.}@*
(October 1992) Kluwer Academic Pub; ISBN: 0-7923-9259-0

@item [Siret]
@pindex Siret
Y. Siret (Editor), E. Tournier, J. H. Davenport, F. Tournier.@*
@cite{Computer Algebra: Systems and Algorithms for Algebraic Computation}@*
2nd edition (June 1993) Academic Press; ISBN: 0-122-04232-8

@item [R5RS]
@pindex R5RS
Richard Kelsey and William Clinger and Jonathan (Rees, editors)@*
@uref{../r5rs_toc, Revised(5) Report on the Algorithmic Language Scheme},@*
@cite{Higher-Order and Symbolic Computation} Volume 11, Number 1 (1998),
@w{pp.@: 7-105}, or@*
@cite{ACM SIGPLAN Notices} 33(9), September 1998.@*
@ifinfo
@ref{Top, , Revised(5) Report on the Algorithmic Language Scheme, r5rs, Revised(5) Report on the Algorithmic Language Scheme}.@*
@end ifinfo

@item [SLIB]
@pindex SLIB
Todd R. Eigenschink and Aubrey Jaffer.@*
@uref{../slib_toc, SLIB; The Portable Scheme Library}@*
@ifinfo
@ref{Top, , SLIB; The Portable Scheme Library, slib, SLIB; The Portable Scheme Library}.
@end ifinfo
@end table

@node Installation, GNU Free Documentation License, Authors and Bibliography, Overview
@section Installation
@ifset html
<A NAME="Installation"> </A>
@end ifset

@cindex Scheme
The JACAL program is written in the Algorithmic Language @dfn{Scheme}.
So you must have or install a Scheme implementation in order to run
it.  JACAL also requires the SLIB Portable Scheme library which is
available from @uref{https://www.gnu.org/software/slib}.  The
installation procedures given here provide the SCM Scheme
implementation along with SLIB and JACAL.  If your system has a Scheme
(or Guile) implementation installed, then the @samp{scm} steps are
unnecessary.

@deftp System Unix
@deftpx System GNU/Linux

If you lack permission to install into /usr/local/, you can install
into your home directory by changing @code{/usr/local/} to your home
directory in this script.

@example
wget https://ftp.gnu.org/gnu/scm/scm-5f5.tar.gz
wget https://ftp.gnu.org/gnu/slib/slib-3c2.tar.gz
wget https://ftp.gnu.org/gnu/jacal/jacal-2a1.tar.gz
tar -xzf scm-5f5.tar.gz
tar -xzf slib-3c2.tar.gz
tar -xzf jacal-2a1.tar.gz
(cd slib-3c2; ./configure --prefix=/usr/local/; make install)
(cd scm-5f5; ./configure --prefix=/usr/local/; make scm; make install)
(cd jacal-2a1; ./configure --prefix=/usr/local/; make install)
# rm scm-5f5.tar.gz slib-3c2.tar.gz jacal-2a1.tar.gz
@end example

The command @samp{jacal} will start an interactive session.
@end deftp

@deftp System x86_64 GNU/Linux with Redhat Package Manager (rpm)
@example
wget http://groups.csail.mit.edu/mac/ftpdir/scm/scm-5f5-1.x86_64.rpm
wget http://groups.csail.mit.edu/mac/ftpdir/scm/slib-3c2-1.noarch.rpm
wget http://groups.csail.mit.edu/mac/ftpdir/scm/jacal-2a1-1.noarch.rpm
rpm -U scm-5f5-1.x86_64.rpm slib-3c2-1.noarch.rpm jacal-2a1-1.noarch.rpm
# rm scm-5f5-1.x86_64.rpm slib-3c2-1.noarch.rpm jacal-2a1-1.noarch.rpm
@end example

The command @samp{jacal} will start an interactive session using ELK,
Gambit, Gauche, Guile, Larceny, MIT-Scheme, MzScheme, Scheme48, SCM,
or SISC.  Type @samp{jacal --help} for instructions.
@end deftp

@c @deftp System Apple
@c @uref{http://www.io.com/~cobblers/scm/} has downloads and utilities for
@c installing SCM and SLIB on Macintosh computers.
@c @end deftp

@deftp System x86 Microsoft
Download and run
@uref{http://groups.csail.mit.edu/mac/ftpdir/scm/slib-3c2-1.exe},@*
@uref{http://groups.csail.mit.edu/mac/ftpdir/scm/scm-5f4-1.exe}, and@*
@uref{http://groups.csail.mit.edu/mac/ftpdir/scm/jacal-2a1-1.exe}.
@end deftp


@c @subheading Compiling Jacal
@c @cindex Compiling Jacal

@c For Scheme implementations with compilers, it is worthwhile to
@c compile SLIB files, and the JACAL files @file{types.scm} and
@c @file{poly.scm}.

@c  SLIB has initialization files for most Scheme implementations.  It
@c  is available from the same locations and vendors as JACAL.
@c  @xref{Installation, , Installation, slib, SLIB}.
@c @ifinfo
@c @xref{Installation, , , slib, SLIB}.
@c @end ifinfo
@c @iftex
@c See @file{README} in SLIB for how to install SLIB.
@c @end iftex


@subheading Manifest
@cindex Manifest

@table @asis
@item COPYING
details the LACK OF WARRANTY for Jacal and the conditions for
distributing Jacal.
@item HELP
is a short introduction to using Jacal.
@item ChangeLog
documents changes to Jacal.

@item jacal
is a unix (sh) script to start an interactive jacal session.
@item rw.math
is a batch file of Robertson-Walker model of General Relativity.
"batch(rw.math);" to execute its commands in Jacal.
@item test.math
is a batch file which tests Jacal.
@item jacal.texi
is documentation on how to use jacal in TeXinfo format.
@item DOC
has files telling about how jacal works.

@table @asis
@item algdenom
gives an algorithm for clearing radicals and other algebraic field
extensions from denominators.
@item grammar
explains how to create new grammars.
@item lambda
explains mid-level data formats. From a Dr. Dobbs article.
@item ratint.pdf
article explaining jacal's integration algorithm and transcendental
function simplification.
@end table

@item math.scm
is the file you load into scheme in order to run jacal.
@item toploads.scm
contains comments describing the rest of the files.
@item modeinit.scm
has initializations for modes in Jacal.
@end table


@node GNU Free Documentation License,  , Installation, Overview
@section GNU Free Documentation License

@include fdl.texi

@node Introduction, Algebra, Overview, Top
@chapter Introduction


@menu
* Running Jacal::
* Canonical::
* Release Notes::
* Conventions::
@end menu

@node Running Jacal, Canonical, Introduction, Introduction
@section Running Jacal
@cindex Running Jacal

If you successfully executed one of the installations of the previous
section, then typing @samp{jacal} or clicking an icon will begin an
interactive session.

To manually start jacal, start your Scheme implementation with SLIB.
This may involve setting up that implementation's initialization file or
LOADing a @samp{.init} file from the @file{slib} directory.  Then type:

@example
(slib:load "/usr/local/lib/jacal/math")
@end example

@noindent
where @file{/usr/local/lib/jacal/} is a path to the JACAL directory.
JACAL should then print:

@example
JACAL version @value{JACALVERSION}, Copyright 1989-2026 Aubrey Jaffer
JACAL comes with ABSOLUTELY NO WARRANTY; for details type `(terms)'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `(terms)' for details.
;;; Type (math); to begin from Scheme session.
@end example

@noindent
Do as it says:

@example
(math)
@result{}
type qed; to return to scheme, type help; for help.
(%0000)
@end example

@noindent
And you are ready to try the commands described in the rest of the
manual.

@subheading Recovery from Errors
@cindex Recovery from Errors

JACAL tries to catch any errors it encounters and print an informative
message before returning to the prompt.  If there are unmatched
parentheses or missing delimiters in your typed command, type the
closing delimiters, digits for ``expression missing'', and semicolon
(followed by newline) until it returns to the prompt:

@example
@group
(%0000) (@{adf;
          ^ "mismatched delimiter" #\; expecting #\@} 
;
^ "mismatched delimiter" #\; expecting #\) 
;
%0000: adf
(%0001) 
@end group
@end example

If that is unsuccessful, typing @samp{CTRL-C} will likely return you
to the underlying Scheme session.

As JACAL is a complicated program there are bugs which will occasionally
cause the program to stop with some sort of error reported by the
underlying Scheme system.  In interactive implementations (such as SCM)
you can usually continue your session by typing @code{(math)}.  The
expression which was input to JACAL just before the error will be lost
but you should be able to otherwise continue with your session.

If you define identifiers which have already been used in formulas,
the earlier uses are not updated.  You can restore a name to its
unassigned status by defining it to itself:

@example
@group
(%0001) a: 5/7;
a: 5/7
(%0001) a+3;
       26
%0001: --
       7
(%0002) a:a;
a: a
(%0002) a+3;
%0002: 3 + a
@end group
@end example

If the underlying scheme implementation supports a @code{(restart)}
command, then typing @code{restart();} in JACAL will re-initiate the
session, forgetting all the commands and formulas you entered
previously:

@example
@group
(%0003) restart();
..............
JACAL version 2a1, Copyright 1989-2026 Aubrey Jaffer
JACAL comes with ABSOLUTELY NO WARRANTY; for details type `(terms)'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `(terms)' for details.
;;; Type (math); to begin from Scheme session.
Type qed; to return to Scheme, type help; for help.
(%0000)
@end group
@end example

@subheading Stopping Jacal
@cindex Stopping Jacal

The command @code{quit();} will end your JACAL session.

With non-interactive Scheme implementations the JACAL command
@code{qed;} or typing the end-of-file character (@key{C-z} on MS-DOS
and VMS, @key{C-d} on others) will end your JACAL session.

The command @code{qed;} will return to the interactive Scheme session.
Typing @code{(math)} will return to the JACAL session.

From the interactive Scheme session @code{(exit)} or possibly an
end-of-file character will terminate the session.


@node Canonical, Release Notes, Running Jacal, Introduction
@section Canonical
@cindex Canonical

The canonical aspect of JACAL is that all equations and expressions
involving variables undergo nomalization such that two formulas which
are equivalent have the same representation.  This representation is
affected by variable ordering; substituting one variable name for
another looks different but expresses the same mathematical
constraint.

As with all symbolic algebra systems, roots of unity (1) are not
uniquely normalizable.  JACAL's guarantees apply only to expressions
involving variables.

JACAL prioritizes simplicity of expressions over full canonical
reductions.  For instance, all trigonometric functions can be
expressed as (complex number) exponentials and logarithms; but it is
difficult to understand that representation.  Instead, trigonometric
expressions are represented in terms of tangent (tan) and arctangent
(atan).

A transcendental function composed with its inverse cancels each other
if the argument to the inverse function involves at least one
variable.  @code{exp(@var{integer}*log(@var{argument}))} reduces to
@code{@var{argument}^(@var{integer})} if @var{argument} involves at
least one variable.  @code{exp(log(@var{argument})/@var{integer})}
does not reduce if @var{integer} is greater than one.  The @code{^}
function reduces this case to a radical:

@example
@group
(%0000) %expt(a+x,1/5);
           log(a + x)
%0000: exp(----------)
               5
(%0001) (a+x)^(1/5);
              1/5
%0001: (a + x)
@end group
@end example

Trignometric functions have similar reductions:

@example
@group
(%0002) sin(asin(x));
%0002: x
(%0003) asin(sin(x));
%0003: x
(%0004) sin(3*asin(x));
                  3
%0004: - 3 x + 4 x
(%0005) tan(3*atan(x));
                3
       - 3 x + x
%0005: ----------
               2
       -1 + 3 x
(%0006) atan(3*tan(x));
%0006: atan(3 tan(x))
(%0007) tan(6*atan(x));
                   3      5
         6 x - 20 x  + 6 x
%0007: ----------------------
               2       4    6
       1 - 15 x  + 15 x  - x
@end group
@end example

The Lambert-W function (@code{%W}) is the inverse of
@code{@var{z}*exp(@var{z})}.  Currently the reduction works in one
direction; the other will eventually be supported:

@example
@group
(%0008) %W(x*exp(x));
%0008: x
(%0009) %W(x)*exp(%W(x));
%0009: %W(x) exp(%W(x))
@end group
@end example

Because transcendental functions are defined by their differential
equations, JACAL can produce their derivatives:

@example
@group
(%0015) diff(%W(x),x);
          %W(x)
%0015: -----------
       x + x %W(x)
(%0016) diff(tan(x),x);
                   2
%0016: 1 + (tan(x))
(%0017) diff(sin(x),x);
               1
%0017: ------------------
                    2 1/2
       (1 + (tan(x)) )
(%0018) diff(cos(x),x);
              tan(x)
%0018: --------------------
                      2 1/2
       - (1 + (tan(x)) )
(%0019) diff(%expt(x,1/5),x);
           log(x)
       exp(------)
             5
%0019: -----------
           5 x
(%0020) diff(x^(1/5),x);
         1
%0020: ------
          4/5
       5 x
@end group
@end example

The usual algebraic reductions also work:
@example
(%0024) sin(x/a)^2+cos(x/a)^2;
%0024: 1
@end example

JACAL provides some functions which it does not canonicalize:
@code{imagpart}, @code{realpart}, @code{abs}, and @code{cabs}.


@node Release Notes, Conventions, Canonical, Introduction
@section Release Notes
@cindex Release Notes

JACAL-2a1 is a major release incorporating transcendental functions.

Do not raise transcendental functions to powers like @code{sin^2(x)}.
Instead, use @code{sin(x)^2}.

Trigonometric sum and difference of angle formulas do not reduce.

@node Conventions,  , Release Notes, Introduction
@section Conventions
@cindex Conventions

Things that are labeled as Operators can occur in expressions output by
Jacal.  Things that are labeled as Commands act upon their arguments and
do not generally occur in expressions output by Jacal.  Things that are
labeled as flags are @code{set} to control aspects of the Jacal
environment.

The examples throughout this text were produced using the SCM Scheme
implementation.

Jacal has several input grammars it understands.  The @code{standard}
input grammar (which is the same as the @code{std} and @code{disp2d}
input grammars) is used in this manual.  It is very similar to
@code{Maxima} input grammar and the Algol family of computer
languages.

Identifier names are case sensitive.


@node Algebra, Transcendental Functions, Introduction, Top
@chapter Algebra
@cindex Algebra

@menu
* Algebraic Operators::
* Algebraic Commands::
* Rational Expression::
* Polynomials::
* Interpolation::
* Factoring::
@end menu

@node Algebraic Operators, Algebraic Commands, Algebra, Algebra
@section Algebraic Operators
@cindex Algebraic Operators

@deffn Operator + augend addend

Addition of scalar quantities or componentwise addition of bunches is
accomplished by means of the infix operator @code{+}. For example,

@example
@group
(%0000) a:[[1, 3, 5], [2, 4, 7]];
   [ 1  3  5 ]
a: [         ]
   [ 2  4  7 ]
(%0000) b:[2, 4];
b: [2, 4]
(%0000) a + b;
       [ 3  5  7  ]
%0000: [          ]
       [ 6  8  11 ]
(%0001) 3 + 2;
%0001: 5
(%0002) c + b;
%0002: [2 + c, 4 + c]
@end group
@end example
@end deffn

@deffn Operator - minuend subtrahend
@deffnx Operator - subtrahend

The symbol @code{-} is used to denote either the binary infix operator
subtraction or the unary minus.

@example
@group
(%0004) -[1,2,3];
%0004: [-1, -2, -3]
(%0005) 3-7;
%0005: -4
@end group
@end example
@end deffn

@deffn Operator +/- minuend subtrahend
@deffnx Operator -/+ minuend subtrahend
@deffnx Operator +/- augend
@deffnx Operator -/+ augend

Jacal allows the use of @code{+/-} and @code{-/+} as ambiguous signs
(unary plus-or-minus, unary minus-or-plus) and as ambiguous infix
operators (binary plus-or-minus, binary minus-or-plus). The value
@code{+/-} is also represented by the constant @code{%sqrt1}, while
@code{-/+} is represented by @code{-%sqrt1}.

@example
@group
(%0006) u:+/-3;
u: 3 %sqrt1
(%0006) u^2;
%0006: 9
(%0007) +/-(u);
%0007: 3
(%0008) u-/+3;
%0008: 0
@end group
@end example
@end deffn

@deffn Operator * multiplicand1 multiplicand2

Multiplication of scalar expressions such as numbers, polynomials,
rational functions and algebraic functions is denoted by the infix
operator @code{*}.  For example,

@example
@group
(%0000) (2 + 3 * a) * 4 * a * b^2;
                  2   2
%0000: (8 a + 12 a ) b
@end group
@end example

One can also use @code{*} as an infix operator on bunches.  In that
case, it operates componentwise, in an appropriate sense.  If the
bunches are square matrices, the operator @code{*} multiplies
corresponding entries of the two factors.  It does not perform matrix
multiplication.  To multiply matrices one instead uses the operator
@code{.} (i.e., a period).  More generally, any binary scalar operator
other than @code{^} can be used on bunches and acts
componentwise.
@end deffn

@deffn Operator / dividend divisor

The symbol for division in Jacal is @code{/}.  For example, the value
returned by @code{6 / 2} is @code{3}.

@example
@group
(%0001) (x^2 - y^2) / (x - y);
%0001: x + y
@end group
@end example

Note: using @code{divide} to divide a polynomial by an integer does not work.
@end deffn

@deffn Operator ^ expression exponent

The infix operator @code{^} is used for exponentiation of scalar
quantitites or for componentwise exponentiation of bunches.  For
example, @code{2^5} returns 32.  Unlike the other scalar infix
operators, one cannot use @code{^} for component-wise operations on
bunches.  Furthermore, one should not try to use @code{^} to raise a
square matrix to a power.  Instead, one should use @code{^^}.

@example
@group
(%0002) (1+x)^4;
                    2      3    4
%0002: 1 + 4 x + 6 x  + 4 x  + x
@end group
@end example
@end deffn

@deffn Operator = expression1 expression2

In Jacal, the equals sign @code{=} is @emph{not} used for conditionals
and it is @emph{not} used for assignments.  To assign a value to an
identifier, use either @code{:} or @code{:=}.  The operator @code{=}
merely returns a value of the form @code{0 = @var{expression}}.  The
value returned by @code{a = b}, for example is @code{0 = a - b}.

@example
@group
(%0003) 1=2;

;;; eliminate singular-reduction [-1]

@end group
@end example
@end deffn

@deffn Operator || Z1 Z2

The infix operator @code{||} is from electrical engineering and
represents the effective impedance of the parallel connection of
components of impedances @var{Z1} and @var{Z2}:

@example
@group
(%0003) Z1 || Z2;
        Z1 Z2
%0003: -------
       Z1 + Z2
@end group
@end example
@end deffn


@node Algebraic Commands, Rational Expression, Algebraic Operators, Algebra
@section Algebraic Commands
@cindex Algebraic Commands

@deffn Command eliminate [eqn_1 eqn_2 @dots{}] [var_1 var_2 @dots{}]

Here @var{eqn_i} is an equation for @var{i} = 1 @dots{} @var{n} and where
@var{var_j} is a variable for @var{j} = 1 @dots{} @var{m}.
@code{eliminate} returns a list of equations obtained by eliminating the
variables @var{var_1}, @dots{}, @var{var_m} from the equations
@var{eqn_1}, @dots{}, @var{eqn_n}.

@example
@group
(%0004) eliminate([x^2+y=0,x^3+y=0],[x]);
                2
%0004: 0 = y + y
(%0005) eliminate([x+y+z=3,x^2+y^2+z^2=3,x^3+y^3+z^3=3],[x,y]);
%0005: 0 = -1 + z
@end group
@end example
@end deffn

@deffn Command suchthat var eqn

The equation @var{eqn} must contain an occurrence of variable @var{var}.
@code{suchthat} returns an expression for all complex values of
@var{var} satisfying @var{eqn}.  @code{suchthat} is useful for
extracting an expression from an equation.

@example
(%0000) a*x+b*y+c = 0;
%0000: 0 = c + a x + b y
(%0001) suchthat(x,%0000);
       - c - b y
%0001: ---------
           a
@end example
@end deffn

@deffn Command suchthat var exp

If an expression rather than an equation is given to @code{suchthat}, it
is as though the equation @code{@var{exp}=0} was given.

@example
(%0002) suchthat(x, a*x+b*y+c);
       - c - b y
%0002: ---------
           a
@end example
@end deffn

@deffn Operator | var exp_or_eqn
An alternative infix notation is also available for @code{suchthat}.

When used in combination with the @samp{@{ @}} notation for @code{or},
the set notation used by some textbooks results.

If @var{var} in @var{eqn} has multiple roots, a named
@dfn{ring extension} will be introduced to represent any one of those
roots.  When multiple values are returned, the result (in @code{disp2d}
and @code{standard} grammars) is wrapped with @samp{@{ @}}.

@example
(%0003) x | a*x^2 + b*x + c;
                            2
%ext1: c + b %ext1 + a %ext1
(%0003) %ext1^2;
       - c - b %ext1
%0003: -------------
             a
@end example
@end deffn

@deffn Command definition symbol
Returns the rule or expression defining @var{symbol}.

@example
@group
(%0000) @{x | a*x^2 + b*x + c@};
                            2
%ext1: c + b %ext1 + a %ext1
(%0000) definition(%ext1);
                                2
%0000: 0 = c + b %ext1 + a %ext1
(%0001) definition(sqrt);
                    2/2
%0001: 0 = - @@1 + @@1
(%0002) definition(sqrt(x));
                  2/2
%0002: 0 = - x + x
(%0003) definition(tan);
                          2
%0003: 0 = - @@1' + (1 + @@1 ) @@2'
(%0004) definition(tan(x));
                                      2
%0004: 0 = - (tan(x))' + (1 + (tan(x)) ) x'
(%0005) definition(%tanP);
%0005: %tanP          + @@2 %tanQ
            [-1 + @@1]           [-1 + @@1]
(%0006) definition(%tanPQ);
       %tanP
            [@@1]
%0006: ---------
       %tanQ
            [@@1]
@end group
@end example
@end deffn

@deffn Command or expr_1 @dots{}
@deffnx Command or eqn_1 @dots{}

The function @code{or} takes as inputs one or more equations or
values. If the inputs are equations, then @code{or} returns an equation
which is equivalent to the assertion that at least one of the input
equations holds. If the inputs to @code{or} are values instead of two
equations, then the function @code{or} returns a multiple value. If the
inputs to @code{or} consist of both equations and values, then @code{or}
will return the multiple values.

@example
@group
(%0000) or(x=2,y=3);
%0000: 0 = 6 - 3 x + (-2 + x) y
(%0001) or(2,3);
                           2
%0001: @{@@ | 0 = 6 - 5 @@ + @@ @}
(%0002) or(2,3)^2;
                             2
%0002: @{@@ | 0 = 36 - 13 @@ + @@ @}
(%0003) factor %0001;
%0003: 3 2
(%0004) factor %0002;
%0004: 9 4
(%0005) or(x=2,17);
%0005: 17
@end group
@end example

@samp{@{@var{eqn}, @dots{} @}} can be used as an alternate syntax for
@code{or}:

@example
(%0012) : @{+1, -1@};

                     2
%0012: @{:@@ | 0 = -1 + :@@ @}
@end example
@end deffn


@node Rational Expression, Polynomials, Algebraic Commands, Algebra
@section Rational Expression
@cindex Rational Expression

@deffn Command num expr

The function @code{num} takes a rational expression as input and
returns a numerator of the expression.

@example
@group
(%0013) num((x^2+y^2)/(x^2-y^2));
          2    2
%0013: - x  - y
(%0014) num(7/4);
%0014: 7
(%0015) num(7/(4/3));
%0015: 21
@end group
@end example
@end deffn

@deffn Operator denom rational-expression

The Jacal command @code{denom} is used to obtain the denominator of a
rational expression.

@example
@group
(%0016) denom(4/5);
%0016: 5
(%0017) denom((x^2+y^2)/(x^2-y^2));
          2    2
%0017: - x  + y
@end group
@end example
@end deffn

@deffn Command listofvars expr

The command @code{listofvars} takes as input a rational expression and
returns a list of the variables that occur in that expression.

@example
@group
(%0018) listofvars(x^2+y^3);
%0018: [x, y]
(%0019) listofvars((x^2+y^3)/(2*x^7+y*x+z));
%0019: [x, y, z]
@end group
@end example
@end deffn

@deffn Command imagpart z
Returns the coefficient of @code{%i} in expression @var{z};
@end deffn

@deffn Command realpart z
Returns all but the coefficient of @code{%i} in expression @var{z};
@end deffn

@deffn Command abs z
@deffnx Command cabs z
@code{| @var{z} |} 

Returns the square root of the sum of the squares of the @code{realpart}
and the @code{imagpart} of @var{z}.

@example
@group
(%0020) abs(z);
%0020: |z|
(%0021) abs(-z);
%0021: |- z|
(%0022) abs(-3);
%0022: 3
(%0023) abs(1/%i);
%0023: 1
(%0024) realpart(1/%i);
%0024: 0
(%0025) imagpart(1/%i);
%0025: -1
(%0026) imagpart(3/%i);
%0026: -3
@end group
@end example
@end deffn



@node Polynomials, Interpolation, Rational Expression, Algebra
@section Polynomials
@cindex Polynomials

@deffn Operator degree poly var

Returns the degree of polynomial or equation @var{poly} in variable
@var{var}.
@end deffn

@deffn Operator degree poly

Returns the total-degree, the degree of its highest degree monomial,
of polynomial or equation @var{poly}.

@example
@group
(%0028) degree(a*x*x + b*y*x + c*y*y + d*x + e*y + f, y);
%0028: 2
(%0029) degree(a*x*x + b*y*x + c*y*y + d*x + e*y + f);
%0029: 3
@end group
@end example

Note that all roots and radicals count as degree 1.
@end deffn

@deffn Operator coeff poly var
@deffnx Operator coeff poly var deg
@deffnx Operator coeffs poly var

The command @code{coeff} is used to determine the coefficient of a
certain power of a variable in a given polynomial. Here @var{poly} is a
polynomial and @var{var} is a variable. If the optional third argument
is omitted, then Jacal returns the coefficient of the variable @var{var}
in @var{poly}. Otherwise it returns the coefficient of @var{var^deg} in
@var{poly}. The function @code{coeffs} returns a list of all of the
coefficients. For example,

@example
@group
(%0009) coeff((x + 2)^4, x, 3);
%0009: 8
(%0010) (x + 2)^4;
                       2      3    4
%0010: 16 + 32 x + 24 x  + 8 x  + x
(%0011) coeff((x + 2)^4, x);
%0011: 32
(%0012) coeffs((x + 2)^4, x);
%0012: [16, 32, 24, 8, 1]
@end group
@end example
@end deffn

@deffn Operator poly var vect
@deffnx Operator poly var coeff1 @dots{}

The function @code{poly} provides an inverse to the function
@code{coeffs}, allowing one to recover a polynomial from its vector or
list of coefficients.

@example
@group
(%0013) poly(y, [16, 32, 24, 8, 1]);
                       2      3    4
%0013: 16 + 32 y + 24 y  + 8 y  + y
(%0014) poly(y, 16, 32, 24, 8, 1);
                       2      3    4
%0014: 16 + 32 y + 24 y  + 8 y  + y
@end group
@end example
@end deffn

@deffn Operator poly eqn

The function @code{poly} returns the expression equal to 0 in equation
@var{eqn}.  Be aware that the sign and scaling of the returned
polynomial will not necessarily match those in the equation creating
@var{eqn}.

@example
@group
(%0015) 2*a = 4*c;
%0015: 0 = - a + 2 c
(%0016) poly(%0015);
%0016: - a + 2 c
@end group
@end example
@end deffn

@deffn Operator content poly var

Returns a list of content and primitive part of a polynomial with
respect to the variable.  The content is the GCD of the coefficients of
the polynomial in the variable.  The primitive part is @var{poly}
divided by the content.

@example
@group
content(2*x*y+4*x^2*y^2,y);
                      2
%0017: [2 x, y + 2 x y ]
@end group
@end example
@end deffn

@deffn Operator divide dividend divisor var
@deffnx Operator divide dividend divisor

The command @code{divide} treats @var{divident} and @var{divisor} as
polynomials in the variable @var{var} and returns a pair
@samp{[@var{quotient}, @var{remainder}]} such that @code{@var{dividend}
= @var{divisor} * @var{quotient} + @var{remainder}}. If the third
argument @var{var} is omitted Jacal will choose a variable on its own
with respect to which it will do the division. In particular, of
@var{dividend} and @var{divisor} are both numerical, one can safely omit
the third argument.

@example
@group
(%0018) divide(x^2+y^2,x-7*y^2,x);
               2   2       4
%0018: [x + 7 y , y  + 49 y ]
(%0019) divide(-7,3);
%0019: [-2, -1]
(%0020) divide(x^2+y^2+z^2,x+y+z);
                        2              2
%0020: [- x - y + z, 2 x  + 2 x y + 2 y ]
(%0021) divide(x^2+y^2+z^2,x+y+z,y);
                        2              2
%0021: [- x + y - z, 2 x  + 2 x z + 2 z ]
(%0022) divide(x^2+y^2+z^2,x+y+z,z);
                        2              2
%0022: [- x - y + z, 2 x  + 2 x y + 2 y ]
@end group
@end example
@end deffn

@deffn Command mod poly1 eqn var
@deffnx Command mod poly1 poly2 var
@deffnx Command mod poly1 poly2
Returns @var{poly1} reduced with respect to @var{poly2} (or @var{eqn})
and @var{var}.  If @var{poly2} is univariate, the third argument is not
needed.
@end deffn

@deffn Command mod poly1 n
Returns @var{poly1} with all the coefficients taken modulo @var{n}.
@end deffn
@deffn Command mod poly1
Returns @var{poly1} with all the coefficients taken modulo the
current modulus.

If the modulus (@var{n} or the current modulus) is negative, then the
results use symmetric representation.

@example
@group
(%0023) x^4+4 mod 3;
            4
%0023: 1 + x
(%0024) x^4+4 mod x^2=2;
%0024: 8
(%0025) mod(x^3*a*7+x*8+34, -3);
                  3
%0025: 1 - x + a x
(%0026) mod(5,2);
%0026: 1
(%0027) mod(x^4+4,x^2=2,x);
%0027: 8
@end group
@end example
@end deffn

@deffn Command gcd poly_1 poly_2

The Jacal function @code{gcd} takes as arguments two polynomials with
integer coefficients and returns a greatest common divisor of the two
polynomials. This includes the case where the polynomials are
integers.

@example
@group
(%0028) gcd(x^4-y^4,x^6+y^6);
        2    2
%0028: x  + y
(%0029) gcd(4,10);
%0029: 2
@end group
@end example
@end deffn

@deffn Command discriminant poly var

Here @var{poly} is a polynomial and @var{var} is a variable.  This
function returns the square of the product of the differences of the
roots of the polynomial @var{poly} with respect to the variable
@var{var}.

@example
@group
(%0030) discriminant(x^3 - 1, x);
%0030: -27
@end group
@end example
@end deffn

@deffn Command resultant poly_1 poly_2 var

The function @code{resultant} returns the resultant of the polynomials
@var{poly_1} and @var{poly_2} with respect to the variable
@var{var}.

@example
@group
(%0031) resultant(x^2 + a, x^3 + a, x);
        2    3
%0031: a  + a
@end group
@end example
@end deffn


@deffn Command equatecoeffs z1 z2 var
Returns the list of equations formed by equating each coefficient of
variable @var{var}^n in @var{z1} to the corresponding coefficient of
@var{var}^n in @var{z2}.  @var{z1} and @var{z2} can be polynomials or
ratios of polynomials.
@end deffn

@deffn Command decompose poly_1 var
Returns the polynomial decomposition of @var{poly_1} with respect to
@var{var}.  Note that @code{decompose} is not currently working.
@c @example
@c @group
@c e7 : decompose(((x+1)^6),x);

@c                 2           2    3
@c e7: [1 + 2 x + x , 3 x + 3 x  + x ]
@c @end group
@c @end example
@end deffn

@node Interpolation, Factoring, Polynomials, Algebra
@section Interpolation
@cindex Interpolation

@deffn Command interp mat
@deffnx Command interp vec1 vec2 @dots{}
The only argument, @var{mat}, must be an array having at least one row
of two expressions: [[@var{x1},@var{y1}],[@var{x2},@var{y2}],@dots{}].
It is an error if there are any duplicates in the first column of the
second argument,

@code{interp} returns a polynomial function @var{poly}(@var{@@1}) such
that
@var{mat}[1,2]=@var{poly}(@var{mat}[1,1]),
@var{mat}[2,2]=@var{poly}(@var{mat}[2,1]), etc.

There is a variant of the @code{interp} command that takes multiple
vector arguments instead of a matrix. These vectors represent points
to be interpolated over. The same constraints apply as in the matrix
version. All the variants of the interpolation procedure described
later have both these forms.

@example
(%0032) interp([[2, 3], [0, -1]]);
%0032: -1 + 2 @@1
(%0033) interp([[2, 3], [1, z]]);
%0033: -3 + 3 @@1 + (2 - @@1) z
(%0034) interp([2, 3], [y, z]);
       - 3 @@1 + 3 y + (-2 + @@1) z
%0034: --------------------------
                 -2 + y
@end example
@end deffn

@deffn Command interp.lagrange mat
@deffnx Command interp.lagrange vec1 vec2 @dots{}
This is the same as the @code{interp} command.
@end deffn

@deffn Command interp.newton mat
@deffnx Command interp.newton vec1 vec2 @dots{}
This is similar to @code{interp} command with an added option of
including derivative values when defining points. The same constraints
apply as in @code{interp}. You can choose to specify some number of
derivatives for each point. That number does not have to be the same
for all points. 

@example
(%0035) interp.newton([-1, 0], [0, 1], [1, 0]);
             2
%0035: 1 - @@1
(%0036) interp.newton([-1, 0], [0, 1, 0, 20], [1, 0]);
                2        4
%0036: 1 + 10 @@1  - 11 @@1
(%0037) interp.newton([-1, 0], [0, 1, 0, a], [1, 0]);
               4      2     4
       2 - 2 @@1  + (@@1  - @@1 ) a
%0037: -------------------------
                   2
@end example
@end deffn

@deffn Command interp.neville mat
@deffnx Command interp.neville vec1 vec2 @dots{}
The same as @command{interp} in its functionality, but uses Neville
form when constructing the polynomial.
@end deffn

@node Factoring,  , Interpolation, Algebra
@section Factoring
@cindex Factoring

@deffn Command factor int
The Jacal command @code{factor} takes as input an integer and returns a
list of the prime numbers that divide it, each occurring with the
appropriate multiplicity in the list. If the number is negative, the
list will begin with -1.

The results of the @code{factor} command are shown in a special
@dfn{factored} format, which appears as the product of the factors.

@example
@group
(%0038) factor(120);
        3
%0038: 2  3 5
(%0039) factor(-120);
           3
%0039: -1 2  3 5
@end group
@end example
@end deffn

@deffn Command factor polyratio
Given a univariate ratio of polynomials @var{polyratio}, returns a
matrix of factors and exponents.

As above, the results are shown in factored form.

@example
(%0040) factor((14*x^4-10/68*x^-5)/(5*x^2+1));
                    9
          -5 + 476 x
%0040: ------------------
                    2   5
       2 17 (1 + 5 x ) x
@end example

@example
(%0043) factor(x*y);
%0043: x y
(%0044) factor((x+a)*(y^4-z));
                      4
%0044: -1 (a + x) (- y  + z)
(%0045) factor((x+u*a^3)*(y^4-z));
            3            4
%0045: -1 (a  u + x) (- y  + z)
(%0046) factor((x+u*a^3)^2*(y^4-z)/((x+1)*(u^2-v^2)));
            4        3       2
        (- y  + z) (a  u + x)
%0046: -------------------------
       (- u + v) (u + v) (1 + x)
(%0047) factor(200*(-1*x+1+y)*(u-r^6)*(21*x+2-t^4));
           6            4                      2  3
%0047: (- r  + u) (2 - t  + 21 x) (1 - x + y) 5  2
(%0048) factor(2*(a+u)*(-v+b)*(a*x+y)^2);
                                       2
%0048: -1 2 (a + u) (- b + v) (a x + y)
(%0049) factor(2*(a+u)*(-v+b)*(a*x+y)^2/((u^2-v^2)*(11*x+55)));
                                    2
       2 (a + u) (- b + v) (a x + y)
%0049: ------------------------------
        11 (- u + v) (u + v) (5 + x)
(%0050) factor((c^3*u+b*a)*(b*b*a+v*p^2*q^2*c));
               3        2      2  2
%0050: (a b + c  u) (a b  + c p  q  v)
(%0051) factor((2*z+y-x)*(y^3-a*x^2)*(b*z^2+y));
             2    3                          2
%0051: (- a x  + y ) (- x + y + 2 z) (y + b z )
(%0052) factor((a*a*b*z+d)*(2*a*b*b*z+c));
             2                2
%0052: (d + a  b z) (c + 2 a b  z)
(%0053) factor((a*a*b*z+d)*(2*a*b*b*z+c)*((u+a)*x+1));
                             2                2
%0053: (1 + (a + u) x) (d + a  b z) (c + 2 a b  z)
(%0054) factor(a*(z+1)/4);
       a (1 + z)
%0054: ---------
           2
          2
@end example
@end deffn

@noindent
The rest of this section documents commands from the factoring package.
To use this package, execute the following command from the JACAL
prompt:

@code{require("ff");}

@noindent
Several of these commands return a matrix.  The first column contains
the factors and the second column contains the corresponding exponent.

@deffn Command sff poly
Given a primitive univariate polynomial @var{poly}, calculate the square
free factorisation of @var{poly}. A @dfn{primitive} polynomial is one
with no factors (other than units) common to all its coefficients.
@end deffn

@deffn Command ffsff poly p
@deffnx Command ffsff poly p m
Given a monic polynomial @var{poly}, a prime @var{p}, and a positive
integer @var{m}, calculate the square free factorisation of @var{poly}
in GF(p^m)[x].  If @var{m} is not supplied, @code{1} is assumed.

@example
(%0059) ffsff(x^5+x^3+1, 53);
       [                 2    3    ]
       [ 16 - 22 x + 26 x  + x   1 ]
%0059: [                           ]
       [        -13 + x          2 ]
@end example
@end deffn

@deffn Command berl poly n
Given a square-free univariate polynomial @var{poly} and an integer
power of a prime, @var{q}, returns (as a bunch) the irreducible factors
of @var{poly}.

@example
(%0060) berl(x^5+x^3+2, 53);
                           2               2
%0060: [1 + x, 5 - 26 x + x , 11 + 25 x + x ]
@end example
@end deffn

@deffn Command parfrac polyratio
Returns the partial fraction expansion of a rational univariate
polynomial @var{polyratio}.  The denominator of @var{polyratio} must be
square free.
This code is still being developed.
@end deffn

@node Transcendental Functions, Calculus, Algebra, Top
@chapter Transcendental Functions
@cindex Transcendental Functions

JACAL has the ability to manipulate and simplify functions defined by
first order linear differential equations.

The following functions and their reductions are defined by statements
in @file{init.math}.

@menu
* Exponentials and Logarithms::
* Trigonometric Functions::
* Lambert W function::
* Defining Differential Equations::
@end menu

@node Exponentials and Logarithms, Trigonometric Functions, Transcendental Functions, Transcendental Functions
@section Exponentials and Logarithms
@cindex Exponentials and Logarithms

@deffn Operator exp expression

Represents the exponential function of scalar @var{expression}.

@example
(%0043) exp(1+x);
%0043: exp(1 + x)
(%0044) exp(0);
%0044: 1
@end example
@end deffn

@deffn Operator log expression

Represents the natural logarithm of scalar @var{expression}.

@example
(%0045) log(1+x);
%0045: log(1 + x)
(%0046) exp(5*log(a));
        5
%0046: a
@end example
@end deffn

@deffn Operator %expt expression exponent

@code{%expt} is equivalent to
@code{@var{exponent}*log(@var{expression})}.  If @var{exponent} is an
integer, it simplifies to a power of @var{expression}; a fractional
@var{exponent} does not.

@example
(%0048) %expt(a,5);
        5
%0048: a
(%0049) %expt(a,1/5);
           log(a)
%0049: exp(------)
             5
(%0050) a^(1/5);
        1/5
%0050: a
@end example
@end deffn

@node Trigonometric Functions, Lambert W function, Exponentials and Logarithms, Transcendental Functions
@section Trigonometric Functions
@cindex Trigonometric Functions

@deffn Operator tan expression
@deffnx Operator atan expression

These are the tangent and arctangent functions, from which all the
other trigonometric functions are defined.
@end deffn

@deffn Operator cot expression
@deffnx Operator acot expression

@deffnx Operator sin expression
@deffnx Operator asin expression
@deffnx Operator cos expression
@deffnx Operator acos expression
@deffnx Operator sec expression
@deffnx Operator asec expression
@deffnx Operator csc expression
@deffnx Operator acsc expression

The standard trigonometric functions and their inverses.

@example
(%0051) tan(atan(x));
%0051: x
(%0052) atan(tan(x));
%0052: x
(%0053) tan(2*atan(x));
        2 x
%0053: ------
            2
       1 - x
(%0054) tan(3*atan(x));
                3
       - 3 x + x
%0054: ----------
               2
       -1 + 3 x
(%0055) tan(4*atan(x));
                   3
        - 4 x + 4 x
%0055: --------------
               2    4
       -1 + 6 x  - x
(%0056) atan(2*tan(x));
%0056: atan(2 tan(x))
(%0057) sin(3*asin(x));
                  3
%0057: - 3 x + 4 x
@end example
@end deffn

@node Lambert W function, Defining Differential Equations, Trigonometric Functions, Transcendental Functions
@section Lambert W function
@cindex Lambert W function

@deffn Command %W expression

The Lambert W function defined as the inverse of @code{z=%W*exp(%W)}.
@end deffn

@deffn Command lambert_w expression

This equivalent function has the name which MAXIMA uses.  It is
defined as:
@example
lambert_w(z) :: lambert_w(z)'/z'=lambert_w(z)/(z*(1+lambert_w(z)));
@end example

@code{lambert_w(log(x)*exp(log(x)))} does not reduce to @code{log(x)} because
the principal branch of the Lambert-W function reduces only when
@code{x>1/e}.
@end deffn

@node Defining Differential Equations,  , Lambert W function, Transcendental Functions
@section Defining Differential Equations
@cindex Defining Differential Equations

These are the commands used to define transcendental functions.

@deffn Command ::

@example
@var{func}(@var{x}) :: @var{func}(@var{x})'/@var{x}' = @var{expression}
@end example

Where @var{expression} is a function of @var{func}(@var{x}) and/or @var{x},
defines the differential equation for @var{func}.
@end deffn

@deffn Command ::~

@example
@var{inv} ::~ @var{func};
@var{inv}(@var{x}) ::~ @var{expression};
@end example

Defines @var{inv} as the inverse of @var{func} or @var{expression}.
@end deffn

@deffn Command ::=

@example
@var{func}(@var{const1}) ::= @var{const2}
@end example

Where @var{const1} and @var{const2} evaluate to constants, sets an
initial condition for the differential equation defining @var{func}.

The order in which initial conditions are defined matters; the first
initial condition defined is used to vet potential solutions for
differential equations.
@end deffn

The file @file{init.math} also defines expression-valued integer
recurrences which generate the reduction of a transcendental function
composed with an integer multiple of its inverse function.  In the
future these recurrences will be generated automatically from the
differential equations.

@deffn Command :=
@deffnx Command ::=

@example
@var{ident}[@var{index}] := @var{scalar-expression}
@end example

Defines @var{ident} as a memoized recurrence.  The
@var{scalar-expression} can be any expression, and may include
references to @var{ident} or other memoized recurrences with integer
argument @code{[@var{ixpr}]} where @var{ixpr} evaluates to a
non-negative integer.  The result of such a reference may be a
function; that function can take arguments within parentheses after a
@code{[@var{ixpr}]} argument.

@example
@var{ident}[@var{integer}] ::= @var{scalar-expression}
@end example

Sets an initial condition.  This is necessary to prevent runaway
recursion if a recurrence does index arithmetic.  Factorial can be
defined as:

@example
@group
(%0039) fact[n] := n*fact[n-1];
fact[n]: n * fact[n - 1]
(%0039) fact[0] ::= 1;
(%0040) fact[3];
%0040: 6
(%0041) fact[7];
%0041: 5040
@end group
@end example
@end deffn

@node Calculus, Matrices and Tensors, Transcendental Functions, Top
@chapter Calculus
@cindex Calculus

@section Differential Operator

@deffn Operator differential expr
@deffnx Operator ' expr

The Jacal command @code{differential} computes the derivative of the
expression @var{expr} with respect to a generic derivation. It is
generic in the sense that nothing is assumed about its effect on the
individual variables. The derivation is denoted by a right quote.

@example
@group
(%0061) differential(x^2+y^3);
                   2
%0061: 2 x x' + 3 y  y'
(%0062) (x^2+y^3)';
                   2
%0062: 2 x x' + 3 y  y'
@end group
@end example
@end deffn

@section Derivatives

@deffn Command diff expr var1 @dots{}

The Jacal command @code{diff} computes the derivative of the expression
@var{expr} with respect to @var{var1}, @dots{}.

@example
@group
(%0063) diff(x^2+y^3,y);
          2
%0063: 3 y
@end group
@end example
@end deffn

@deffn Command partial expr var1 @dots{}

The Jacal command @code{partial} computes the partial derivative of the
expression @var{expr} with respect to @var{var1}, @dots{}.

@example
@group
(%0064) partial(x^2+@@1^3,1);
           2
%0064: 3 @@1
@end group
@end example
@end deffn

@section Integration

@deffn Command integrate expr var

Returns the indefinite integral of rational expression @var{expr}, if
that integral is a rational expression containing at most one radical
involving @var{var}.
@example
@group
(%0065) integrate((3+x^2)*(1+x^2)^(2/3)/(3+6*x^2+3*x^4),x);
               2 2/3
       x (1 + x )
%0065: -------------
               2
          1 + x
(%0066) integrate((1+x^2)^(2/3),x);

;;; could-not-find-algebraic-anti-derivative
 non-decreasing-rxd 2 vs 0
(%0066) integrate(x*(1+x^2)^(2/3),x);
               2        2 2/3
       (3 + 3 x ) (1 + x )
%0066: ----------------------
                 10
@end group
@end example
@end deffn

@deffn Command integrate expr var a b

If the indefinite integral of rational expression @var{expr} is a
rational expression (optionally including a radical involving
@var{var}), then @code{integrate} returns the difference of that
integral evaluated at @var{b} and @var{a}.
@example
@group
(%0067) integrate(x*(1+x^2)^(2/3),x,0,1);
               2/3
       -3 + 6 2
%0067: -----------
           10
@end group
@end example
@end deffn

@node Matrices and Tensors, Lambda Calculus, Calculus, Top
@chapter Matrices and Tensors

In JACAL, a matrix is just a @code{bunch} of equal length
@code{bunch}s, and this is the structure that the matrix operations
currently supported by JACAL (ncmult(), ^^, transpose(), etc.) expect.
A row-vector is coded like @code{[[a,b,c]]}; a column-vector is coded
by @code{[[a],[b],[c]]} or @code{[[a,b,c]]^^t} or @code{[a,b,c]^^t}.

@menu
* Generating Matrices::
* Matrix Parts::
* Matrix commands::
* Tensors::
* tmult::                       Tensor Multiplication
* contract::                    Tensor Contraction
* indexshift::                  Shift an index within a tensor
* indexswap::                   Swaps two indices within a tensor
@end menu

@node Generating Matrices, Matrix Parts, Matrices and Tensors, Matrices and Tensors
@section Generating Matrices

@deffn Operator bunch elt_1 elt_2 @dots{}
@code{[@var{elt_1}, @var{elt_2}, @dots{}]}

To collect any number of Jacal objects into a bunch, simply enclose them
in square brackets. For example, to make the bunch whose elements are
@code{1}, @code{2}, @code{4}, type @code{[1, 2, 4]}. One can also nest
bunches, for example, @code{[1, [[1, 3], [2, 5]], [1, 4]]}.

A bunch whose only element is @code{[1, 2, 3]} is a row vector, which
displays as @code{[1 2 3]}.  The bunch has commas; the row vector does
not.

@example
@group
(%0068) B1:bunch(1, 2, 3);
B1: [1, 2, 3]
(%0068) B2:[B1];
B2: [ 1  2  3 ]
(%0068) [B2];
%0068: [ [1, 2, 3] ]
(%0069) [[[1, 2, 3]]];
%0069: [ [1, 2, 3] ]
@end group
@end example
@end deffn

@deffn Operator flatten bnch

Removes bunch nesting from @var{bnch}, returning a single bunch of the
constituent expressions and equations.

@example
@group
(%0070) flatten([a, [b, [c, d]], [5]]);
%0070: [a, b, c, d, 5]
@end group
@end example
@end deffn

@deffn Command ident n
The command @code{ident} takes as argument a positive integer @var{n}
and returns an @var{n}x@var{n} identity matrix. This is sometimes more
convenient than obtaining this same matrix using the command
@code{scalarmatrix}.

@example
@group
(%0071) ident(4);
       [ 1  0  0  0 ]
       [            ]
       [ 0  1  0  0 ]
%0071: [            ]
       [ 0  0  1  0 ]
       [            ]
       [ 0  0  0  1 ]
@end group
@end example
@end deffn

@deffn Command scalarmatrix size entry
The command @code{scalarmatrix} takes as inputs a positive integer
@var{size} and an algebraic expression @var{entry} and returns an
@code{@var{n} * @var{n}} diagonal matrix whose diagonal entries are all
equal to @var{entry}, where @code{@var{n} = @var{size}}.

@example
@group
(%0072) scalarmatrix(3, 6);
       [ 6  0  0 ]
       [         ]
%0072: [ 0  6  0 ]
       [         ]
       [ 0  0  6 ]
@end group
@end example
@end deffn

@deffn Command diagmatrix list
The Jacal command @code{diagmatrix} takes as input a list of objects and
returns the diagonal matrix having those objects as diagonal entries. In
case one wants all of the diagonal entries to be equal, it is more
convenient to use the command @code{scalarmatrix}.

@example
@group
(%0073) diagmatrix(12,3,a,s^2);
       [ 12  0  0  0  ]
       [              ]
       [ 0   3  0  0  ]
%0073: [              ]
       [ 0   0  a  0  ]
       [              ]
       [ 0   0  0   2 ]
       [           s  ]
(%0074) diagmatrix([1,2],2);
       [ [1, 2]  0 ]
%0074: [           ]
       [   0     2 ]
@end group
@end example
@end deffn

@deffn Command sylvester poly_1 poly_2 var
Here, @var{poly_1} and @var{poly_2} are polynomials and @var{var} is a
variable.  The function @code{sylvester} returns the matrix introduced
by Sylvester (@cite{A Method of Determining By Mere Inspection the
Derivatives from Two Equations of Any Degree, Phil.Mag. @code{16} (1840)
pp. 132-135, Mathematical Papers, vol. I, pp. 54-57}) for computing the
resultant of the two polynomials @var{poly_1} and @var{poly_2} with
respect to the variable @var{var}. If one wants to compute the resultant
itself, one can simply use the command @code{resultant} with the same
syntax.

@example
@group
(%0075) sylvester(a0 + a1*x + a2*x^2 + a3*x^3, b0 + b1*x + b2*x^2, x);
       [ a3  a2  a1  a0  0  ]
       [                    ]
       [ 0   a3  a2  a1  a0 ]
       [                    ]
%0075: [ b2  b1  b0  0   0  ]
       [                    ]
       [ 0   b2  b1  b0  0  ]
       [                    ]
       [ 0   0   b2  b1  b0 ]
@end group
@end example
@end deffn

@deffn Command genmatrix function rows cols
The function @code{genmatrix} takes as arguments a @var{function} of two
variables and two positive integers, @var{rows} and @var{cols}. It
returns a matrix with the indicated numbers of rows and columns in which
the $(i,j)$th entry is obtained by evaluating @var{function} at
$(i,j)$. The function may be defined in any of the ways available in
Jacal, i.e previously by an explicit algebraic definition, by an
explicit lambda expression or by an implicit lambda expression.

@example
@group
(%0076) genfun: @@1^2+@@2^2;
          2     2
genfun: @@1  + @@2
(%0076) genmatrix(genfun,3,5);
       [ 2   5   10  17  26 ]
       [                    ]
%0076: [ 5   8   13  20  29 ]
       [                    ]
       [ 10  13  18  25  34 ]
@end group
@end example
@end deffn

@node Matrix Parts, Matrix commands, Generating Matrices, Matrices and Tensors
@section Matrix Parts

@deffn Command rank matrix
The rank of @var{matrix} is the maximal number of linearly independent
columns of @var{matrix}, which is always equalt to the maximal number
of linearly independent rows of @var{matrix}.
@example
@group
(%0077) rank([[0,0],[0,0]]);
%0077: 0
(%0078) rank([[0,0],[0,1]]);
%0078: 1
(%0079) rank([[2,0],[0,1]]);
%0079: 2
(%0080) rank([[b,c],[0,a]]);
%0080: 2
(%0081) rank([[b,c,d],[a,0,a],[e,f,a]]);
%0081: 3
@end group
@end example
@end deffn

@deffn Command row matrix i
The command @code{row} returns the @var{i}th row of the matrix
@var{matrix}, where @code{i = @var{int}}.  If @var{int} is larger than
the number of rows of @var{matrix}, then Jacal prints an error message.
The corresponding command for columns of a matrix is @code{col}.

@example
@group
(%0082) U1:[[1, 2, 3], [1, 5, 3]];
    [ 1  2  3 ]
U1: [         ]
    [ 1  5  3 ]
(%0082) row(U1, 2);
%0082: [1, 5, 3]
@end group
@end example
@end deffn

@deffn Command col matrix integer
The command @code{col} is used to extract a column of a matrix.  Here,
@var{matrix} is a matrix and @var{integer} is a positive integer.  It
is an error if that integer exceeds the number of columns.

@example
@group
(%0084) C1:[[1,2,4],[2,5,6]];
    [ 1  2  4 ]
C1: [         ]
    [ 2  5  6 ]
(%0084) col(C1,2);
       [ 2 ]
%0084: [   ]
       [ 5 ]
@end group
@end example
@end deffn

@deffn Command minor matrix i j
The command @code{minor} returns the submatrix of @var{matrix}
obtained by deleting the @var{i}th row and the @var{j}th column.

@example
@group
(%0085) M3:[[1,2,3],[3,1,5],[5,2,7]];
    [ 1  2  3 ]
    [         ]
M3: [ 3  1  5 ]
    [         ]
    [ 5  2  7 ]
(%0085) minor(M3,3,1);
       [ 2  3 ]
%0085: [      ]
       [ 1  5 ]
@end group
@end example
@end deffn

@deffn Command cofactor matrix i j
The command @code{cofactor} returns the determinant of the @var{i},
@var{j} @code{minor} of @var{matrix}.
@end deffn

@deffn Command rref bunch int_1 int_2 @dots{}
The function @code{rref} is used to access elements of bunches.  It
can also access elements nested at lower levels in a bunch.  In
particular, it can also access matrix elements.  In the above syntax,
@var{bunch} is the bunch whose parts one wishes to access, and @var{n},
@var{int_1}, @var{int_2}, @dots{}, @var{int_n} are positive integers.
It returns the @var{int_n}-th element of the @var{int_@{n-1@}}-th element
of @dots{} of the @var{int_2}-th element of the @var{int_1}-th element
of @var{bunch}.  One can have @code{n = 0}.  In that case, @code{rref}
simply returns the bunch.

@example
@group
(%0088) [[1,2,3],[1,4,6],3] [2] [3];
%0088: 6
(%0089) [a,b] [2];
%0089: b
@end group
@end example
@end deffn

@node Matrix commands, Tensors, Matrix Parts, Matrices and Tensors
@section Matrix commands


@deffn Command transpose matrix
Computes the transpose of @code{(@var{matrix})}.

@example
@group
(%0000) transpose([[a,b],[c,d]]);
       [ a  c ]
%0000: [      ]
       [ b  d ]
(%0001) [[a,b],[c,d]]^^t;
       [ a  c ]
%0001: [      ]
       [ b  d ]
@end group
@end example

@end deffn


@deffn Command determinant matrix
The Jacal command @code{determinant} computes the determinant of a
square matrix.  Attempting to take the determinant of a non-square
matrix will produce an error message.

@example
@group
(%0008) A1:[[1,2],[6,7]];
    [ 1  2 ]
A1: [      ]
    [ 6  7 ]
(%0008) determinant(A1);
%0008: -5
@end group
@end example
@end deffn


@deffn Command charpoly matrix var
The characteristic polynomial of @var{matrix}:

determinant(@var{matrix} - I @var{var})

@end deffn


@deffn Command . matrix1 matrix2
Matrix multiplication.

@example
@group
(%0009) A1:[[1, 2, 3], [5, 2, 7]];
    [ 1  2  3 ]
A1: [         ]
    [ 5  2  7 ]
(%0009) A2:[[3, 2], [6, 4]];
    [ 3  2 ]
A2: [      ]
    [ 6  4 ]
(%0009) A2 . A1;
       [ 13  10  23 ]
%0009: [            ]
       [ 26  20  46 ]
@end group
@end example
@end deffn

@deffn Command ^^ matrix exponent

The infix operator @code{^^} is used for raising a square matrix to an
integral power.

@example
@group
(%0010) A3:[[1, 0], [-1, 1]];
    [ 1   0 ]
A3: [       ]
    [ -1  1 ]
(%0010) A3^^3;
       [ 1   0 ]
%0010: [       ]
       [ -3  1 ]
@end group
@end example

Negative exponents raise the inverse matrix to a power.

@example
@group
(%0000) A4: [[a, b], [c, d]];
    [ a  b ]
A4: [      ]
    [ c  d ]
(%0000) A4^^-1;
       [      d           - b     ]
       [ -----------  ----------- ]
       [ - b c + a d  - b c + a d ]
       [                          ]
%0000: [     - c           a      ]
       [ -----------  ----------- ]
       [ - b c + a d  - b c + a d ]
(%0001) A4^^-2;
       [                2                  - a b - b d        ]
       [         b c + d            ------------------------- ]
       [ -------------------------   2  2                2  2 ]
       [  2  2                2  2  b  c  - 2 a b c d + a  d  ]
       [ b  c  - 2 a b c d + a  d                             ]
       [                                     2                ]
%0001: [        - a c - c d                 a  + b c          ]
       [ -------------------------  ------------------------- ]
       [  2  2                2  2   2  2                2  2 ]
       [ b  c  - 2 a b c d + a  d   b  c  - 2 a b c d + a  d  ]
@end group

@group
(%0002) A4 . A4.1;
       [ 1  0 ]
%0002: [      ]
       [ 0  1 ]
(%0003) A4.1 . A4;
       [ 1  0 ]
%0003: [      ]
       [ 0  1 ]
(%0004) A4.2 . A4 . A4;
       [ 1  0 ]
%0004: [      ]
       [ 0  1 ]
@end group
@end example

@end deffn


@deffn Command dotproduct vector_1 vector_2
The Jacal function @code{dotproduct} returns the dot product of two
row vectors of the same length. It will also give the dot product of
two matrices of the same size by computing the sum of the dot products
of the corresponding rows or, what is the same, the trace of one
matrix times the transpose of the other one.

@example
@group
(%0005) V1: [1,2,3]; V2: [3,1,5];
V1: [1, 2, 3]
V2: [3, 1, 5]
(%0005) dotproduct(V1, V2);
%0005: 20
@end group
@end example
@end deffn

@deffn Command crossproduct vector_1 vector_2
The Jacal command @code{crossproduct} computes the cross product of two
vectors.  By definition, the two vectors must each have three
components.

@example
@group
(%0007) crossproduct([1,2,3],[4,2,5]);
%0007: [4, 7, -6]
@end group
@end example
@end deffn

@node Tensors, tmult, Matrix commands, Matrices and Tensors
@section Tensors
The @code{tensors} supported by JACAL are an extension of the matrix
structure (i.e., a bunch of bunches of bunches @dots{}) with the added
stipulation that all @code{dimensions} of the tensor be the same length
(e.g., 4x4x4).  The number of dimensions (indices) in a tensor is its
rank: A scalar is a tensor of rank 0; a vector is a rank 1 tensor; a
matrix has rank 2; and so on.

Further, just as matrix binary operations place restrictions on the
matrices involved (e.g., the row/column length requirement for matrix
multiplication), the tensor binary operations require that the dimensions
of each tensor be of the same length.  For example, you could not multiply
a 3x3 tensor and a 4x4x4 tensor.

JACAL's tensors do not support the construct of contravariant and covariant
indices.  Users must keep track of this information themselves, and perform
the necessary operations with an appropriate metric so that the "index
gymnastics" is performed correctly.

JACAL currently supports four tensor operations: @code{tmult},
@code{contract}, @code{indexshift}, and @code{indexswap}.  Each of these is
described in detail below.

To use JACAL's tensor operations, execute the following command from
the JACAL prompt:

        require("tensor");

To see tensor examples, download @file{rw.math} from the JACAL website
@url{https://www.gnu.org/software/jacal/}.  Typing
@code{batch("rw.math");} will execute the commands in the file,
computing tensors for The Robertson-Walker Cosmology Model.  You can
then view a tensor by typing its label (name before @samp{:}) followed
by a semicolon.

@example
(%0001) metric_ll: diagmatrix((S(x4))^2/(1 - k * x1^2), (S(x4))^2 * x1^2, (S(x4))^2 * x1^2 * (sin(x2))^2, - 1)
(%0002) metric_uu: diagmatrix(1/metric_ll[1][1], 1/metric_ll[2][2], 1/metric_ll[3][3], 1/metric_ll[4][4])
(%0002) metric_ul: ident(4)
(%0002) det_metric: determinant(metric_ll)
(%0002) d_metric_lll: indexshift([diff(metric_ll, x1), diff(metric_ll, x2), diff(metric_ll, x3), diff(metric_ll, x4)], 1, 3)
(%0002) Christoffel_ull: (tmult(metric_uu, d_metric_lll, 2, 1) + indexswap(tmult(metric_uu, d_metric_lll, 2, 1), 2, 3) - tmult(metric_uu, d_metric_lll, 2, 3))/2
(%0002) d_Christoffel_ulll: indexshift([diff(Christoffel_ull, x1), diff(Christoffel_ull, x2), diff(Christoffel_ull, x3), diff(Christoffel_ull, x4)], 1, 4)
(%0002) R_temp: d_Christoffel_ulll + indexshift(tmult(Christoffel_ull, Christoffel_ull, 2, 1), 2, 4)
(%0002) Riemann_ulll: indexswap(R_temp, 3, 4) - R_temp
(%0002) Ricci_ll: contract(Riemann_ulll, 1, 3)
(%0002) Ricci_ul: tmult(metric_uu, Ricci_ll, 2, 1)
(%0002) Ricci_uu: tmult(Ricci_ul, metric_uu, 2, 1)
(%0002) scalar_curv: contract(Ricci_ul, 1, 2)
(%0002) Einstein_ll: Ricci_ll - scalar_curv * metric_ll/2
(%0002) Einstein_ul: Ricci_ul - scalar_curv * metric_ul/2
(%0002) Einstein_uu: Ricci_uu - scalar_curv * metric_uu/2
(%0002) 
@group
(%0002) Einstein_uu;
             [        2   2                                                      ]
             [ - k + k  x1         0                                             ]
             [ ------------                              0                       ]
             [          4          k                                             ]
             [   (S(x4))     --------------              0                 0     ]
             [                   2        4                                      ]
             [      0        - x1  (S(x4))                      2          0     ]
Einstein_uu: [                                   k + k (tan(x2))                 ]
             [      0              0         -------------------------     0     ]
             [                                   2        4          2           ]
             [      0              0         - x1  (S(x4))  (tan(x2))     3 k    ]
             [                                                          -------- ]
             [                                           0                     2 ]
             [                                                          (S(x4))  ]
@end group
@end example

@node tmult, contract, Tensors, Matrices and Tensors
@section Tensor Multiplication
@deffn Command tmult matrix_1 matrix_2 index_1 index_2
@code{tmult} takes a minimum of two arguments which are the tensors on
which the multiplication operation is to be performed.

With no additional arguments, @code{tmult} will produce the outer
product of the two input tensors.  The rank of the resulting tensor is
the sum of the inputs' ranks, and the components of the result are
formed from the pair-wise products of components of the inputs.  For
example, for the input tensors @code{x[a,b]} and @code{y[c]}
@example
z:tmult(x,y); @result{} z[a,b,c] = x[a,b]*y[c]
@end example

With an additional argument, @code{tmult} will produce the inner product
of the two tensors on the specified index.  For example, given
@code{x[i,j]} and @code{y[k,l,m]}
@example
@group
z:tmult(x,y,3);
@result{}
                        length
                        -----
                        \
             z[a,b,c] =  >   x[a,q] * y[b,c,q]
                        /
                        -----
                        q = 1
@end group
@end example

Note that in this case @var{x} only has 2 indices.  All of JACAL's tensor
operations modify index inputs to be between 1 and the rank of the
tensor.  Thus, in this example, the 3 is modified to 2 in the case of @var{x}.
As another example, with @code{x[i,j,k]} and @code{y[l,m,n]}
@example
@group
z:tmult(x,y,2);
@result{}
                          length
                          -----
                          \
             z[a,b,c,d] =  >   x[a,q,b] * y[c,q,d]
                          /
                          -----
                          q = 1
@end group
@end example

With four arguments, @code{tmult} produces an inner product of the two
tensors on the specified indices.  For example, for @code{x[i,j]} and
@code{y[k,l,m]}
@example
@group
z:tmult(x,y,1,3);
@result{}
                        length
                        -----
                        \
             z[a,b,c] =  >   x[q,a] * y[b,c,q]
                        /
                        -----
                        q = 1
@end group
@end example

Note that matrix multiplication is the special case of an inner product (of
two "two dimensional matrices") on the second and first indices,
respectively: @code{tmult(x,y,2,1) @equiv{} ncmult(x,y)}

Finally, tmult handles the case of a scalar times a tensor, in which case
each component of the tensor is multiplied by the scalar.
@end deffn

@node contract, indexshift, tmult, Matrices and Tensors
@section Tensor contraction
@deffn Command contract matrix index1 @dots{}

The contraction operation produces a tensor of rank two less than a given
tensor.  It does this by performing a summation over two of the indices of
the given tensor, as clarified in the examples below.

@code{contract} takes at least one argument which is the tensor on which the
contraction operation is to be performed.  One or two additional arguments
may be provided to specify the indices to be used in the summation.  If no
additional arguments are provided, the summation is performed over the
first and second indices.  With one additional argument, the summation is
over the specified index and the one following it (e.g., if 3 is specified,
the third and fourth indices are used).  With two additional arguments, the
summation is performed over the indices specified.  The actual indices used
will be constrained to be between 1 and the rank of the tensor.

Examples:

1) For a square matrix (tensor of rank 2), @code{contract} returns a scalar that
is the sum of the diagonal elements of the matrix.

2) Given @code{x[i,j,k,l]}, the command
@example
y:contract(x,2,4);
@end example
produces:
@example
@group
                        length
                        -----
                        \
               y[a,b] =  >   x[a,q,b,q]
                        /
                        -----
                        q = 1
@end group
@end example

Special cases:  If @code{contract} is given a scalar (rank 0 tensor) as input,
it just returns the scalar.  For a vector (tensor of rank 1), @code{contract}
returns a scalar that is the sum of the elements of the vector.
@end deffn

@node indexshift, indexswap, contract, Matrices and Tensors
@section Shifting of Tensor Indices
@deffn Command indexshift matrix index1 @dots{}

@code{indexshift} rearranges the indices of a tensor.  It is one of two
generalizations of the matrix transpose operation (cf. @code{indexswap}).

@code{indexshift} takes at least one argument which is the tensor on which the
index shifting is to be performed.  One or two additional arguments may be
provided to specify the index and the position to which it is to be
shifted.  If no additional arguments are provided, the first index of the
tensor is shifted to the second position (equivalent the matrix transpose
operation).  If one additional argument is provided, it specifies the index
to be shifted, and that index will be shifted "to the right" one position
(e.g., if 3 is specified, the third index will be shifted to the forth
position).  If two additional arguments are provided, the first specifies
the index and the second specifies the position to which it is to be
shifted.  The actual index shifted and its shifted position will be
constrained to be between 1 and the rank of the tensor.

For example, given @code{x[a,b,c,d]}, the command
@code{y:indexshift(x,1,3);} produces a tensor @var{y} such that
@code{y[a,b,c,d] @equiv{} x[b,c,a,d]}.  In this example, the element
that was in position @code{[a,b,c,d]} in @var{x} will be in position
@code{[b,c,a,d]} in @var{y}.

Special cases:  If @code{indexshift} is given a scalar (rank 0 tensor) as input,
it just returns the scalar.  For a vector (tensor of rank 1), @code{indexshift}
transposes the 1-by-n matrix (row vector) to an n-by-1 matrix (column
vector).
@end deffn

@node indexswap,  , indexshift, Matrices and Tensors
@section Swapping of Tensor Indices
@deffn Command indexswap tensor @dots{}

@code{indexswap} rearranges the indices of a tensor.  It is one of two
generalizations of the matrix transpose operation (cf. @code{indexshift}).

@code{indexswap} takes at least one argument which is the tensor on which index
swapping is to be performed.  One or two additional arguments may be
provided to specify the indices to be swapped.  If no additional arguments
are provided, the first and second indices of the tensor are swapped
(equivalent the matrix transpose operation).   With one additional
argument, the specified index is swapped with the one following it (e.g.,
if 2 is specified, the second and third indices will be swapped).  If two
additional arguments are provided, they specify the indices to be swapped.
The actual indices used will be constrained to be between 1 and the rank of
the tensor.

For example, given x[a,b,c,d], the command @code{y:indexswap(x,2,4);}
produces a tensor @var{y} such that y[a,b,c,d] = x[a,d,c,b].  In this
example, the element that was in position [a,b,c,d] in @var{x} will be
in position [a,d,c,b] in @var{y}.

Special cases:  If @code{indexswap} is given a scalar (rank 0 tensor) as input,
it just returns the scalar.  For a vector (tensor of rank 1), @code{indexswap}
transposes the 1-by-n matrix (row vector) to an n-by-1 matrix (column
vector).
@end deffn

@node Lambda Calculus, Miscellaneous, Matrices and Tensors, Top
@chapter Lambda Calculus

@deffn Operator lambda varlist expression
Jacal has the ability to work with lambda expressions, via the command
@code{lambda}. Furthermore, Jacal always converts user definitions of
functions by any method into lambda expressions and converts the dummy
variables of the function definition into symbols such as @var{1},
@var{2}, @dots{}. Jacal can manipulate lambda expressions by
manipulating their function parts, as in @samp{e14} below.  Jacal can
also invert a function using the command @code{finv}.

@example
@group
(%0012) lambda([x],x^2);
         2
%0012: @@1
(%0013) lambda([x,y,z],x*y*z);
%0013: @@1 @@2 @@3
(%0014) %0012 + %0013;
         2
%0014: @@1  + @@1 @@2 @@3
@end group
@end example
@end deffn

@deffn Command elementwise function matrix1 matrix2 @dots{}
The arguments @var{matrix1}, @var{matrix2}, @dots{} must have the same
shape.  The command @code{elementwise} returns a new matrix formed by
applying @var{function} to each tuple of elements of @var{matrix1},
@var{matrix2}, @dots{}.

@example
@group
(%0015) elementwise(foo,[a, b], [c, d]);
%0015: [foo(a, c), foo(b, d)]
(%0016) elementwise(@@1+5*@@2,[a, b], [c, d]);
%0016: [a + 5 c, b + 5 d]
(%0017) elementwise(@@1-@@2,[9,8,7],[[1,0],[4,5],[6,3]]);
       [ 8  9 ]
       [      ]
%0017: [ 4  3 ]
       [      ]
       [ 1  4 ]
@end group
@end example
@end deffn


@deffn Command finv function
@code{@var{function}^^-1}

The command @code{finv} takes as input a function of one variable and
returns the inverse of that function. The function may be defined in any
of the ways permitted in Jacal, i.e. by an explicit algebraic
definition, by an explicit lambda expression or by an implicit lamba
expression. If @var{f} is the function, then typing @code{f^^-1} has the
same effect as typing @code{finv(@var{f})}.

@example
@group
(%0008) w(t):=t+1;
w(t): t + 1
(%0009) finv(w);
%0009: -1 + @@1
@end group
@end example
@end deffn

@node Miscellaneous, Flags, Lambda Calculus, Top
@chapter Miscellaneous

@deffn Command %
The symbol @code{%} represents the last expression obtained by Jacal. It
can be used in formulas like any other constant or variable or
expression.

@example
@group
(%0010) 5+x;
%0010: 5 + x
(%0011) %^2-%;
                   2
%0011: 20 + 9 x + x
@end group
@end example
@end deffn

@deffn Command batch filename
The command @code{batch} is used to read in a file containing scripts
of Jacal commands. Here, @var{filename} is a string in double
quotes. The precise way in which one refers to a file is, of course,
system dependent.
@end deffn


@deffn Command tex expr
@deffnx Command scheme expr
@deffnx Command disp2d expr
@deffnx Command standard expr
@deffnx Command std expr
Displays @var{expr} in TeX, the Scheme programming language, Jacal's
two-dimensional output format, Jacal's infix input format, or
compressed infix format respectively.

If one these top-level function calls is prefixed with @code{%horner},
the output will be in Horner's rule format, multiplication instead of
exponentiation.

@example
@group
(%0002) disp2d((x-1)^3/(x+1)^3);
              2    3
-1 + 3 x - 3 x  + x
--------------------
             2    3
1 + 3 x + 3 x  + x
(%0002) horner(disp2d((x-1)^3/(x+1)^3));
-1 + (3 + (-3 + x) x) x
-----------------------
 1 + (3 + (3 + x) x) x
(%0002) scheme((x-1)^3/(x+1)^3);
(/ (+ (- (+ -1 (* 3 x)) (* 3 (expt x 2)))
      (expt x 3))
   (+ 1 (* 3 x) (* 3 (expt x 2)) (expt x 3)))
(%0002) standard((x-1)^3/(x+1)^3);
(-1 + 3 * x - 3 * x^2 + x^3)/(1 + 3 * x + 3 * x^2 + x^3)
(%0002) std((x-1)^3/(x+1)^3);
(-1+3*x-3*x^2+x^3)/(1+3*x+3*x^2+x^3)
(%0002) tex((x-1)^3/(x+1)^3);
@{@{-1+3\,x-3\,x^@{2@}+x^@{3@}@}\over@{1+3\,x+3\,x^@{2@}+x^@{3@}@}@}
@end group
@end example
@end deffn

@deffn Command tex "string"
Read TeX expression @var{string}.
The @code{tex} command reads its double-quoted argument as a TeX
expression
@end deffn

@deffn Command scheme "string"
Read Scheme double-quoted @var{string} argument as Scheme cdoe.

@example
@group
(%0000) scheme("(- (expt b 2) (* 4 a c))");
        2
%0000: b  - 4 a c
@end group
@end example
@end deffn

@deffn Command disp2d "string"
@deffnx Command standard "string"
@deffnx Command std "string"
Reads double-quoted @var{string} in Jacal's infix input format.
@end deffn

@deffn Command commands
The command @code{commands} produces a list of all of the command
available in Jacal.  It is called as a function of no arguments.
@end deffn

@example
@group
@exdent commands();
% * + - / = ^ ^^ abs args arity augcoefmatrix b+/- b-/+ batch bunch cabs
canon chain chainables charpoly coeff coeffs coefmatrix cofactor col
commands compose content continue crossproduct decompose degree denom
depends derivative describe determinant diagmatrix diff
differential discriminant disp2d divide dotproduct elementwise eliminate
equatecoeffs example extensions definition factorial factors finv flatten
func gcd genmatrix help ident imagpart integrate interp interp.lagrange
interp.neville interp.newton jacobi jacobian listofvars load matrix minor
mod monomial ncmult negate normalize num or over parallel partial poly
polyelim prime? qed quit rank raw realpart require restart resultant row
rref scalarmatrix scheme scheme2d set shade shadows show
squarefreefactors squarefreefactorslist standard std sylvester system
taylor terms tex transcript transpose u+/- u-/+ varpri vd verify wronski
wronskian
@end group
@end example

@deffn Command describe command
The command @code{describe} is the heart of the builtin help facility of
Jacal.  Here, @var{command} is a string which is the name of a command
and @code{describe} produces a brief description of the command and in
many cases includes an example of its use. Together with the command
@code{commands()}, which prints a list of all available Jacal commands,
and the command @code{example}, which gives an example of the use of the
command, one can in principle use Jacal without a manual after one has
learned how to get started.

@example
@group
(%0012) describe(col);
built-in-operation
column.  column of a matrix
(%0012) describe(resultant);
built-in-operation
resultant.  The result of eliminating a variable between 2
equations (or polynomials).
(%0012) describe(/);
built-in-operation
Quotient, division, divide, over.
a/b
@end group
@end example
@end deffn


@deffn Command example command

Here, @var{command} is a string which is the name of a Jacal command.
@code{example} gives an example of the use of the command.
See also @ref{Miscellaneous,describe}.

@example
@group
(%0013) example(*);
a * 7
%0013: 7 a
@end group
@end example

Note: the command @code{example} executes the example it gives.  This
can lead to unpredictable results if the variables and constants in
the example have already been given values by the user.
@end deffn

@deffn Command load string
The Jacal command @code{load} takes as input a string and reads in a
@samp{Scheme} file whose name is obtained by appending the extension
@file{.scm} to the string.  If you want to read in a file of Jacal
commands, do not use @code{load}.  Instead use the command
@code{batch}. To load in the file @file{tensor.scm},

@example
@group
(%0014) load("tensor.scm"); 
"tensor.scm"
@end group
@end example
@end deffn



@deffn Command qed
Exit from Jacal to Scheme.  With interactive Scheme systems (such as
SCM), It does not return you to the operating system.  Instead it
suspends Jacal and returns you to the underlying scheme.  You can return
to the Jacal session where you left off by simply typing @code{(math)}.
If you do not wish to return to Jacal but really want to terminate the
session and return to the operating system, then after typing
@code{qed;}, type @code{(slib:exit)} or use @code{quit}.
@end deffn

@deffn Command quit
Exit directly from Jacal to the operating system.  You will not be able
to continue your Jacal session.

@example
@group
(%0015) qed;
scheme
> (math)
Type qed; to return to Scheme, type help; for help.
(%0015) quit();
unix>
@end group
@end example
@end deffn


@deffn Command system command
One can issue commands to the operating system without leaving Jacal. To
do this, one uses the command @code{system}. For example, in a UNIX
operating system, the command @code{system("ls");} will print the
directory. One way in which the command @code{system} might be
especially useful is to edit files containing Jacal scripts without
leaving Jacal, particularly in non-UNIX machines or on machines without
GNU emacs.

@example
@group
(%0000) system("echo hi there");
hi there
%0000: 0
@end group
@end example
@end deffn


@deffn Command terms
Prints a copy of the GNU General Public License
@example
@group
(%0001) terms();
                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.
@end group
@end example
                  [ rest deleted for brevity]
@end deffn

@deffn Command transcript string
The command @code{transcript} allows one to record a Jacal session. It
is called with the syntax @code{transcript(@var{string});}, where
@var{string} is the name of the file in which one wants to keep the
transcript of the session. When one wishes to stop recording, one types
@code{transcript();}. One is then free to use @code{transcript} again
later in the session on another file. One can use it on the same file,
but the file is overwritten. Presently, the command @code{transcript}
does not echo commands to a file.

@example
@group
(%0001) a:[1,2,3];
a: [1, 2, 3]
(%0001) transcript("foo");
"foo"
(%0002) a;
a: [1, 2, 3]
(%0002) transcript();
(%0002) system("cat foo");


(%0002) a;

(%0002) transcript();%0002: 0
@end group
@end example
@end deffn


@deffn Command set flag value
There are various flags that the Jacal user can control, namely the
Jacal command line prompt, the priority for printing terms in Jacal
output, the input grammar and the output grammar.  For a discussion of
the various grammars please @xref{Flags}.  The command @code{show} is
closely related, allowing one to see what the current settings are.
@end deffn


@deffn Command show flag
The command @code{show} enables the Jacal user to examine the current
setting of various flags as well as to list the flags that can be set
by the user and to display other information. To change the settings
of the flags, use the command @code{set}. To see all the information
accessible through the @code{show} command, type @code{show all}. To
see the available grammars, type @code{show grammars}.  To see the
current input grammar type @code{show ingrammar}. To see the current
output grammar, type @code{show outgrammar}. To see the current
variable ordering, type @code{show ordering}.
@end deffn

@example
@group
(%0003) show all;

     all debug echogrammar elims grammars horner ingrammar linkradicals
     ordering outgrammar page phases priority prompt trace version width

(%0003) show prompt;
%0003: %0003

(%0000) show ordering;

     @@ %W (exp(@@2*log(@@1)))' ((tanh(@@1))^(1/2))' ((1+(tan(@@1))^2)^(1/2))'
     ((-1+(tanh(@@1))^2)^(1/2))' (tanh(@@1))' (tan(@@1))' (log(@@1))' (exp(@@1^2))'
     (exp(@@1))' (exp(1))' (exp(-@@2^2))' (exp(-@@1^2))' (erf(@@1*%i))' (erf(@@1))'
     (atanh(1/@@1))' (atan(1/@@1))' (atan(1))'
     (atan((-@@1*%i*(-1+@@1^2)^(1/2))/(-1+@@1^2)))'
     (atan((-1+@@1^2)^(1/2)/(-1+@@1^2)))' (atan((-1+@@1^2)^(1/2)))'
     (atan(%i*(-1+@@1^2)^(1/2)/@@1))' exp(@@2*log(@@1)) (tanh(@@1))^(1/2)
     (1+(tan(@@1))^2)^(1/2) (-1+(tanh(@@1))^2)^(1/2) tanh(@@1) tan(@@1) log(@@1)
     exp(@@1^2) exp(@@1) exp(1) exp(-@@2^2) exp(-@@1^2) erf(@@1*%i) erf(@@1)
     atanh(1/@@1) atan(1/@@1) atan(1) atan((-@@1*%i*(-1+@@1^2)^(1/2))/(-1+@@1^2))
     atan((-1+@@1^2)^(1/2)/(-1+@@1^2)) atan((-1+@@1^2)^(1/2))
     atan(%i*(-1+@@1^2)^(1/2)/@@1) tanh tan log fre exp erf atanh atan lambert_w
     ((atan(1))^(1/2))' (atan(1))^(1/2) @@2' @@1' (@@1^(1/3))' (@@1^(1/2))'
     ((-1+@@1^2)^(1/2))' %i' @@' %tanhQ[@@1] %tanhQ[-1+@@1] %tanhP[@@1]
     %tanhP[-1+@@1] %tanQ[@@1] %tanQ[-1+@@1] %tanP[@@1] %tanP[-1+@@1] %expPQ[-1+@@1]
     @@3 @@2: @@2 @@1^(1/3) @@1^(1/2) (-1+@@1^2)^(1/2) %i @@1: @@1 %sqrt1 y x t
     ordering c b a ? ::@@ %tanhQ %tanhPQ %tanhP %tanQ %tanPQ %tanP %expPQ
     "Currently in math mode."
(%0000) show outgrammar;
%0000: disp2d
(%0001) show ingrammar;
%0001: standard
(%0002) show grammars;
%0002: [null, raw, scheme, scheme2d, std, standard, disp2d, tex]
@end group
@end example


@node Flags, Index, Miscellaneous, Top
@chapter Flags


@defvr Flag prompt string
If one changes the prompt, @var{string} is a string of
alphanumeric characters without quotes.  After this command is executed,
subsequent commands will cause new prompts to be obtained from
@var{string} by incrementing it.  If the prompt ends in a letter, it
will be treated as a digit in base 26 and incremented.  If it ends in a
string of digits, that string will be treated as a number in base 10 and
incremented.  The remaining characters in the string will play no role
in this incrementation.

@example
@group
(%0003) set prompt "az9Z";
(az9Z) a+b;
az9Z: a + b
(az9AA) a+b;
az9AA: a + b
(az9AB) set prompt "ok99";
(ok99) a+b;
ok99: a + b
(ok100) b+c;
ok100: b + c
@end group
@end example
@end defvr

@defvr Flag ingrammar grammar
@defvrx Flag outgrammar grammar
The following examples show how one changes the input grammar or the
output grammar.
@example
@group
(%0000) a:[[[1,2,3]]];
a: [ [1, 2, 3] ]
(%0000) set outgrammar standard;
(%0000) a;
a: [[[1, 2, 3]]]
(%0000) set outgrammar scheme;
(%0000) a;
(define a #(#(#(1 2 3))))

(%0000) (1+x)^5;
(define %0000 (+ 1 (* 5 x) (* 10 (expt x 2)) (* 10 (expt x 3)) (* 5 (expt x 4)) (expt x 5)))

(%0001) set ingrammar scheme;
(%0001) (+ %0000 1);
(define %0002 (+ 2 (* 5 x) (* 10 (expt x 2)) (* 10 (expt x 3)) (* 5 (expt x 4)) (expt x 5)))

(set ingrammar disp2d)
(%0003) diagmatrix(3,6);
(define %0003 #(#(3 0) #(0 6)))

(%0004) set outgrammar disp2d;
(%0004) %0003;
       [ 3  0 ]
%0003: [      ]
       [ 0  6 ]
(%0004) set outgrammar standard;
(%0004) %0003;
%0003: [[3, 0], [0, 6]]
@end group
@end example

Note that in the above examples, it is possible to input and output
expressions in scheme by setting the ingrammar and/or outgrammar to
@code{scheme}.  Doing so result in linear output (as with
@code{standard grammar}) as opposed to a two dimensional display (as
with @code{disp2d}).  The analogue of @code{disp2d} for scheme output
is Scheme pretty-printing.  To have such output, set the output
grammar to @code{scheme2d}.

@example
@group
(%0004) set outgrammar scheme2d;
(%0004) (1+x)^5;
(define %0004
  (+ 1
     (* 5 x)
     (* 10 (expt x 2))
     (* 10 (expt x 3))
     (* 5 (expt x 4))
     (expt x 5)))

@end group
@end example

Jacal also allows for output to be automatically typeset in @TeX{}.
This can be quite useful if one wants to use the results of one's
computations in published articles.  Continuing with the example of
@code{(1+x)^5} above, we have:

@example
@group
(%0005) set outgrammar tex;
(%0005) %0004;
%0004: 1+5\,x+10\,x^@{2@}+10\,x^@{3@}+5\,x^@{4@}+x^@{5@}
(%0005) (1+1/x)^3/(1-1/y)^4;
%0005: @{@{\left(1+3\,x+3\,x^@{2@}+x^@{3@}\right)\,y^@{4@}@}\over@{x^@{3@}-
  4\,x^@{3@}\,y+6\,x^@{3@}\,y^@{2@}-4\,x^@{3@}\,y^@{3@}+x^@{3@}\,y^@{4@}@}@}
@end group
@end example
@ifinfo

That looks much better when formatted by TeX in an article than the
Jacal output using @code{disp2d} grammar.
@end ifinfo
@tex
After being included in a document in math display mode, these two
examples will appear in the following way.
$$1+5\,x+10\,x^{2}+10\,x^{3}+5\,x^{4}+x^{5}$$
$${{\left(1+3\,x+3\,x^{2}+x^{3}\right)\,y^{4}}\over{x^{3}-
  4\,x^{3}\,y+6\,x^{3}\,y^{2}-4\,x^{3}\,y^{3}+x^{3}\,y^{4}}}$$
@end tex
@end defvr

@defvr Flag priority int
The following examples show how to set the priority of printing terms.
@example
@group
(%0000) a: [[[1,2,3]]];
a: [ [1, 2, 3] ]
(%0000) show priority a;

;;; expl->var not a simple variable:  [[[1 2 3]]]

(%0000) show priority b;
%0000: 3000
(%0001) show priority c;
%0001: 3000
(%0002) b+c;
%0002: b + c
(%0003) c+b;
%0003: b + c
(%0004) set priority b 2000;
(%0004) b+c;
%0004: b + c
(%0005) set priority b 4000;
(%0005) b+c;
%0005: c + b
(%0006) %0002;
%0002: b + c
@end group
@end example
@end defvr

@node Index,  , Flags, Top
@unnumbered Index

@printindex fn

@bye
