daveg@csvax.caltech.edu (David Gillespie) (06/06/90)
Posting-number: Volume 13, Issue 45 Submitted-by: daveg@csvax.caltech.edu (David Gillespie) Archive-name: gmcalc/part19 ---- Cut Here and unpack ---- #!/bin/sh # this is part 19 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file calc.texinfo continued # CurArch=19 if test ! -r s2_seq_.tmp then echo "Please unpack part 1 first!" exit 1; fi ( read Scheck if test "$Scheck" != $CurArch then echo "Please unpack part $Scheck next!" exit 1; else exit 0; fi ) < s2_seq_.tmp || exit 1 echo "x - Continuing file calc.texinfo" sed 's/^X//' << 'SHAR_EOF' >> calc.texinfo Xdue to roundoff error. X@end defun X X@defun is-true x XReturn true if the formula @var{x} represents a true value in XCalc, not Lisp, terms. It tests if @var{x} is a non-zero number. X@end defun X X@defun reject-arg val pred XAbort the current function evaluation due to unacceptable argument values. XThis calls @samp{(calc-record-why @var{pred} @var{val})}, then signals a XLisp error which @code{normalize} will trap. The net effect is that the Xfunction call which led here will be left in symbolic form.@refill X@end defun X X@defun inexact-value XIf Symbolic Mode is enabled, this will signal an error that causes X@code{normalize} to leave the formula in symbolic form, with the message X``Inexact result.'' (This function has no effect when not in Symbolic Mode.) XNote that if your function calls @samp{(sin 5)} in Symbolic Mode, the X@code{sin} function will call @code{inexact-value}, which will cause your Xfunction to be left unsimplified. You may instead wish to call X@samp{(normalize (list 'calcFunc-sin 5))}, which in Symbolic Mode will Xreturn the formula @samp{sin(5)} to your function.@refill X@end defun X X@node Computational Lisp Functions, Vector Lisp Functions, Predicates, Internals X@subsubsection Computational Functions X XThe functions described here do the actual computational work of the XCalculator. In addition to these, note that any function described in Xthe main body of this manual may be called from Lisp; for example, if Xthe documentation refers to the @code{calc-sqrt} [@code{sqrt}] command, Xthis means @code{calc-sqrt} is an interactive stack-based square-root Xcommand and @code{sqrt} (which @code{defmath} expands to @code{calcFunc-sqrt}) Xis the actual Lisp function for taking square roots.@refill X XThe functions @code{math-add}, @code{math-sub}, @code{math-mul}, X@code{math-div}, @code{math-mod}, and @code{math-neg} are not included Xin this list, since @code{defmath} allows you to write native Lisp X@code{+}, @code{-}, @code{*}, @code{/}, @code{%}, and unary @code{-}, Xrespectively, instead.@refill X X@defun normalize val X(Full form: @code{math-normalize}.) XReduce the value @var{val} to standard form. For example, if @var{val} Xis a fixnum, it will be converted to a bignum if it is too large, and Xif @var{val} is a bignum it will be normalized by clipping off trailing X(i.e., most-significant) zero digits and converting to a fixnum if it is Xsmall. All the various data types are similarly converted to their standard Xforms. Variables are left alone, but function calls are actually evaluated Xin formulas. For example, normalizing @samp{(+ 2 (calcFunc-abs -4))} will Xreturn 6.@refill X XIf a function call fails, because the function is void or has the wrong Xnumber of parameters, or because it returns @code{nil} or calls X@code{reject-arg} or @code{inexact-result}, @code{normalize} returns Xthe formula still in symbolic form.@refill X XIf the current Simplification Mode is ``none'' or ``numeric arguments Xonly,'' function calls may not be normalized. However, the more Xpowerful simplification modes (like algebraic simplification) are Xnot handled by @code{normalize}. They are handled by @code{calc-normalize}, Xwhich calls @code{normalize} and possibly some other routines, such Xas @code{simplify} or @code{simplify-units}. Programs should never Xcall @code{calc-normalize} except when popping or pushing values on Xthe stack.@refill X@end defun X X@defun evaluate-expr expr XReplace all variables in @var{expr} that have values with their values, Xthen use @code{normalize} to simplify the result. This is what happens Xwhen you press the @kbd{=} key interactively.@refill X@end defun X X@defmac with-extra-prec n body XEvaluate the Lisp forms in @var{body} with precision increased by @var{n} Xdigits. This is a macro which expands to X X@example X(math-normalize X (let ((calc-internal-prec (+ calc-internal-prec @var{n}))) X @var{body})) X@end example X XThe surrounding call to @code{math-normalize} causes a floating-point Xresult to be rounded down to the original precision afterwards. This Xis important because some arithmetic operations assume a number's Xmantissa contains no more digits than the current precision allows. X@end defmac X X@defun make-frac n d XBuild a fraction @samp{@var{n}:@var{d}}. This is equivalent to calling X@samp{(normalize (list 'frac @var{n} @var{d}))}, but more efficient. X@end defun X X@defun make-float mant exp XBuild a floating-point value out of @var{mant} and @var{exp}. X@end defun X X@defun make-sdev x sigma XBuild an error form out of @var{x} and the absolute value of @var{sigma}. XIf @var{sigma} is zero, the result is the number @var{x} directly. XIf @var{x} or @var{sigma} is not a valid type of object for use in Xerror forms, this calls @code{reject-arg}. X@end defun X X@defun make-intv mask lo hi XBuild an interval form out of @var{mask} (which is assumed to be an Xinteger from 0 to 3), and the limits @var{lo} and @var{hi}. If X@var{lo} is greater than @var{hi}, an empty interval form is returned. XThis calls @code{reject-arg} if @var{lo} or @var{hi} is unsuitable. X@end defun X X@defun sort-intv mask lo hi XBuild an interval form, similar to @code{make-intv}, except that if X@var{lo} is less than @var{hi} they are simply exchanged, and the Xbits of @var{mask} are swapped accordingly. X@end defun X X@defun make-mod n m X@tindex makemod XBuild a modulo form out of @var{n} and the modulus @var{m}. Since modulo Xforms do not allow formulas as their components, if @var{n} or @var{m} Xis not a real number or HMS form the result will be a formula which Xis a call to @code{makemod}, the algebraic version of this function. X@end defun X X@defun float x XConvert @var{x} to floating-point form. Integers and fractions are Xconverted to numerically equivalent floats; components of complex Xnumbers, vectors, HMS forms, error forms, intervals, and modulo forms Xare recursively floated. If the argument is a variable or formula, Xthis calls @code{reject-arg}. X@end defun X X@defun compare x y XCompare the numbers @var{x} and @var{y}, and return -1 if X@samp{(lessp @var{x} @var{y})}, 1 if @samp{(lessp @var{y} @var{x})}, X0 if @samp{(math-equal @var{x} @var{y})}, or 2 if the order is Xundefined or cannot be determined.@refill X@end defun X X@defun numdigs n XReturn the number of digits of integer @var{n}, effectively X@samp{ceil(log10(@var{n}))}, but much more efficient. Zero is Xconsidered to have zero digits. X@end defun X X@defun scale-int x n XShift integer @var{x} left @var{n} digits, or right -@var{n} digits Xwith truncation toward zero. X@end defun X X@defun scale-rounding x n XLike @code{scale-int}, except that a right shift rounds to the nearest Xinteger rather than truncating. X@end defun X X@defun fixnum n XReturn the integer @var{n} as a fixnum, i.e., a native Lisp integer. XIf @var{n} is outside the permissible range for Lisp integers (usually X24 binary bits) the result is undefined. X@end defun X X@defun sqr x XCompute the square of @var{x}; short for @samp{(^ @var{x} 2)}. X@end defun X X@defun quotient x y XDivide integer @var{x} by integer @var{y}; return an integer quotient Xand discard the remainder. If @var{x} or @var{y} is negative, the Xdirection of rounding is undefined. X@end defun X X@defun idiv x y XPerform an integer division; if @var{x} and @var{y} are both nonnegative Xintegers, this uses @code{quotient}, otherwise it computes X@samp{floor(@var{x}/@var{y})}. Thus the result is well-defined but Xslower than for @code{quotient}. X@end defun X X@defun imod x y XDivide integer @var{x} by integer @var{y}; return the integer remainder Xand discard the quotient. Like @code{quotient}, this works only for Xinteger arguments and is not well-defined for negative arguments. XFor a more well-defined result, use @samp{(% @var{x} @var{y})}. X@end defun X X@defun idivmod x y XDivide integer @var{x} by integer @var{y}; return a cons cell whose X@code{car} is @samp{(quotient @var{x} @var{y})} and whose @code{cdr} Xis @samp{(imod @var{x} @var{y})}.@refill X@end defun X X@defun pow x y XCompute @var{x} to the power @var{y}. In @code{defmath}, this can also Xbe written @samp{(^ @var{x} @var{y})} or @samp{(expt @var{x} @var{y})}. X@end defun X X@defun abs-approx x XCompute a fast approximation to the absolute value of @var{x}. For Xexample, for a rectangular complex number the result is the sum of Xthe absolute values of the components. X@end defun X X@findex two-pi X@findex pi-over-2 X@findex pi-over-4 X@findex pi-over-180 X@findex sqrt-two-pi X@findex sqrt-e X@findex e X@findex ln-2 X@findex ln-10 X@defun pi XThe function @samp{(pi)} computes @samp{pi} to the current precision. XSome other related constant-generating functions are @code{two-pi}, X@code{pi-over-2}, @code{pi-over-4}, @code{pi-over-180}, @code{sqrt-two-pi}, X@code{e}, @code{sqrt-e}, @code{ln-2}, and @code{ln-10}. Each function Xreturns a floating-point value in the current precision, and each uses Xcaching so that all calls after the first are essentially free.@refill X@end defun X X@defmac math-defcache @var{func} @var{initial} @var{form} XThis macro, usually used as a top-level call like @code{defun} or X@code{defvar}, defines a new cached constant analogous to @code{pi}, etc. XIt defines a function @code{func} which returns the requested value; Xif @var{initial} is non-@code{nil} it must be a @samp{(float @dots{})} Xform which serves as an initial value for the cache. If @var{func} Xis called when the cache is empty or does not have enough digits to Xsatisfy the current precision, the Lisp expression @var{form} is evaluated Xwith the current precision increased by four, and the result minus its Xtwo least significant digits is stored in the cache. For example, Xcalling @samp{(pi)} with a precision of 30 computes @samp{pi} to 34 Xdigits, rounds it down to 32 digits for future use, then rounds it Xagain to 30 digits for use in the present request.@refill X@end defmac X X@findex half-circle X@findex quarter-circle X@defun full-circle symb XIf the current angular mode is Degrees or HMS, this function returns the Xinteger 360. In Radians mode, this function returns either the Xcorresponding value in radians to the current precision, or the formula X@samp{2*pi}, depending on the Symbolic Mode. There are also similar Xfunction @code{half-circle} and @code{quarter-circle}. X@end defun X X@defun power-of-2 n XCompute two to the integer power @var{n}, as a (potentially very large) Xinteger. Powers of two are cached, so only the first call for a Xparticular @var{n} is expensive. X@end defun X X@defun integer-log2 n XCompute the base-2 logarithm of @var{n}, which must be an integer which Xis a power of two. If @var{n} is not a power of two, this function will Xreturn @code{nil}. X@end defun X X@defun div-mod a b m XDivide @var{a} by @var{b}, modulo @var{m}. This returns @code{nil} if Xthere is no solution, or if any of the arguments are not integers.@refill X@end defun X X@defun pow-mod a b m XCompute @var{a} to the power @var{b}, modulo @var{m}. If @var{a}, X@var{b}, and @var{m} are integers, this uses an especially efficient Xalgorithm. Otherwise, it simply computes @samp{(% (^ a b) m)}. X@end defun X X@defun isqrt n XCompute the integer square root of @var{n}. This is the square root Xof @var{n} rounded down toward zero, i.e., @samp{floor(sqrt(@var{n}))}. XIf @var{n} is itself an integer, the computation is especially efficient. X@end defun X X@defun to-hms a ang XConvert the argument @var{a} into an HMS form. If @var{ang} is specified, Xit is the angular mode in which to interpret @var{a}, either @samp{'deg} Xor @samp{'rad}. Otherwise, the current angular mode is used. If @var{a} Xis already an HMS form it is returned as-is. X@end defun X X@defun from-hms a ang XConvert the HMS form @var{a} into a real number. If @var{ang} is specified, Xit is the angular mode in which to express the result, otherwise the Xcurrent angular mode is used. If @var{a} is already a real number, it Xis returned as-is. X@end defun X X@defun to-radians a XConvert the number or HMS form @var{a} to radians from the current Xangular mode. X@end defun X X@defun from-radians a XConvert the number @var{a} from radians to the current angular mode. XIf @var{a} is a formula, this returns the formula @samp{deg(@var{a})}. X@end defun X X@defun to-radians-2 a XLike @code{to-radians}, except that in Symbolic Mode a degrees to Xradians conversion yields a formula like @samp{@var{a}*pi/180}. X@end defun X X@defun from-radians-2 a XLike @code{from-radians}, except that in Symbolic Mode a radians to Xdegrees conversion yields a formula like @samp{@var{a}*180/pi}. X@end defun X X@defun random-digit XProduce a random base-1000 digit in the range 0 to 999. X@end defun X X@defun random-digits n XProduce a random @var{n}-digit integer; this will be an integer Xin the interval @samp{[0, 10^@var{n})}. X@end defun X X@defun random-float XProduce a random float in the interval @samp{[0, 1)}. X@end defun X X@defun prime-test n iters XDetermine whether the integer @var{n} is prime. Return a list which has Xone of these forms: @samp{(nil @var{f})} means the number is non-prime Xbecause it was found to be divisible by @var{f}; @samp{(nil)} means it Xwas found to be non-prime by table look-up (so no factors are known); X@samp{(nil unknown)} means it is definitely non-prime but no factors Xare known because @var{n} was large enough that Fermat's probabilistic Xtest had to be used; @samp{(t)} means the number is definitely prime; Xand @samp{(maybe @var{i} @var{p})} means that Fermat's test, after @var{i} Xiterations, is @var{p} percent sure that the number is prime. The X@var{iters} parameter is the number of Fermat iterations to use, in the Xcase that this is necessary. If @code{prime-test} returns ``maybe,'' Xyou can call it again with the same @var{n} to get a greater certainty; X@code{prime-test} remembers where it left off.@refill X@end defun X X@defun to-simple-fraction f XIf @var{f} is a floating-point number which can be represented exactly Xas a small rational number. return that number, else return @var{f}. XFor example, 0.75 would be converted to 3:4. This function is very Xfast. X@end defun X X@defun to-fraction f tol XFind a rational approximation to floating-point number @var{f} to within Xa specified tolerance @var{tol}; this corresponds to the algebraic Xfunction @code{frac}, and can be rather slow. X@end defun X X@node Vector Lisp Functions, Symbolic Lisp Functions, Computational Lisp Functions, Internals X@subsubsection Vector Functions X XThe functions described here perform various operations on vectors and Xmatrices. X X@defun math-concat x y XDo a vector concatenation; this operation is written @samp{@var{x} | @var{y}} Xin a symbolic formula. @xref{Building Vectors}. X@end defun X X@defun vec-length v XReturn the length of vector @var{v}. If @var{v} is not a vector, the Xresult is zero. If @var{v} is a matrix, this returns the number of Xrows in the matrix. X@end defun X X@defun mat-dimens m XDetermine the dimensions of vector or matrix @var{m}. If @var{m} is not Xa vector, the result is an empty list. If @var{m} is a plain vector Xbut not a matrix, the result is a one-element list containing the length Xof the vector. If @var{m} is a matrix with @var{r} rows and @var{c} columns, Xthe result is the list @samp{(@var{r} @var{c})}. Higher-order tensors Xproduce lists of more than two dimensions. Note that the object X@samp{[[1, 2, 3], [4, 5]]} is a vector of vectors not all the same size, Xand is treated by this and other Calc routines as a plain vector of two Xelements.@refill X@end defun X X@defun dimension-error XAbort the current function with a message of ``Dimension error.'' XThe Calculator will leave the function being evaluated in symbolic Xform; this is really just a special case of @code{reject-arg}. X@end defun X X@defun build-vector args XReturn a Calc vector with the zero-or-more @var{args} as elements. XFor example, @samp{(build-vector 1 2 3)} returns the Calc vector X@samp{[1, 2, 3]}, stored internally as the list @samp{(vec 1 2 3)}. X@end defun X X@defun make-vec obj dims XReturn a Calc vector or matrix all of whose elements are equal to X@var{obj}. For example, @samp{(make-vec 27 3 4)} returns a 3x4 matrix Xfilled with 27's. X@end defun X X@defun row-matrix v XIf @var{v} is a plain vector, convert it into a row matrix, i.e., Xa matrix whose single row is @var{v}. If @var{v} is already a matrix, Xleave it alone. X@end defun X X@defun col-matrix v XIf @var{v} is a plain vector, convert it into a column matrix, i.e., a Xmatrix with each element of @var{v} as a separate row. If @var{v} is Xalready a matrix, leave it alone. X@end defun X X@defun map-vec f v XMap the Lisp function @var{f} over the Calc vector @var{v}. For example, X@samp{(map-vec 'math-floor v)} returns a vector of the floored components Xof vector @var{v}. X@end defun X X@defun map-vec-2 f a b XMap the Lisp function @var{f} over the two vectors @var{a} and @var{b}. XIf @var{a} and @var{b} are vectors of equal length, the result is a Xvector of the results of calling @samp{(@var{f} @var{ai} @var{bi})} Xfor each pair of elements @var{ai} and @var{bi}. If either @var{a} or X@var{b} is a scalar, it is matched with each value of the other vector. XFor example, @samp{(map-vec-2 'math-add v 1)} returns the vector @var{v} Xwith each element increased by one. Note that using @samp{'+} would not Xwork here, since @code{defmath} does not expand function names everywhere, Xjust where they are in the function position of a Lisp expression.@refill X@end defun X X@defun reduce-vec f v XReduce the function @var{f} over the vector @var{v}. For example, if X@var{v} is @samp{[10, 20, 30, 40]}, this calls @samp{(f (f (f 10 20) 30) 40)}. XIf @var{v} is a matrix, this reduces over the rows of @var{v}. X@end defun X X@defun reduce-cols f m XReduce the function @var{f} over the columns of matrix @var{m}. For Xexample, if @var{m} is @samp{[[1, 2], [3, 4], [5, 6]]}, the result Xis a vector of the two elements @samp{(f (f 1 3) 5)} and @samp{(f (f 2 4) 6)}. X@end defun X X@defun mat-row m n XReturn the @var{n}th row of matrix @var{m}. This is equivalent to X@samp{(elt m n)}. For a slower but safer version, use @code{mrow}. X(@xref{Extracting Elements}.) X@end defun X X@defun mat-col m n XReturn the @var{n}th column of matrix @var{m}, in the form of a vector. XThe arguments are not checked for correctness. X@end defun X X@defun mat-less-row m n XReturn a copy of matrix @var{m} with its @var{n}th row deleted. The Xnumber @var{n} must be in range from 1 to the number of rows in @var{m}. X@end defun X X@defun mat-less-col m n XReturn a copy of matrix @var{m} with its @var{n}th column deleted. X@end defun X X@defun transpose m XReturn the transpose of matrix @var{m}. X@end defun X X@defun flatten-vector v XFlatten nested vector @var{v} into a vector of scalars. For example, Xif @var{v} is @samp{[[1, 2, 3], [4, 5]]} the result is @samp{[1, 2, 3, 4, 5]}. X@end defun X X@defun copy-matrix m XIf @var{m} is a matrix, return a copy of @var{m}. This maps X@code{copy-sequence} over the rows of @var{m}; in Lisp terms, each Xelement of the result matrix will be @code{eq} to the corresponding Xelement of @var{m}, but none of the @code{cons} cells that make up Xthe structure of the matrix will be @code{eq}. If @var{m} is a plain Xvector, this is the same as @code{copy-sequence}.@refill X@end defun X X@defun swap-rows m r1 r2 XExchange rows @var{r1} and @var{r2} of matrix @var{m} in-place. In Xother words, unlike most of the other functions described here, this Xfunction changes @var{m} itself rather than building up a new result Xmatrix. The return value is @var{m}, i.e., @samp{(eq (swap-rows m 1 2) m)} Xis true, with the side effect of exchanging the first two rows of X@var{m}.@refill X@end defun X X@node Symbolic Lisp Functions, Formatting Lisp Functions, Vector Lisp Functions, Internals X@subsubsection Symbolic Functions X XThe functions described here operate on symbolic formulas in the XCalculator. X X@defun simplify expr XSimplify the expression @var{expr} by applying various algebraic rules. XThis is what the @kbd{a s} (@code{calc-simplify}) command uses. X@end defun X X@defun simplify-extended expr XSimplify the expression @var{expr}, with additional rules enabled that Xhelp do a more thorough job, while not being entirely ``safe'' in all Xcircumstances. (For example, this mode will simplify @samp{sqrt(x^2)} Xto @samp{x}, which is only valid when @var{x} is positive.) This is Ximplemented by temporarily binding the variable @code{math-living-dangerously} Xto @code{t} (using a @code{let} form) and calling @code{simplify}. XDangerous simplification rules are written to check this variable Xbefore taking any action.@refill X@end defun X X@defun simplify-units expr XSimplify the expression @var{expr}, treating variable names as units Xwhenever possible. This works by binding the variable X@code{math-simplifying-units} to @code{t} while calling @code{simplify}. X@end defun X X@defmac math-defsimplify funcs body XRegister a new simplification rule; this is normally called as a top-level Xform, like @code{defun} or @code{defmath}. If @var{funcs} is a symbol X(like @code{+} or @code{calcFunc-sqrt}), this simplification rule is Xapplied to the formulas which are calls to the specified function. Or, X@var{funcs} can be a list of such symbols; the rule applies to all Xfunctions on the list. The @var{body} is written like the body of a Xfunction with a single argument called @code{expr}. The body will be Xexecuted with @code{expr} bound to a formula which is a call to one of Xthe functions @var{funcs}. If the function body returns @code{nil}, or Xif it returns a result @code{equal} to the original @code{expr}, it is Xignored and Calc goes on to try the next simplification rule that applies. XIf the function body returns something different, that new formula is Xsubstituted for @var{expr} in the original formula. The simplifier Xmakes multiple passes until no rules produce any further change. The Xsimplifier calls @code{normalize} after every pass.@refill X XNote that, since @code{defmath} is not being used here, @var{body} must Xbe written in true Lisp code without the conveniences that @code{defmath} Xprovides. If you prefer, you can have @var{body} simply call another Xfunction (defined with @code{defmath}) which does the real work. X XThe arguments of a function call will already have been simplified Xbefore any rules for the call itself are invoked. Since a new argument Xlist is consed up when this happens, this means that the rule's body is Xallowed to rearrange the function's arguments destructively if that is Xconvenient. Here is a typical example of a simplification rule: X X@example X(math-defsimplify calcFunc-sin X (or (and (eq (car-safe (nth 1 expr)) 'calcFunc-arcsin) X (nth 1 (nth 1 expr))) X (and math-living-dangerously X (eq (car-safe (nth 1 expr)) 'calcFunc-arccos) X (list 'calcFunc-sqrt X (math-sub 1 (math-sqr (nth 1 (nth 1 expr)))))))) X@end example X XThis is really a pair of rules written with one @code{math-defsimplify} Xfor convenience; the first replaces @samp{sin(arcsin(x))} with @samp{x}, Xand the second, which is not safe for all @samp{x}, replaces X@samp{sin(arccos(x))} with @samp{sqrt(1-x^2)}. Note that a @code{sqrt} Xformula is built rather than simply calling @samp{(sqrt @dots{})} to Xavoid problems with, for example, @samp{(sqrt 2)} aborting the computation Xif Symbolic Mode is enabled. Since @code{normalize} is called after every Xsimplification pass, this @code{sqrt} formula will have a chance to be Xevaluated before the user sees it.@refill X@end defmac X X@defun common-constant-factor expr XCheck @var{expr} to see if it is a sum of terms all multiplied by the Xsame rational value. If so, return this value. If not, return @code{nil}. XFor example, if called on @samp{6x + 9y + 12z}, it would return 3, since X3 is a common factor of all the terms. X@end defun X X@defun cancel-common-factor expr factor XAssuming @var{expr} is a sum with @var{factor} as a common factor, Xdivide each term of the sum by @var{factor}. This is done by Xdestructively modifying parts of @var{expr}, on the assumption that Xit is being used by a simplification rule (where such things are Xallowed; see above). For example, consider this built-in rule for Xsquare roots: X X@example X(math-defsimplify calcFunc-sqrt X (let ((fac (math-common-constant-factor (nth 1 expr)))) X (and fac X (math-mul (list 'calcFunc-sqrt fac) X (list 'calcFunc-sqrt X (math-cancel-common-factor X (nth 1 expr) fac)))))) X@end example X@end defun X X@defun frac-gcd a b XCompute a ``rational GCD'' of @var{a} and @var{b}, which must both be Xrational numbers. This is the fraction composed of the GCD of the Xnumerators of @var{a} and @var{b}, over the GCD of the denominators. XIt is used by @code{common-constant-factor}.@refill X@end defun X X@defun map-tree func expr many XTry applying Lisp function @var{func} to various sub-expressions of X@var{expr}. Initially, call @var{func} with @var{expr} itself as an Xargument. If this returns an expression which is not @code{equal} to X@var{expr}, apply @var{func} again until eventually it does return X@var{expr} with no changes. Then, if @var{expr} is a function call, Xrecursively apply @var{func} to each of the arguments. This keeps going Xuntil no changes occur anywhere in the expression; this final expression Xis returned by @code{map-tree}. Note that, unlike simplification rules, X@var{func} functions may @emph{not} make destructive changes to X@var{expr}. If a third argument @var{many} is provided, it is an Xinteger which says how many times @var{func} may be applied; the Xdefault, as described above, is infinitely many times.@refill X@end defun X X@defun apply-rewrite expr old new cond XApply a rewrite rule at the top level of @var{expr}, if possible, and Xreturn the rewritten expression. If the rule does not match, return X@code{nil}. X@end defun X X@defun check-rewrite-rules rules XMake sure @var{rules} is a Calc expression in a form suitable for use Xas rewrite rules (i.e., a vector of two or three elements, a vector Xof such vectors, or a variable whose definition is a valid set of Xrewrite rules). If so, return it in the form of a Lisp list of rewrite Xrules. If it is not valid, call @code{error} to abort the command. X@end defun X X@defun apply-rewrite-rules expr rules XApply a Lisp list of rewrite rules at the top level of an expression. XUse the first rule that applies; if none apply, return @code{nil}. X@end defun X X@defun deriv expr var value symb XCompute the derivative of @var{expr} with respect to variable @var{var} X(which may actually be any sub-expression). If @var{value} is specified, Xthe derivative is evaluated at the value of @var{var}; otherwise, the Xderivative is left in terms of @var{var}. If the expression contains Xfunctions for which no derivative formula is known, new derivative Xfunctions are invented by adding primes to the names; @pxref{Calculus}. XHowever, if @var{symb} is non-@code{nil}, the presence of undifferentiable Xfunctions in @var{expr} instead cancels the whole differentiation, and X@code{deriv} returns @code{nil} instead. X XDerivatives of an function of one argument can be defined by Xadding a @code{math-derivative} property to the function's property Xlist. The value of the property should be a Lisp function of one Xargument (which is the argument that appears in the function call being Xdifferentiated), which should return a formula for the derivative. XFor example, the derivative of @code{ln} is defined by X X@example X(put 'calcFunc-ln 'math-derivative X (function (lambda (u) (math-div 1 u)))) X@end example X@end defun X X@defun tderiv expr var value symb XCompute the total derivative of @var{expr}. This is the same as X@code{deriv}, except that variables other than @var{var} are not Xassumed to be constant with respect to @var{var}. X@end defun X X@defun integ expr var low high XCompute the integral of @var{expr} with respect to @var{var}. X@xref{Calculus}, for further details. X@end defun X X@defmac math-defintegral funcs body XDefine a rule for integrating a function or functions of one argument; Xthis macro is very similar in format to @code{math-defsimplify}. XThe main difference is that here @var{body} is the body of a function Xwith a single argument @code{u} which is bound to the argument to the Xfunction being integrated, not the function call itself. Also, the Xvariable of integration is available as @code{math-integ-var}. If Xevaluation of the integral requires doing further integrals, the body Xshould call @samp{(math-integral @var{x})} to find the integral of X@var{x} with respect to @code{math-integ-var}; this function returns X@code{nil} if the integral could not be done. Some examples: X X@example X(math-defintegral calcFunc-conj X (let ((int (math-integral u))) X (and int X (list 'calcFunc-conj int)))) X X(math-defintegral calcFunc-cos X (and (equal u math-integ-var) X (math-from-radians-2 (list 'calcFunc-sin u)))) X@end example X XIn the @code{cos} example, we define only the integral of @samp{cos(x) dx}, Xrelying on the general integration-by-substitution facility to handle Xcosines of more complicated arguments. An integration rule should return X@code{nil} if it can't do the integral; if several rules are defined for Xthe same function, they are tried in order until one returns a non-@code{nil} Xresult.@refill X@end defmac X X@defmac math-defintegral-2 funcs body XDefine a rule for integrating a function or functions of two arguments. XThis is exactly analogous to @code{math-defintegral}, except that @var{body} Xis written as the body of a function with two arguments, @var{u} and X@var{v}.@refill X@end defmac X X@defun solve-for lhs rhs var full XAttempt to solve the equation @samp{@var{lhs} = @var{rhs}} by isolating Xthe variable @var{var} on the lefthand side; return the resulting righthand Xside, or @code{nil} if the equation cannot be solved. The variable X@var{var} must appear at least once in @var{lhs} or @var{rhs}; if it Xappears more than once, Calc can solve the equation in only a few cases X(such as when the quadratic formula can be applied). Note that the Xreturn value is a formula which does not contain @var{var}; this is Xdifferent from the user-level @code{solve} and @code{finv} functions, Xwhich return a rearranged equation or a functional inverse, respectively. XIf @var{full} is non-@code{nil}, a full solution including dummy signs Xand dummy integers will be produced. User-defined inverses are provided Xas properties in a manner similar to derivatives:@refill X X@example X(put 'calcFunc-ln 'math-inverse X (function (lambda (x) (list 'calcFunc-exp x)))) X@end example X XThis function can call @samp{(math-solve-get-sign @var{x})} to create Xa new arbitrary sign variable, returning @var{x} times that sign, and X@samp{(math-solve-get-int @var{x})} to create a new arbitrary integer Xvariable multiplied by @var{x}. These functions simply return @var{x} Xif the caller requested a non-``full'' solution. X@end defun X X@defun expr-contains expr var XReturns the number of occurrences of @var{var} as a subexpression Xof @var{expr}, or @code{nil} if there are no occurrences. Thus, Xthis function can be used as a Lisp predicate or as an actual counting Xfunction.@refill X@end defun X X@defun expr-depends expr var XReturns true if @var{expr} refers to any variable the occurs in @var{var}. XIn other words, it checks if @var{expr} and @var{var} have any variables Xin common. X@end defun X X@defun expr-contains-vars expr XReturn true if @var{expr} contains any variables, or @code{nil} if @var{expr} Xcontains only constants and functions with constant arguments. X@end defun X X@defun expr-subst expr old new XReturns a copy of @var{expr}, with all occurrences of @var{old} replaced Xby @var{new}. This treats the derivative forms specially with respect Xto the dummy variable, so that the effect is always to return @var{expr} Xevaluated at @var{old} = @var{new}.@refill X@end defun X X@defun expr-weight expr XReturns the ``weight'' of @var{expr}, basically a count of the total Xnumber of objects and function calls that appear in @var{expr}. For X``primitive'' objects, this will be one. X@end defun X X@defun expr-height expr XReturns the ``height'' of @var{expr}, which is the deepest level to Xwhich function calls are nested. (Note that @samp{@var{a} + @var{b}} Xcounts as a function call.) For primitive objects, this returns zero.@refill X@end defun X X@defun polynomial-p expr var XCheck if @var{expr} is a polynomial in variable (or sub-expression) X@var{var}. If so, return the degree of the polynomial, that is, the Xhighest power of @var{var} that appears in @var{expr}. For example, Xfor @samp{(x^2 + 3)^3 + 4} this would return 6. This function returns X@code{nil} unless @var{expr}, when expanded out by @kbd{a x} X(@code{calc-expand}), would consist of a sum of terms in which @var{var} Xappears only raised to nonnegative integer powers. Note that if X@var{var} does not occur in @var{expr}, then @var{expr} is considered Xa polynomial of degree 0.@refill X@end defun X X@defun is-polynomial expr var degree loose XCheck if @var{expr} is a polynomial in variable or sub-expression X@var{var}, and, if so, return a list representation of the polynomial Xwhere the elements of the list are coefficients of successive powers of X@var{var}: @samp{@var{a} + @var{b} x + @var{c} x^3} would produce the Xlist @samp{(@var{a} @var{b} 0 @var{c})}, and @samp{(x + 1)^2} would Xproduce the list @samp{(1 2 1)}. The highest element of the list will Xbe non-zero, with the special exception that if @var{expr} is the Xconstant zero, the returned value will be @samp{(0)}. Return @code{nil} Xif @var{expr} is not a polynomial in @var{var}. If @var{degree} is Xspecified, this will not consider polynomials of degree higher than that Xvalue. This is a good precaution because otherwise an input of X@samp{(x+1)^1000} will cause a huge coefficient list to be built. If X@var{loose} is non-@code{nil}, then a looser definition of a polynomial Xis used in which coefficients are no longer required not to depend on X@var{var}, but are only required not to take the form of polynomials Xthemselves. For example, @samp{sin(x) x^2 + cos(x)} is a loose Xpolynomial with coefficients @samp{((calcFunc-cos x) 0 (calcFunc-sin Xx))}. The result will never be @code{nil} in loose mode, since any Xexpression can be interpreted as a ``constant'' loose polynomial.@refill X@end defun X X@defun polynomial-base expr pred XCheck if @var{expr} is a polynomial in any variable that occurs in it; Xif so, return that variable. (If @var{expr} is a multivariate polynomial, Xchoose one variable arbitrarily.) If @var{pred} is specified, it should Xbe a Lisp function which is called as @samp{(@var{pred} @var{subexpr})}, Xand which should return true if @code{mpb-top-expr} (a global name for Xthe original @var{expr}) is a suitable polynomial in @var{subexpr}. XThe default predicate uses @samp{(polynomial-p mpb-top-expr @var{subexpr})}; Xyou can use @var{pred} to specify additional conditions. Or, you could Xhave @var{pred} build up a list of every suitable @var{subexpr} that Xis found.@refill X@end defun X X@defun poly-simplify poly XSimplify polynomial coefficient list @var{poly} by (destructively) Xclipping off trailing zeros. X@end defun X X@defun poly-mix a ac b bc XMix two polynomial lists @var{a} and @var{b} (in the form returned by X@code{is-polynomial}) in a linear combination with coefficient expressions X@var{ac} and @var{bc}. The result is a (not necessarily simplified) Xpolynomial list representing @samp{@var{ac} @var{a} + @var{bc} @var{b}}.@refill X@end defun X X@defun poly-mul a b XMultiply two polynomial coefficient lists @var{a} and @var{b}. The Xresult will be in simplified form if the inputs were simplified. X@end defun X X@defun build-polynomial-expr poly var XConstruct a Calc formula which represents the polynomial coefficient Xlist @var{poly} applied to variable @var{var}. The @kbd{a c} X(@code{calc-collect}) command uses @code{is-polynomial} to turn an Xexpression into a coefficient list, then @code{build-polynomial-expr} Xto turn the list back into an expression in regular form.@refill X@end defun X X@defun check-unit-name var XCheck if @var{var} is a variable which can be interpreted as a unit Xname. If so, return the units table entry for that unit. This Xwill be a list whose first element is the unit name (not counting Xprefix characters) as a symbol and whose second element is the XCalc expression which defines the unit. (Refer to the Calc sources Xfor details on the remaining elements of this list.) If @var{var} Xis not a variable or is not a unit name, return @code{nil}. X@end defun X X@defun units-in-expr-p expr sub-exprs XReturn true if @var{expr} contains any variables which can be Xinterpreted as units. If @var{sub-exprs} is @code{t}, the entire Xexpression is searched. If @var{sub-exprs} is @code{nil}, this Xchecks whether @var{expr} is directly a units expression.@refill X@end defun X X@defun single-units-in-expr-p expr XCheck whether @var{expr} contains exactly one units variable. If so, Xreturn the units table entry for the variable. If @var{expr} does Xnot contain any units, return @code{nil}. If @var{expr} contains Xtwo or more units, return the symbol @samp{'wrong}. X@end defun X X@defun to-standard-units expr which XConvert units expression @var{expr} to base units. If @var{which} Xis @code{nil}, use Calc's native base units. Otherwise, @var{which} Xcan specify a units system, which is a list of two-element lists, Xwhere the first element is a Calc base symbol name and the second Xis an expression to substitute for it.@refill X@end defun X X@defun remove-units expr XReturn a copy of @var{expr} with all units variables replaced by ones. XThis expression is generally normalized before use. X@end defun X X@defun extract-units expr XReturn a copy of @var{expr} with everything but units variables replaced Xby ones. X@end defun X X@node Formatting Lisp Functions, Lisp Variables, Symbolic Lisp Functions, Internals X@subsubsection I/O and Formatting Functions X XThe functions described here are responsible for parsing and formatting XCalc numbers and formulas. X X@defun read-number str XIf string @var{str} contains a valid Calc number, either integer, Xfraction, float, or HMS form, this function parses and returns that Xnumber. Otherwise, it returns @code{nil}. X@end defun X X@defun read-expr str XRead an algebraic expression from string @var{str}. If @var{str} does Xnot have the form of a valid expression, return a list of the form X@samp{(error @var{pos} @var{msg})} where @var{pos} is an integer index Xinto @var{str} of the general location of the error, and @var{msg} is Xa string describing the problem.@refill X@end defun X X@defun read-exprs str XRead a list of expressions separated by commas, and return it as a XLisp list. If an error occurs in any expressions, an error list as Xshown above is returned instead. X@end defun X X@defun calc-do-alg-entry initial prompt no-norm XRead an algebraic formula or formulas using the minibuffer. All Xconventions of regular algebraic entry are observed. The return value Xis a list of Calc formulas; there will be more than one if the user Xentered a list of values separated by commas. The result is @code{nil} Xif the user presses Return with a blank line. If @var{initial} is Xgiven, it is a string which the minibuffer will initially contain. XIf @var{prompt} is given, it is the prompt string to use; the default Xis ``Algebraic:''. If @var{no-norm} is @code{t}, the formulas will Xbe returned exactly as parsed; otherwise, they will be passed through X@code{calc-normalize} first.@refill X XTo support the use of @kbd{$} characters in the algebraic entry, use X@code{let} to bind @code{calc-dollar-values} to a list of the values Xto be substituted for @kbd{$}, @kbd{$$}, and so on, and bind X@code{calc-dollar-used} to 0. Upon return, @code{calc-dollar-used} Xwill have been changed to the highest number of consecutive @kbd{$}s Xthat actually appeared in the input.@refill X@end defun X X@defun format-number a XConvert the real or complex number or HMS form @var{a} to string form. X@end defun X X@defun format-flat-expr a prec XConvert the arbitrary Calc number or formula @var{a} to string form, Xin the style used by the trail buffer. This is a simple format designed Xmostly to guarantee the string is of a form that can be re-parsed by X@code{read-expr}. Most formatting modes, such as digit grouping, Xcomplex number format, and point character, are ignored to ensure the Xresult will be re-readable. The @var{prec} parameter is normally 0; if Xyou pass a large integer like 1000 instead, the expression will be Xsurrounded by parentheses unless it is a plain number or variable name. X@end defun X X@defun format-value a width XConvert the Calc number or formula @var{a} to string form, using the Xformat seen in the stack buffer. Beware the the string returned may Xnot be re-readable by @code{read-expr}, for example, because of digit Xgrouping. Multi-line objects like matrices produce strings that Xcontain newline characters to separate the lines. The @var{w} Xparameter, if given, is the target window size for which to format Xthe expressions. If @var{w} is omitted, the width of the Calculator Xwindow is used.@refill X@end defun X X@defun compose-expr a prec XFormat the Calc number or formula @var{a} according to the current Xlanguage mode, returning a ``composition.'' To learn about the Xstructure of compositions, see the comments in the Calc source code. XIn the ``big'' language mode, you can specify the format of a given Xtype of function call by putting a @code{math-compose-big} property Xon the function's symbol, whose value is a Lisp function that takes X@var{a} and @var{prec} as arguments and returns a composition. X@end defun X X@defun composition-to-string c w XConvert a composition structure returned by @code{compose-expr} into Xa string. Multi-line compositions convert to strings containing Xnewline characters. The target window size is given by @var{w}. XThe @code{format-value} function basically calls @code{compose-expr} Xfollowed by @code{composition-to-string}. X@end defun X X@defun comp-width c XCompute the width in characters of composition @var{c}. X@end defun X X@defun comp-height c XCompute the height in lines of composition @var{c}. X@end defun X X@defun comp-ascent c XCompute the portion of the height of composition @var{c} which is on or Xabove the baseline. For a one-line composition, this will be one. X@end defun X X@defun comp-descent c XCompute the portion of the height of composition @var{c} which is below Xthe baseline. For a one-line composition, this will be zero. X@end defun X X@defun comp-first-char c XIf composition @var{c} is a simple horizontal composition, return the Xfirst (leftmost) character of the composition as an integer. Otherwise, Xreturn @code{nil}.@refill X@end defun X X@defun comp-last-char c XIf composition @var{c} is a simple horizontal composition, return the Xlast (rightmost) character, otherwise return @code{nil}. X@end defun X X@node Lisp Variables, Hooks, Formatting Lisp Functions, Internals X@subsubsection Lisp Variables X X(This section is currently unfinished.) X X@node Hooks, , Lisp Variables, Internals X@subsubsection Hooks X X(This section is currently unfinished.) X X@node Installation, Reporting Bugs, Programming, Top X@chapter Installation X XCalc comes as a pair of Emacs Lisp files, generally called X@file{calc.el} and @file{calc-ext.el}. The first contains the basic Xfoundations of the Calculator, and is as small as possible to promote Xquick loading. The second contains all the more advanced commands and Xfunctions. Calc is usually installed so that the @kbd{M-x calc} or X@kbd{M-#} command auto-loads only the first part, and the second part is Xauto-loaded whenever the first advanced feature is used.@refill X XCalc is written in a way that maximizes performance when its code has been Xbyte-compiled; a side effect is that performance is seriously degraded if Xit @emph{isn't} compiled. Thus, it is essential to compile the Calculator Xbefore trying to use it. The Emacs command @kbd{M-x byte-compile-file} Xis used to compile an Emacs Lisp file. Compile each of @file{calc.el} and X@file{calc-ext.el} to obtain byte-code files @file{calc.elc} and X@file{calc-ext.elc}. You may find you need to do @kbd{M-x load-file Xcalc.elc} before compiling @file{calc-ext.el} will work. X XFor your convenience, the FTP distribution of Calc, obtainable from Xanonymous FTP on @samp{csvax.caltech.edu}, includes already-compiled Xversions of both of these files. X XTo teach Emacs how to load in Calc when you type @kbd{M-x calc} for the Xfirst time, include these lines in your @file{.emacs} file (if you are Xinstalling Calc just for your own use), or the system's @file{lisp/default} Xfile (if you are installing Calc publicly). X X@example X(autoload 'calc ".../calc.elc" "Calculator Mode" t nil) X(autoload 'calc-extensions ".../calc-ext.elc" nil nil nil) X(autoload 'quick-calc ".../calc.elc" "Quick Calculator" t nil) X(autoload 'calc-grab-region ".../calc-ext.elc" nil t nil) X(autoload 'defmath ".../calc-ext.elc" nil t t) X@end example X Xwhere @file{.../calc.elc} represents the full path to the @file{calc.elc} Xfile, and similarly for @file{.../calc-ext.elc}. If you have installed Xthese files in Emacs' main @file{lisp/} directory, you can just write X@samp{"calc.elc"} and @samp{"calc-ext.elc"}. X XThe @code{autoload} command for @code{calc} is what loads @file{calc.elc} Xwhen you type @kbd{M-x calc}. The @code{autoload} for @code{calc-extensions} Xbrings in the extensions module; Calc takes care to call the X@code{calc-extensions} function (which doesn't actually do anything) Xbefore any operation that requires the extensions to be present. XThe other three @code{autoload} commands are for functions which might Xreasonably be used before the user has typed @kbd{M-x calc} for the Xfirst time. X XIf you don't want to bother with a split Calculator, you can simply Xconcatenate @code{calc-ext.elc} onto the end of @code{calc.elc}, rewrite Xthe above @code{autoload} commands all to point to the combined file, Xand treat Calc as one big program. You may need to do this if X@code{autoload} is giving you problems. X XYou may also wish to bind the @code{calc} command to a key. The Xrecommended keystroke is @kbd{M-#} (i.e., Meta-Shift-3). To set up Xthis key binding, include this command in your @file{.emacs} or X@file{lisp/default} file: X X@example X(global-set-key "\e#" 'calc) X@end example X XThere are no standard key assignments for @code{quick-calc} and X@code{calc-grab-region}, but you may wish to define some. X XThe file @file{macedit.el} contains another useful Emacs extension Xcalled @code{edit-kbd-macro}. It allows you to edit a keyboard macro Xin human-readable form. The @kbd{Z E} command in Calc knows how to Xuse it to edit user commands that have been defined by keyboard macros. XTo autoload it, you will want to include the commands, X X@example X(autoload 'edit-kbd-macro ".../macedit.elc" "Edit Keyboard Macro" t nil) X(autoload 'edit-last-kbd-macro ".../macedit.elc" "Edit Keyboard Macro" t nil) X@end example X XThe documentation for Calc (i.e., this manual) comes in a file X@file{calc.texinfo}. To format this for use as an on-line manual, Xopen this file for editing in Emacs and give the command X@kbd{M-x texinfo-format-buffer}. When this finishes, type @kbd{C-x C-s} Xto save. The result will be a collection of files whose names begin Xwith @file{calc-info}. You can also format this into a printable Xdocument using @TeX{}, but beware, the manual is about 170 printed pages! X X@vindex calc-info-filename XThere is a Lisp variable called @code{calc-info-filename} which holds Xthe name of the Info file containing Calc's on-line documentation. XIts default value is @samp{calc-info}, which will work correctly if Xthe Info files are stored in Emacs' main @file{info/} directory. If Xyou keep them elsewhere, you will want to put a command of the form, X X@example X(setq calc-info-filename ".../calc-info") X@end example X X@noindent Xin your @file{.emacs} or @file{lisp/default} file, where again @file{...} Xrepresents the directory containing the Info files. X X@vindex calc-settings-file XAnother variable you might want to set is @code{calc-settings-file}, Xwhich holds the file name in which commands like @kbd{m m} and @kbd{Z P} Xstore ``permanent'' definitions. The default value for this variable Xis @samp{"~/.emacs"}. If @code{calc-settings-file} does not contain X@samp{".emacs"} as a substring, and if the variable X@code{calc-loaded-settings-file} is @code{nil}, then Calc will Xautomatically load your settings file (if it exists) the first time XCalc is invoked.@refill X XTo test your installation of Calc, start a fresh Emacs and type @kbd{M-#} Xto make sure the autoload commands and key bindings work. Now, type X@kbd{i} to make sure Calc can find its Info documentation. Press @kbd{q} Xto exit the Info system. Type @kbd{20 S} to compute the sine of X20 degrees; this will test the autoloading of the extensions module. XThe result should be 0.342020143326. Finally, press @kbd{M-#} again to Xmake sure the Calculator can exit. X X(The above text is included in both the Calc documentation and the Xfile INSTALL in the Calc distribution directory.) X X@node Reporting Bugs, Key Index, Installation, Top X@chapter Reporting Bugs X XIf you find a bug in Calc, send e-mail to Dave Gillespie, X@samp{daveg@@csvax.caltech.edu}. While I cannot guarantee that I Xwill have time to work on your bug, I do try to fix bugs quickly Xwhenever I can. X XThere is an automatic @kbd{M-x report-calc-bug} command which helps Xyou to report bugs. This command prompts you for a brief subject Xline, then leaves you in a mail editing buffer. Type @kbd{C-c C-s} to Xsend your mail. Make sure your subject line indicates that you are Xreporting a Calc bug; this command sends mail to my regular mailbox. X XIf you have suggestions for additional features for Calc, I would Xlove to hear them. Some have dared to suggest that Calc is already Xtop-heavy with features; I really don't see what they're talking Xabout, so, if you have ideas, send them right in. (I may even have Xtime to implement them!) X XAt the front of the source file, @file{calc.el}, is a list of ideas for Xfuture work which I have not had time to do. If any enthusiastic souls Xwish to take it upon themselves to work on these, I would be delighted. XPlease let me know if you plan to contribute to Calc so I can coordinate Xyour efforts with mine and those of others. I will do my best to help Xyou in whatever way I can. X X@node Key Index, Command Index, Reporting Bugs, Top X@unnumbered Index of Key Sequences X X@printindex ky X X@node Command Index, Function Index, Key Index, Top X@unnumbered Index of Calculator Commands X XSince all Calculator commands begin with the prefix @samp{calc-}, the X@kbd{x} key has been provided as a variant of @kbd{M-x} which automatically Xtypes @samp{calc-} for you. Thus, @kbd{x last-x} is short for X@kbd{M-x calc-last-x}. X X@printindex pg X X@node Function Index, Concept Index, Command Index, Top X@unnumbered Index of Algebraic Functions X XThis is a list of built-in functions usable in algebraic expressions. XTheir full Lisp names are derived by adding the prefix @samp{calcFunc-}, Xas in @samp{calcFunc-sqrt}. X X@printindex tp X X@node Concept Index, Lisp Function Index, Function Index, Top X@unnumbered Concept Index X X@printindex cp X X@node Lisp Function Index, Lisp Variable Index, Concept Index, Top X@unnumbered Index of Lisp Math Functions X XThe following functions are meant to be used with @code{defmath}, not X@code{defun} definitions. For names that do not start with @samp{calc-}, Xthe corresponding full Lisp name is derived by adding a prefix of X@samp{math-}. X X@printindex fn X X@node Lisp Variable Index, , Lisp Function Index, Top X@unnumbered Index of Lisp Variables X X@printindex vr X X@summarycontents X@contents X@bye X X SHAR_EOF echo "File calc.texinfo is complete" chmod 0664 calc.texinfo || echo "restore of calc.texinfo fails" set `wc -c calc.texinfo`;Sum=$1 if test "$Sum" != "465844" then echo original size 465844, current size $Sum;fi rm -f s2_seq_.tmp echo "You have unpacked the last part" exit 0