This is Info file calc.info, produced by Makeinfo-1.55 from the input file calc.texinfo. This file documents Calc, the GNU Emacs calculator. Copyright (C) 1990, 1991 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the section entitled "GNU General Public License" is included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that the section entitled "GNU General Public License" may be included in a translation approved by the author instead of in the original English. File: calc.info, Node: Programming Tutorial, Next: Answers to Exercises, Prev: Algebra Tutorial, Up: Tutorial Programming Tutorial ==================== The Calculator is written entirely in Emacs Lisp, a highly extensible language. If you know Lisp, you can program the Calculator to do anything you like. Rewrite rules also work as a powerful programming system. But Lisp and rewrite rules take a while to master, and often all you want to do is define a new function or repeat a command a few times. Calc has features that allow you to do these things easily. (Note that the programming commands relating to user-defined keys are not yet supported under Lucid Emacs 19.) One very limited form of programming is defining your own functions. Calc's `Z F' command allows you to define a function name and key sequence to correspond to any formula. Programming commands use the shift-`Z' prefix; the user commands they create use the lower case `z' prefix. 1: 1 + x + x^2 / 2 + x^3 / 6 1: 1 + x + x^2 / 2 + x^3 / 6 . . ' 1 + x + x^2/2! + x^3/3! RET Z F e myexp RET RET RET y This polynomial is a Taylor series approximation to `exp(x)'. The `Z F' command asks a number of questions. The above answers say that the key sequence for our function should be `z e'; the `M-x' equivalent should be `calc-myexp'; the name of the function in algebraic formulas should also be `myexp'; the default argument list `(x)' is acceptable; and finally `y' answers the question "leave it in symbolic form for non-constant arguments?" 1: 1.3495 2: 1.3495 3: 1.3495 . 1: 1.34986 2: 1.34986 . 1: myexp(a + 1) . .3 z e .3 E ' a+1 RET z e First we call our new `exp' approximation with 0.3 as an argument, and compare it with the true `exp' function. Then we note that, as requested, if we try to give `z e' an argument that isn't a plain number, it leaves the `myexp' function call in symbolic form. If we had answered `n' to the final question, `myexp(a + 1)' would have evaluated by plugging in `a + 1' for `x' in the defining formula. (*) *Exercise 1.* The "sine integral" function `Si(x)' is defined as the integral of `sin(t)/t' for `t = 0' to `x' in radians. (It was invented because this integral has no solution in terms of basic functions; if you give it to Calc's `a i' command, it will ponder it for a long time and then give up.) We can use the numerical integration command, however, which in algebraic notation is written like `ninteg(f(t), t, 0, x)' with any integrand `f(t)'. Define a `z s' command and `Si' function that implement this. You will need to edit the default argument list a bit. As a test, `Si(1)' should return 0.946083. (Hint: `ninteg' will run a lot faster if you reduce the precision to, say, six digits beforehand.) *Note 1: Programming Answer 1. (*) The simplest way to do real "programming" of Emacs is to define a "keyboard macro". A keyboard macro is simply a sequence of keystrokes which Emacs has stored away and can play back on demand. For example, if you find yourself typing `H a S x RET' often, you may wish to program a keyboard macro to type this for you. 1: y = sqrt(x) 1: x = y^2 . . ' y=sqrt(x) RET C-x ( H a S x RET C-x ) 1: y = cos(x) 1: x = s1 arccos(y) + 2 pi n1 . . ' y=cos(x) RET X When you type `C-x (', Emacs begins recording. But it is also still ready to execute your keystrokes, so you're really "training" Emacs by walking it through the procedure once. When you type `C-x )', the macro is recorded. You can now type `X' to re-execute the same keystrokes. You can give a name to your macro by typing `Z K'. 1: . 1: y = x^4 1: x = s2 sqrt(s1 sqrt(y)) . . Z K x RET ' y=x^4 RET z x Notice that we use shift-`Z' to define the command, and lower-case `z' to call it up. Keyboard macros can call other macros. 1: abs(x) 1: x = s1 y 1: 2 / x 1: x = 2 / y . . . . ' abs(x) RET C-x ( ' y RET a = z x C-x ) ' 2/x RET X (*) *Exercise 2.* Define a keyboard macro to negate the item in level 3 of the stack, without disturbing the rest of the stack. *Note 2: Programming Answer 2. (*) (*) *Exercise 3.* Define keyboard macros to compute the following functions: 1. Compute `sin(x) / x', where `x' is the number on the top of the stack. 2. Compute the base-`b' logarithm, just like the `B' key except the arguments are taken in the opposite order. 3. Produce a vector of integers from 1 to the integer on the top of the stack. *Note 3: Programming Answer 3. (*) (*) *Exercise 4.* Define a keyboard macro to compute the average (mean) value of a list of numbers. *Note 4: Programming Answer 4. (*) In many programs, some of the steps must execute several times. Calc has "looping" commands that allow this. Loops are useful inside keyboard macros, but actually work at any time. 1: x^6 2: x^6 1: 360 x^2 . 1: 4 . . ' x^6 RET 4 Z < a d x RET Z > Here we have computed the fourth derivative of `x^6' by enclosing a derivative command in a "repeat loop" structure. This structure pops a repeat count from the stack, then executes the body of the loop that many times. If you make a mistake while entering the body of the loop, type `Z C-g' to cancel the loop command. Here's another example: 3: 1 2: 10946 2: 1 1: 17711 1: 20 . . 1 RET RET 20 Z < TAB C-j + Z > The numbers in levels 2 and 1 should be the 21st and 22nd Fibonacci numbers, respectively. (To see what's going on, try a few repetitions of the loop body by hand; `C-j', also on the Line-Feed or LFD key if you have one, makes a copy of the number in level 2.) A fascinating property of the Fibonacci numbers is that the `n'th Fibonacci number can be found directly by computing `phi^n / sqrt(5)' and then rounding to the nearest integer, where `phi', the "golden ratio," is `(1 + sqrt(5)) / 2'. (For convenience, this constant is available from the `phi' variable, or the `I H P' command.) 1: 1.61803 1: 24476.0000409 1: 10945.9999817 1: 10946 . . . . I H P 21 ^ 5 Q / R (*) *Exercise 5.* The "continued fraction" representation of `phi' is `1 + 1/(1 + 1/(1 + 1/( ... )))'. We can compute an approximate value by carrying this however far and then replacing the innermost `1/( ... )' by 1. Approximate `phi' using a twenty-term continued fraction. *Note 5: Programming Answer 5. (*) (*) *Exercise 6.* Linear recurrences like the one for Fibonacci numbers can be expressed in terms of matrices. Given a vector `[a, b]' determine a matrix which, when multiplied by this vector, produces the vector `[b, c]', where `a', `b' and `c' are three successive Fibonacci numbers. Now write a program that, given an integer `n', computes the `n'th Fibonacci number using matrix arithmetic. *Note 6: Programming Answer 6. (*) A more sophisticated kind of loop is the "for" loop. Suppose we wish to compute the 20th "harmonic" number, which is equal to the sum of the reciprocals of the integers from 1 to 20. 3: 0 1: 3.597739 2: 1 . 1: 20 . 0 RET 1 RET 20 Z ( & + 1 Z ) The "for" loop pops two numbers, the lower and upper limits, then repeats the body of the loop as an internal counter increases from the lower limit to the upper one. Just before executing the loop body, it pushes the current loop counter. When the loop body finishes, it pops the "step," i.e., the amount by which to increment the loop counter. As you can see, our loop always uses a step of one. This harmonic number function uses the stack to hold the running total as well as for the various loop housekeeping functions. If you find this disorienting, you can sum in a variable instead: 1: 0 2: 1 . 1: 3.597739 . 1: 20 . . 0 t 7 1 RET 20 Z ( & s + 7 1 Z ) r 7 The `s +' command adds the top-of-stack into the value in a variable (and removes that value from the stack). It's worth noting that many jobs that call for a "for" loop can also be done more easily by Calc's high-level operations. Two other ways to compute harmonic numbers are to use vector mapping and reduction (`v x 20', then `V M &', then `V R +'), or to use the summation command `a +'. Both of these are probably easier than using loops. However, there are some situations where loops really are the way to go: (*) *Exercise 7.* Use a "for" loop to find the first harmonic number which is greater than 4.0. *Note 7: Programming Answer 7. (*) Of course, if we're going to be using variables in our programs, we have to worry about the programs clobbering values that the caller was keeping in those same variables. This is easy to fix, though: . 1: 0.6667 1: 0.6667 3: 0.6667 . . 2: 3.597739 1: 0.6667 . Z ` p 4 RET 2 RET 3 / s 7 s s a RET Z ' r 7 s r a RET When we type `Z `' (that's a back-quote character), Calc saves its mode settings and the contents of the ten "quick variables" for later reference. When we type `Z '' (that's an apostrophe now), Calc restores those saved values. Thus the `p 4' and `s 7' commands have no effect outside this sequence. Wrapping this around the body of a keyboard macro ensures that it doesn't interfere with what the user of the macro was doing. Notice that the contents of the stack, and the values of named variables, survive past the `Z '' command. The "Bernoulli numbers" are a sequence with the interesting property that all of the odd Bernoulli numbers are zero, and the even ones, while difficult to compute, can be roughly approximated by the formula `2 n! / (2 pi)^n'. Let's write a keyboard macro to compute (approximate) Bernoulli numbers. (Calc has a command, `k b', to compute exact Bernoulli numbers, but this command is very slow for large `n' since the higher Bernoulli numbers are very large fractions.) 1: 10 1: 0.0756823 . . 10 C-x ( RET 2 % Z [ DEL 0 Z : ' 2 $! / (2 pi)^$ RET = Z ] C-x ) You can read `Z [' as "then," `Z :' as "else," and `Z ]' as "end-if." There is no need for an explicit "if" command. For the purposes of `Z [', the condition is "true" if the value it pops from the stack is a nonzero number, or "false" if it pops zero or something that is not a number (like a formula). Here we take our integer argument modulo 2; this will be nonzero if we're asking for an odd Bernoulli number. The actual tenth Bernoulli number is `5/66'. 3: 0.0756823 1: 0 1: 0.25305 1: 0 1: 1.16659 2: 5:66 . . . . 1: 0.0757575 . 10 k b RET c f M-0 DEL 11 X DEL 12 X DEL 13 X DEL 14 X Just to exercise loops a bit more, let's compute a table of even Bernoulli numbers. 3: [] 1: [0.10132, 0.03079, 0.02340, 0.033197, ...] 2: 2 . 1: 30 . [ ] 2 RET 30 Z ( X | 2 Z ) The vertical-bar `|' is the vector-concatenation command. When we execute it, the list we are building will be in stack level 2 (initially this is an empty list), and the next Bernoulli number will be in level 1. The effect is to append the Bernoulli number onto the end of the list. (To create a table of exact fractional Bernoulli numbers, just replace `X' with `k b' in the above sequence of keystrokes.) With loops and conditionals, you can program essentially anything in Calc. One other command that makes looping easier is `Z /', which takes a condition from the stack and breaks out of the enclosing loop if the condition is true (non-zero). You can use this to make "while" and "until" style loops. If you make a mistake when entering a keyboard macro, you can edit it using `Z E'. First, you must attach it to a key with `Z K'. One technique is to enter a throwaway dummy definition for the macro, then enter the real one in the edit command. 1: 3 1: 3 Keyboard Macro Editor. . . Original keys: 1 RET 2 + type "1\r" type "2" calc-plus C-x ( 1 RET 2 + C-x ) Z K h RET Z E h This shows the screen display assuming you have the `macedit' keyboard macro editing package installed, which is usually the case since a copy of `macedit' comes bundled with Calc. A keyboard macro is stored as a pure keystroke sequence. The `macedit' package (invoked by `Z E') scans along the macro and tries to decode it back into human-readable steps. If a key or keys are simply shorthand for some command with a `M-x' name, that name is shown. Anything that doesn't correspond to a `M-x' command is written as a `type' command. Let's edit in a new definition, for computing harmonic numbers. First, erase the three lines of the old definition. Then, type in the new definition (or use Emacs `M-w' and `C-y' commands to copy it from this page of the Info file; you can skip typing the comments that begin with `#'). calc-kbd-push # Save local values (Z `) type "0" # Push a zero calc-store-into # Store it in variable 1 type "1" type "1" # Initial value for loop calc-roll-down # This is the TAB key; swap initial & final calc-kbd-for # Begin "for" loop... calc-inv # Take reciprocal calc-store-plus # Add to accumulator type "1" type "1" # Loop step is 1 calc-kbd-end-for # End "for" loop calc-recall # Now recall final accumulated value type "1" calc-kbd-pop # Restore values (Z ') Press `M-# M-#' to finish editing and return to the Calculator. 1: 20 1: 3.597739 . . 20 z h If you don't know how to write a particular command in `macedit' format, you can always write it as keystrokes in a `type' command. There is also a `keys' command which interprets the rest of the line as standard Emacs keystroke names. In fact, `macedit' defines a handy `read-kbd-macro' command which reads the current region of the current buffer as a sequence of keystroke names, and defines that sequence on the `X' (and `C-x e') key. Because this is so useful, Calc puts this command on the `M-# m' key. Try reading in this macro in the following form: Press `C-@' (or `C-SPC') at one end of the text below, then type `M-# m' at the other. Z ` 0 t 1 1 TAB Z ( & s + 1 1 Z ) r 1 Z ' (*) *Exercise 8.* A general algorithm for solving equations numerically is "Newton's Method". Given the equation `f(x) = 0' for any function `f', and an initial guess `x_0' which is reasonably close to the desired solution, apply this formula over and over: new_x = x - f(x)/f'(x) where `f'(x)' is the derivative of `f'. The `x' values will quickly converge to a solution, i.e., eventually `new_x' and `x' will be equal to within the limits of the current precision. Write a program which takes a formula involving the variable `x', and an initial guess `x_0', on the stack, and produces a value of `x' for which the formula is zero. Use it to find a solution of `sin(cos(x)) = 0.5' near `x = 4.5'. (Use angles measured in radians.) Note that the built-in `a R' (`calc-find-root') command uses Newton's method when it is able. *Note 8: Programming Answer 8. (*) (*) *Exercise 9.* The "digamma" function `psi(z)' is defined as the derivative of `ln(gamma(z))'. For large values of `z', it can be approximated by the infinite sum psi(z) ~= ln(z) - 1/2z - sum(bern(2 n) / 2 n z^(2 n), n, 1, inf) where `sum' represents the sum over `n' from 1 to infinity (or to some limit high enough to give the desired accuracy), and the `bern' function produces (exact) Bernoulli numbers. While this sum is not guaranteed to converge, in practice it is safe. An interesting mathematical constant is Euler's gamma, which is equal to about 0.5772. One way to compute it is by the formula, `gamma = -psi(1)'. Unfortunately, 1 isn't a large enough argument for the above formula to work (5 is a much safer value for `z'). Fortunately, we can compute `psi(1)' from `psi(5)' using the recurrence `psi(z+1) = psi(z) + 1/z'. Your task: Develop a program to compute `psi(z)'; it should "pump up" `z' if necessary to be greater than 5, then use the above summation formula. Use looping commands to compute the sum. Use your function to compute `gamma' to twelve decimal places. (Calc has a built-in command for Euler's constant, `I P', which you can use to check your answer.) *Note 9: Programming Answer 9. (*) (*) *Exercise 10.* Given a polynomial in `x' and a number `m' on the stack, where the polynomial is of degree `m' or less (i.e., does not have any terms higher than `x^m'), write a program to convert the polynomial into a list-of-coefficients notation. For example, `5 x^4 + (x + 1)^2' with `m = 6' should produce the list `[1, 2, 1, 0, 5, 0, 0]'. Also develop a way to convert from this form back to the standard algebraic form. *Note 10: Programming Answer 10. (*) (*) *Exercise 11.* The "Stirling numbers of the first kind" are defined by the recurrences, s(n,n) = 1 for n >= 0, s(n,0) = 0 for n > 0, s(n+1,m) = s(n,m-1) - n s(n,m) for n >= m >= 1. This can be implemented using a "recursive" program in Calc; the program must invoke itself in order to calculate the two righthand terms in the general formula. Since it always invokes itself with "simpler" arguments, it's easy to see that it must eventually finish the computation. Recursion is a little difficult with Emacs keyboard macros since the macro is executed before its definition is complete. So here's the recommended strategy: Create a "dummy macro" and assign it to a key with, e.g., `Z K s'. Now enter the true definition, using the `z s' command to call itself recursively, then assign it to the same key with `Z K s'. Now the `z s' command will run the complete recursive program. (Another way is to use `Z E' or `M-# m' (`read-kbd-macro') to read the whole macro at once, thus avoiding the "training" phase.) The task: Write a program that computes Stirling numbers of the first kind, given `n' and `m' on the stack. Test it with *small* inputs like `s(4,2)'. (There is a built-in command for Stirling numbers, `k s', which you can use to check your answers.) *Note 11: Programming Answer 11. (*) The programming commands we've seen in this part of the tutorial are low-level, general-purpose operations. Often you will find that a higher-level function, such as vector mapping or rewrite rules, will do the job much more easily than a detailed, step-by-step program can: (*) *Exercise 12.* Write another program for computing Stirling numbers of the first kind, this time using rewrite rules. Once again, `n' and `m' should be taken from the stack. *Note 12: Programming Answer 12. (*) This ends the tutorial section of the Calc manual. Now you know enough about Calc to use it effectively for many kinds of calculations. But Calc has many features that were not even touched upon in this tutorial. The rest of this manual tells the whole story. File: calc.info, Node: Answers to Exercises, Prev: Programming Tutorial, Up: Tutorial Answers to Exercises ==================== This section includes answers to all the exercises in the Calc tutorial. * Menu: * RPN Answer 1:: 1 RET 2 RET 3 RET 4 + * - * RPN Answer 2:: 2*4 + 7*9.5 + 5/4 * RPN Answer 3:: Operating on levels 2 and 3 * RPN Answer 4:: Joe's complex problems * Algebraic Answer 1:: Simulating Q command * Algebraic Answer 2:: Joe's algebraic woes * Algebraic Answer 3:: 1 / 0 * Modes Answer 1:: 3#0.1 = 3#0.0222222? * Modes Answer 2:: 16#f.e8fe15 * Modes Answer 3:: Joe's rounding bug * Modes Answer 4:: Why floating point? * Arithmetic Answer 1:: Why the \ command? * Arithmetic Answer 2:: Tripping up the B command * Vector Answer 1:: Normalizing a vector * Vector Answer 2:: Average position * Matrix Answer 1:: Row and column sums * Matrix Answer 2:: Symbolic system of equations * Matrix Answer 3:: Over-determined system * List Answer 1:: Powers of two * List Answer 2:: Least-squares fit with matrices * List Answer 3:: Geometric mean * List Answer 4:: Divisor function * List Answer 5:: Duplicate factors * List Answer 6:: Triangular list * List Answer 7:: Another triangular list * List Answer 8:: Maximum of Bessel function * List Answer 9:: Integers the hard way * List Answer 10:: All elements equal * List Answer 11:: Estimating pi with darts * List Answer 12:: Estimating pi with matchsticks * List Answer 13:: Hash codes * List Answer 14:: Random walk * Types Answer 1:: Square root of pi times rational * Types Answer 2:: Infinities * Types Answer 3:: What can "nan" be? * Types Answer 4:: Abbey Road * Types Answer 5:: Friday the 13th * Types Answer 6:: Leap years * Types Answer 7:: Erroneous donut * Types Answer 8:: Dividing intervals * Types Answer 9:: Squaring intervals * Types Answer 10:: Fermat's primality test * Types Answer 11:: pi * 10^7 seconds * Types Answer 12:: Abbey Road on CD * Types Answer 13:: Not quite pi * 10^7 seconds * Types Answer 14:: Supercomputers and c * Types Answer 15:: Sam the Slug * Algebra Answer 1:: Squares and square roots * Algebra Answer 2:: Building polynomial from roots * Algebra Answer 3:: Integral of x sin(pi x) * Algebra Answer 4:: Simpson's rule * Rewrites Answer 1:: Multiplying by conjugate * Rewrites Answer 2:: Alternative fib rule * Rewrites Answer 3:: Rewriting opt(a) + opt(b) x * Rewrites Answer 4:: Sequence of integers * Rewrites Answer 5:: Number of terms in sum * Rewrites Answer 6:: Defining 0^0 = 1 * Rewrites Answer 7:: Truncated Taylor series * Programming Answer 1:: Fresnel's C(x) * Programming Answer 2:: Negate third stack element * Programming Answer 3:: Compute sin(x) / x, etc. * Programming Answer 4:: Average value of a list * Programming Answer 5:: Continued fraction phi * Programming Answer 6:: Matrix Fibonacci numbers * Programming Answer 7:: Harmonic number greater than 4 * Programming Answer 8:: Newton's method * Programming Answer 9:: Digamma function * Programming Answer 10:: Unpacking a polynomial * Programming Answer 11:: Recursive Stirling numbers * Programming Answer 12:: Stirling numbers with rewrites File: calc.info, Node: RPN Answer 1, Next: RPN Answer 2, Prev: Answers to Exercises, Up: Answers to Exercises RPN Tutorial Exercise 1 ----------------------- `1 RET 2 RET 3 RET 4 + * -' The result is `1 - (2 * (3 + 4)) = -13'. File: calc.info, Node: RPN Answer 2, Next: RPN Answer 3, Prev: RPN Answer 1, Up: Answers to Exercises RPN Tutorial Exercise 2 ----------------------- `2*4 + 7*9.5 + 5/4 = 75.75' After computing the intermediate term `2*4 = 8', you can leave that result on the stack while you compute the second term. With both of these results waiting on the stack you can then compute the final term, then press `+ +' to add everything up. 2: 2 1: 8 3: 8 2: 8 1: 4 . 2: 7 1: 66.5 . 1: 9.5 . . 2 RET 4 * 7 RET 9.5 * 4: 8 3: 8 2: 8 1: 75.75 3: 66.5 2: 66.5 1: 67.75 . 2: 5 1: 1.25 . 1: 4 . . 5 RET 4 / + + Alternatively, you could add the first two terms before going on with the third term. 2: 8 1: 74.5 3: 74.5 2: 74.5 1: 75.75 1: 66.5 . 2: 5 1: 1.25 . . 1: 4 . . ... + 5 RET 4 / + On an old-style RPN calculator this second method would have the advantage of using only three stack levels. But since Calc's stack can grow arbitrarily large this isn't really an issue. Which method you choose is purely a matter of taste. File: calc.info, Node: RPN Answer 3, Next: RPN Answer 4, Prev: RPN Answer 2, Up: Answers to Exercises RPN Tutorial Exercise 3 ----------------------- The TAB key provides a way to operate on the number in level 2. 3: 10 3: 10 4: 10 3: 10 3: 10 2: 20 2: 30 3: 30 2: 30 2: 21 1: 30 1: 20 2: 20 1: 21 1: 30 . . 1: 1 . . . TAB 1 + TAB Similarly, M-TAB gives you access to the number in level 3. 3: 10 3: 21 3: 21 3: 30 3: 11 2: 21 2: 30 2: 30 2: 11 2: 21 1: 30 1: 10 1: 11 1: 21 1: 30 . . . . . M-TAB 1 + M-TAB M-TAB File: calc.info, Node: RPN Answer 4, Next: Algebraic Answer 1, Prev: RPN Answer 3, Up: Answers to Exercises RPN Tutorial Exercise 4 ----------------------- Either `( 2 , 3 )' or `( 2 SPC 3 )' would have worked, but using both the comma and the space at once yields: 1: ( ... 2: ( ... 1: (2, ... 2: (2, ... 2: (2, ... . 1: 2 . 1: (2, ... 1: (2, 3) . . . ( 2 , SPC 3 ) Joe probably tried to type `TAB DEL' to swap the extra incomplete object to the top of the stack and delete it. But a feature of Calc is that DEL on an incomplete object deletes just one component out of that object, so he had to press DEL twice to finish the job. 2: (2, ... 2: (2, 3) 2: (2, 3) 1: (2, 3) 1: (2, 3) 1: (2, ... 1: ( ... . . . . TAB DEL DEL (As it turns out, deleting the second-to-top stack entry happens often enough that Calc provides a special key, `M-DEL', to do just that. `M-DEL' is just like `TAB DEL', except that it doesn't exhibit the "feature" that tripped poor Joe.) File: calc.info, Node: Algebraic Answer 1, Next: Algebraic Answer 2, Prev: RPN Answer 4, Up: Answers to Exercises Algebraic Entry Tutorial Exercise 1 ----------------------------------- Type `' sqrt($) RET'. If the `Q' key is broken, you could use `' $^0.5 RET'. Or, RPN style, `0.5 ^'. (Actually, `$^1:2', using the fraction one-half as the power, is a closer equivalent, since `9^0.5' yields `3.0' whereas `sqrt(9)' and `9^1:2' yield the exact integer `3'.) File: calc.info, Node: Algebraic Answer 2, Next: Algebraic Answer 3, Prev: Algebraic Answer 1, Up: Answers to Exercises Algebraic Entry Tutorial Exercise 2 ----------------------------------- In the formula `2 x (1+y)', `x' was interpreted as a function name with `1+y' as its argument. Assigning a value to a variable has no relation to a function by the same name. Joe needed to use an explicit `*' symbol here: `2 x*(1+y)'. File: calc.info, Node: Algebraic Answer 3, Next: Modes Answer 1, Prev: Algebraic Answer 2, Up: Answers to Exercises Algebraic Entry Tutorial Exercise 3 ----------------------------------- The result from `1 RET 0 /' will be the formula `1 / 0'. The "function" `/' cannot be evaluated when its second argument is zero, so it is left in symbolic form. When you now type `0 *', the result will be zero because Calc uses the general rule that "zero times anything is zero." The `m i' command enables an "infinite mode" in which `1 / 0' results in a special symbol that represents "infinity." If you multiply infinity by zero, Calc uses another special new symbol to show that the answer is "indeterminate." *Note Infinities::, for further discussion of infinite and indeterminate values. File: calc.info, Node: Modes Answer 1, Next: Modes Answer 2, Prev: Algebraic Answer 3, Up: Answers to Exercises Modes Tutorial Exercise 1 ------------------------- Calc always stores its numbers in decimal, so even though one-third has an exact base-3 representation (`3#0.1'), it is still stored as 0.3333333 (chopped off after 12 or however many decimal digits) inside the calculator's memory. When this inexact number is converted back to base 3 for display, it may still be slightly inexact. When we multiply this number by 3, we get 0.999999, also an inexact value. When Calc displays a number in base 3, it has to decide how many digits to show. If the current precision is 12 (decimal) digits, that corresponds to `12 / log10(3) = 25.15' base-3 digits. Because 25.15 is not an exact integer, Calc shows only 25 digits, with the result that stored numbers carry a little bit of extra information that may not show up on the screen. When Joe entered `3#0.2', the stored number 0.666666 happened to round to a pleasing value when it lost that last 0.15 of a digit, but it was still inexact in Calc's memory. When he divided by 2, he still got the dreaded inexact value 0.333333. (Actually, he divided 0.666667 by 2 to get 0.333334, which is why he got something a little higher than `3#0.1' instead of a little lower.) If Joe didn't want to be bothered with all this, he could have typed `M-24 d n' to display with one less digit than the default. (If you give `d n' a negative argument, it uses default-minus-that, so `M-- d n' would be an easier way to get the same effect.) Those inexact results would still be lurking there, but they would now be rounded to nice, natural-looking values for display purposes. (Remember, `0.022222' in base 3 is like `0.099999' in base 10; rounding off one digit will round the number up to `0.1'.) Depending on the nature of your work, this hiding of the inexactness may be a benefit or a danger. With the `d n' command, Calc gives you the choice. Incidentally, another consequence of all this is that if you type `M-30 d n' to display more digits than are "really there," you'll see garbage digits at the end of the number. (In decimal display mode, with decimally-stored numbers, these garbage digits are always zero so they vanish and you don't notice them.) Because Calc rounds off that 0.15 digit, there is the danger that two numbers could be slightly different internally but still look the same. If you feel uneasy about this, set the `d n' precision to be a little higher than normal; you'll get ugly garbage digits, but you'll always be able to tell two distinct numbers apart. An interesting side note is that most computers store their floating-point numbers in binary, and convert to decimal for display. Thus everyday programs have the same problem: Decimal 0.1 cannot be represented exactly in binary (try it: `0.1 d 2'), so `0.1 * 10' comes out as an inexact approximation to 1 on some machines (though they generally arrange to hide it from you by rounding off one digit as we did above). Because Calc works in decimal instead of binary, you can be sure that numbers that look exact *are* exact as long as you stay in decimal display mode. It's not hard to show that any number that can be represented exactly in binary, octal, or hexadecimal is also exact in decimal, so the kinds of problems we saw in this exercise are likely to be severe only when you use a relatively unusual radix like 3. File: calc.info, Node: Modes Answer 2, Next: Modes Answer 3, Prev: Modes Answer 1, Up: Answers to Exercises Modes Tutorial Exercise 2 ------------------------- If the radix is 15 or higher, we can't use the letter `e' to mark the exponent because `e' is interpreted as a digit. When Calc needs to display scientific notation in a high radix, it writes `16#F.E8F*16.^15'. You can enter a number like this as an algebraic entry. Also, pressing `e' without any digits before it normally types `1e', but in a high radix it types `16.^' and puts you in algebraic entry: `16#f.e8f RET e 15 RET *' is another way to enter this number. The reason Calc puts a decimal point in the `16.^' is to prevent huge integers from being generated if the exponent is large (consider `16#1.23*16^1000', where we compute `16^1000' as a giant exact integer and then throw away most of the digits when we multiply it by the floating-point `16#1.23'). While this wouldn't normally matter for display purposes, it could give you a nasty surprise if you copied that number into a file and later moved it back into Calc. File: calc.info, Node: Modes Answer 3, Next: Modes Answer 4, Prev: Modes Answer 2, Up: Answers to Exercises Modes Tutorial Exercise 3 ------------------------- The answer he got was `0.5000000000006399'. The problem is not that the square operation is inexact, but that the sine of 45 that was already on the stack was accurate to only 12 places. Arbitrary-precision calculations still only give answers as good as their inputs. The real problem is that there is no 12-digit number which, when squared, comes out to 0.5 exactly. The `f [' and `f ]' commands decrease or increase a number by one unit in the last place (according to the current precision). They are useful for determining facts like this. 1: 0.707106781187 1: 0.500000000001 . . 45 S 2 ^ 1: 0.707106781187 1: 0.707106781186 1: 0.499999999999 . . . U DEL f [ 2 ^ A high-precision calculation must be carried out in high precision all the way. The only number in the original problem which was known exactly was the quantity 45 degrees, so the precision must be raised before anything is done after the number 45 has been entered in order for the higher precision to be meaningful. File: calc.info, Node: Modes Answer 4, Next: Arithmetic Answer 1, Prev: Modes Answer 3, Up: Answers to Exercises Modes Tutorial Exercise 4 ------------------------- Many calculations involve real-world quantities, like the width and height of a piece of wood or the volume of a jar. Such quantities can't be measured exactly anyway, and if the data that is input to a calculation is inexact, doing exact arithmetic on it is a waste of time. Fractions become unwieldy after too many calculations have been done with them. For example, the sum of the reciprocals of the integers from 1 to 10 is 7381:2520. The sum from 1 to 30 is 9304682830147:2329089562800. After a point it will take a long time to add even one more term to this sum, but a floating-point calculation of the sum will not have this problem. Also, rational numbers cannot express the results of all calculations. There is no fractional form for the square root of two, so if you type `2 Q', Calc has no choice but to give you a floating-point answer. File: calc.info, Node: Arithmetic Answer 1, Next: Arithmetic Answer 2, Prev: Modes Answer 4, Up: Answers to Exercises Arithmetic Tutorial Exercise 1 ------------------------------ Dividing two integers that are larger than the current precision may give a floating-point result that is inaccurate even when rounded down to an integer. Consider `123456789 / 2' when the current precision is 6 digits. The true answer is `61728394.5', but with a precision of 6 this will be rounded to `12345700. / 2. = 61728500.'. The result, when converted to an integer, will be off by 106. Here are two solutions: Raise the precision enough that the floating-point round-off error is strictly to the right of the decimal point. Or, convert to fraction mode so that `123456789 / 2' produces the exact fraction `123456789:2', which can be rounded down by the `F' command without ever switching to floating-point format. File: calc.info, Node: Arithmetic Answer 2, Next: Vector Answer 1, Prev: Arithmetic Answer 1, Up: Answers to Exercises Arithmetic Tutorial Exercise 2 ------------------------------ `27 RET 9 B' could give the exact result `3:2', but it does a floating-point calculation instead and produces `1.5'. Calc will find an exact result for a logarithm if the result is an integer or the reciprocal of an integer. But there is no efficient way to search the space of all possible rational numbers for an exact answer, so Calc doesn't try. File: calc.info, Node: Vector Answer 1, Next: Vector Answer 2, Prev: Arithmetic Answer 2, Up: Answers to Exercises Vector Tutorial Exercise 1 -------------------------- Duplicate the vector, compute its length, then divide the vector by its length: `RET A /'. 1: [1, 2, 3] 2: [1, 2, 3] 1: [0.27, 0.53, 0.80] 1: 1. . 1: 3.74165738677 . . . r 1 RET A / A The final `A' command shows that the normalized vector does indeed have unit length. File: calc.info, Node: Vector Answer 2, Next: Matrix Answer 1, Prev: Vector Answer 1, Up: Answers to Exercises Vector Tutorial Exercise 2 -------------------------- The average position is equal to the sum of the products of the positions times their corresponding probabilities. This is the definition of the dot product operation. So all you need to do is to put the two vectors on the stack and press `*'. File: calc.info, Node: Matrix Answer 1, Next: Matrix Answer 2, Prev: Vector Answer 2, Up: Answers to Exercises Matrix Tutorial Exercise 1 -------------------------- The trick is to multiply by a vector of ones. Use `r 4 [1 1 1] *' to get the row sum. Similarly, use `[1 1] r 4 *' to get the column sum. File: calc.info, Node: Matrix Answer 2, Next: Matrix Answer 3, Prev: Matrix Answer 1, Up: Answers to Exercises Matrix Tutorial Exercise 2 -------------------------- x + a y = 6 x + b y = 10 Just enter the righthand side vector, then divide by the lefthand side matrix as usual. 1: [6, 10] 2: [6, 10] 1: [6 - 4 a / (b - a), 4 / (b - a) ] . 1: [ [ 1, a ] . [ 1, b ] ] . ' [6 10] RET ' [1 a; 1 b] RET / This can be made more readable using `d B' to enable "big" display mode: 4 a 4 1: [6 - -----, -----] b - a b - a Type `d N' to return to "normal" display mode afterwards. File: calc.info, Node: Matrix Answer 3, Next: List Answer 1, Prev: Matrix Answer 2, Up: Answers to Exercises Matrix Tutorial Exercise 3 -------------------------- To solve `trn(A) * A * X = trn(A) * B', first we compute `A2 = trn(A) * A' and `B2 = trn(A) * B'; now, we have a system `A2 * X = B2' which we can solve using Calc's `/' command. a + 2b + 3c = 6 4a + 5b + 6c = 2 7a + 6b = 3 2a + 4b + 6c = 11 The first step is to enter the coefficient matrix. We'll store it in quick variable number 7 for later reference. Next, we compute the `B2' vector. 1: [ [ 1, 2, 3 ] 2: [ [ 1, 4, 7, 2 ] 1: [57, 84, 96] [ 4, 5, 6 ] [ 2, 5, 6, 4 ] . [ 7, 6, 0 ] [ 3, 6, 0, 6 ] ] [ 2, 4, 6 ] ] 1: [6, 2, 3, 11] . . ' [1 2 3; 4 5 6; 7 6 0; 2 4 6] RET s 7 v t [6 2 3 11] * Now we compute the matrix `A2' and divide. 2: [57, 84, 96] 1: [-11.64, 14.08, -3.64] 1: [ [ 70, 72, 39 ] . [ 72, 81, 60 ] [ 39, 60, 81 ] ] . r 7 v t r 7 * / (The actual computed answer will be slightly inexact due to round-off error.) Notice that the answers are similar to those for the 3x3 system solved in the text. That's because the fourth equation that was added to the system is almost identical to the first one multiplied by two. (If it were identical, we would have gotten the exact same answer since the 4x3 system would be equivalent to the original 3x3 system.) Since the first and fourth equations aren't quite equivalent, they can't both be satisfied at once. Let's plug our answers back into the original system of equations to see how well they match. 2: [-11.64, 14.08, -3.64] 1: [5.6, 2., 3., 11.2] 1: [ [ 1, 2, 3 ] . [ 4, 5, 6 ] [ 7, 6, 0 ] [ 2, 4, 6 ] ] . r 7 TAB * This is reasonably close to our original `B' vector, `[6, 2, 3, 11]'. File: calc.info, Node: List Answer 1, Next: List Answer 2, Prev: Matrix Answer 3, Up: Answers to Exercises List Tutorial Exercise 1 ------------------------ We can use `v x' to build a vector of integers. This needs to be adjusted to get the range of integers we desire. Mapping `-' across the vector will accomplish this, although it turns out the plain `-' key will work just as well. 2: 2 2: 2 1: [1, 2, 3, 4, 5, 6, 7, 8, 9] 1: [-4, -3, -2, -1, 0, 1, 2, 3, 4] . . 2 v x 9 RET 5 V M - or 5 - Now we use `V M ^' to map the exponentiation operator across the vector. 1: [0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16] . V M ^ File: calc.info, Node: List Answer 2, Next: List Answer 3, Prev: List Answer 1, Up: Answers to Exercises List Tutorial Exercise 2 ------------------------ Given `x' and `y' vectors in quick variables 1 and 2 as before, the first job is to form the matrix that describes the problem. m*x + b*1 = y Thus we want a 19x2 matrix with our `x' vector as one column and ones as the other column. So, first we build the column of ones, then we combine the two columns to form our `A' matrix. 2: [1.34, 1.41, 1.49, ... ] 1: [ [ 1.34, 1 ] 1: [1, 1, 1, ...] [ 1.41, 1 ] . [ 1.49, 1 ] ... r 1 1 v b 19 RET M-2 v p v t s 3 Now we compute `trn(A) * y' and `trn(A) * A' and divide. 1: [33.36554, 13.613] 2: [33.36554, 13.613] . 1: [ [ 98.0003, 41.63 ] [ 41.63, 19 ] ] . v t r 2 * r 3 v t r 3 * (Hey, those numbers look familiar!) 1: [0.52141679, -0.425978] . / Since we were solving equations of the form `m*x + b*1 = y', these numbers should be `m' and `b', respectively. Sure enough, they agree exactly with the result computed using `V M' and `V R'! The moral of this story: `V M' and `V R' will probably solve your problem, but there is often an easier way using the higher-level arithmetic functions! In fact, there is a built-in `a F' command that does least-squares fits. *Note Curve Fitting::. File: calc.info, Node: List Answer 3, Next: List Answer 4, Prev: List Answer 2, Up: Answers to Exercises List Tutorial Exercise 3 ------------------------ Move to one end of the list and press `C-@' (or `C-SPC' or whatever) to set the mark, then move to the other end of the list and type `M-# g'. 1: [2.3, 6, 22, 15.1, 7, 15, 14, 7.5, 2.5] . To make things interesting, let's assume we don't know at a glance how many numbers are in this list. Then we could type: 2: [2.3, 6, 22, ... ] 2: [2.3, 6, 22, ... ] 1: [2.3, 6, 22, ... ] 1: 126356422.5 . . RET V R * 2: 126356422.5 2: 126356422.5 1: 7.94652913734 1: [2.3, 6, 22, ... ] 1: 9 . . . TAB v l I ^ (The `I ^' command computes the Nth root of a number. You could also type `& ^' to take the reciprocal of 9 and then raise the number to that power.) File: calc.info, Node: List Answer 4, Next: List Answer 5, Prev: List Answer 3, Up: Answers to Exercises List Tutorial Exercise 4 ------------------------ A number `j' is a divisor of `n' if `n % j = 0'. The first step is to get a vector that identifies the divisors. 2: 30 2: [0, 0, 0, 2, ...] 1: [1, 1, 1, 0, ...] 1: [1, 2, 3, 4, ...] 1: 0 . . . 30 RET v x 30 RET s 1 V M % 0 V M a = s 2 This vector has 1's marking divisors of 30 and 0's marking non-divisors. The zeroth divisor function is just the total number of divisors. The first divisor function is the sum of the divisors. 1: 8 3: 8 2: 8 2: 8 2: [1, 2, 3, 4, ...] 1: [1, 2, 3, 0, ...] 1: 72 1: [1, 1, 1, 0, ...] . . . V R + r 1 r 2 V M * V R + Once again, the last two steps just compute a dot product for which a simple `*' would have worked equally well. File: calc.info, Node: List Answer 5, Next: List Answer 6, Prev: List Answer 4, Up: Answers to Exercises List Tutorial Exercise 5 ------------------------ The obvious first step is to obtain the list of factors with `k f'. This list will always be in sorted order, so if there are duplicates they will be right next to each other. A suitable method is to compare the list with a copy of itself shifted over by one. 1: [3, 7, 7, 7, 19] 2: [3, 7, 7, 7, 19] 2: [3, 7, 7, 7, 19, 0] . 1: [3, 7, 7, 7, 19, 0] 1: [0, 3, 7, 7, 7, 19] . . 19551 k f RET 0 | TAB 0 TAB | 1: [0, 0, 1, 1, 0, 0] 1: 2 1: 0 . . . V M a = V R + 0 a = Note that we have to arrange for both vectors to have the same length so that the mapping operation works; no prime factor will ever be zero, so adding zeros on the left and right is safe. From then on the job is pretty straightforward. Incidentally, Calc provides the "Moebius mu" function which is zero if and only if its argument is square-free. It would be a much more convenient way to do the above test in practice. File: calc.info, Node: List Answer 6, Next: List Answer 7, Prev: List Answer 5, Up: Answers to Exercises List Tutorial Exercise 6 ------------------------ First use `v x 6 RET' to get a list of integers, then `V M v x' to get a list of lists of integers!