home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-10-31 | 55.5 KB | 1,750 lines |
- Newsgroups: comp.sources.misc
- From: daveg@synaptics.com (David Gillespie)
- Subject: v24i084: gnucalc - GNU Emacs Calculator, v2.00, Part36/56
- Message-ID: <1991Oct31.214616.2631@sparky.imd.sterling.com>
- X-Md4-Signature: 6bec56d735e7b86dd2319265b709ef85
- Date: Thu, 31 Oct 1991 21:46:16 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: daveg@synaptics.com (David Gillespie)
- Posting-number: Volume 24, Issue 84
- Archive-name: gnucalc/part36
- Environment: Emacs
- Supersedes: gmcalc: Volume 13, Issue 27-45
-
- ---- Cut Here and unpack ----
- #!/bin/sh
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file calc.texinfo continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 36; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping calc.texinfo'
- else
- echo 'x - continuing file calc.texinfo'
- sed 's/^X//' << 'SHAR_EOF' >> 'calc.texinfo' &&
- by four, except that they don't occur in years divisible by 100, except
- that they @emph{do} in years divisible by 400. We could work out the
- answer by carefully counting the years divisible by four and the
- exceptions, but there is a much simpler way that works even if we
- don't know the leap year rule.
- X
- Let's assume the present year is 1991. Years have 365 days, except
- that leap years (whenever they occur) have 366 days. So let's count
- the number of days between now and then, and compare that to the
- number of years times 365. The number of extra days we find must be
- equal to the number of leap years there were.
- X
- @group
- @smallexample
- 1: <Mon Jan 1, 10001> 2: <Mon Jan 1, 10001> 1: 2925593
- X . 1: <Tue Jan 1, 1991> .
- X .
- X
- X ' <jan 1 10001> RET ' <jan 1 1991> RET -
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 3: 2925593 2: 2925593 2: 2925593 1: 1943
- 2: 10001 1: 8010 1: 2923650 .
- 1: 1991 . .
- X .
- X
- X 10001 RET 1991 - 365 * -
- @end smallexample
- @end group
- X
- @c [fix-ref Date Forms]
- @noindent
- There will be 1943 leap years before the year 10001. (Assuming,
- of course, that the algorithm for computing leap years remains
- unchanged for that long. @xref{Date Forms}, for some interesting
- background information in that regard.)
- X
- @node Types Answer 7, Types Answer 8, Types Answer 6, Answers to Exercises
- @subsection Types Tutorial Exercise 7
- X
- @noindent
- The relative errors must be converted to absolute errors so that
- @samp{+/-} notation may be used.
- X
- @group
- @smallexample
- 1: 1. 2: 1.
- X . 1: 0.2
- X .
- X
- X 20 RET .05 * 4 RET .05 *
- @end smallexample
- @end group
- X
- Now we simply chug through the formula.
- X
- @group
- @smallexample
- 1: 19.7392088022 1: 394.78 +/- 19.739 1: 6316.5 +/- 706.21
- X . . .
- X
- X 2 P 2 ^ * 20 p 1 * 4 p .2 RET 2 ^ *
- @end smallexample
- @end group
- X
- It turns out the @kbd{v u} command will unpack an error form as
- well as a vector. This saves us some retyping of numbers.
- X
- @group
- @smallexample
- 3: 6316.5 +/- 706.21 2: 6316.5+/- 706.21
- 2: 6316.5 1: 0.1118
- 1: 706.21 .
- X .
- X
- X RET v u TAB /
- @end smallexample
- @end group
- X
- @noindent
- Thus the volume is 6316 cubic centimeters, within about 11 percent.
- X
- @node Types Answer 8, Types Answer 9, Types Answer 7, Answers to Exercises
- @subsection Types Tutorial Exercise 8
- X
- @noindent
- The first answer is pretty simple: @samp{1 / (0 .. 10) = (0.1 .. inf)}.
- Since a number in the interval @samp{(0 .. 10)} can get arbitrarily
- close to zero, its reciprocal can get arbitrarily large, so the answer
- is an interval that effectively means, ``any number greater than 0.1''
- but with no upper bound.
- X
- The second answer, similarly, is @samp{1 / (-10 .. 0) = (-inf .. -0.1)}.
- X
- Calc normally treats division by zero as an error, so that the formula
- @w{@samp{1 / 0}} is left unsimplified. Our third problem,
- @w{@samp{1 / [0 .. 10]}}, also (potentially) divides by zero because zero
- is now a member of the interval. So Calc leaves this one unevaluated, too.
- X
- If you turn on ``infinite'' mode by pressing @kbd{m i}, you will
- instead get the answer @samp{[0.1 .. inf]}, which includes infinity
- as a possible value.
- X
- The fourth calculation, @samp{1 / (-10 .. 10)}, has the same problem.
- Zero is buried inside the interval, but it's still a possible value.
- It's not hard to see that the actual result of @samp{1 / (-10 .. 10)}
- will be either greater than @i{0.1}, or less than @i{-0.1}. Thus
- the interval goes from minus infinity to plus infinity, with a ``hole''
- in it from @i{-0.1} to @i{0.1}. Calc doesn't have any way to
- represent this, so it just reports @samp{[-inf .. inf]} as the answer.
- It may be disappointing to hear ``the answer lies somewhere between
- minus infinity and plus infinity, inclusive,'' but that's the best
- that interval arithmetic can do in this case.
- X
- @node Types Answer 9, Types Answer 10, Types Answer 8, Answers to Exercises
- @subsection Types Tutorial Exercise 9
- X
- @group
- @smallexample
- 1: [-3 .. 3] 2: [-3 .. 3] 2: [0 .. 9]
- X . 1: [0 .. 9] 1: [-9 .. 9]
- X . .
- X
- X [ 3 n .. 3 ] RET 2 ^ TAB RET *
- @end smallexample
- @end group
- X
- @noindent
- In the first case the result says, ``if a number is between @i{-3} and
- 3, its square is between 0 and 9.'' The second case says, ``the product
- of two numbers each between @i{-3} and 3 is between @i{-9} and 9.''
- X
- An interval form is not a number; it is a symbol that can stand for
- many different numbers. Two identical-looking interval forms can stand
- for different numbers.
- X
- The same issue arises when you try to square an error form.
- X
- @node Types Answer 10, Types Answer 11, Types Answer 9, Answers to Exercises
- @subsection Types Tutorial Exercise 10
- X
- @noindent
- Testing the first number, we might arbitrarily choose 17 for @cite{x}.
- X
- @group
- @smallexample
- 1: 17 mod 811749613 2: 17 mod 811749613 1: 533694123 mod 811749613
- X . 811749612 .
- X .
- X
- X 17 M 811749613 RET 811749612 ^
- @end smallexample
- @end group
- X
- @noindent
- Since 533694123 is (considerably) different from 1, the number 811749613
- must not be prime.
- X
- It's awkward to type the number in twice as we did above. There are
- various ways to avoid this, and algebraic entry is one. In fact, using
- a vector mapping operation we can perform several tests at once. Let's
- use this method to test the second number.
- X
- @group
- @smallexample
- 2: [17, 42, 100000] 1: [1 mod 15485863, 1 mod ... ]
- 1: 15485863 .
- X .
- X
- X [17 42 100000] 15485863 RET V M ' ($$ mod $)^($-1) RET
- @end smallexample
- @end group
- X
- @noindent
- The result is three ones (modulo @cite{n}), so it's very probable that
- 15485863 is prime. (In fact, this number is the millionth prime.)
- X
- Note that the functions @samp{($$^($-1)) mod $} or @samp{$$^($-1) % $}
- would have been hopelessly inefficient, since they would have calculated
- the power using full integer arithmetic.
- X
- Calc has a @kbd{k p} command that does primality testing. For small
- numbers it does an exact test; for large numbers it uses a variant
- of the Fermat test we used here. You can use @kbd{k p} repeatedly
- to prove that a large integer is prime with any desired probability.
- X
- @node Types Answer 11, Types Answer 12, Types Answer 10, Answers to Exercises
- @subsection Types Tutorial Exercise 11
- X
- @noindent
- There are several ways to insert a calculated number into an HMS form.
- One way to convert a number of seconds to an HMS form is simply to
- multiply the number by an HMS form representing one second:
- X
- @group
- @smallexample
- 1: 31415926.5359 2: 31415926.5359 1: 8726@@ 38' 46.5359"
- X . 1: 0@@ 0' 1" .
- X .
- X
- X P 1e7 * 0@@ 0' 1" *
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 2: 8726@@ 38' 46.5359" 1: 6@@ 6' 2.5359" mod 24@@ 0' 0"
- 1: 15@@ 27' 16" mod 24@@ 0' 0" .
- X .
- X
- X x time RET +
- @end smallexample
- @end group
- X
- @noindent
- It will be just after six in the morning.
- X
- The algebraic @code{hms} function can also be used to build an
- HMS form:
- X
- @group
- @smallexample
- 1: hms(0, 0, 10000000. pi) 1: 8726@@ 38' 46.5359"
- X . .
- X
- X ' hms(0, 0, 1e7 pi) RET =
- @end smallexample
- @end group
- X
- @noindent
- The @kbd{=} key is necessary to evaluate the symbol @samp{pi} to
- the actual number 3.14159...
- X
- @node Types Answer 12, Types Answer 13, Types Answer 11, Answers to Exercises
- @subsection Types Tutorial Exercise 12
- X
- @noindent
- As we recall, there are 17 songs of about 2 minutes and 47 seconds
- each.
- X
- @group
- @smallexample
- 2: 0@@ 2' 47" 1: [0@@ 3' 7" .. 0@@ 3' 47"]
- 1: [0@@ 0' 20" .. 0@@ 1' 0"] .
- X .
- X
- X [ 0@@ 20" .. 0@@ 1' ] +
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: [0@@ 52' 59." .. 1@@ 4' 19."]
- X .
- X
- X 17 *
- @end smallexample
- @end group
- X
- @noindent
- No matter how long it is, the album will fit nicely on one CD.
- X
- @node Types Answer 13, Types Answer 14, Types Answer 12, Answers to Exercises
- @subsection Types Tutorial Exercise 13
- X
- @noindent
- Type @kbd{' 1 yr RET u c s RET}. The answer is 31557600 seconds.
- X
- @node Types Answer 14, Types Answer 15, Types Answer 13, Answers to Exercises
- @subsection Types Tutorial Exercise 14
- X
- @noindent
- How long will it take for a signal to get from one end of the computer
- to the other?
- X
- @group
- @smallexample
- 1: m / c 1: 3.3356 ns
- X . .
- X
- X ' 1 m / c RET u c ns RET
- @end smallexample
- @end group
- X
- @noindent
- (Recall, @samp{c} is a ``unit'' corresponding to the speed of light.)
- X
- @group
- @smallexample
- 1: 3.3356 ns 1: 0.81356 ns / ns 1: 0.81356
- 2: 4.1 ns . .
- X .
- X
- X ' 4.1 ns RET / u s
- @end smallexample
- @end group
- X
- @noindent
- Thus a signal could take up to 81 percent of a clock cycle just to
- go from one place to another inside the computer, assuming the signal
- could actually attain the full speed of light. Pretty tight!
- X
- @node Types Answer 15, Algebra Answer 1, Types Answer 14, Answers to Exercises
- @subsection Types Tutorial Exercise 15
- X
- @noindent
- The speed limit is 55 miles per hour on most highways. We want to
- find the ratio of Sam's speed to the US speed limit.
- X
- @group
- @smallexample
- 1: 55 mph 2: 55 mph 3: 11 hr mph / yd
- X . 1: 5 yd / hr .
- X .
- X
- X ' 55 mph RET ' 5 yd/hr RET /
- @end smallexample
- @end group
- X
- The @kbd{u s} command doesn't figure out how to simplify this,
- but @w{@kbd{u b}} (convert to base units) does. Now we take the
- logarithm base two to find the final answer, assuming that each
- successive pill doubles his speed.
- X
- @group
- @smallexample
- 1: 19360. 2: 19360. 1: 14.24
- X . 1: 2 .
- X .
- X
- X u b 2 B
- @end smallexample
- @end group
- X
- @noindent
- Thus Sam can take up to 14 pills without a worry.
- X
- @node Algebra Answer 1, Algebra Answer 2, Types Answer 15, Answers to Exercises
- @subsection Algebra Tutorial Exercise 1
- X
- @noindent
- @c [fix-ref Declarations]
- The result @samp{sqrt(x)^2} is simplified back to @cite{x} by the
- Calculator, but @samp{sqrt(x^2)} is not. (Consider what happens
- if @w{@cite{x = -4}}.) If @cite{x} is real, this formula could be
- simplified to @samp{abs(x)}, but for general complex arguments even
- that is not safe. (@xref{Declarations}, for a way to tell Calc
- that @cite{x} is known to be real.)
- X
- @node Algebra Answer 2, Algebra Answer 3, Algebra Answer 1, Answers to Exercises
- @subsection Algebra Tutorial Exercise 2
- X
- @noindent
- It is easiest to use @kbd{a P x RET} to get a list of solutions.
- X
- @group
- @smallexample
- 1: 17 x^2 - 6 x^4 + 3 = 0 2: 17 x^2 - 6 x^4 + 3 = 0
- 2: 17 x^2 - 6 x^4 + 3 = 0 1: [(0, 0.408), (0, -0.408), 1.732, -1.732]
- X . .
- X
- X RET a P x RET
- @end smallexample
- @end group
- X
- @noindent
- Now we can substitute these into the original formula.
- X
- @group
- @smallexample
- 4: 17 x^2 - 6 x^4 + 3 = 0
- 3: [(0., 0.408), (0., -0.408), 1.732, -1.732]
- 2: [(0., 0.408), (0., -0.408), 1.732, -1.732]
- 1: 17 x^2 - 6 x^4 + 3
- X .
- X
- X M-2 RET TAB v u DEL
- @end smallexample
- @end group
- X
- @noindent
- The @kbd{v u} command unpacks @samp{a = 0} to @samp{a} and 0; we then
- delete the 0.
- X
- @group
- @smallexample
- 3: 17 x^2 - 6 x^4 + 3 = 0
- 2: [(0., 0.408), (0., -0.408), 1.732, -1.732]
- 1: [1e-11, 1e-11, -1e-10, -1e-10]
- X .
- X
- X V M $ RET
- @end smallexample
- @end group
- X
- @noindent
- These numbers are reasonable approximations to zero, considering
- the precision to which we computed the solutions.
- X
- @node Algebra Answer 3, Algebra Answer 4, Algebra Answer 2, Answers to Exercises
- @subsection Algebra Tutorial Exercise 3
- X
- @group
- @smallexample
- 1: x sin(pi x) 1: (sin(pi x) - pi x cos(pi x)) / pi^2
- X . .
- X
- X ' x sin(pi x) RET m r a i x RET
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: [y, 1]
- 2: (sin(pi x) - pi x cos(pi x)) / pi^2
- X .
- X
- X ' [y,1] RET TAB
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: [(sin(pi y) - pi y cos(pi y)) / pi^2, (sin(pi) - pi cos(pi)) / pi^2]
- X .
- X
- X V M $ RET
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: (sin(pi y) - pi y cos(pi y)) / pi^2 + (pi cos(pi) + sin(pi)) / pi^2
- X .
- X
- X V R -
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: (sin(3.14159 y) - 3.14159 y cos(3.14159 y)) / 9.8696 - 0.3183
- X .
- X
- X =
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: [0., -0.95493, 0.63662, -1.5915, 1.2732]
- X .
- X
- X v x 5 RET TAB V M $ RET
- @end smallexample
- @end group
- X
- @node Algebra Answer 4, Rewrites Answer 1, Algebra Answer 3, Answers to Exercises
- @subsection Algebra Tutorial Exercise 4
- X
- @noindent
- The hard part is that @kbd{V R +} is no longer sufficient to add up all
- the contributions from the slices, since the slices have varying
- coefficients. So first we must come up with a vector of these
- coefficients. Here's one way:
- X
- @group
- @smallexample
- 2: -1 2: 3 1: [4, 2, ..., 4]
- 1: [1, 2, ..., 9] 1: [-1, 1, ..., -1] .
- X . .
- X
- X 1 n v x 9 RET V M ^ 3 TAB -
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: [4, 2, ..., 4, 1] 1: [1, 4, 2, ..., 4, 1]
- X . .
- X
- X 1 | 1 TAB |
- @end smallexample
- @end group
- X
- @noindent
- Now we compute the function values. Note that for this method we need
- eleven values, including both endpoints of the desired interval.
- X
- @group
- @smallexample
- 2: [1, 4, 2, ..., 4, 1]
- 1: [1, 1.1, 1.2, ... , 1.8, 1.9, 2.]
- X .
- X
- X 11 RET 1 RET .1 RET C-u v x
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 2: [1, 4, 2, ..., 4, 1]
- 1: [0., 0.084941, 0.16993, ... ]
- X .
- X
- X ' sin(x) ln(x) RET m r p 5 RET V M $ RET
- @end smallexample
- @end group
- X
- @noindent
- Once again this calls for @kbd{V M * V R +}; a simple @kbd{*} does the
- same thing.
- X
- @group
- @smallexample
- 1: 11.22 1: 1.122 1: 0.374
- X . . .
- X
- X * .1 * 3 /
- @end smallexample
- @end group
- X
- @noindent
- Wow! That's even better than the result from the Taylor series method.
- X
- @node Rewrites Answer 1, Rewrites Answer 2, Algebra Answer 4, Answers to Exercises
- @subsection Rewrites Tutorial Exercise 1
- X
- @noindent
- We'll use Big mode to make the formulas more readable.
- X
- @group
- @smallexample
- X ___
- X 2 + V 2
- 1: (2 + sqrt(2)) / (1 + sqrt(2)) 1: --------
- X . ___
- X 1 + V 2
- X
- X .
- X
- X ' (2+sqrt(2)) / (1+sqrt(2)) RET d B
- @end smallexample
- @end group
- X
- @noindent
- Multiplying by the conjugate helps because @cite{(a+b) (a-b) = a^2 - b^2}.
- X
- @group
- @smallexample
- X ___ ___
- 1: (2 + V 2 ) (V 2 - 1)
- X .
- X
- X a r a/(b+c) := a*(b-c) / (b^2-c^2) RET
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- X ___ ___
- 1: 2 + V 2 - 2 1: V 2
- X . .
- X
- X a r a*(b+c) := a*b + a*c a s
- @end smallexample
- @end group
- X
- @noindent
- (We could have used @kbd{a x} instead of a rewrite rule for the
- second step.)
- X
- The multiply-by-conjugate rule turns out to be useful in many
- different circumstances, such as when the denominator involves
- sines and cosines or the imaginary constant @code{i}.
- X
- @node Rewrites Answer 2, Rewrites Answer 3, Rewrites Answer 1, Answers to Exercises
- @subsection Rewrites Tutorial Exercise 2
- X
- @noindent
- Here is the rule set:
- X
- @group
- @smallexample
- [ fib(n) := fib(n, 1, 1) :: integer(n) :: n >= 1,
- X fib(1, x, y) := x,
- X fib(n, x, y) := fib(n-1, y, x+y) ]
- @end smallexample
- @end group
- X
- @noindent
- The first rule turns a one-argument @code{fib} that people like to write
- into a three-argument @code{fib} that makes computation easier. The
- second rule converts back from three-argument form once the computation
- is done. The third rule does the computation itself. It basically
- says that if @cite{x} and @cite{y} are two consecutive Fibonacci numbers,
- then @cite{y} and @cite{x+y} are the next (overlapping) pair of Fibonacci
- numbers.
- X
- Notice that because the number @cite{n} was ``validated'' by the
- conditions on the first rule, there is no need to put conditions on
- the other rules because the rule set would never get that far unless
- the input were valid. That further speeds computation, since no
- extra conditions need to be checked at every step.
- X
- Actually, a user with a nasty sense of humor could enter a bad
- three-argument @code{fib} call directly, say, @samp{fib(0, 1, 1)},
- which would get the rules into an infinite loop. One thing that would
- help keep this from happening by accident would be to use something like
- @samp{ZzFib} instead of @code{fib} as the name of the three-argument
- function.
- X
- @node Rewrites Answer 3, Rewrites Answer 4, Rewrites Answer 2, Answers to Exercises
- @subsection Rewrites Tutorial Exercise 3
- X
- @noindent
- He got an infinite loop. First, Calc did as expected and rewrote
- @w{@samp{2 + 3 x}} to @samp{f(2, 3, x)}. Then it looked for ways to
- apply the rule again, and found that @samp{f(2, 3, x)} looks like
- @samp{a + b x} with @w{@samp{a = 0}} and @samp{b = 1}, so it rewrote to
- @samp{f(0, 1, f(2, 3, x))}. It then wrapped another @samp{f(0, 1, ...)}
- around that, and so on, ad infinitum. Joe should have used @kbd{M-1 a r}
- to make sure the rule applied only once.
- X
- (Actually, even the first step didn't work as he expected. What Calc
- really gives for @kbd{M-1 a r} in this situation is @samp{f(3 x, 1, 2)},
- treating 2 as the ``variable,'' and @samp{3 x} as a constant being added
- to it. While this may seem odd, it's just as valid a solution as the
- ``obvious'' one. One way to fix this would be to add the condition
- @samp{:: variable(x)} to the rule, to make sure the thing that matches
- @samp{x} is indeed a variable, or to change @samp{x} to @samp{quote(x)}
- on the lefthand side, so that the rule matches the actual variable
- @samp{x} rather than letting @samp{x} stand for something else.)
- X
- @node Rewrites Answer 4, Rewrites Answer 5, Rewrites Answer 3, Answers to Exercises
- @subsection Rewrites Tutorial Exercise 4
- X
- @noindent
- @tindex seq
- Here is a suitable set of rules to solve the first part of the problem:
- X
- @group
- @smallexample
- [ seq(n, c) := seq(n/2, c+1) :: n%2 = 0,
- X seq(n, c) := seq(3n+1, c+1) :: n%2 = 1 :: n > 1 ]
- @end smallexample
- @end group
- X
- Given the initial formula @samp{seq(6, 0)}, application of these
- rules produces the following sequence of formulas:
- X
- @example
- seq( 3, 1)
- seq(10, 2)
- seq( 5, 3)
- seq(16, 4)
- seq( 8, 5)
- seq( 4, 6)
- seq( 2, 7)
- seq( 1, 8)
- @end example
- X
- @noindent
- whereupon neither of the rules match, and rewriting stops.
- X
- We can pretty this up a bit with a couple more rules:
- X
- @group
- @smallexample
- [ seq(n) := seq(n, 0),
- X seq(1, c) := c,
- X ... ]
- @end smallexample
- @end group
- X
- @noindent
- Now, given @samp{seq(6)} as the starting configuration, we get 8
- as the result.
- X
- The change to return a vector is quite simple:
- X
- @group
- @smallexample
- [ seq(n) := seq(n, []) :: integer(n) :: n > 0,
- X seq(1, v) := v | 1,
- X seq(n, v) := seq(n/2, v | n) :: n%2 = 0,
- X seq(n, v) := seq(3n+1, v | n) :: n%2 = 1 ]
- @end smallexample
- @end group
- X
- @noindent
- Given @samp{seq(6)}, the result is @samp{[6, 3, 10, 5, 16, 8, 4, 2, 1]}.
- X
- Notice that the @cite{n > 1} guard is no longer necessary on the last
- rule since the @cite{n = 1} case is now detected by another rule.
- But a guard has been added to the initial rule to make sure the
- initial value is suitable before the computation begins.
- X
- While still a good idea, this guard is not as vitally important as it
- was for the @code{fib} function, since calling, say, @samp{seq(x, [])}
- will not get into an infinite loop. Calc will not be able to prove
- the symbol @samp{x} is either even or odd, so none of the rules will
- apply and the rewrites will stop right away.
- X
- @node Rewrites Answer 5, Rewrites Answer 6, Rewrites Answer 4, Answers to Exercises
- @subsection Rewrites Tutorial Exercise 5
- X
- @noindent
- @tindex nterms
- If @cite{x} is the sum @cite{a + b}, then `@t{nterms(}@i{x}@t{)}' must
- be `@t{nterms(}@i{a}@t{)}' plus `@t{nterms(}@i{b}@t{)}'. If @cite{x}
- is not a sum, then `@t{nterms(}@i{x}@t{)}' = 1.
- X
- @group
- @smallexample
- [ nterms(a + b) := nterms(a) + nterms(b),
- X nterms(x) := 1 ]
- @end smallexample
- @end group
- X
- @noindent
- Here we have taken advantage of the fact that earlier rules always
- match before later rules; @samp{nterms(x)} will only be tried if we
- already know that @samp{x} is not a sum.
- X
- @node Rewrites Answer 6, Programming Answer 1, Rewrites Answer 5, Answers to Exercises
- @subsection Rewrites Tutorial Exercise 6
- X
- @noindent
- Here is a rule set that will do the job:
- X
- @group
- @smallexample
- [ a*(b + c) := a*b + a*c,
- X opt(a) O(x^n) + opt(b) O(x^m) := O(x^n) :: n <= m
- X :: constant(a) :: constant(b),
- X opt(a) O(x^n) + opt(b) x^m := O(x^n) :: n <= m
- X :: constant(a) :: constant(b),
- X a O(x^n) := O(x^n) :: constant(a),
- X x^opt(m) O(x^n) := O(x^(n+m)),
- X O(x^n) O(x^m) := O(x^(n+m)) ]
- @end smallexample
- @end group
- X
- If we really want the @kbd{+} and @kbd{*} keys to operate naturally
- on power series, we should put these rules in @code{EvalRules}. For
- testing purposes, it is better to put them in a different variable,
- say, @code{O}, first.
- X
- The first rule just expands products of sums so that the rest of the
- rules can assume they have an expanded-out polynomial to work with.
- Note that this rule does not mention @samp{O} at all, so it will
- apply to any product-of-sum it encounters---this rule may surprise
- you if you put it into @code{EvalRules}!
- X
- In the second rule, the sum of two O's is changed to the smaller O.
- The optional constant coefficients are there mostly so that
- @samp{O(x^2) - O(x^3)} and @samp{O(x^3) - O(x^2)} are handled
- as well as @samp{O(x^2) + O(x^3)}.
- X
- The third rule absorbs higher powers of @samp{x} into O's.
- X
- The fourth rule says that a constant times a negligible quantity
- is still negligible. (This rule will also match @samp{O(x^3) / 4},
- with @samp{a = 1/4}.)
- X
- The fifth rule rewrites, for example, @samp{x^2 O(x^3)} to @samp{O(x^5)}.
- (It is easy to see that if one of these forms is negligible, the other
- is, too.) Notice the @samp{x^opt(m)} to pick up terms like
- @w{@samp{x O(x^3)}}. Optional powers will match @samp{x} as @samp{x^1}
- but not 1 as @samp{x^0}. This turns out to be exactly what we want here.
- X
- The sixth rule is the corresponding rule for products of two O's.
- X
- Another way to solve this problem would be to create a new ``data type''
- that represents truncated power series. We might represent these as
- function calls @samp{series(@var{coefs}, @var{x})} where @var{coefs} is
- a vector of coefficients for @cite{x^0}, @cite{x^1}, @cite{x^2}, and so
- on. Rules would exist for sums and products of such @code{series}
- objects, and as an optional convenience could also know how to combine a
- @code{series} object with a normal polynomial. (With this, and with a
- rule that rewrites @samp{O(x^n)} to the equivalent @code{series} form,
- you could still enter power series in exactly the same notation as
- before.) Operations on such objects would probably be more efficient,
- although the objects would be a bit harder to read.
- X
- @c [fix-ref Compositions]
- Some other symbolic math programs provide a power series data type
- similar to this. Mathematica, for example, has an object that looks
- like @samp{PowerSeries[@var{x}, @var{x0}, @var{coefs}, @var{nmin},
- @var{nmax}, @var{den}]}, where @var{x0} is the point about which the
- power series is taken (we've been assuming this was always zero),
- and @var{nmin}, @var{nmax}, and @var{den} allow pseudo-power-series
- with fractional or negative powers. Also, the @code{PowerSeries}
- objects have a special display format that makes them look like
- @samp{2 x^2 + O(x^4)} when they are printed out. (@xref{Compositions},
- for a way to do this in Calc, although for something as involved as
- this it would probably be better to write the formatting routine
- in Lisp.)
- X
- @node Programming Answer 1, Programming Answer 2, Rewrites Answer 6, Answers to Exercises
- @subsection Programming Tutorial Exercise 1
- X
- Just enter the formula @samp{ninteg(cos(pi t^2/2), t, 0, x)}, type
- @kbd{Z F}, and answer the questions. Since this formula contains two
- variables, the default argument list will be @samp{(t x)}. We want to
- change this to @samp{(x)} since @cite{t} is really a dummy variable
- to be used within @code{ninteg}.
- X
- The exact keystrokes are @kbd{Z F c fresC RET RET C-b C-b DEL DEL RET y}.
- (The @kbd{C-b C-b DEL DEL} are what fix the argument list.)
- X
- While this definition works, you'll find the @code{erf}-based definition
- described afterwards to be much more efficient; @code{erf} is also defined
- by an integral (involving @samp{exp(-t^2)}), but Calc has good algorithms
- for computing it that don't rely on brute-force numerical integration.
- The @kbd{Z F} formula would be @samp{re((i+1) erf(sqrt(pi) (1-i) x / 2) / 2)},
- where @code{re} is the function that extracts the real part of a complex
- number. Actually, you'd want to type @kbd{=} on this formula first to
- evaluate the @code{pi} and @code{i} variables in it; otherwise your
- @kbd{z c} function will return a formula that needs to have @kbd{=}
- typed on it each time.
- X
- @node Programming Answer 2, Programming Answer 3, Programming Answer 1, Answers to Exercises
- @subsection Programming Tutorial Exercise 2
- X
- @noindent
- One way is to move the number to the top of the stack, operate on
- it, then move it back: @kbd{C-x ( M-TAB n M-TAB M-TAB C-x )}.
- X
- Another way is to negate the top three stack entries, then negate
- again the top two stack entries: @kbd{C-x ( M-3 n M-2 n C-x )}.
- X
- Finally, it turns out that a negative prefix argument causes a
- command like @kbd{n} to operate on just the specified stack entry,
- which is just what we want: @kbd{C-x ( M-- 3 n C-x )}.
- X
- Just for kicks, let's also do it algebraically:
- @w{@kbd{C-x ( ' -$$$, $$, $ RET C-x )}}.
- X
- @node Programming Answer 3, Programming Answer 4, Programming Answer 2, Answers to Exercises
- @subsection Programming Tutorial Exercise 3
- X
- @noindent
- Each of these functions can be computed using the stack, or using
- algebraic entry, whichever way you prefer:
- X
- @noindent
- Computing @c{$\displaystyle{\sin x \over x}$}
- @cite{sin(x) / x}:
- X
- Using the stack: @kbd{C-x ( RET S TAB / C-x )}.
- X
- Using algebraic entry: @kbd{C-x ( ' sin($)/$ RET C-x )}.
- X
- @noindent
- Computing the logarithm:
- X
- Using the stack: @kbd{C-x ( TAB B C-x )}
- X
- Using algebraic entry: @kbd{C-x ( ' log($,$$) RET C-x )}.
- X
- @noindent
- Computing the vector of integers:
- X
- Using the stack: @kbd{C-x ( 1 RET 1 C-u v x C-x )}. (Recall that
- @kbd{C-u v x} takes the vector size, starting value, and increment
- from the stack.)
- X
- Alternatively: @kbd{C-x ( ~ v x C-x )}. (The @kbd{~} key pops a
- number from the stack and uses it as the prefix argument for the
- next command.)
- X
- Using algebraic entry: @kbd{C-x ( ' index($) RET C-x )}.
- X
- @node Programming Answer 4, Programming Answer 5, Programming Answer 3, Answers to Exercises
- @subsection Programming Tutorial Exercise 4
- X
- @noindent
- Here's one way: @kbd{C-x ( RET V R + TAB v l / C-x )}.
- X
- @node Programming Answer 5, Programming Answer 6, Programming Answer 4, Answers to Exercises
- @subsection Programming Tutorial Exercise 5
- X
- @group
- @smallexample
- 2: 1 1: 1.61803398502 2: 1.61803398502
- 1: 20 . 1: 1.61803398875
- X . .
- X
- X 1 RET 20 Z < & 1 + Z > I H P
- @end smallexample
- @end group
- X
- @noindent
- This answer is quite accurate.
- X
- @node Programming Answer 6, Programming Answer 7, Programming Answer 5, Answers to Exercises
- @subsection Programming Tutorial Exercise 6
- X
- @noindent
- Here is the matrix:
- X
- @example
- [ [ 0, 1 ] * [a, b] = [b, a + b]
- X [ 1, 1 ] ]
- @end example
- X
- @noindent
- Thus @samp{[0, 1; 1, 1]^n * [1, 1]} computes Fibonacci numbers @cite{n+1}
- and @cite{n+2}. Here's one program that does the job:
- X
- @example
- C-x ( ' [0, 1; 1, 1] ^ ($-1) * [1, 1] RET v u DEL C-x )
- @end example
- X
- @noindent
- This program is quite efficient because Calc knows how to raise a
- matrix (or other value) to the power @cite{n} in only @c{$\log_2 n$}
- @cite{log(n,2)}
- steps. For example, this program can compute the 1000th Fibonacci
- number (a 209-digit integer!) in about 10 steps; even though the
- @kbd{Z < ... Z >} solution had much simpler steps, it would have
- required so many steps that it would not have been practical.
- X
- @node Programming Answer 7, Programming Answer 8, Programming Answer 6, Answers to Exercises
- @subsection Programming Tutorial Exercise 7
- X
- @noindent
- The trick here is to compute the harmonic numbers differently, so that
- the loop counter itself accumulates the sum of reciprocals. We use
- a separate variable to hold the integer counter.
- X
- @group
- @smallexample
- 1: 1 2: 1 1: .
- X . 1: 4
- X .
- X
- X 1 t 1 1 RET 4 Z ( t 2 r 1 1 + s 1 & Z )
- @end smallexample
- @end group
- X
- @noindent
- The body of the loop goes as follows: First save the harmonic sum
- so far in variable 2. Then delete it from the stack; the for loop
- itself will take care of remembering it for us. Next, recall the
- count from variable 1, add one to it, and feed its reciprocal to
- the for loop to use as the step value. The for loop will increase
- the ``loop counter'' by that amount and keep going until the
- loop counter exceeds 4.
- X
- @group
- @smallexample
- 2: 31 3: 31
- 1: 3.99498713092 2: 3.99498713092
- X . 1: 4.02724519544
- X .
- X
- X r 1 r 2 RET 31 & +
- @end smallexample
- @end group
- X
- Thus we find that the 30th harmonic number is 3.99, and the 31st
- harmonic number is 4.02.
- X
- @node Programming Answer 8, Programming Answer 9, Programming Answer 7, Answers to Exercises
- @subsection Programming Tutorial Exercise 8
- X
- @noindent
- The first step is to compute the derivative @cite{f'(x)} and thus
- the formula @c{$\displaystyle{x - {f(x) \over f'(x)}}$}
- @cite{x - f(x)/f'(x)}.
- X
- (Because this definition is long, it will be repeated in concise form
- below. You can use @w{@kbd{M-# m}} to load it from there. While you are
- entering a @kbd{Z ` Z '} body in a macro, Calc simply collects
- keystrokes without executing them. In the following diagrams we'll
- pretend Calc actually executed the keystrokes as you typed them,
- just for purposes of illustration.)
- X
- @group
- @smallexample
- 2: sin(cos(x)) - 0.5 3: 4.5
- 1: 4.5 2: sin(cos(x)) - 0.5
- X . 1: -(sin(x) cos(cos(x)))
- X .
- X
- ' sin(cos(x))-0.5 RET 4.5 m r C-x ( Z ` TAB RET a d x RET
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 2: 4.5
- 1: x + (sin(cos(x)) - 0.5) / sin(x) cos(cos(x))
- X .
- X
- X / ' x RET TAB - t 1
- @end smallexample
- @end group
- X
- Now, we enter the loop. We'll use a repeat loop with a 20-repetition
- limit just in case the method fails to converge for some reason.
- (Normally, the @w{@kbd{Z /}} command will stop the loop before all 20
- repetitions are done.)
- X
- @group
- @smallexample
- 1: 4.5 3: 4.5 2: 4.5
- X . 2: x + (sin(cos(x)) ... 1: 5.24196456928
- X 1: 4.5 .
- X .
- X
- X 20 Z < RET r 1 TAB s l x RET
- @end smallexample
- @end group
- X
- This is the new guess for @cite{x}. Now we compare it with the
- old one to see if we've converged.
- X
- @group
- @smallexample
- 3: 5.24196 2: 5.24196 1: 5.24196 1: 5.26345856348
- 2: 5.24196 1: 0 . .
- 1: 4.5 .
- X .
- X
- X RET M-TAB a = Z / Z > Z ' C-x )
- @end smallexample
- @end group
- X
- The loop converges in just a few steps to this value. To check
- the result, we can simply substitute it back into the equation.
- X
- @group
- @smallexample
- 2: 5.26345856348
- 1: 0.499999999997
- X .
- X
- X RET ' sin(cos($)) RET
- @end smallexample
- @end group
- X
- Let's test the new definition again:
- X
- @group
- @smallexample
- 2: x^2 - 9 1: 3.
- 1: 1 .
- X .
- X
- X ' x^2-9 RET 1 X
- @end smallexample
- @end group
- X
- Once again, here's the full Newton's Method definition:
- X
- @group
- @example
- C-x ( Z ` TAB RET a d x RET / ' x RET TAB - t 1
- X 20 Z < RET r 1 TAB s l x RET
- X RET M-TAB a = Z /
- X Z >
- X Z '
- C-x )
- @end example
- @end group
- X
- @c [fix-ref Nesting and Fixed Points]
- It turns out that Calc has a built-in command for applying a formula
- repeatedly until it converges to a number. @xref{Nesting and Fixed Points},
- to see how to use it.
- X
- @c [fix-ref Root Finding]
- Also, of course, @kbd{a R} is a built-in command that uses Newton's
- method (among others) to look for numerical solutions to any equation.
- @xref{Root Finding}.
- X
- @node Programming Answer 9, Programming Answer 10, Programming Answer 8, Answers to Exercises
- @subsection Programming Tutorial Exercise 9
- X
- @noindent
- The first step is to adjust @cite{z} to be greater than 5. A simple
- ``for'' loop will do the job here. If @cite{z} is less than 5, we
- reduce the problem using @c{$\psi(z) = \psi(z+1) - 1/z$}
- @cite{psi(z) = psi(z+1) - 1/z}. We go
- on to compute @c{$\psi(z+1)$}
- @cite{psi(z+1)}, and remember to add back a factor of
- @cite{-1/z} when we're done. This step is repeated until @cite{z > 5}.
- X
- (Because this definition is long, it will be repeated in concise form
- below. You can use @w{@kbd{M-# m}} to load it from there. While you are
- entering a @kbd{Z ` Z '} body in a macro, Calc simply collects
- keystrokes without executing them. In the following diagrams we'll
- pretend Calc actually executed the keystrokes as you typed them,
- just for purposes of illustration.)
- X
- @group
- @smallexample
- 1: 1. 1: 1.
- X . .
- X
- X 1.0 RET C-x ( Z ` s 1 0 t 2
- @end smallexample
- @end group
- X
- Here, variable 1 holds @cite{z} and variable 2 holds the adjustment
- factor. If @cite{z < 5}, we use a loop to increase it.
- X
- (By the way, we started with @samp{1.0} instead of the integer 1 because
- otherwise the calculation below will try to do exact fractional arithmetic,
- and will never converge because fractions compare equal only if they
- are exactly equal, not just the same to within the current precision.)
- X
- @group
- @smallexample
- 3: 1. 2: 1. 1: 6.
- 2: 1. 1: 1 .
- 1: 5 .
- X .
- X
- X RET 5 a < Z [ 5 Z ( & s + 2 1 s + 1 1 Z ) r 1 Z ]
- @end smallexample
- @end group
- X
- Now we compute the initial part of the sum: @c{$\ln z - {1 \over 2z}$}
- @cite{ln(z) - 1/2z}
- minus the adjustment factor.
- X
- @group
- @smallexample
- 2: 1.79175946923 2: 1.7084261359 1: -0.57490719743
- 1: 0.0833333333333 1: 2.28333333333 .
- X . .
- X
- X L r 1 2 * & - r 2 -
- @end smallexample
- @end group
- X
- Now we evaluate the series. We'll use another ``for'' loop counting
- up the value of @cite{2 n}. (Calc does have a summation command,
- @kbd{a +}, but we'll use loops just to get more practice with them.)
- X
- @group
- @smallexample
- 3: -0.5749 3: -0.5749 4: -0.5749 2: -0.5749
- 2: 2 2: 1:6 3: 1:6 1: 2.3148e-3
- 1: 40 1: 2 2: 2 .
- X . . 1: 36.
- X .
- X
- X 2 RET 40 Z ( RET k b TAB RET r 1 TAB ^ * /
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 3: -0.5749 3: -0.5772 2: -0.5772 1: -0.577215664892
- 2: -0.5749 2: -0.5772 1: 0 .
- 1: 2.3148e-3 1: -0.5749 .
- X . .
- X
- X TAB RET M-TAB - RET M-TAB a = Z / 2 Z ) Z ' C-x )
- @end smallexample
- @end group
- X
- This is the value of @c{$-\gamma$}
- @cite{- gamma}, with a slight bit of roundoff error.
- To get a full 12 digits, let's use a higher precision:
- X
- @group
- @smallexample
- 2: -0.577215664892 2: -0.577215664892
- 1: 1. 1: -0.577215664901532
- X
- X 1. RET p 16 RET X
- @end smallexample
- @end group
- X
- Here's the complete sequence of keystrokes:
- X
- @group
- @example
- C-x ( Z ` s 1 0 t 2
- X RET 5 a < Z [ 5 Z ( & s + 2 1 s + 1 1 Z ) r 1 Z ]
- X L r 1 2 * & - r 2 -
- X 2 RET 40 Z ( RET k b TAB RET r 1 TAB ^ * /
- X TAB RET M-TAB - RET M-TAB a = Z /
- X 2 Z )
- X Z '
- C-x )
- @end example
- @end group
- X
- @node Programming Answer 10, Programming Answer 11, Programming Answer 9, Answers to Exercises
- @subsection Programming Tutorial Exercise 10
- X
- @noindent
- Taking the derivative of a term of the form @cite{x^n} will produce
- a term like @c{$n x^{n-1}$}
- @cite{n x^(n-1)}. Taking the derivative of a constant
- produces zero. From this it is easy to see that the @cite{n}th
- derivative of a polynomial, evaluated at @cite{x = 0}, will equal the
- coefficient on the @cite{x^n} term times @cite{n!}.
- X
- (Because this definition is long, it will be repeated in concise form
- below. You can use @w{@kbd{M-# m}} to load it from there. While you are
- entering a @kbd{Z ` Z '} body in a macro, Calc simply collects
- keystrokes without executing them. In the following diagrams we'll
- pretend Calc actually executed the keystrokes as you typed them,
- just for purposes of illustration.)
- X
- @group
- @smallexample
- 2: 5 x^4 + (x + 1)^2 3: 5 x^4 + (x + 1)^2
- 1: 6 2: 0
- X . 1: 6
- X .
- X
- X ' 5 x^4 + (x+1)^2 RET 6 C-x ( Z ` [ ] t 1 0 TAB
- @end smallexample
- @end group
- X
- @noindent
- Variable 1 will accumulate the vector of coefficients.
- X
- @group
- @smallexample
- 2: 0 3: 0 2: 5 x^4 + ...
- 1: 5 x^4 + ... 2: 5 x^4 + ... 1: 1
- X . 1: 1 .
- X .
- X
- X Z ( TAB RET 0 s l x RET M-TAB ! / s | 1
- @end smallexample
- @end group
- X
- @noindent
- Note that @kbd{s | 1} appends the top-of-stack value to the vector
- in a variable; it is completely analogous to @kbd{s + 1}. We could
- have written instead, @kbd{r 1 TAB | t 1}.
- X
- @group
- @smallexample
- 1: 20 x^3 + 2 x + 2 1: 0 1: [1, 2, 1, 0, 5, 0, 0]
- X . . .
- X
- X a d x RET 1 Z ) DEL r 1 Z ' C-x )
- @end smallexample
- @end group
- X
- To convert back, a simple method is just to map the coefficients
- against a table of powers of @cite{x}.
- X
- @group
- @smallexample
- 2: [1, 2, 1, 0, 5, 0, 0] 2: [1, 2, 1, 0, 5, 0, 0]
- 1: 6 1: [0, 1, 2, 3, 4, 5, 6]
- X . .
- X
- X 6 RET 1 + 0 RET 1 C-u v x
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 2: [1, 2, 1, 0, 5, 0, 0] 2: 1 + 2 x + x^2 + 5 x^4
- 1: [1, x, x^2, x^3, ... ] .
- X .
- X
- X ' x RET TAB V M ^ *
- @end smallexample
- @end group
- X
- Once again, here are the whole polynomial to/from vector programs:
- X
- @group
- @example
- C-x ( Z ` [ ] t 1 0 TAB
- X Z ( TAB RET 0 s l x RET M-TAB ! / s | 1
- X a d x RET
- X 1 Z ) r 1
- X Z '
- C-x )
- X
- C-x ( 1 + 0 RET 1 C-u v x ' x RET TAB V M ^ * C-x )
- @end example
- @end group
- X
- @node Programming Answer 11, Programming Answer 12, Programming Answer 10, Answers to Exercises
- @subsection Programming Tutorial Exercise 11
- X
- @noindent
- First we define a dummy program to go on the @kbd{z s} key. The true
- @w{@kbd{z s}} key is supposed to take two numbers from the stack and
- return one number, so @kbd{DEL} as a dummy definition will make
- sure the stack comes out right.
- X
- @group
- @smallexample
- 2: 4 1: 4 2: 4
- 1: 2 . 1: 2
- X . .
- X
- X 4 RET 2 C-x ( DEL C-x ) Z K s RET 2
- @end smallexample
- @end group
- X
- The last step replaces the 2 that was eaten during the creation
- of the dummy @kbd{z s} command. Now we move on to the real
- definition. The recurrence needs to be rewritten slightly,
- to the form @cite{s(n,m) = s(n-1,m-1) - (n-1) s(n-1,m)}.
- X
- (Because this definition is long, it will be repeated in concise form
- below. You can use @kbd{M-# m} to load it from there.)
- X
- @group
- @smallexample
- 2: 4 4: 4 3: 4 2: 4
- 1: 2 3: 2 2: 2 1: 2
- X . 2: 4 1: 0 .
- X 1: 2 .
- X .
- X
- X C-x ( M-2 RET a = Z [ DEL DEL 1 Z :
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 4: 4 2: 4 2: 3 4: 3 4: 3 3: 3
- 3: 2 1: 2 1: 2 3: 2 3: 2 2: 2
- 2: 2 . . 2: 3 2: 3 1: 3
- 1: 0 1: 2 1: 1 .
- X . . .
- X
- X RET 0 a = Z [ DEL DEL 0 Z : TAB 1 - TAB M-2 RET 1 - z s
- @end smallexample
- @end group
- X
- @noindent
- (Note that the value 3 that our dummy @kbd{z s} produces is not correct;
- it is merely a placeholder that will do just as well for now.)
- X
- @group
- @smallexample
- 3: 3 4: 3 3: 3 2: 3 1: -6
- 2: 3 3: 3 2: 3 1: 9 .
- 1: 2 2: 3 1: 3 .
- X . 1: 2 .
- X .
- X
- X M-TAB M-TAB TAB RET M-TAB z s * -
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: -6 2: 4 1: 11 2: 11
- X . 1: 2 . 1: 11
- X . .
- X
- X Z ] Z ] C-x ) Z K s RET DEL 4 RET 2 z s M-RET k s
- @end smallexample
- @end group
- X
- Even though the result that we got during the definition was highly
- bogus, once the definition is complete the @kbd{z s} command gets
- the right answers.
- X
- Here's the full program once again:
- X
- @group
- @example
- C-x ( M-2 RET a =
- X Z [ DEL DEL 1
- X Z : RET 0 a =
- X Z [ DEL DEL 0
- X Z : TAB 1 - TAB M-2 RET 1 - z s
- X M-TAB M-TAB TAB RET M-TAB z s * -
- X Z ]
- X Z ]
- C-x )
- @end example
- @end group
- X
- You can read this definition using @kbd{M-# m} (@code{read-kbd-macro})
- followed by @kbd{Z K s}, without having to make a dummy definition
- first, because @code{read-kbd-macro} doesn't need to execute the
- definition as it reads it in. For this reason, @code{M-# m} is often
- the easiest way to create recursive programs in Calc.
- X
- @node Programming Answer 12, , Programming Answer 11, Answers to Exercises
- @subsection Programming Tutorial Exercise 12
- X
- @noindent
- This turns out to be a much easier way to solve the problem. Let's
- denote Stirling numbers as calls of the function @samp{s}.
- X
- First, we store the rewrite rules corresponding to the definition of
- Stirling numbers in a convenient variable:
- X
- @smallexample
- s e StirlingRules RET
- [ s(n,n) := 1 :: n >= 0,
- X s(n,0) := 0 :: n > 0,
- X s(n,m) := s(n-1,m-1) - (n-1) s(n-1,m) :: n >= m :: m >= 1 ]
- C-c C-c
- @end smallexample
- X
- Now, it's just a matter of applying the rules:
- X
- @group
- @smallexample
- 2: 4 1: s(4, 2) 1: 11
- 1: 2 . .
- X .
- X
- X 4 RET 2 C-x ( ' s($$,$) RET a r StirlingRules RET C-x )
- @end smallexample
- @end group
- X
- As in the case of the @code{fib} rules, it would be useful to put these
- rules in @code{EvalRules} and to add a @samp{:: remember} condition to
- the last rule.
- X
- @c This ends the table-of-contents kludge from above:
- @tex
- \global\let\chapternofonts=\oldchapternofonts
- @end tex
- X
- @c [reference]
- X
- @node Introduction, Data Types, Tutorial, Top
- @chapter Introduction
- X
- @noindent
- This chapter is the beginning of the Calc reference manual.
- It covers basic concepts such as the stack, algebraic and
- numeric entry, undo, numeric prefix arguments, etc.
- X
- @c [when-split]
- @c (Chapter 2, the Tutorial, has been printed in a separate volume.)
- X
- @menu
- * Basic Commands::
- * Help Commands::
- * Stack Basics::
- * Numeric Entry::
- * Algebraic Entry::
- * Quick Calculator::
- * Keypad Mode::
- * Prefix Arguments::
- * Undo::
- * Error Messages::
- * Multiple Calculators::
- * Troubleshooting Commands::
- @end menu
- X
- @node Basic Commands, Help Commands, Introduction, Introduction
- @section Basic Commands
- X
- @noindent
- @pindex calc
- @pindex calc-mode
- @cindex Starting the Calculator
- @cindex Running the Calculator
- To start the Calculator in its standard interface, type @kbd{M-x calc}.
- By default this creates a pair of small windows, @samp{*Calculator*}
- and @samp{*Calc Trail*}. The former displays the contents of the
- Calculator stack and is manipulated exclusively through Calc commands.
- It is possible (though not usually necessary) to create several Calc
- Mode buffers each of which has an independent stack, undo list, and
- mode settings. There is exactly one Calc Trail buffer; it records a
- list of the results of all calculations that have been done. The
- Calc Trail buffer uses a variant of Calc Mode, so Calculator commands
- still work when the trail buffer's window is selected. It is possible
- to turn the trail window off, but the @samp{*Calc Trail*} buffer still
- exists and is updated silently. @xref{Trail Commands}.@refill
- X
- @kindex M-# M-#
- @kindex M-# #
- @kindex M-# c
- In most installations, the @kbd{M-#} (Meta-Shift-3) keystroke is a more
- convenient way to start the Calculator. If you don't have a Meta key,
- press @key{ESC}, then @kbd{#}. Follow @kbd{M-#} with a letter key
- that says which Calc interface or function you desire. @kbd{M-# c}
- is equivalent to @kbd{M-x calc}. @kbd{M-# M-#} or @kbd{M-# #} is
- also generally equivalent to @kbd{M-x calc}. @xref{Other M-# Commands}.
- X
- @kindex x
- @kindex M-x
- @pindex calc-execute-extended-command
- Most Calc commands use one or two keystrokes. Lower- and upper-case
- letters are distinct. Commands may also be entered in @kbd{M-x} form;
- for some commands this is the only form. As a convenience, the @kbd{x}
- key (@code{calc-execute-extended-command})
- is like @kbd{M-x} except that it enters the initial string @samp{calc-}
- for you. For example, the following key sequences are equivalent:
- @kbd{S}, @kbd{M-x calc-sin @key{RET}}, @kbd{x sin @key{RET}}.@refill
- X
- @cindex Extensions module
- @cindex @file{calc-ext} module
- The Calculator exists in many parts. When you type @kbd{M-x calc}, the
- Emacs ``auto-load'' mechanism will bring in only the first part, which
- contains the basic arithmetic functions. The other parts will be
- auto-loaded the first time you use the more advanced commands like trig
- functions or matrix operations. This is done to improve the response time
- of the Calculator in the common case when all you need to do is a
- little arithmetic. If for some reason the Calculator fails to load an
- extension module automatically, you can force it to load all the
- extensions by using the @kbd{m X} or @kbd{M-# L}
- (@code{calc-load-everything}) command.
- @xref{Mode Settings}.@refill
- X
- If you type @kbd{M-x calc} or @kbd{M-# c} with any numeric prefix argument,
- the Calculator is loaded if necessary, but it is not actually started.
- If the argument is positive, the extensions are also loaded if necessary.
- User-written Lisp code that wishes to make use of Calc's arithmetic
- routines can use @samp{(calc 0)} or @samp{(calc 1)} to auto-load the
- Calculator.@refill
- X
- @kindex M-# b
- @pindex full-calc
- If you type @kbd{M-# b}, then next time you use @kbd{M-# c} you
- will get a Calculator that uses the full height of the Emacs screen.
- When full-screen mode is on, @kbd{M-# c} runs the @code{full-calc}
- command instead of @code{calc}. From the Unix shell you can type
- @samp{emacs -f full-calc} to start a new Emacs specifically for use
- as a calculator. When Calc is started from the Emacs command line
- like this, Calc's normal ``quit'' commands actually quit Emacs itself.
- X
- @kindex M-# o
- @pindex calc-other-window
- The @kbd{M-# o} command is like @kbd{M-# c} except that the Calc
- window is not actually selected. If you are already in the Calc
- window, @kbd{M-# o} switches you out of it. (The regular Emacs
- @kbd{C-x o} command would also work for this, but it has a
- tendency to drop you into the Calc Trail window instead, which
- @kbd{M-# o} takes care not to do.)
- X
- For one quick calculation, you can type @kbd{M-# q} (@code{quick-calc})
- which prompts you for a formula (like @samp{2+3/4}). The result is
- displayed at the bottom of the Emacs screen without ever creating
- any special Calculator windows. @xref{Quick Calculator}.
- X
- Finally, if you are using the X window system you may want to try
- @kbd{M-# k} (@code{calc-keypad}) which runs Calc with a
- ``calculator keypad'' picture as well as a stack display. Click on
- the keys with the mouse to operate the calculator. @xref{Keypad Mode}.
- X
- @kindex q
- @pindex calc-quit
- @cindex Quitting the Calculator
- @cindex Exiting the Calculator
- The @kbd{q} key (@code{calc-quit}) exits Calc Mode and closes the
- Calculator's window(s). It does not delete the Calculator buffers.
- If you type @kbd{M-x calc} again, the Calculator will reappear with the
- contents of the stack intact. Typing @kbd{M-# c} or @kbd{M-# M-#}
- again from inside the Calculator buffer is equivalent to executing
- @code{calc-quit}; you can think of @kbd{M-# M-#} as toggling the
- Calculator on and off.@refill
- X
- @kindex M-# x
- The @kbd{M-# x} key also turns the Calculator off, no matter which
- user interface (standard, Keypad, or Embedded) is current active.
- It also cancels @code{calc-edit} mode if used from there.
- X
- @kindex d SPC
- @kindex d ~
- @pindex calc-refresh
- @cindex Refreshing a garbled display
- @cindex Garbled displays, refreshing
- The @kbd{d SPC} key sequence (@code{calc-refresh}) redraws the contents
- of the Calculator buffer from memory. Use this if the contents of the
- buffer have been damaged somehow. The @kbd{d ~} key is also bound to
- @code{calc-refresh}.
- X
- The @kbd{o} key (@code{calc-realign}) moves the cursor back to its
- ``home'' position at the bottom of the Calculator buffer.
- X
- @kindex <
- @kindex >
- @pindex calc-scroll-left
- @pindex calc-scroll-right
- @cindex Horizontal scrolling
- @cindex Scrolling
- @cindex Wide text, scrolling
- The @kbd{<} and @kbd{>} keys are bound to @code{calc-scroll-left} and
- @code{calc-scroll-right}. These are just like the normal horizontal
- scrolling commands except that they scroll one half-screen at a time by
- default. (Calc formats its output to fit within the bounds of the
- window whenever it can.)@refill
- X
- @kindex @{
- @kindex @}
- @pindex calc-scroll-down
- @pindex calc-scroll-up
- @cindex Vertical scrolling
- The @kbd{@{} and @kbd{@}} keys are bound to @code{calc-scroll-down}
- and @code{calc-scroll-up}. They scroll up or down by one-half the
- height of the Calc window.@refill
- X
- @pindex calc-version
- The @code{calc-version} command displays the current version number
- of Calc and the name of the person who installed it on your system.
- (This information is also present in the @samp{*Calc Trail*} buffer,
- and in the output of the @kbd{h h} command.)
- X
- @node Help Commands, Stack Basics, Basic Commands, Introduction
- @section Help Commands
- X
- @noindent
- @cindex Help commands
- @kindex ?
- @pindex calc-help
- The @kbd{?} key (@code{calc-help}) displays a series of brief help messages.
- Some keys (such as @kbd{b} and @kbd{d}) are prefix keys, like Emacs'
- @key{ESC} and @kbd{C-x} prefixes. You can type
- @kbd{?} after a prefix to see a list of commands beginning with that
- prefix. (If the message includes @samp{[MORE]}, press @kbd{?} again
- to see additional commands for that prefix.)
- X
- @kindex h h
- @pindex calc-full-help
- The @kbd{h h} (@code{calc-full-help}) command displays all the @kbd{?}
- responses at once. When printed, this makes a nice, compact (three pages)
- summary of Calc keystrokes.
- X
- In general, the @kbd{h} key prefix introduces various commands that
- provide help within Calc. Many of the @kbd{h} key functions are
- Calc-specific analogues to the @kbd{C-h} functions for Emacs help.
- X
- @kindex h i
- @kindex M-# i
- @kindex i
- @pindex calc-info
- The @kbd{h i} (@code{calc-info}) command runs the Emacs Info system
- to read this manual on-line. This is basically the same as typing
- @kbd{C-h i} (the regular way to run the Info system), then, if Info
- is not already in the Calc manual, selecting the beginning of the
- manual. The @kbd{M-# i} command is another way to read the Calc
- manual; it is different from @kbd{h i} in that it works any time,
- not just inside Calc. The plain @kbd{i} key is also equivalent to
- @kbd{h i}, though this key is obsolete and may be replaced with a
- different command in a future version of Calc.
- X
- @kindex h t
- @kindex M-# t
- @pindex calc-tutorial
- The @kbd{h t} (@code{calc-tutorial}) command runs the Info system on
- the Tutorial section of the Calc manual. It is like @kbd{h i},
- except that it selects the starting node of the tutorial rather
- than the beginning of the whole manual. (It actually selects the
- node @samp{Interactive Tutorial} which tells a few things about
- using the Info system before going on to the actual tutorial.)
- The @kbd{M-# t} key is equivalent to @kbd{h t} (but it works at
- all times).
- X
- @kindex h s
- @kindex M-# s
- @pindex calc-info-summary
- The @kbd{h s} (@code{calc-info-summary}) command runs the Info system
- on the Summary node of the Calc manual. @xref{Summary}. The @kbd{M-# s}
- key is equivalent to @kbd{h s}.
- X
- @kindex h k
- @pindex calc-describe-key
- The @kbd{h k} (@code{calc-describe-key}) command looks up a key
- sequence in the Calc manual. For example, @kbd{h k H a S} looks
- up the documentation on the @kbd{H a S} (@code{calc-solve-for})
- command. This works by looking up the textual description of
- the keys you press in the @samp{Key Index} of the manual, then
- jumping to the node indicated by the index.
- X
- Most Calc commands do not have traditional Emacs documentation
- strings, since the @kbd{h k} command is both more convenient and
- more instructive. This means the regular Emacs @kbd{C-h k}
- (@code{describe-key}) command will not be useful for Calc keystrokes.
- SHAR_EOF
- true || echo 'restore of calc.texinfo failed'
- fi
- echo 'End of part 36'
- echo 'File calc.texinfo is continued in part 37'
- echo 37 > _shar_seq_.tmp
- exit 0
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-