# Programming

There are several ways to "program" the Emacs Calculator, depending on the nature of the problem you need to solve.

1. Keyboard macros allow you to record a sequence of keystrokes and play them back at a later time. This is just the standard Emacs keyboard macro mechanism, dressed up with a few more features such as loops and conditionals.
2. Algebraic definitions allow you to use any formula to define a new function. This function can then be used in algebraic formulas or as an interactive command.
3. Rewrite rules are discussed in the section on algebra commands. See section Rewrite Rules. If you put your rewrite rules in the variable EvalRules, they will be applied automatically to all Calc results in just the same way as an internal "rule" is applied to evaluate sqrt(9)' to 3 and so on. See section Automatic Rewrites.
4. Lisp is the programming language that Calc (and most of Emacs) is written in. If the above techniques aren't powerful enough, you can write Lisp functions to do anything that built-in Calc commands can do. Lisp code is also somewhat faster than keyboard macros or rewrite rules.

Programming features are available through the z and Z prefix keys. New commands that you define are two-key sequences beginning with z. Commands for managing these definitions use the shift-Z prefix. (The Z T (calc-timing) command is described elsewhere; see section Troubleshooting Commands. The Z C (calc-user-define-composition) command is also described elsewhere; see section User-Defined Compositions.)

## Creating User Keys

Any Calculator command may be bound to a key using the Z D (calc-user-define) command. Actually, it is bound to a two-key sequence beginning with the lower-case z prefix.

The Z D command first prompts for the key to define. For example, press Z D a to define the new key sequence z a. You are then prompted for the name of the Calculator command that this key should run. For example, the calc-sincos command is not normally available on a key. Typing Z D s sincos RET programs the z s key sequence to run calc-sincos. This definition will remain in effect for the rest of this Emacs session, or until you redefine z s to be something else.

You can actually bind any Emacs command to a z key sequence by backspacing over the calc-' when you are prompted for the command name.

As with any other prefix key, you can type z ? to see a list of all the two-key sequences you have defined that start with z. Initially, no z sequences (except z ? itself) are defined.

User keys are typically letters, but may in fact be any key. (META-keys are not permitted, nor are a terminal's special function keys which generate multi-character sequences when pressed.) You can define different commands on the shifted and unshifted versions of a letter if you wish.

The Z U (calc-user-undefine) command unbinds a user key. For example, the key sequence Z U s will undefine the sincos key we defined above.

The Z P (calc-user-define-permanent) command makes a key binding permanent so that it will remain in effect even in future Emacs sessions. (It does this by adding a suitable bit of Lisp code into your .emacs' file.) For example, Z P s would register our sincos command permanently. If you later wish to unregister this command you must edit your .emacs' file by hand. (See section General Mode Commands, for a way to tell Calc to use a different file instead of .emacs'.)

The Z P command also saves the user definition, if any, for the command bound to the key. After Z F and Z C, a given user key could invoke a command, which in turn calls an algebraic function, which might have one or more special display formats. A single Z P command will save all of these definitions.

To save a command or function without its key binding (or if there is no key binding for the command or function), type ' (the apostrophe) when prompted for a key. Then, type the function name, or backspace to change the calcFunc-' prefix to calc-' and enter a command name. (If the command you give implies a function, the function will be saved, and if the function has any display formats, those will be saved, but not the other way around: Saving a function will not save any commands or key bindings associated with the function.)

The Z E (calc-user-define-edit) command edits the definition of a user key. This works for keys that have been defined by either keyboard macros or formulas; further details are contained in the relevant following sections.

## Programming with Keyboard Macros

The easiest way to "program" the Emacs Calculator is to use standard keyboard macros. Press C-x ( to begin recording a macro. From this point on, keystrokes you type will be saved away as well as performing their usual functions. Press C-x ) to end recording. Press shift-X (or the standard Emacs key sequence C-x e) to execute your keyboard macro by replaying the recorded keystrokes. See section Keyboard Macros' in the Emacs Manual, for further information.

When you use X to invoke a keyboard macro, the entire macro is treated as a single command by the undo and trail features. The stack display buffer is not updated during macro execution, but is instead fixed up once the macro completes. Thus, commands defined with keyboard macros are convenient and efficient. The C-x e command, on the other hand, invokes the keyboard macro with no special treatment: Each command in the macro will record its own undo information and trail entry, and update the stack buffer accordingly. If your macro uses features outside of Calc's control to operate on the contents of the Calc stack buffer, or if it includes Undo, Redo, or last-arguments commands, you must use C-x e to make sure the buffer and undo list are up-to-date at all times. You could also consider using K (calc-keep-args) instead of M-RET (calc-last-args).

Calc extends the standard Emacs keyboard macros in several ways. Keyboard macros can be used to create user-defined commands. Keyboard macros can include conditional and iteration structures, somewhat analogous to those provided by a traditional programmable calculator.

### Naming Keyboard Macros

Once you have defined a keyboard macro, you can bind it to a z key sequence with the Z K (calc-user-define-kbd-macro) command. This command prompts first for a key, then for a command name. For example, if you type C-x ( n TAB n TAB C-x ) you will define a keyboard macro which negates the top two numbers on the stack (TAB swaps the top two stack elements). Now you can type Z K n RET to define this keyboard macro onto the z n key sequence. The default command name (if you answer the second prompt with just the RET key as in this example) will be something like calc-User-n'. The keyboard macro will now be available as both z n and M-x calc-User-n. You can backspace and enter a more descriptive command name if you wish.

Macros defined by Z K act like single commands; they are executed in the same way as by the X key. If you wish to define the macro as a standard no-frills Emacs macro (to be executed as if by C-x e), give a negative prefix argument to Z K.

Once you have bound your keyboard macro to a key, you can use Z P to register it permanently with Emacs. See section Creating User Keys.

The Z E (calc-user-define-edit) command on a key that has been defined by a keyboard macro tries to use the edit-kbd-macro command to edit the macro. This command may be found in the macedit' package, a copy of which comes with Calc. It decomposes the macro definition into full Emacs command names, like calc-pop and calc-add. Type M-# M-# to finish editing and update the definition stored on the key, or, to cancel the edit, type M-# x.

If you give a negative numeric prefix argument to Z E, the keyboard macro is edited in spelled-out keystroke form. For example, the editing buffer might contain the nine characters 1 RET 2 +'. When you press M-# M-#, the read-kbd-macro feature of the macedit' package is used to reinterpret these key names. The notations RET, LFD, TAB, SPC, DEL, and NUL must be written in all uppercase, as must the prefixes C- and M-. Spaces and line breaks are ignored. Other characters are copied verbatim into the keyboard macro. Basically, the notation is the same as is used in all of this manual's examples, except that the manual takes some liberties with spaces: When we say ' [1 2 3] RET, we take it for granted that it is clear we really mean ' [1 SPC 2 SPC 3] RET, which is what read-kbd-macro wants to see.

If macedit' is not available, Z E edits the keyboard macro in "raw" form; the editing buffer simply contains characters like 1^M2+' (here ^M' represents the carriage-return character). Editing in this mode, you will have to use C-q to enter new control characters into the buffer.

The M-# m (read-kbd-macro) command reads an Emacs "region" of spelled-out keystrokes and defines it as the current keyboard macro. It is a convenient way to define a keyboard macro that has been stored in a file, or to define a macro without executing it at the same time. The M-# m command works only if macedit' is present.

### Conditionals in Keyboard Macros

The Z [ (calc-kbd-if) and Z ] (calc-kbd-end-if) commands allow you to put simple tests in a keyboard macro. When Calc sees the Z [, it pops an object from the stack and, if the object is a non-zero value, continues executing keystrokes. But if the object is zero, or if it is not provably nonzero, Calc skips ahead to the matching Z ] keystroke. See section Logical Operations, for a set of commands for performing tests which conveniently produce 1 for true and 0 for false.

For example, RET 0 a < Z [ n Z ] implements an absolute-value function in the form of a keyboard macro. This macro duplicates the number on the top of the stack, pushes zero and compares using a < (calc-less-than), then, if the number was less than zero, executes n (calc-change-sign). Otherwise, the change-sign command is skipped.

To program this macro, type C-x (, type the above sequence of keystrokes, then type C-x ). Note that the keystrokes will be executed while you are making the definition as well as when you later re-execute the macro by typing X. Thus you should make sure a suitable number is on the stack before defining the macro so that you don't get a stack-underflow error during the definition process.

Conditionals can be nested arbitrarily. However, there should be exactly one Z ] for each Z [ in a keyboard macro.

The Z : (calc-kbd-else) command allows you to choose between two keystroke sequences. The general format is cond Z [ then-part Z : else-part Z ]. If cond is true (i.e., if the top of stack contains a non-zero number after cond has been executed), the then-part will be executed and the else-part will be skipped. Otherwise, the then-part will be skipped and the else-part will be executed.

The Z | (calc-kbd-else-if) command allows you to choose between any number of alternatives. For example, cond1 Z [ part1 Z : cond2 Z | part2 Z : part3 Z ] will execute part1 if cond1 is true, otherwise it will execute part2 if cond2 is true, otherwise it will execute part3.

More precisely, Z [ pops a number and conditionally skips to the next matching Z : or Z ] key. Z ] has no effect when actually executed. Z : skips to the next matching Z ]. Z | pops a number and conditionally skips to the next matching Z : or Z ]; thus, Z [ and Z | are functionally equivalent except that Z [ participates in nesting but Z | does not.

Calc's conditional and looping constructs work by scanning the keyboard macro for occurrences of character sequences like Z:' and Z]'. One side-effect of this is that if you use these constructs you must be careful that these character pairs do not occur by accident in other parts of the macros. Since Calc rarely uses shift-Z for any purpose except as a prefix character, this is not likely to be a problem. Another side-effect is that it will not work to define your own custom key bindings for these commands. Only the standard shift-Z bindings will work correctly.

If Calc gets stuck while skipping characters during the definition of a macro, type Z C-g to cancel the definition. (Typing plain C-g actually adds a C-g keystroke to the macro.)

### Loops in Keyboard Macros

The Z < (calc-kbd-repeat) and Z > (calc-kbd-end-repeat) commands pop a number from the stack, which must be an integer, then repeat the keystrokes between the brackets the specified number of times. If the integer is zero or negative, the body is skipped altogether. For example, 1 TAB Z < 2 * Z > computes two to a nonnegative integer power. First, we push 1 on the stack and then swap the integer argument back to the top. The Z < pops that argument leaving the 1 back on top of the stack. Then, we repeat a multiply-by-two step however many times.

Once again, the keyboard macro is executed as it is being entered. In this case it is especially important to set up reasonable initial conditions before making the definition: Suppose the integer 1000 just happened to be sitting on the stack before we typed the above definition! Another approach is to enter a harmless dummy definition for the macro, then go back and edit in the real one with a Z E command. Yet another approach is to type the macro as written-out keystroke names in a buffer, then use M-# m (read-kbd-macro) to read the macro.

The Z / (calc-kbd-break) command allows you to break out of a keyboard macro loop prematurely. It pops an object from the stack; if that object is true (a non-zero number), control jumps out of the innermost enclosing Z < ... Z > loop and continues after the Z >. If the object is false, the Z / has no effect. Thus cond Z / is similar to if (cond) break;' in the C language.

The Z ( (calc-kbd-for) and Z ) (calc-kbd-end-for) commands are similar to Z < and Z >, except that they make the value of the counter available inside the loop. The general layout is init final Z ( body step Z ). The Z ( command pops initial and final values from the stack. It then creates a temporary internal counter and initializes it with the value init. The Z ( command then repeatedly pushes the counter value onto the stack and executes body and step, adding step to the counter each time until the loop finishes.

By default, the loop finishes when the counter becomes greater than (or less than) final, assuming initial is less than (greater than) final. If initial is equal to final, the body executes exactly once. The body of the loop always executes at least once. For example, 0 1 10 Z ( 2 ^ + 1 Z ) computes the sum of the squares of the integers from 1 to 10, in steps of 1.

If you give a numeric prefix argument of 1 to Z (, the loop is forced to use upward-counting conventions. In this case, if initial is greater than final the body will not be executed at all. Note that step may still be negative in this loop; the prefix argument merely constrains the loop-finished test. Likewise, a prefix argument of -1 forces downward-counting conventions.

The Z { (calc-kbd-loop) and Z } (calc-kbd-end-loop) commands are similar to Z < and Z >, except that they do not pop a count from the stack--they effectively create an infinite loop. Every Z { ... Z } loop ought to include at least one Z / to make sure the loop doesn't run forever. (If any error message occurs which causes Emacs to beep, the keyboard macro will also be halted; this is a standard feature of Emacs. You can also generally press C-g to halt a running keyboard macro, although not all versions of Unix support this feature.)

The conditional and looping constructs are not actually tied to keyboard macros, but they are most often used in that context. For example, the keystrokes 10 Z < 23 RET Z > push ten copies of 23 onto the stack. This can be typed "live" just as easily as in a macro definition.

See section Conditionals in Keyboard Macros, for some additional notes about conditional and looping commands.

### Local Values in Macros

Keyboard macros sometimes want to operate under known conditions without affecting surrounding conditions. For example, a keyboard macro may wish to turn on Fraction Mode, or set a particular precision, independent of the user's normal setting for those modes.

Macros also sometimes need to use local variables. Assignments to local variables inside the macro should not affect any variables outside the macro. The Z  (calc-kbd-push) and Z ' (calc-kbd-pop) commands give you both of these capabilities.

When you type Z  (with a backquote or accent grave character), the values of various mode settings are saved away. The ten "quick" variables q0 through q9 are also saved. When you type Z ' (with an apostrophe), these values are restored. Pairs of Z  and Z ' commands may be nested.

If a keyboard macro halts due to an error in between a Z  and a Z ', the saved values will be restored correctly even though the macro never reaches the Z ' command. Thus you can use Z  and Z ' without having to worry about what happens in exceptional conditions.

If you type Z  "live" (not in a keyboard macro), Calc puts you into a "recursive edit." You can tell you are in a recursive edit because there will be extra square brackets in the mode line, as in [(Calculator)]'. These brackets will go away when you type the matching Z ' command. The modes and quick variables will be saved and restored in just the same way as if actual keyboard macros were involved.

The modes saved by Z  and Z ' are the current precision and binary word size, the angular mode (Deg, Rad, or HMS), the simplification mode, Algebraic mode, Symbolic mode, Infinite mode, Matrix or Scalar mode, Fraction mode, and the current complex mode (Polar or Rectangular). The ten "quick" variables' values (or lack thereof) are also saved.

Most mode-setting commands act as toggles, but with a numeric prefix they force the mode either on (positive prefix) or off (negative or zero prefix). Since you don't know what the environment might be when you invoke your macro, it's best to use prefix arguments for all mode-setting commands inside the macro.

In fact, C-u Z  is like Z  except that it sets the modes listed above to their default values. As usual, the matching Z ' will restore the modes to their settings from before the C-u Z . Also, Z  with a negative prefix argument resets algebraic mode to its default (off) but leaves the other modes the same as they were outside the construct.

The contents of the stack and trail, values of non-quick variables, and other settings such as the language mode and the various display modes, are not affected by Z  and Z '.

### Queries in Keyboard Macros

The Z = (calc-kbd-report) command displays an informative message including the value on the top of the stack. You are prompted to enter a string. That string, along with the top-of-stack value, is displayed unless m w (calc-working) has been used to turn such messages off.

#### Error Handling

If calc-eval encounters an error, it returns a list containing the character position of the error, plus a suitable message as a string. Note that 1 / 0' is not an error by Calc's standards; it simply returns the string "1 / 0" which is the division left in symbolic form. But (calc-eval "1/")' will return the list (2 "Expected a number")'.

If you bind the variable calc-eval-error to t using a let form surrounding the call to calc-eval, errors instead call the Emacs error function which aborts to the Emacs command loop with a beep and an error message.

If you bind this variable to the symbol string, error messages are returned as strings instead of lists. The character position is ignored.

As a courtesy to other Lisp code which may be using Calc, be sure to bind calc-eval-error using let rather than changing it permanently with setq.

#### Numbers Only

Sometimes it is preferable to treat 1 / 0' as an error rather than returning a symbolic result. If you pass the symbol num as the second argument to calc-eval, results that are not constants are treated as errors. The error message reported is the first calc-why message if there is one, or otherwise "Number expected."

A result is "constant" if it is a number, vector, or other object that does not include variables or function calls. If it is a vector, the components must themselves be constants.

#### Default Modes

If the first argument to calc-eval is a list whose first element is a formula string, then calc-eval sets all the various Calc modes to their default values while the formula is evaluated and formatted. For example, the precision is set to 12 digits, digit grouping is turned off, and the normal language mode is used.

This same principle applies to the other options discussed below. If the first argument would normally be x, then it can also be the list (x)' to use the default mode settings.

If there are other elements in the list, they are taken as variable-name/value pairs which override the default mode settings. Look at the documentation at the front of the calc.el' file to find the names of the Lisp variables for the various modes. The mode settings are restored to their original values when calc-eval is done.

For example, (calc-eval '("$+$$" calc-internal-prec 8) 'num a b)' computes the sum of two numbers, requiring a numeric result, and using default mode settings except that the precision is 8 instead of the default of 12. It's usually best to use this form of calc-eval unless your program actually considers the interaction with Calc's mode settings to be a feature. This will avoid all sorts of potential "gotchas"; consider what happens with (calc-eval "sqrt(2)" 'num)' when the user has left Calc in symbolic mode or no-simplify mode. As another example, (equal (calc-eval '("<$$") nil a b) "1")' checks if the number in string a is less than the one in string b. Without using a list, the integer 1 might come out in a variety of formats which would be hard to test for conveniently: "1", "8#1", "00001". (But see "Predicates" mode, below.) #### Raw Numbers Normally all input and output for calc-eval is done with strings. You can do arithmetic with, say, (calc-eval "$+$$" nil a b)' in place of (+ a b)', but this is very inefficient since the numbers must be converted to and from string format as they are passed from one calc-eval to the next. If the separator is the symbol raw, the result will be returned as a raw Calc data structure rather than a string. You can read about how these objects look in the following sections, but usually you can treat them as "black box" objects with no important internal structure. There is also a rawnum symbol, which is a combination of raw (returning a raw Calc object) and num (signalling an error if that object is not a constant). You can pass a raw Calc object to calc-eval in place of a string, either as the formula itself or as one of the ' arguments. Thus (calc-eval "+$$" 'raw a b)' is an addition function that operates on raw Calc objects. Of course in this case it would be easier to call the low-level math-add function in Calc, if you can remember its name.

In particular, note that a plain Lisp integer is acceptable to Calc as a raw object. (All Lisp integers are accepted on input, but integers of more than six decimal digits are converted to "big-integer" form for output. See section Data Type Formats.)

When it comes time to display the object, just use (calc-eval a)' to format it as a string.

It is an error if the input expression evaluates to a list of values. The separator symbol list is like raw except that it returns a list of one or more raw Calc objects.

Note that a Lisp string is not a valid Calc object, nor is a list containing a string. Thus you can still safely distinguish all the various kinds of error returns discussed above.

#### Predicates

If the separator symbol is pred, the result of the formula is treated as a true/false value; calc-eval returns t or nil, respectively. A value is considered "true" if it is a non-zero number, or false if it is zero or if it is not a number.

For example, (calc-eval "$<$$" 'pred a b)' tests whether one value is less than another. As usual, it is also possible for calc-eval to return one of the error indicators described above. Lisp will interpret such an indicator as "true" if you don't check for it explicitly. If you wish to have an error register as "false", use something like (eq (calc-eval ...) t)'. #### Variable Values Variables in the formula passed to calc-eval are not normally replaced by their values. If you wish this, you can use the evalv function (see section Algebraic Manipulation). For example, if 4 is stored in Calc variable a (i.e., in Lisp variable var-a), then (calc-eval "a+pi")' will return the formula "a + pi", but (calc-eval "evalv(a+pi)")' will return "7.14159265359". To store in a Calc variable, just use setq to store in the corresponding Lisp variable. (This is obtained by prepending var-' to the Calc variable name.) Calc routines will understand either string or raw form values stored in variables, although raw data objects are much more efficient. For example, to increment the Calc variable a: (setq var-a (calc-eval "evalv(a+1)" 'raw))  #### Stack Access If the separator symbol is push, the formula argument is evaluated (with possible ' expansions, as usual). The result is pushed onto the Calc stack. The return value is nil (unless there is an error from evaluating the formula, in which case the return value depends on calc-eval-error in the usual way). If the separator symbol is pop, the first argument to calc-eval must be an integer instead of a string. That many values are popped from the stack and thrown away. A negative argument deletes the entry at that stack level. The return value is the number of elements remaining in the stack after popping; (calc-eval 0 'pop)' is a good way to measure the size of the stack. If the separator symbol is top, the first argument to calc-eval must again be an integer. The value at that stack level is formatted as a string and returned. Thus (calc-eval 1 'top)' returns the top-of-stack value. If the integer is out of range, nil is returned. The separator symbol rawtop is just like top except that the stack entry is returned as a raw Calc object instead of as a string. In all of these cases the first argument can be made a list in order to force the default mode settings, as described above. Thus (calc-eval '(2 calc-number-radix 16) 'top)' returns the second-to-top stack entry, formatted as a string using the default instead of current display modes, except that the radix is hexadecimal instead of decimal. It is, of course, polite to put the Calc stack back the way you found it when you are done, unless the user of your program is actually expecting it to affect the stack. Note that you do not actually have to switch into the *Calculator*' buffer in order to use calc-eval; it temporarily switches into the stack buffer if necessary. #### Keyboard Macros If the separator symbol is macro, the first argument must be a string of characters which Calc can execute as a sequence of keystrokes. This switches into the Calc buffer for the duration of the macro. For example, (calc-eval "vx5\rVR+" 'macro)' pushes the vector [1,2,3,4,5]' on the stack and then replaces it with the sum of those numbers. Note that \r' is the Lisp notation for the carriage-return, RET, character. If your keyboard macro wishes to pop the stack, \C-d' is safer than \177' (the DEL character) because some installations may have switched the meanings of DEL and C-h. Calc always interprets C-d as a synonym for "pop-stack" regardless of key mapping. If you provide a third argument to calc-eval, evaluation of the keyboard macro will leave a record in the Trail using that argument as a tag string. Normally the Trail is unaffected. The return value in this case is always nil. #### Lisp Evaluation Finally, if the separator symbol is eval, then the Lisp eval function is called on the first argument, which must be a Lisp expression rather than a Calc formula. Remember to quote the expression so that it is not evaluated until inside calc-eval. The difference from plain eval is that calc-eval switches to the Calc buffer before evaluating the expression. For example, (calc-eval '(setq calc-internal-prec 17) 'eval)' will correctly affect the buffer-local Calc precision variable. An alternative would be (calc-eval '(calc-precision 17) 'eval)'. This is evaluating a call to the function that is normally invoked by the p key, giving it 17 as its "numeric prefix argument." Note that this function will leave a message in the echo area as a side effect. Also, all Calc functions switch to the Calc buffer automatically if not invoked from there, so the above call is also equivalent to (calc-precision 17)' by itself. In all cases, Calc uses save-excursion to switch back to your original buffer when it is done. As usual the first argument can be a list that begins with a Lisp expression to use default instead of current mode settings. The result of calc-eval in this usage is just the result returned by the evaluated Lisp expression. #### Example Here is a sample Emacs command that uses calc-eval. Suppose you have a document with lots of references to temperatures on the Fahrenheit scale, say "98.6 F", and you wish to convert these references to Centigrade. The following command does this conversion. Place the Emacs cursor right after the letter "F" and invoke the command to change "98.6 F" to "37 C". Or, if the temperature is already in Centigrade form, the command changes it back to Fahrenheit. (defun convert-temp () (interactive) (save-excursion (re-search-backward "[^-.0-9]\$$[-.0-9]+\$$ *\$$[FC]\$$") (let* ((top1 (match-beginning 1)) (bot1 (match-end 1)) (number (buffer-substring top1 bot1)) (top2 (match-beginning 2)) (bot2 (match-end 2)) (type (buffer-substring top2 bot2))) (if (equal type "F") (setq type "C" number (calc-eval "( - 32)*5/9" nil number)) (setq type "F" number (calc-eval "*9/5 + 32" nil number))) (goto-char top2) (delete-region top2 bot2) (insert-before-markers type) (goto-char top1) (delete-region top1 bot1) (if (string-match "\\." number) ; change "37." to "37" (setq number (substring number 0 -1))) (insert number))))  Note the use of insert-before-markers when changing between "F" and "C", so that the character winds up before the cursor instead of after it. ### Calculator Internals This section describes the Lisp functions defined by the Calculator that may be of use to user-written Calculator programs (as described in the rest of this chapter). These functions are shown by their names as they conventionally appear in defmath. Their full Lisp names are generally gotten by prepending calcFunc-' or math-' to their apparent names. (Names that begin with calc-' are already in their full Lisp form.) You can use the actual full names instead if you prefer them, or if you are calling these functions from regular Lisp. The functions described here are scattered throughout the various Calc component files. Note that calc.el' includes autoloads for only a few component files; when Calc wants to call an advanced function it calls (calc-extensions)' first; this function autoloads calc-ext.el', which in turn autoloads all the functions in the remaining component files. Because defmath itself uses the extensions, user-written code generally always executes with the extensions already loaded, so normally you can use any Calc function and be confident that it will be autoloaded for you when necessary. If you are doing something special, check carefully to make sure each function you are using is from calc.el' or its components, and call (calc-extensions)' before using any function based in calc-ext.el' if you can't prove this file will already be loaded. #### Data Type Formats Integers are stored in either of two ways, depending on their magnitude. Integers less than one million in absolute value are stored as standard Lisp integers. This is the only storage format for Calc data objects which is not a Lisp list. Large integers are stored as lists of the form (bigpos d0 d1 d2 ...)' for positive integers 1000000 or more, or (bigneg d0 d1 d2 ...)' for negative integers -1000000 or less. Each d is a base-1000 "digit," a Lisp integer from 0 to 999. The least significant digit is d0; the last digit, dn, which is always nonzero, is the most significant digit. For example, the integer -12345678 is stored as (bigneg 678 345 12)'. The distinction between small and large integers is entirely hidden from the user. In defmath definitions, the Lisp predicate integerp returns true for either kind of integer, and in general both big and small integers are accepted anywhere the word "integer" is used in this manual. If the distinction must be made, native Lisp integers are called fixnums and large integers are called bignums. Fractions are stored as a list of the form, (frac n d)' where n is an integer (big or small) numerator, d is an integer denominator greater than one, and n and d are relatively prime. Note that fractions where d is one are automatically converted to plain integers by all math routines; fractions where d is negative are normalized by negating the numerator and denominator. Floating-point numbers are stored in the form, (float mant exp)', where mant (the "mantissa") is an integer less than 10^p' in absolute value (p represents the current precision), and exp (the "exponent") is a fixnum. The value of the float is mant * 10^exp'. For example, the number -3.14 is stored as (float -314 -2) = -314*10^-2'. Other constraints are that the number 0.0 is always stored as (float 0 0)', and, except for the 0.0 case, the rightmost base-10 digit of mant is always nonzero. (If the rightmost digit is zero, the number is rearranged by dividing mant by ten and incrementing exp.) Rectangular complex numbers are stored in the form (cplx re im)', where re and im are each real numbers, either integers, fractions, or floats. The value is re + imi'. The im part is nonzero; complex numbers with zero imaginary components are converted to real numbers automatically. Polar complex numbers are stored in the form (polar r theta)', where r is a positive real value and theta is a real value or HMS form representing an angle. This angle is usually normalized to lie in the interval (-180 .. 180)' degrees, or (-pi .. pi)' radians, according to the current angular mode. If the angle is 0 the value is converted to a real number automatically. (If the angle is 180 degrees, the value is usually also converted to a negative real number.) Hours-minutes-seconds forms are stored as (hms h m s)', where h is an integer or an integer-valued float (i.e., a float with exp >= 0'), m is an integer or integer-valued float in the range [0 .. 60)', and s is any real number in the range [0 .. 60)'. Date forms are stored as (date n)', where n is a real number that counts days since midnight on the morning of January 1, 1 AD. If n is an integer, this is a pure date form. If n is a fraction or float, this is a date/time form. Modulo forms are stored as (mod n m)', where m is a positive real number or HMS form, and n is a real number or HMS form in the range [0 .. m)'. Error forms are stored as (sdev x sigma)', where x is the mean value and sigma is the standard deviation. Each component is either a number, an HMS form, or a symbolic object (a variable or function call). If sigma is zero, the value is converted to a plain real number. If sigma is negative or complex, it is automatically normalized to be a positive real. Interval forms are stored as (intv mask lo hi)', where mask is one of the integers 0, 1, 2, or 3, and lo and hi are real numbers, HMS forms, or symbolic objects. The mask is a binary integer where 1 represents the fact that the interval is closed on the high end, and 2 represents the fact that it is closed on the low end. (Thus 3 represents a fully closed interval.) The interval (intv 3 x x)' is converted to the plain number x; intervals (intv mask x x)' for any other mask represent empty intervals. If hi is less than lo, the interval is converted to a standard empty interval by replacing hi with lo. Vectors are stored as (vec v1 v2 ...)', where v1 is the first element of the vector, v2 is the second, and so on. An empty vector is stored as (vec)'. A matrix is simply a vector where all v's are themselves vectors of equal lengths. Note that Calc vectors are unrelated to the Emacs Lisp "vector" type, which is generally unused by Calc data structures. Variables are stored as (var name sym)', where name is a Lisp symbol whose print name is used as the visible name of the variable, and sym is a Lisp symbol in which the variable's value is actually stored. Thus, (var pi var-pi)' represents the special constant pi'. Almost always, the form is (var v var-v)'. If the variable name was entered with # signs (which are converted to hyphens internally), the form is (var u v)', where u is a symbol whose name contains # characters, and v is a symbol that contains - characters instead. The value of a variable is the Calc object stored in its sym symbol's value cell. If the symbol's value cell is void or if it contains nil, the variable has no value. Special constants have the form (special-const value)' stored in their value cell, where value is a formula which is evaluated when the constant's value is requested. Variables which represent units are not stored in any special way; they are units only because their names appear in the units table. If the value cell contains a string, it is parsed to get the variable's value when the variable is used. A Lisp list with any other symbol as the first element is a function call. The symbols +, -, *, /, %, ^, and | represent special binary operators; these lists are always of the form (op lhs rhs)' where lhs is the sub-formula on the lefthand side and rhs is the sub-formula on the right. The symbol neg represents unary negation; this list is always of the form (neg arg)'. Any other symbol func represents a function that would be displayed in function-call notation; the symbol func is in general always of the form calcFunc-name'. The function cell of the symbol func should contain a Lisp function for evaluating a call to func. This function is passed the remaining elements of the list (themselves already evaluated) as arguments; such functions should return nil or call reject-arg to signify that they should be left in symbolic form, or they should return a Calc object which represents their value, or a list of such objects if they wish to return multiple values. (The latter case is allowed only for functions which are the outer-level call in an expression whose value is about to be pushed on the stack; this feature is considered obsolete and is not used by any built-in Calc functions.) #### Interactive Functions The functions described here are used in implementing interactive Calc commands. Note that this list is not exhaustive! If there is an existing command that behaves similarly to the one you want to define, you may find helpful tricks by checking the source code for that command. Function: calc-set-command-flag flag Set the command flag flag. This is generally a Lisp symbol, but may in fact be anything. The effect is to add flag to the list stored in the variable calc-command-flags, unless it is already there. See section Defining New Simple Commands. Function: calc-clear-command-flag flag If flag appears among the list of currently-set command flags, remove it from that list. Function: calc-record-undo rec Add the "undo record" rec to the list of steps to take if the current operation should need to be undone. Stack push and pop functions automatically call calc-record-undo, so the kinds of undo records you might need to create take the form (set sym value)', which says that the Lisp variable sym was changed and had previously contained value; (store var value)' which says that the Calc variable var (a string which is the name of the symbol that contains the variable's value) was stored and its previous value was value (either a Calc data object, or nil if the variable was previously void); or (eval undo redo args ...)', which means that to undo requires calling the function (undo args ...)' and, if the undo is later redone, calling (redo args ...)'. Function: calc-record-why msg args Record the error or warning message msg, which is normally a string. This message will be replayed if the user types w (calc-why); if the message string begins with a *', it is considered important enough to display even if the user doesn't type w. If one or more args are present, the displayed message will be of the form, msg: arg1, arg2, ...', where the arguments are formatted on the assumption that they are either strings or Calc objects of some sort. If msg is a symbol, it is the name of a Calc predicate (such as integerp or numvecp) which the arguments did not satisfy; it is expanded to a suitable string such as "Expected an integer." The reject-arg function calls calc-record-why automatically; see section Predicates. Function: calc-is-inverse This predicate returns true if the current command is inverse, i.e., if the Inverse (I key) flag was set. Function: calc-is-hyperbolic This predicate is the analogous function for the H key. #### Stack-Oriented Functions The functions described here perform various operations on the Calc stack and trail. They are to be used in interactive Calc commands. Function: calc-push-list vals n Push the Calc objects in list vals onto the stack at stack level n. If n is omitted it defaults to 1, so that the elements are pushed at the top of the stack. If n is greater than 1, the elements will be inserted into the stack so that the last element will end up at level n, the next-to-last at level n+1, etc. The elements of vals are assumed to be valid Calc objects, and are not evaluated, rounded, or renormalized in any way. If vals is an empty list, nothing happens. The stack elements are pushed without any sub-formula selections. You can give an optional third argument to this function, which must be a list the same size as vals of selections. Each selection must be eq to some sub-formula of the corresponding formula in vals, or nil if that formula should have no selection. Function: calc-top-list n m Return a list of the n objects starting at level m of the stack. If m is omitted it defaults to 1, so that the elements are taken from the top of the stack. If n is omitted, it also defaults to 1, so that the top stack element (in the form of a one-element list) is returned. If m is greater than 1, the mth stack element will be at the end of the list, the m+1st element will be next-to-last, etc. If n or m are out of range, the command is aborted with a suitable error message. If n is zero, the function returns an empty list. The stack elements are not evaluated, rounded, or renormalized. If any stack elements contain selections, and selections have not been disabled by the j e (calc-enable-selections) command, this function returns the selected portions rather than the entire stack elements. It can be given a third "selection-mode" argument which selects other behaviors. If it is the symbol t, then a selection in any of the requested stack elements produces an "illegal operation on selections" error. If it is the symbol full, the whole stack entry is always returned regardless of selections. If it is the symbol sel, the selected portion is always returned, or nil if there is no selection. (This mode ignores the j e command.) If the symbol is entry, the complete stack entry in list form is returned; the first element of this list will be the whole formula, and the third element will be the selection (or nil). Function: calc-pop-stack n m Remove the specified elements from the stack. The parameters n and m are defined the same as for calc-top-list. The return value of calc-pop-stack is uninteresting. If there are any selected sub-formulas among the popped elements, and j e has not been used to disable selections, this produces an error without changing the stack. If you supply an optional third argument of t, the stack elements are popped even if they contain selections. Function: calc-record-list vals tag This function records one or more results in the trail. The vals are a list of strings or Calc objects. The tag is the four-character tag string to identify the values. If tag is omitted, a blank tag will be used. Function: calc-normalize n This function takes a Calc object and "normalizes" it. At the very least this involves re-rounding floating-point values according to the current precision and other similar jobs. Also, unless the user has selected no-simplify mode (see section Simplification Modes), this involves actually evaluating a formula object by executing the function calls it contains, and possibly also doing algebraic simplification, etc. Function: calc-top-list-n n m This function is identical to calc-top-list, except that it calls calc-normalize on the values that it takes from the stack. They are also passed through check-complete, so that incomplete objects will be rejected with an error message. All computational commands should use this in preference to calc-top-list; the only standard Calc commands that operate on the stack without normalizing are stack management commands like calc-enter and calc-roll-up. This function accepts the same optional selection-mode argument as calc-top-list. Function: calc-top-n m This function is a convenient form of calc-top-list-n in which only a single element of the stack is taken and returned, rather than a list of elements. This also accepts an optional selection-mode argument. Function: calc-enter-result n tag vals This function is a convenient interface to most of the above functions. The vals argument should be either a single Calc object, or a list of Calc objects; the object or objects are normalized, and the top n stack entries are replaced by the normalized objects. If tag is non-nil, the normalized objects are also recorded in the trail. A typical stack-based computational command would take the form, (calc-enter-result n tag (cons 'calcFunc-func (calc-top-list-n n)))  If any of the n stack elements replaced contain sub-formula selections, and selections have not been disabled by j e, this function takes one of two courses of action. If n is equal to the number of elements in vals, then each element of vals is spliced into the corresponding selection; this is what happens when you use the TAB key, or when you use a unary arithmetic operation like sqrt. If vals has only one element but n is greater than one, there must be only one selection among the top n stack elements; the element from vals is spliced into that selection. This is what happens when you use a binary arithmetic operation like +. Any other combination of n and vals is an error when selections are present. Function: calc-unary-op tag func arg This function implements a unary operator that allows a numeric prefix argument to apply the operator over many stack entries. If the prefix argument arg is nil, this uses calc-enter-result as outlined above. Otherwise, it maps the function over several stack elements; see section Numeric Prefix Arguments. For example, (defun calc-zeta (arg) (interactive "P") (calc-unary-op "zeta" 'calcFunc-zeta arg))  Function: calc-binary-op tag func arg ident unary This function implements a binary operator, analogously to calc-unary-op. The optional ident and unary arguments specify the behavior when the prefix argument is zero or one, respectively. If the prefix is zero, the value ident is pushed onto the stack, if specified, otherwise an error message is displayed. If the prefix is one, the unary function unary is applied to the top stack element, or, if unary is not specified, nothing happens. When the argument is two or more, the binary function func is reduced across the top arg stack elements; when the argument is negative, the function is mapped between the next-to-top -arg stack elements and the top element. Function: calc-stack-size Return the number of elements on the stack as an integer. This count does not include elements that have been temporarily hidden by stack truncation; see section Truncating the Stack. Function: calc-cursor-stack-index n Move the point to the nth stack entry. If n is zero, this will be the .' line. If n is from 1 to the current stack size, this will be the beginning of the first line of that stack entry's display. If line numbers are enabled, this will move to the first character of the line number, not the stack entry itself. Function: calc-substack-height n Return the number of lines between the beginning of the nth stack entry and the bottom of the buffer. If n is zero, this will be one (assuming no stack truncation). If all stack entries are one line long (i.e., no matrices are displayed), the return value will be equal n+1 as long as n is in range. (Note that in Big mode, the return value includes the blank lines that separate stack entries.) Function: calc-refresh Erase the *Calculator* buffer and reformat its contents from memory. This must be called after changing any parameter, such as the current display radix, which might change the appearance of existing stack entries. (During a keyboard macro invoked by the X key, refreshing is suppressed, but a flag is set so that the entire stack will be refreshed rather than just the top few elements when the macro finishes.) #### Predicates The functions described here are predicates, that is, they return a true/false value where nil means false and anything else means true. These predicates are expanded by defmath, for example, from zerop to math-zerop. In many cases they correspond to native Lisp functions by the same name, but are extended to cover the full range of Calc data types. Function: zerop x Returns true if x is numerically zero, in any of the Calc data types. (Note that for some types, such as error forms and intervals, it never makes sense to return true.) In defmath, the expression (= x 0)' will automatically be converted to (math-zerop x)', and (/= x 0)' will be converted to (not (math-zerop x))'. Function: negp x Returns true if x is negative. This accepts negative real numbers of various types, negative HMS and date forms, and intervals in which all included values are negative. In defmath, the expression (< x 0)' will automatically be converted to (math-negp x)', and (>= x 0)' will be converted to (not (math-negp x))'. Function: posp x Returns true if x is positive (and non-zero). For complex numbers, none of these three predicates will return true. Function: looks-negp x Returns true if x is "negative-looking." This returns true if x is a negative number, or a formula with a leading minus sign such as -a/b'. In other words, this is an object which can be made simpler by calling (- x). Function: integerp x Returns true if x is an integer of any size. Function: fixnump x Returns true if x is a native Lisp integer. Function: natnump x Returns true if x is a nonnegative integer of any size. Function: fixnatnump x Returns true if x is a nonnegative Lisp integer. Function: num-integerp x Returns true if x is numerically an integer, i.e., either a true integer or a float with no significant digits to the right of the decimal point. Function: messy-integerp x Returns true if x is numerically, but not literally, an integer. A value is num-integerp if it is integerp or messy-integerp (but it is never both at once). Function: num-natnump x Returns true if x is numerically a nonnegative integer. Function: evenp x Returns true if x is an even integer. Function: looks-evenp x Returns true if x is an even integer, or a formula with a leading multiplicative coefficient which is an even integer. Function: oddp x Returns true if x is an odd integer. Function: ratp x Returns true if x is a rational number, i.e., an integer or a fraction. Function: realp x Returns true if x is a real number, i.e., an integer, fraction, or floating-point number. Function: anglep x Returns true if x is a real number or HMS form. Function: floatp x Returns true if x is a float, or a complex number, error form, interval, date form, or modulo form in which at least one component is a float. Function: complexp x Returns true if x is a rectangular or polar complex number (but not a real number). Function: rect-complexp x Returns true if x is a rectangular complex number. Function: polar-complexp x Returns true if x is a polar complex number. Function: numberp x Returns true if x is a real number or a complex number. Function: scalarp x Returns true if x is a real or complex number or an HMS form. Function: vectorp x Returns true if x is a vector (this simply checks if its argument is a list whose first element is the symbol vec). Function: numvecp x Returns true if x is a number or vector. Function: matrixp x Returns true if x is a matrix, i.e., a vector of one or more vectors, all of the same size. Function: square-matrixp x Returns true if x is a square matrix. Function: objectp x Returns true if x is any numeric Calc object, including real and complex numbers, HMS forms, date forms, error forms, intervals, and modulo forms. (Note that error forms and intervals may include formulas as their components; see constp below.) Function: objvecp x Returns true if x is an object or a vector. This also accepts incomplete objects, but it rejects variables and formulas (except as mentioned above for objectp). Function: primp x Returns true if x is a "primitive" or "atomic" Calc object, i.e., one whose components cannot be regarded as sub-formulas. This includes variables, and all objectp types except error forms and intervals. Function: constp x Returns true if x is constant, i.e., a real or complex number, HMS form, date form, or error form, interval, or vector all of whose components are constp. Function: lessp x y Returns true if x is numerically less than y. Returns false if x is greater than or equal to y, or if the order is undefined or cannot be determined. Generally speaking, this works by checking whether x - y' is negp. In defmath, the expression (< x y)' will automatically be converted to (lessp x y)'; expressions involving >, <=, and >= are similarly converted in terms of lessp. Function: beforep x y Returns true if x comes before y in a canonical ordering of Calc objects. If x and y are both real numbers, this will be the same as lessp. But whereas lessp considers other types of objects to be unordered, beforep puts any two objects into a definite, consistent order. The beforep function is used by the V S vector-sorting command, and also by a s to put the terms of a product into canonical order: This allows x y + y x' to be simplified easily to 2 x y'. Function: equal x y This is the standard Lisp equal predicate; it returns true if x and y are structurally identical. This is the usual way to compare numbers for equality, but note that equal will treat 0 and 0.0 as different. Function: math-equal x y Returns true if x and y are numerically equal, either because they are equal, or because their difference is zerop. In defmath, the expression (= x y)' will automatically be converted to (math-equal x y)'. Function: equal-int x n Returns true if x and n are numerically equal, where n is a fixnum which is not a multiple of 10. This will automatically be used by defmath in place of the more general math-equal whenever possible. Function: nearly-equal x y Returns true if x and y, as floating-point numbers, are equal except possibly in the last decimal place. For example, 314.159 and 314.166 are considered nearly equal if the current precision is 6 (since they differ by 7 units), but not if the current precision is 7 (since they differ by 70 units). Most functions which use series expansions use with-extra-prec to evaluate the series with 2 extra digits of precision, then use nearly-equal to decide when the series has converged; this guards against cumulative error in the series evaluation without doing extra work which would be lost when the result is rounded back down to the current precision. In defmath, this can be written (~= x y)'. The x and y can be numbers of any kind, including complex. Function: nearly-zerop x y Returns true if x is nearly zero, compared to y. This checks whether x plus y would by be nearly-equal to y itself, to within the current precision, in other words, if adding x to y would have a negligible effect on y due to roundoff error. X may be a real or complex number, but y must be real. Function: is-true x Return true if the formula x represents a true value in Calc, not Lisp, terms. It tests if x is a non-zero number or a provably non-zero formula. Function: reject-arg val pred Abort the current function evaluation due to unacceptable argument values. This calls (calc-record-why pred val)', then signals a Lisp error which normalize will trap. The net effect is that the function call which led here will be left in symbolic form. Function: inexact-value If Symbolic Mode is enabled, this will signal an error that causes normalize to leave the formula in symbolic form, with the message "Inexact result." (This function has no effect when not in Symbolic Mode.) Note that if your function calls (sin 5)' in Symbolic Mode, the sin function will call inexact-value, which will cause your function to be left unsimplified. You may instead wish to call (normalize (list 'calcFunc-sin 5))', which in Symbolic Mode will return the formula sin(5)' to your function. Function: overflow This signals an error that will be reported as a floating-point overflow. Function: underflow This signals a floating-point underflow. #### Computational Functions The functions described here do the actual computational work of the Calculator. In addition to these, note that any function described in the main body of this manual may be called from Lisp; for example, if the documentation refers to the calc-sqrt [sqrt] command, this means calc-sqrt is an interactive stack-based square-root command and sqrt (which defmath expands to calcFunc-sqrt) is the actual Lisp function for taking square roots. The functions math-add, math-sub, math-mul, math-div, math-mod, and math-neg are not included in this list, since defmath allows you to write native Lisp +, -, *, /, %, and unary -, respectively, instead. Function: normalize val (Full form: math-normalize.) Reduce the value val to standard form. For example, if val is a fixnum, it will be converted to a bignum if it is too large, and if val is a bignum it will be normalized by clipping off trailing (i.e., most-significant) zero digits and converting to a fixnum if it is small. All the various data types are similarly converted to their standard forms. Variables are left alone, but function calls are actually evaluated in formulas. For example, normalizing (+ 2 (calcFunc-abs -4))' will return 6. If a function call fails, because the function is void or has the wrong number of parameters, or because it returns nil or calls reject-arg or inexact-result, normalize returns the formula still in symbolic form. If the current Simplification Mode is "none" or "numeric arguments only," normalize will act appropriately. However, the more powerful simplification modes (like algebraic simplification) are not handled by normalize. They are handled by calc-normalize, which calls normalize and possibly some other routines, such as simplify or simplify-units. Programs generally will never call calc-normalize except when popping or pushing values on the stack. Function: evaluate-expr expr Replace all variables in expr that have values with their values, then use normalize to simplify the result. This is what happens when you press the = key interactively. Macro: with-extra-prec n body Evaluate the Lisp forms in body with precision increased by n digits. This is a macro which expands to (math-normalize (let ((calc-internal-prec (+ calc-internal-prec n))) body))  The surrounding call to math-normalize causes a floating-point result to be rounded down to the original precision afterwards. This is important because some arithmetic operations assume a number's mantissa contains no more digits than the current precision allows. Function: make-frac n d Build a fraction n:d'. This is equivalent to calling (normalize (list 'frac n d))', but more efficient. Function: make-float mant exp Build a floating-point value out of mant and exp, both of which are arbitrary integers. This function will return a properly normalized float value, or signal an overflow or underflow if exp is out of range. Function: make-sdev x sigma Build an error form out of x and the absolute value of sigma. If sigma is zero, the result is the number x directly. If sigma is negative or complex, its absolute value is used. If x or sigma is not a valid type of object for use in error forms, this calls reject-arg. Function: make-intv mask lo hi Build an interval form out of mask (which is assumed to be an integer from 0 to 3), and the limits lo and hi. If lo is greater than hi, an empty interval form is returned. This calls reject-arg if lo or hi is unsuitable. Function: sort-intv mask lo hi Build an interval form, similar to make-intv, except that if lo is less than hi they are simply exchanged, and the bits of mask are swapped accordingly. Function: make-mod n m Build a modulo form out of n and the modulus m. Since modulo forms do not allow formulas as their components, if n or m is not a real number or HMS form the result will be a formula which is a call to makemod, the algebraic version of this function. Function: float x Convert x to floating-point form. Integers and fractions are converted to numerically equivalent floats; components of complex numbers, vectors, HMS forms, date forms, error forms, intervals, and modulo forms are recursively floated. If the argument is a variable or formula, this calls reject-arg. Function: compare x y Compare the numbers x and y, and return -1 if (lessp x y)', 1 if (lessp y x)', 0 if (math-equal x y)', or 2 if the order is undefined or cannot be determined. Function: numdigs n Return the number of digits of integer n, effectively ceil(log10(n))', but much more efficient. Zero is considered to have zero digits. Function: scale-int x n Shift integer x left n decimal digits, or right -n digits with truncation toward zero. Function: scale-rounding x n Like scale-int, except that a right shift rounds to the nearest integer rather than truncating. Function: fixnum n Return the integer n as a fixnum, i.e., a native Lisp integer. If n is outside the permissible range for Lisp integers (usually 24 binary bits) the result is undefined. Function: sqr x Compute the square of x; short for (* x x)'. Function: quotient x y Divide integer x by integer y; return an integer quotient and discard the remainder. If x or y is negative, the direction of rounding is undefined. Function: idiv x y Perform an integer division; if x and y are both nonnegative integers, this uses the quotient function, otherwise it computes floor(x/y)'. Thus the result is well-defined but slower than for quotient. Function: imod x y Divide integer x by integer y; return the integer remainder and discard the quotient. Like quotient, this works only for integer arguments and is not well-defined for negative arguments. For a more well-defined result, use (% x y)'. Function: idivmod x y Divide integer x by integer y; return a cons cell whose car is (quotient x y)' and whose cdr is (imod x y)'. Function: pow x y Compute x to the power y. In defmath code, this can also be written (^ x y)' or (expt x y)'. Function: abs-approx x Compute a fast approximation to the absolute value of x. For example, for a rectangular complex number the result is the sum of the absolute values of the components. Function: pi The function (pi)' computes pi' to the current precision. Other related constant-generating functions are two-pi, pi-over-2, pi-over-4, pi-over-180, sqrt-two-pi, e, sqrt-e, ln-2, and ln-10. Each function returns a floating-point value in the current precision, and each uses caching so that all calls after the first are essentially free. Macro: math-defcache func initial form This macro, usually used as a top-level call like defun or defvar, defines a new cached constant analogous to pi, etc. It defines a function func which returns the requested value; if initial is non-nil it must be a (float ...)' form which serves as an initial value for the cache. If func is called when the cache is empty or does not have enough digits to satisfy the current precision, the Lisp expression form is evaluated with the current precision increased by four, and the result minus its two least significant digits is stored in the cache. For example, calling (pi)' with a precision of 30 computes pi' to 34 digits, rounds it down to 32 digits for future use, then rounds it again to 30 digits for use in the present request. Function: full-circle symb If the current angular mode is Degrees or HMS, this function returns the integer 360. In Radians mode, this function returns either the corresponding value in radians to the current precision, or the formula 2*pi', depending on the Symbolic Mode. There are also similar function half-circle and quarter-circle. Function: power-of-2 n Compute two to the integer power n, as a (potentially very large) integer. Powers of two are cached, so only the first call for a particular n is expensive. Function: integer-log2 n Compute the base-2 logarithm of n, which must be an integer which is a power of two. If n is not a power of two, this function will return nil. Function: div-mod a b m Divide a by b, modulo m. This returns nil if there is no solution, or if any of the arguments are not integers. Function: pow-mod a b m Compute a to the power b, modulo m. If a, b, and m are integers, this uses an especially efficient algorithm. Otherwise, it simply computes (% (^ a b) m)'. Function: isqrt n Compute the integer square root of n. This is the square root of n rounded down toward zero, i.e., floor(sqrt(n))'. If n is itself an integer, the computation is especially efficient. Function: to-hms a ang Convert the argument a into an HMS form. If ang is specified, it is the angular mode in which to interpret a, either deg or rad. Otherwise, the current angular mode is used. If a is already an HMS form it is returned as-is. Function: from-hms a ang Convert the HMS form a into a real number. If ang is specified, it is the angular mode in which to express the result, otherwise the current angular mode is used. If a is already a real number, it is returned as-is. Function: to-radians a Convert the number or HMS form a to radians from the current angular mode. Function: from-radians a Convert the number a from radians to the current angular mode. If a is a formula, this returns the formula deg(a)'. Function: to-radians-2 a Like to-radians, except that in Symbolic Mode a degrees to radians conversion yields a formula like a*pi/180'. Function: from-radians-2 a Like from-radians, except that in Symbolic Mode a radians to degrees conversion yields a formula like a*180/pi'. Function: random-digit Produce a random base-1000 digit in the range 0 to 999. Function: random-digits n Produce a random n-digit integer; this will be an integer in the interval [0, 10^n)'. Function: random-float Produce a random float in the interval [0, 1)'. Function: prime-test n iters Determine whether the integer n is prime. Return a list which has one of these forms: (nil f)' means the number is non-prime because it was found to be divisible by f; (nil)' means it was found to be non-prime by table look-up (so no factors are known); (nil unknown)' means it is definitely non-prime but no factors are known because n was large enough that Fermat's probabilistic test had to be used; (t)' means the number is definitely prime; and (maybe i p)' means that Fermat's test, after i iterations, is p percent sure that the number is prime. The iters parameter is the number of Fermat iterations to use, in the case that this is necessary. If prime-test returns "maybe," you can call it again with the same n to get a greater certainty; prime-test remembers where it left off. Function: to-simple-fraction f If f is a floating-point number which can be represented exactly as a small rational number. return that number, else return f. For example, 0.75 would be converted to 3:4. This function is very fast. Function: to-fraction f tol Find a rational approximation to floating-point number f to within a specified tolerance tol; this corresponds to the algebraic function frac, and can be rather slow. Function: quarter-integer n If n is an integer or integer-valued float, this function returns zero. If n is a half-integer (i.e., an integer plus 1:2 or 0.5), it returns 2. If n is a quarter-integer, it returns 1 or 3. If n is anything else, this function returns nil. #### Vector Functions The functions described here perform various operations on vectors and matrices. Function: math-concat x y Do a vector concatenation; this operation is written x | y' in a symbolic formula. See section Building Vectors. Function: vec-length v Return the length of vector v. If v is not a vector, the result is zero. If v is a matrix, this returns the number of rows in the matrix. Function: mat-dimens m Determine the dimensions of vector or matrix m. If m is not a vector, the result is an empty list. If m is a plain vector but not a matrix, the result is a one-element list containing the length of the vector. If m is a matrix with r rows and c columns, the result is the list (r c)'. Higher-order tensors produce lists of more than two dimensions. Note that the object [[1, 2, 3], [4, 5]]' is a vector of vectors not all the same size, and is treated by this and other Calc routines as a plain vector of two elements. Function: dimension-error Abort the current function with a message of "Dimension error." The Calculator will leave the function being evaluated in symbolic form; this is really just a special case of reject-arg. Function: build-vector args Return a Calc vector with the zero-or-more args as elements. For example, (build-vector 1 2 3)' returns the Calc vector [1, 2, 3]', stored internally as the list (vec 1 2 3)'. Function: make-vec obj dims Return a Calc vector or matrix all of whose elements are equal to obj. For example, (make-vec 27 3 4)' returns a 3x4 matrix filled with 27's. Function: row-matrix v If v is a plain vector, convert it into a row matrix, i.e., a matrix whose single row is v. If v is already a matrix, leave it alone. Function: col-matrix v If v is a plain vector, convert it into a column matrix, i.e., a matrix with each element of v as a separate row. If v is already a matrix, leave it alone. Function: map-vec f v Map the Lisp function f over the Calc vector v. For example, (map-vec 'math-floor v)' returns a vector of the floored components of vector v. Function: map-vec-2 f a b Map the Lisp function f over the two vectors a and b. If a and b are vectors of equal length, the result is a vector of the results of calling (f ai bi)' for each pair of elements ai and bi. If either a or b is a scalar, it is matched with each value of the other vector. For example, (map-vec-2 'math-add v 1)' returns the vector v with each element increased by one. Note that using '+' would not work here, since defmath does not expand function names everywhere, just where they are in the function position of a Lisp expression. Function: reduce-vec f v Reduce the function f over the vector v. For example, if v is [10, 20, 30, 40]', this calls (f (f (f 10 20) 30) 40)'. If v is a matrix, this reduces over the rows of v. Function: reduce-cols f m Reduce the function f over the columns of matrix m. For example, if m is [[1, 2], [3, 4], [5, 6]]', the result is a vector of the two elements (f (f 1 3) 5)' and (f (f 2 4) 6)'. Function: mat-row m n Return the nth row of matrix m. This is equivalent to (elt m n)'. For a slower but safer version, use mrow. (See section Extracting Vector Elements.) Function: mat-col m n Return the nth column of matrix m, in the form of a vector. The arguments are not checked for correctness. Function: mat-less-row m n Return a copy of matrix m with its nth row deleted. The number n must be in range from 1 to the number of rows in m. Function: mat-less-col m n Return a copy of matrix m with its nth column deleted. Function: transpose m Return the transpose of matrix m. Function: flatten-vector v Flatten nested vector v into a vector of scalars. For example, if v is [[1, 2, 3], [4, 5]]' the result is [1, 2, 3, 4, 5]'. Function: copy-matrix m If m is a matrix, return a copy of m. This maps copy-sequence over the rows of m; in Lisp terms, each element of the result matrix will be eq to the corresponding element of m, but none of the cons cells that make up the structure of the matrix will be eq. If m is a plain vector, this is the same as copy-sequence. Function: swap-rows m r1 r2 Exchange rows r1 and r2 of matrix m in-place. In other words, unlike most of the other functions described here, this function changes m itself rather than building up a new result matrix. The return value is m, i.e., (eq (swap-rows m 1 2) m)' is true, with the side effect of exchanging the first two rows of m. #### Symbolic Functions The functions described here operate on symbolic formulas in the Calculator. Function: calc-prepare-selection num Prepare a stack entry for selection operations. If num is omitted, the stack entry containing the cursor is used; otherwise, it is the number of the stack entry to use. This function stores useful information about the current stack entry into a set of variables. calc-selection-cache-num contains the number of the stack entry involved (equal to num if you specified it); calc-selection-cache-entry contains the stack entry as a list (such as calc-top-list would return with entry as the selection mode); and calc-selection-cache-comp contains a special "tagged" composition (see section I/O and Formatting Functions) which allows Calc to relate cursor positions in the buffer with their corresponding sub-formulas. A slight complication arises in the selection mechanism because formulas may contain small integers. For example, in the vector [1, 2, 1]' the first and last elements are eq to each other; selections are recorded as the actual Lisp object that appears somewhere in the tree of the whole formula, but storing 1 would falsely select both 1's in the vector. So calc-prepare-selection also checks the stack entry and replaces any plain integers with "complex number" lists of the form (cplx n 0)'. This list will be displayed the same as a plain n and the change will be completely invisible to the user, but it will guarantee that no two sub-formulas of the stack entry will be eq to each other. Next time the stack entry is involved in a computation, calc-normalize will replace these lists with plain numbers again, again invisibly to the user. Function: calc-encase-atoms x This modifies the formula x to ensure that each part of the formula is a unique atom, using the (cplx n 0)' trick described above. This function may use setcar to modify the formula in-place. Function: calc-find-selected-part Find the smallest sub-formula of the current formula that contains the cursor. This assumes calc-prepare-selection has been called already. If the cursor is not actually on any part of the formula, this returns nil. Function: calc-change-current-selection selection Change the currently prepared stack element's selection to selection, which should be eq to some sub-formula of the stack element, or nil to unselect the formula. The stack element's appearance in the Calc buffer is adjusted to reflect the new selection. Function: calc-find-nth-part expr n Return the nth sub-formula of expr. This function is used by the selection commands, and (unless j b has been used) treats sums and products as flat many-element formulas. Thus if expr is ((a + b) - c) + d', calling calc-find-nth-part with n equal to four will return d'. Function: calc-find-parent-formula expr part Return the sub-formula of expr which immediately contains part. If expr is a*b + (c+1)*d' and part is eq to the c+1' term of expr, then this function will return (c+1)*d'. If part turns out not to be a sub-formula of expr, the function returns nil. If part is eq to expr, the function returns t. This function does not take associativity into account. Function: calc-find-assoc-parent-formula expr part This is the same as calc-find-parent-formula, except that (unless j b has been used) it continues widening the selection to contain a complete level of the formula. Given a' from ((a + b) - c) + d', calc-find-parent-formula will return a + b' but calc-find-assoc-parent-formula will return the whole expression. Function: calc-grow-assoc-formula expr part This expands sub-formula part of expr to encompass a complete level of the formula. If part and its immediate parent are not compatible associative operators, or if j b has been used, this simply returns part. Function: calc-find-sub-formula expr part This finds the immediate sub-formula of expr which contains part. It returns an index n such that (calc-find-nth-part expr n)' would return part. If part is not a sub-formula of expr, it returns nil. If part is eq to expr, it returns t. This function does not take associativity into account. Function: calc-replace-sub-formula expr old new This function returns a copy of formula expr, with the sub-formula that is eq to old replaced by new. Function: simplify expr Simplify the expression expr by applying various algebraic rules. This is what the a s (calc-simplify) command uses. This always returns a copy of the expression; the structure expr points to remains unchanged in memory. More precisely, here is what simplify does: The expression is first normalized and evaluated by calling normalize. If any AlgSimpRules have been defined, they are then applied. Then the expression is traversed in a depth-first, bottom-up fashion; at each level, any simplifications that can be made are made until no further changes are possible. Once the entire formula has been traversed in this way, it is compared with the original formula (from before the call to normalize) and, if it has changed, the entire procedure is repeated (starting with normalize) until no further changes occur. Usually only two iterations are needed: one to simplify the formula, and another to verify that no further simplifications were possible. Function: simplify-extended expr Simplify the expression expr, with additional rules enabled that help do a more thorough job, while not being entirely "safe" in all circumstances. (For example, this mode will simplify sqrt(x^2)' to x', which is only valid when x is positive.) This is implemented by temporarily binding the variable math-living-dangerously to t (using a let form) and calling simplify. Dangerous simplification rules are written to check this variable before taking any action. Function: simplify-units expr Simplify the expression expr, treating variable names as units whenever possible. This works by binding the variable math-simplifying-units to t while calling simplify. Macro: math-defsimplify funcs body Register a new simplification rule; this is normally called as a top-level form, like defun or defmath. If funcs is a symbol (like + or calcFunc-sqrt), this simplification rule is applied to the formulas which are calls to the specified function. Or, funcs can be a list of such symbols; the rule applies to all functions on the list. The body is written like the body of a function with a single argument called expr. The body will be executed with expr bound to a formula which is a call to one of the functions funcs. If the function body returns nil, or if it returns a result equal to the original expr, it is ignored and Calc goes on to try the next simplification rule that applies. If the function body returns something different, that new formula is substituted for expr in the original formula. At each point in the formula, rules are tried in the order of the original calls to math-defsimplify; the search stops after the first rule that makes a change. Thus later rules for that same function will not have a chance to trigger until the next iteration of the main simplify loop. Note that, since defmath is not being used here, body must be written in true Lisp code without the conveniences that defmath provides. If you prefer, you can have body simply call another function (defined with defmath) which does the real work. The arguments of a function call will already have been simplified before any rules for the call itself are invoked. Since a new argument list is consed up when this happens, this means that the rule's body is allowed to rearrange the function's arguments destructively if that is convenient. Here is a typical example of a simplification rule: (math-defsimplify calcFunc-arcsinh (or (and (math-looks-negp (nth 1 expr)) (math-neg (list 'calcFunc-arcsinh (math-neg (nth 1 expr))))) (and (eq (car-safe (nth 1 expr)) 'calcFunc-sinh) (or math-living-dangerously (math-known-realp (nth 1 (nth 1 expr)))) (nth 1 (nth 1 expr)))))  This is really a pair of rules written with one math-defsimplify for convenience; the first replaces arcsinh(-x)' with -arcsinh(x)', and the second, which is safe only for real x', replaces arcsinh(sinh(x))' with x'. Function: common-constant-factor expr Check expr to see if it is a sum of terms all multiplied by the same rational value. If so, return this value. If not, return nil. For example, if called on 6x + 9y + 12z', it would return 3, since 3 is a common factor of all the terms. Function: cancel-common-factor expr factor Assuming expr is a sum with factor as a common factor, divide each term of the sum by factor. This is done by destructively modifying parts of expr, on the assumption that it is being used by a simplification rule (where such things are allowed; see above). For example, consider this built-in rule for square roots: (math-defsimplify calcFunc-sqrt (let ((fac (math-common-constant-factor (nth 1 expr)))) (and fac (not (eq fac 1)) (math-mul (math-normalize (list 'calcFunc-sqrt fac)) (math-normalize (list 'calcFunc-sqrt (math-cancel-common-factor (nth 1 expr) fac)))))))  Function: frac-gcd a b Compute a "rational GCD" of a and b, which must both be rational numbers. This is the fraction composed of the GCD of the numerators of a and b, over the GCD of the denominators. It is used by common-constant-factor. Note that the standard gcd function uses the LCM to combine the denominators. Function: map-tree func expr many Try applying Lisp function func to various sub-expressions of expr. Initially, call func with expr itself as an argument. If this returns an expression which is not equal to expr, apply func again until eventually it does return expr with no changes. Then, if expr is a function call, recursively apply func to each of the arguments. This keeps going until no changes occur anywhere in the expression; this final expression is returned by map-tree. Note that, unlike simplification rules, func functions may not make destructive changes to expr. If a third argument many is provided, it is an integer which says how many times func may be applied; the default, as described above, is infinitely many times. Function: compile-rewrites rules Compile the rewrite rule set specified by rules, which should be a formula that is either a vector or a variable name. If the latter, the compiled rules are saved so that later compile-rules calls for that same variable can return immediately. If there are problems with the rules, this function calls error with a suitable message. Function: apply-rewrites expr crules heads Apply the compiled rewrite rule set crules to the expression expr. This will make only one rewrite and only checks at the top level of the expression. The result nil if no rules matched, or if the only rules that matched did not actually change the expression. The heads argument is optional; if is given, it should be a list of all function names that (may) appear in expr. The rewrite compiler tags each rule with the rarest-looking function name in the rule; if you specify heads, apply-rewrites can use this information to narrow its search down to just a few rules in the rule set. Function: rewrite-heads expr Compute a heads list for expr suitable for use with apply-rewrites, as discussed above. Function: rewrite expr rules many This is an all-in-one rewrite function. It compiles the rule set specified by rules, then uses map-tree to apply the rules throughout expr up to many (default infinity) times. Function: match-patterns pat vec not-flag Given a Calc vector vec and an uncompiled pattern set or pattern set variable pat, this function returns a new vector of all elements of vec which do (or don't, if not-flag is non-nil) match any of the patterns in pat. Function: deriv expr var value symb Compute the derivative of expr with respect to variable var (which may actually be any sub-expression). If value is specified, the derivative is evaluated at the value of var; otherwise, the derivative is left in terms of var. If the expression contains functions for which no derivative formula is known, new derivative functions are invented by adding primes to the names; see section Calculus. However, if symb is non-nil, the presence of undifferentiable functions in expr instead cancels the whole differentiation, and deriv returns nil instead. Derivatives of an n-argument function can be defined by adding a math-derivative-n property to the property list of the symbol for the function's derivative, which will be the function name followed by an apostrophe. The value of the property should be a Lisp function; it is called with the same arguments as the original function call that is being differentiated. It should return a formula for the derivative. For example, the derivative of ln is defined by (put 'calcFunc-ln\' 'math-derivative-1 (function (lambda (u) (math-div 1 u))))  The two-argument log function has two derivatives, (put 'calcFunc-log\' 'math-derivative-2 ; d(log(x,b)) / dx (function (lambda (x b) ... ))) (put 'calcFunc-log\'2 'math-derivative-2 ; d(log(x,b)) / db (function (lambda (x b) ... )))  Function: tderiv expr var value symb Compute the total derivative of expr. This is the same as deriv, except that variables other than var are not assumed to be constant with respect to var. Function: integ expr var low high Compute the integral of expr with respect to var. See section Calculus, for further details. Macro: math-defintegral funcs body Define a rule for integrating a function or functions of one argument; this macro is very similar in format to math-defsimplify. The main difference is that here body is the body of a function with a single argument u which is bound to the argument to the function being integrated, not the function call itself. Also, the variable of integration is available as math-integ-var. If evaluation of the integral requires doing further integrals, the body should call (math-integral x)' to find the integral of x with respect to math-integ-var; this function returns nil if the integral could not be done. Some examples: (math-defintegral calcFunc-conj (let ((int (math-integral u))) (and int (list 'calcFunc-conj int)))) (math-defintegral calcFunc-cos (and (equal u math-integ-var) (math-from-radians-2 (list 'calcFunc-sin u))))  In the cos example, we define only the integral of cos(x) dx', relying on the general integration-by-substitution facility to handle cosines of more complicated arguments. An integration rule should return nil if it can't do the integral; if several rules are defined for the same function, they are tried in order until one returns a non-nil result. Macro: math-defintegral-2 funcs body Define a rule for integrating a function or functions of two arguments. This is exactly analogous to math-defintegral, except that body is written as the body of a function with two arguments, u and v. Function: solve-for lhs rhs var full Attempt to solve the equation lhs = rhs' by isolating the variable var on the lefthand side; return the resulting righthand side, or nil if the equation cannot be solved. The variable var must appear at least once in lhs or rhs. Note that the return value is a formula which does not contain var; this is different from the user-level solve and finv functions, which return a rearranged equation or a functional inverse, respectively. If full is non-nil, a full solution including dummy signs and dummy integers will be produced. User-defined inverses are provided as properties in a manner similar to derivatives: (put 'calcFunc-ln 'math-inverse (function (lambda (x) (list 'calcFunc-exp x))))  This function can call (math-solve-get-sign x)' to create a new arbitrary sign variable, returning x times that sign, and (math-solve-get-int x)' to create a new arbitrary integer variable multiplied by x. These functions simply return x if the caller requested a non-"full" solution. Function: solve-eqn expr var full This version of solve-for takes an expression which will typically be an equation or inequality. (If it is not, it will be interpreted as the equation expr = 0'.) It returns an equation or inequality, or nil if no solution could be found. Function: solve-system exprs vars full This function solves a system of equations. Generally, exprs and vars will be vectors of equal length. See section Solving Systems of Equations, for other options. Function: expr-contains expr var Returns a non-nil value if var occurs as a subexpression of expr. This function might seem at first to be identical to calc-find-sub-formula. The key difference is that expr-contains uses equal to test for matches, whereas calc-find-sub-formula uses eq. In the formula f(a, a)', the two a's will be equal but not eq to each other. Function: expr-contains-count expr var Returns the number of occurrences of var as a subexpression of expr, or nil if there are no occurrences. Function: expr-depends expr var Returns true if expr refers to any variable the occurs in var. In other words, it checks if expr and var have any variables in common. Function: expr-contains-vars expr Return true if expr contains any variables, or nil if expr contains only constants and functions with constant arguments. Function: expr-subst expr old new Returns a copy of expr, with all occurrences of old replaced by new. This treats lambda forms specially with respect to the dummy argument variables, so that the effect is always to return expr evaluated at old = new. Function: multi-subst expr old new This is like expr-subst, except that old and new are lists of expressions to be substituted simultaneously. If one list is shorter than the other, trailing elements of the longer list are ignored. Function: expr-weight expr Returns the "weight" of expr, basically a count of the total number of objects and function calls that appear in expr. For "primitive" objects, this will be one. Function: expr-height expr Returns the "height" of expr, which is the deepest level to which function calls are nested. (Note that a + b' counts as a function call.) For primitive objects, this returns zero. Function: polynomial-p expr var Check if expr is a polynomial in variable (or sub-expression) var. If so, return the degree of the polynomial, that is, the highest power of var that appears in expr. For example, for (x^2 + 3)^3 + 4' this would return 6. This function returns nil unless expr, when expanded out by a x (calc-expand), would consist of a sum of terms in which var appears only raised to nonnegative integer powers. Note that if var does not occur in expr, then expr is considered a polynomial of degree 0. Function: is-polynomial expr var degree loose Check if expr is a polynomial in variable or sub-expression var, and, if so, return a list representation of the polynomial where the elements of the list are coefficients of successive powers of var: a + b x + c x^3' would produce the list (a b 0 c)', and (x + 1)^2' would produce the list (1 2 1)'. The highest element of the list will be non-zero, with the special exception that if expr is the constant zero, the returned value will be (0)'. Return nil if expr is not a polynomial in var. If degree is specified, this will not consider polynomials of degree higher than that value. This is a good precaution because otherwise an input of (x+1)^1000' will cause a huge coefficient list to be built. If loose is non-nil, then a looser definition of a polynomial is used in which coefficients are no longer required not to depend on var, but are only required not to take the form of polynomials themselves. For example, sin(x) x^2 + cos(x)' is a loose polynomial with coefficients ((calcFunc-cos x) 0 (calcFunc-sin x))'. The result will never be nil in loose mode, since any expression can be interpreted as a "constant" loose polynomial. Function: polynomial-base expr pred Check if expr is a polynomial in any variable that occurs in it; if so, return that variable. (If expr is a multivariate polynomial, this chooses one variable arbitrarily.) If pred is specified, it should be a Lisp function which is called as (pred subexpr)', and which should return true if mpb-top-expr (a global name for the original expr) is a suitable polynomial in subexpr. The default predicate uses (polynomial-p mpb-top-expr subexpr)'; you can use pred to specify additional conditions. Or, you could have pred build up a list of every suitable subexpr that is found. Function: poly-simplify poly Simplify polynomial coefficient list poly by (destructively) clipping off trailing zeros. Function: poly-mix a ac b bc Mix two polynomial lists a and b (in the form returned by is-polynomial) in a linear combination with coefficient expressions ac and bc. The result is a (not necessarily simplified) polynomial list representing ac a + bc b'. Function: poly-mul a b Multiply two polynomial coefficient lists a and b. The result will be in simplified form if the inputs were simplified. Function: build-polynomial-expr poly var Construct a Calc formula which represents the polynomial coefficient list poly applied to variable var. The a c (calc-collect) command uses is-polynomial to turn an expression into a coefficient list, then build-polynomial-expr to turn the list back into an expression in regular form. Function: check-unit-name var Check if var is a variable which can be interpreted as a unit name. If so, return the units table entry for that unit. This will be a list whose first element is the unit name (not counting prefix characters) as a symbol and whose second element is the Calc expression which defines the unit. (Refer to the Calc sources for details on the remaining elements of this list.) If var is not a variable or is not a unit name, return nil. Function: units-in-expr-p expr sub-exprs Return true if expr contains any variables which can be interpreted as units. If sub-exprs is t, the entire expression is searched. If sub-exprs is nil, this checks whether expr is directly a units expression. Function: single-units-in-expr-p expr Check whether expr contains exactly one units variable. If so, return the units table entry for the variable. If expr does not contain any units, return nil. If expr contains two or more units, return the symbol wrong. Function: to-standard-units expr which Convert units expression expr to base units. If which is nil, use Calc's native base units. Otherwise, which can specify a units system, which is a list of two-element lists, where the first element is a Calc base symbol name and the second is an expression to substitute for it. Function: remove-units expr Return a copy of expr with all units variables replaced by ones. This expression is generally normalized before use. Function: extract-units expr Return a copy of expr with everything but units variables replaced by ones. #### I/O and Formatting Functions The functions described here are responsible for parsing and formatting Calc numbers and formulas. Function: calc-eval str sep arg1 arg2 ... This is the simplest interface to the Calculator from another Lisp program. See section Calling Calc from Your Lisp Programs. Function: read-number str If string str contains a valid Calc number, either integer, fraction, float, or HMS form, this function parses and returns that number. Otherwise, it returns nil. Function: read-expr str Read an algebraic expression from string str. If str does not have the form of a valid expression, return a list of the form (error pos msg)' where pos is an integer index into str of the general location of the error, and msg is a string describing the problem. Function: read-exprs str Read a list of expressions separated by commas, and return it as a Lisp list. If an error occurs in any expressions, an error list as shown above is returned instead. Function: calc-do-alg-entry initial prompt no-norm Read an algebraic formula or formulas using the minibuffer. All conventions of regular algebraic entry are observed. The return value is a list of Calc formulas; there will be more than one if the user entered a list of values separated by commas. The result is nil if the user presses Return with a blank line. If initial is given, it is a string which the minibuffer will initially contain. If prompt is given, it is the prompt string to use; the default is "Algebraic:". If no-norm is t, the formulas will be returned exactly as parsed; otherwise, they will be passed through calc-normalize first. To support the use of characters in the algebraic entry, use let to bind calc-dollar-values to a list of the values to be substituted for ,$$, and so on, and bind calc-dollar-used to 0. Upon return, calc-dollar-used will have been changed to the highest number of consecutive$s that actually appeared in the input.

Function: format-number a
Convert the real or complex number or HMS form a to string form.

Function: format-flat-expr a prec
Convert the arbitrary Calc number or formula a to string form, in the style used by the trail buffer and the calc-edit command. This is a simple format designed mostly to guarantee the string is of a form that can be re-parsed by read-expr. Most formatting modes, such as digit grouping, complex number format, and point character, are ignored to ensure the result will be re-readable. The prec parameter is normally 0; if you pass a large integer like 1000 instead, the expression will be surrounded by parentheses unless it is a plain number or variable name.

Function: format-nice-expr a width
This is like format-flat-expr (with prec equal to 0), except that newlines will be inserted to keep lines down to the specified width, and vectors that look like matrices or rewrite rules are written in a pseudo-matrix format. The calc-edit command uses this when only one stack entry is being edited.

Function: format-value a width
Convert the Calc number or formula a to string form, using the format seen in the stack buffer. Beware the the string returned may not be re-readable by read-expr, for example, because of digit grouping. Multi-line objects like matrices produce strings that contain newline characters to separate the lines. The w parameter, if given, is the target window size for which to format the expressions. If w is omitted, the width of the Calculator window is used.

Function: compose-expr a prec
Format the Calc number or formula a according to the current language mode, returning a "composition." To learn about the structure of compositions, see the comments in the Calc source code. You can specify the format of a given type of function call by putting a math-compose-lang property on the function's symbol, whose value is a Lisp function that takes a and prec as arguments and returns a composition. Here lang is a language mode name, one of normal, big, c, pascal, fortran, tex, eqn, math, or maple. In Big mode, Calc actually tries math-compose-big first, then tries math-compose-normal. If this property does not exist, or if the function returns nil, the function is written in the normal function-call notation for that language.

Function: composition-to-string c w
Convert a composition structure returned by compose-expr into a string. Multi-line compositions convert to strings containing newline characters. The target window size is given by w. The format-value function basically calls compose-expr followed by composition-to-string.

Function: comp-width c
Compute the width in characters of composition c.

Function: comp-height c
Compute the height in lines of composition c.

Function: comp-ascent c
Compute the portion of the height of composition c which is on or above the baseline. For a one-line composition, this will be one.

Function: comp-descent c
Compute the portion of the height of composition c which is below the baseline. For a one-line composition, this will be zero.

Function: comp-first-char c
If composition c is a "flat" composition, return the first (leftmost) character of the composition as an integer. Otherwise, return nil.

Function: comp-last-char c
If composition c is a "flat" composition, return the last (rightmost) character, otherwise return nil.

#### Hooks

Hooks are variables which contain Lisp functions (or lists of functions) which are called at various times. Calc defines a number of hooks that help you to customize it in various ways. Calc uses the Lisp function run-hooks to invoke the hooks shown below. Several other customization-related variables are also described here.

This hook is called at the end of calc.el', after the file has been loaded, before any functions in it have been called, but after calc-mode-map and similar variables have been set up.

This hook is called at the end of calc-ext.el'.

Variable: calc-start-hook
This hook is called as the last step in a M-x calc command. At this point, the Calc buffer has been created and initialized if necessary, the Calc window and trail window have been created, and the "Welcome to Calc" message has been displayed.

Variable: calc-mode-hook
This hook is called when the Calc buffer is being created. Usually this will only happen once per Emacs session. The hook is called after Emacs has switched to the new buffer, the mode-settings file has been read if necessary, and all other buffer-local variables have been set up. After this hook returns, Calc will perform a calc-refresh operation, set up the mode line display, then evaluate any deferred calc-define properties that have not been evaluated yet.

Variable: calc-trail-mode-hook
This hook is called when the Calc Trail buffer is being created. It is called as the very last step of setting up the Trail buffer. Like calc-mode-hook, this will normally happen only once per Emacs session.

Variable: calc-end-hook
This hook is called by calc-quit, generally because the user presses q or M-# c while in Calc. The Calc buffer will be the current buffer. The hook is called as the very first step, before the Calc window is destroyed.

Variable: calc-window-hook
If this hook exists, it is called to create the Calc window. Upon return, this new Calc window should be the current window. (The Calc buffer will already be the current buffer when the hook is called.) If the hook is not defined, Calc will generally use split-window, set-window-buffer, and select-window to create the Calc window.

Variable: calc-trail-window-hook
If this hook exists, it is called to create the Calc Trail window. The variable calc-trail-buffer will contain the buffer which the window should use. Unlike calc-window-hook, this hook must not switch into the new window.

Variable: calc-edit-mode-hook
This hook is called by calc-edit (and the other "edit" commands) when the temporary editing buffer is being created. The buffer will have been selected and set up to be in calc-edit-mode, but will not yet have been filled with text. (In fact it may still have leftover text from a previous calc-edit command.)

Variable: calc-mode-save-hook
This hook is called by the calc-save-modes command, after Calc's own mode features have been inserted into the .emacs' buffer and just before the "End of mode settings" message is inserted.

Variable: calc-reset-hook
This hook is called after M-# 0 (calc-reset) has reset all modes. The Calc buffer will be the current buffer.

Variable: calc-other-modes
This variable contains a list of strings. The strings are concatenated at the end of the modes portion of the Calc mode line (after standard modes such as "Deg", "Inv" and "Hyp"). Each string should be a short, single word followed by a space. The variable is nil by default.

Variable: calc-mode-map
This is the keymap that is used by Calc mode. The best time to adjust it is probably in a calc-mode-hook. If the Calc extensions package (calc-ext.el') has not yet been loaded, many of these keys will be bound to calc-missing-key, which is a command that loads the extensions package and "retypes" the key. If your calc-mode-hook rebinds one of these keys, it will probably be overridden when the extensions are loaded.

Variable: calc-digit-map
This is the keymap that is used during numeric entry. Numeric entry uses the minibuffer, but this map binds every non-numeric key to calcDigit-nondigit which generally calls exit-minibuffer and "retypes" the key.

Variable: calc-alg-ent-map
This is the keymap that is used during algebraic entry. This is mostly a copy of minibuffer-local-map.

Variable: calc-store-var-map
This is the keymap that is used during entry of variable names for commands like calc-store and calc-recall. This is mostly a copy of minibuffer-local-completion-map.

Variable: calc-edit-mode-map
This is the (sparse) keymap used by calc-edit and other temporary editing commands. It binds RET, LFD, and C-c C-c to calc-edit-finish.

Variable: calc-mode-var-list
This is a list of variables which are saved by calc-save-modes. Each entry is a list of two items, the variable (as a Lisp symbol) and its default value. When modes are being saved, each variable is compared with its default value (using equal) and any non-default variables are written out.

Variable: calc-local-var-list
This is a list of variables which should be buffer-local to the Calc buffer. Each entry is a variable name (as a Lisp symbol). These variables also have their default values manipulated by the calc and calc-quit commands; see section Multiple Calculators. Since calc-mode-hook is called after this list has been used the first time, your hook should add a variable to the list and also call make-local-variable itself.