home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-10-31 | 55.5 KB | 1,755 lines |
- Newsgroups: comp.sources.misc
- From: daveg@synaptics.com (David Gillespie)
- Subject: v24i083: gnucalc - GNU Emacs Calculator, v2.00, Part35/56
- Message-ID: <1991Oct31.214552.2554@sparky.imd.sterling.com>
- X-Md4-Signature: 17d91c5c5faf3e2cf7d24ae52b02bd56
- Date: Thu, 31 Oct 1991 21:45:52 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: daveg@synaptics.com (David Gillespie)
- Posting-number: Volume 24, Issue 83
- Archive-name: gnucalc/part35
- 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" != 35; 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' &&
- * 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:: Solving a quartic equation
- * 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:: 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
- @end menu
- X
- @c The following kludgery prevents the individual answers from
- @c being entered on the table of contents.
- @tex
- \global\let\oldwrite=\write
- \global\def\skipwrite#1#2{\let\write=\oldwrite}
- \global\let\oldchapternofonts=\chapternofonts
- \global\def\chapternofonts{\let\write=\skipwrite\oldchapternofonts}
- @end tex
- X
- @node RPN Answer 1, RPN Answer 2, Answers to Exercises, Answers to Exercises
- @subsection RPN Tutorial Exercise 1
- X
- @noindent
- @kbd{1 @key{RET} 2 @key{RET} 3 @key{RET} 4 + * -}
- X
- The result is @c{$1 - (2 \times (3 + 4)) = -13$}
- @cite{1 - (2 * (3 + 4)) = -13}.
- X
- @node RPN Answer 2, RPN Answer 3, RPN Answer 1, Answers to Exercises
- @subsection RPN Tutorial Exercise 2
- X
- @noindent
- @c{$2\times4 + 7\times9.5 + {5\over4} = 75.75$}
- @cite{2*4 + 7*9.5 + 5/4 = 75.75}
- X
- After computing the intermediate term @c{$2\times4 = 8$}
- @cite{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 @kbd{+ +} to add everything up.
- X
- @group
- @smallexample
- 2: 2 1: 8 3: 8 2: 8
- 1: 4 . 2: 7 1: 66.5
- X . 1: 9.5 .
- X .
- X
- X 2 RET 4 * 7 RET 9.5 *
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 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 .
- X .
- X
- X 5 RET 4 / + +
- @end smallexample
- @end group
- X
- Alternatively, you could add the first two terms before going on
- with the third term.
- X
- @group
- @smallexample
- 2: 8 1: 74.5 3: 74.5 2: 74.5 1: 75.75
- 1: 66.5 . 2: 5 1: 1.25 .
- X . 1: 4 .
- X .
- X
- X ... + 5 RET 4 / +
- @end smallexample
- @end group
- X
- 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.
- X
- @node RPN Answer 3, RPN Answer 4, RPN Answer 2, Answers to Exercises
- @subsection RPN Tutorial Exercise 3
- X
- @noindent
- The @key{TAB} key provides a way to operate on the number in level 2.
- X
- @group
- @smallexample
- 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
- X . . 1: 1 . .
- X .
- X
- X TAB 1 + TAB
- @end smallexample
- @end group
- X
- Similarly, @key{M-TAB} gives you access to the number in level 3.
- X
- @group
- @smallexample
- 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
- X . . . . .
- X
- X M-TAB 1 + M-TAB M-TAB
- @end smallexample
- @end group
- X
- @node RPN Answer 4, Algebraic Answer 1, RPN Answer 3, Answers to Exercises
- @subsection RPN Tutorial Exercise 4
- X
- @noindent
- Either @kbd{( 2 , 3 )} or @kbd{( 2 @key{SPC} 3 )} would have worked,
- but using both the comma and the space at once yields:
- X
- @group
- @smallexample
- 1: ( ... 2: ( ... 1: (2, ... 2: (2, ... 2: (2, ...
- X . 1: 2 . 1: (2, ... 1: (2, 3)
- X . . .
- X
- X ( 2 , SPC 3 )
- @end smallexample
- @end group
- X
- Joe probably tried to type @kbd{@key{TAB} @key{DEL}} to swap the
- extra incomplete object to the top of the stack and delete it.
- But a feature of Calc is that @key{DEL} on an incomplete object
- deletes just one component out of that object, so he had to press
- @key{DEL} twice to finish the job.
- X
- @group
- @smallexample
- 2: (2, ... 2: (2, 3) 2: (2, 3) 1: (2, 3)
- 1: (2, 3) 1: (2, ... 1: ( ... .
- X . . .
- X
- X TAB DEL DEL
- @end smallexample
- @end group
- X
- (As it turns out, deleting the second-to-top stack entry happens often
- enough that Calc provides a special key, @kbd{M-DEL}, to do just that.
- @kbd{M-DEL} is just like @kbd{TAB DEL}, except that it doesn't exhibit
- the ``feature'' that tripped poor Joe.)
- X
- @node Algebraic Answer 1, Algebraic Answer 2, RPN Answer 4, Answers to Exercises
- @subsection Algebraic Entry Tutorial Exercise 1
- X
- @noindent
- Type @kbd{' sqrt($) @key{RET}}.
- X
- If the @kbd{Q} key is broken, you could use @kbd{' $^0.5 @key{RET}}.
- Or, RPN style, @kbd{0.5 ^}.
- X
- (Actually, @samp{$^1:2}, using the fraction one-half as the power, is
- a closer equivalent, since @samp{9^0.5} yields @cite{3.0} whereas
- @samp{sqrt(9)} and @samp{9^1:2} yield the exact integer @cite{3}.)
- X
- @node Algebraic Answer 2, Algebraic Answer 3, Algebraic Answer 1, Answers to Exercises
- @subsection Algebraic Entry Tutorial Exercise 2
- X
- @noindent
- In the formula @samp{2 x (1+y)}, @samp{x} was interpreted as a function
- name with @samp{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 @samp{*} symbol here: @samp{2 x*(1+y)}.
- X
- @node Algebraic Answer 3, Modes Answer 1, Algebraic Answer 2, Answers to Exercises
- @subsection Algebraic Entry Tutorial Exercise 3
- X
- @noindent
- The result from @kbd{1 @key{RET} 0 /} will be the formula @cite{1 / 0}.
- The ``function'' @samp{/} cannot be evaluated when its second argument
- is zero, so it is left in symbolic form. When you now type @kbd{0 *},
- the result will be zero because Calc uses the general rule that ``zero
- times anything is zero.''
- X
- @c [fix-ref Infinities]
- The @kbd{m i} command enables an @dfn{infinite mode} in which @cite{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.'' @xref{Infinities}, for
- further discussion of infinite and indeterminate values.
- X
- @node Modes Answer 1, Modes Answer 2, Algebraic Answer 3, Answers to Exercises
- @subsection Modes Tutorial Exercise 1
- X
- @noindent
- Calc always stores its numbers in decimal, so even though one-third has
- an exact base-3 representation (@samp{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.
- X
- 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 @samp{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 @samp{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.)
- X
- If Joe didn't want to be bothered with all this, he could have typed
- @kbd{M-24 d n} to display with one less digit than the default. (If
- you give @kbd{d n} a negative argument, it uses default-minus-that,
- so @kbd{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,
- @samp{0.022222} in base 3 is like @samp{0.099999} in base 10; rounding
- off one digit will round the number up to @samp{0.1}.) Depending on the
- nature of your work, this hiding of the inexactness may be a benefit or
- a danger. With the @kbd{d n} command, Calc gives you the choice.
- X
- Incidentally, another consequence of all this is that if you type
- @kbd{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 @kbd{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.
- X
- 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: @kbd{0.1 d 2}), so @samp{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 @emph{are} exact as long as you stay
- in decimal display mode.
- X
- 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.
- X
- @node Modes Answer 2, Modes Answer 3, Modes Answer 1, Answers to Exercises
- @subsection Modes Tutorial Exercise 2
- X
- If the radix is 15 or higher, we can't use the letter @samp{e} to mark
- the exponent because @samp{e} is interpreted as a digit. When Calc
- needs to display scientific notation in a high radix, it writes
- @samp{16#F.E8F*16.^15}. You can enter a number like this as an
- algebraic entry. Also, pressing @kbd{e} without any digits before it
- normally types @kbd{1e}, but in a high radix it types @kbd{16.^} and
- puts you in algebraic entry: @kbd{16#f.e8f RET e 15 RET *} is another
- way to enter this number.
- X
- The reason Calc puts a decimal point in the @samp{16.^} is to prevent
- huge integers from being generated if the exponent is large (consider
- @samp{16#1.23*16^1000}, where we compute @samp{16^1000} as a giant
- exact integer and then throw away most of the digits when we multiply
- it by the floating-point @samp{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 yanked it back into Calc.
- X
- @node Modes Answer 3, Modes Answer 4, Modes Answer 2, Answers to Exercises
- @subsection Modes Tutorial Exercise 3
- X
- @noindent
- The answer he got was @cite{0.5000000000006399}.
- X
- 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.
- X
- The real problem is that there is no 12-digit number which, when
- squared, comes out to 0.5 exactly. The @kbd{f [} and @kbd{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.
- X
- @group
- @smallexample
- 1: 0.707106781187 1: 0.500000000001
- X . .
- X
- X 45 S 2 ^
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: 0.707106781187 1: 0.707106781186 1: 0.499999999999
- X . . .
- X
- X U DEL f [ 2 ^
- @end smallexample
- @end group
- X
- 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.
- X
- @node Modes Answer 4, Arithmetic Answer 1, Modes Answer 3, Answers to Exercises
- @subsection Modes Tutorial Exercise 4
- X
- @noindent
- 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.
- X
- 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.
- X
- 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
- @w{@kbd{2 Q}}, Calc has no choice but to give you a floating-point answer.
- X
- @node Arithmetic Answer 1, Arithmetic Answer 2, Modes Answer 4, Answers to Exercises
- @subsection Arithmetic Tutorial Exercise 1
- X
- @noindent
- 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 @cite{123456789 / 2} when the current
- precision is 6 digits. The true answer is @cite{61728394.5}, but
- with a precision of 6 this will be rounded to @c{$12345700.0/2.0 = 61728500.0$}
- @cite{12345700.@: / 2.@: = 61728500.}.
- The result, when converted to an integer, will be off by 106.
- X
- 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 @cite{123456789 / 2}
- produces the exact fraction @cite{123456789:2}, which can be rounded
- down by the @kbd{F} command without ever switching to floating-point
- format.
- X
- @node Arithmetic Answer 2, Vector Answer 1, Arithmetic Answer 1, Answers to Exercises
- @subsection Arithmetic Tutorial Exercise 2
- X
- @noindent
- @kbd{27 @key{RET} 9 B} could give the exact result @cite{3:2}, but it
- does a floating-point calculation instead and produces @cite{1.5}.
- X
- 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.
- X
- @node Vector Answer 1, Vector Answer 2, Arithmetic Answer 2, Answers to Exercises
- @subsection Vector Tutorial Exercise 1
- X
- @noindent
- Duplicate the vector, compute its length, then divide the vector
- by its length: @kbd{@key{RET} A /}.
- X
- @group
- @smallexample
- 1: [1, 2, 3] 2: [1, 2, 3] 1: [0.27, 0.53, 0.80] 1: 1.
- X . 1: 3.74165738677 . .
- X .
- X
- X r 1 RET A / A
- @end smallexample
- @end group
- X
- The final @kbd{A} command shows that the normalized vector does
- indeed have unit length.
- X
- @node Vector Answer 2, Matrix Answer 1, Vector Answer 1, Answers to Exercises
- @subsection Vector Tutorial Exercise 2
- X
- @noindent
- 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 @kbd{*}.
- X
- @node Matrix Answer 1, Matrix Answer 2, Vector Answer 2, Answers to Exercises
- @subsection Matrix Tutorial Exercise 1
- X
- @noindent
- The trick is to multiply by a vector of ones. Use @kbd{r 4 [1 1 1] *} to
- get the row sum. Similarly, use @kbd{[1 1] r 4 *} to get the column sum.
- X
- @node Matrix Answer 2, Matrix Answer 3, Matrix Answer 1, Answers to Exercises
- @subsection Matrix Tutorial Exercise 2
- X
- @ifinfo
- @group
- @example
- X x + a y = 6
- X x + b y = 10
- @end example
- @end group
- @end ifinfo
- @tex
- \turnoffactive
- $$ \eqalign{ x &+ a y = 6 \cr
- X x &+ b y = 10}
- $$
- @end tex
- X
- Just enter the righthand side vector, then divide by the lefthand side
- matrix as usual.
- X
- @group
- @smallexample
- 1: [6, 10] 2: [6, 10] 1: [6 - 4 a / (b - a), 4 / (b - a) ]
- X . 1: [ [ 1, a ] .
- X [ 1, b ] ]
- X .
- X
- ' [6 10] RET ' [1 a; 1 b] RET /
- @end smallexample
- @end group
- X
- This can be made more readable using @kbd{d B} to enable ``big'' display
- mode:
- X
- @group
- @smallexample
- X 4 a 4
- 1: [6 - -----, -----]
- X b - a b - a
- @end smallexample
- @end group
- X
- Type @kbd{d N} to return to ``normal'' display mode afterwards.
- X
- @node Matrix Answer 3, List Answer 1, Matrix Answer 2, Answers to Exercises
- @subsection Matrix Tutorial Exercise 3
- X
- @noindent
- To solve @c{$A^T A \, X = A^T B$}
- @cite{trn(A) * A * X = trn(A) * B}, first we compute
- @c{$A' = A^T A$}
- @cite{A2 = trn(A) * A} and @c{$B' = A^T B$}
- @cite{B2 = trn(A) * B}; now, we have a
- system @c{$A' X = B'$}
- @cite{A2 * X = B2} which we can solve using Calc's @samp{/}
- command.
- X
- @ifinfo
- @group
- @example
- X a + 2b + 3c = 6
- X 4a + 5b + 6c = 2
- X 7a + 6b = 3
- X 2a + 4b + 6c = 11
- @end example
- @end group
- @end ifinfo
- @tex
- \turnoffactive
- $$ \openup1\jot \tabskip=0pt plus1fil
- \halign to\displaywidth{\tabskip=0pt
- X $\hfil#$&$\hfil{}#{}$&
- X $\hfil#$&$\hfil{}#{}$&
- X $\hfil#$&${}#\hfil$\tabskip=0pt plus1fil\cr
- X a&+&2b&+&3c&=6 \cr
- X 4a&+&5b&+&6c&=2 \cr
- X 7a&+&6b& & &=3 \cr
- X 2a&+&4b&+&6c&=11 \cr}
- $$
- @end tex
- X
- 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
- @c{$B'$}
- @cite{B2} vector.
- X
- @group
- @smallexample
- 1: [ [ 1, 2, 3 ] 2: [ [ 1, 4, 7, 2 ] 1: [57, 84, 96]
- X [ 4, 5, 6 ] [ 2, 5, 6, 4 ] .
- X [ 7, 6, 0 ] [ 3, 6, 0, 6 ] ]
- X [ 2, 4, 6 ] ] 1: [6, 2, 3, 11]
- X . .
- X
- ' [1 2 3; 4 5 6; 7 6 0; 2 4 6] RET s 7 v t [6 2 3 11] *
- @end smallexample
- @end group
- X
- @noindent
- Now we compute the matrix @c{$A'$}
- @cite{A2} and divide.
- X
- @group
- @smallexample
- 2: [57, 84, 96] 1: [-11.64, 14.08, -3.64]
- 1: [ [ 70, 72, 39 ] .
- X [ 72, 81, 60 ]
- X [ 39, 60, 81 ] ]
- X .
- X
- X r 7 v t r 7 * /
- @end smallexample
- @end group
- X
- @noindent
- (The actual computed answer will be slightly inexact due to
- round-off error.)
- X
- Notice that the answers are similar to those for the @c{$3\times3$}
- @asis{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 @c{$4\times3$}
- @asis{4x3} system would be equivalent to the original @c{$3\times3$}
- @asis{3x3}
- system.)
- X
- 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.
- X
- @group
- @smallexample
- 2: [-11.64, 14.08, -3.64] 1: [5.6, 2., 3., 11.2]
- 1: [ [ 1, 2, 3 ] .
- X [ 4, 5, 6 ]
- X [ 7, 6, 0 ]
- X [ 2, 4, 6 ] ]
- X .
- X
- X r 7 TAB *
- @end smallexample
- @end group
- X
- @noindent
- This is reasonably close to our original @cite{B} vector,
- @cite{[6, 2, 3, 11]}.
- X
- @node List Answer 1, List Answer 2, Matrix Answer 3, Answers to Exercises
- @subsection List Tutorial Exercise 1
- X
- @noindent
- We can use @kbd{v x} to build a vector of integers. This needs to be
- adjusted to get the range of integers we desire. Mapping @samp{-}
- across the vector will accomplish this, although it turns out the
- plain @samp{-} key will work just as well.
- X
- @group
- @smallexample
- 2: 2 2: 2
- 1: [1, 2, 3, 4, 5, 6, 7, 8, 9] 1: [-4, -3, -2, -1, 0, 1, 2, 3, 4]
- X . .
- X
- X 2 v x 9 RET 5 V M - or 5 -
- @end smallexample
- @end group
- X
- @noindent
- Now we use @kbd{V M ^} to map the exponentiation operator across the
- vector.
- X
- @group
- @smallexample
- 1: [0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16]
- X .
- X
- X V M ^
- @end smallexample
- @end group
- X
- @node List Answer 2, List Answer 3, List Answer 1, Answers to Exercises
- @subsection List Tutorial Exercise 2
- X
- @noindent
- Given @cite{x} and @cite{y} vectors in quick variables 1 and 2 as before,
- the first job is to form the matrix that describes the problem.
- X
- @ifinfo
- @example
- X m*x + b*1 = y
- @end example
- @end ifinfo
- @tex
- \turnoffactive
- $$ m \times x + b \times 1 = y $$
- @end tex
- X
- Thus we want a @c{$19\times2$}
- @asis{19x2} matrix with our @cite{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 @cite{A} matrix.
- X
- @group
- @smallexample
- 2: [1.34, 1.41, 1.49, ... ] 1: [ [ 1.34, 1 ]
- 1: [1, 1, 1, ...] [ 1.41, 1 ]
- X . [ 1.49, 1 ]
- X @dots{}
- X
- X r 1 1 v b 19 RET M-2 v p v t s 3
- @end smallexample
- @end group
- X
- @noindent
- Now we compute @c{$A^T y$}
- @cite{trn(A) * y} and @c{$A^T A$}
- @cite{trn(A) * A} and divide.
- X
- @group
- @smallexample
- 1: [33.36554, 13.613] 2: [33.36554, 13.613]
- X . 1: [ [ 98.0003, 41.63 ]
- X [ 41.63, 19 ] ]
- X .
- X
- X v t r 2 * r 3 v t r 3 *
- @end smallexample
- @end group
- X
- @noindent
- (Hey, those numbers look familiar!)
- X
- @group
- @smallexample
- 1: [0.52141679, -0.425978]
- X .
- X
- X /
- @end smallexample
- @end group
- X
- Since we were solving equations of the form @c{$m \times x + b \times 1 = y$}
- @cite{m*x + b*1 = y}, these
- numbers should be @cite{m} and @cite{b}, respectively. Sure enough, they
- agree exactly with the result computed using @kbd{V M} and @kbd{V R}!
- X
- The moral of this story: @kbd{V M} and @kbd{V R} will probably solve
- your problem, but there is often an easier way using the higher-level
- arithmetic functions!
- X
- @c [fix-ref Curve Fitting]
- In fact, there is a built-in @kbd{a F} command that does least-squares
- fits. @xref{Curve Fitting}.
- X
- @node List Answer 3, List Answer 4, List Answer 2, Answers to Exercises
- @subsection List Tutorial Exercise 3
- X
- @noindent
- Move to one end of the list and press @kbd{C-@@} (or @kbd{C-SPC} or
- whatever) to set the mark, then move to the other end of the list
- and type @w{@kbd{M-# g}}.
- X
- @group
- @smallexample
- 1: [2.3, 6, 22, 15.1, 7, 15, 14, 7.5, 2.5]
- X .
- @end smallexample
- @end group
- X
- 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:
- X
- @group
- @smallexample
- 2: [2.3, 6, 22, ... ] 2: [2.3, 6, 22, ... ]
- 1: [2.3, 6, 22, ... ] 1: 126356422.5
- X . .
- X
- X RET V R *
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 2: 126356422.5 2: 126356422.5 1: 7.94652913734
- 1: [2.3, 6, 22, ... ] 1: 9 .
- X . .
- X
- X TAB v l I ^
- @end smallexample
- @end group
- X
- @noindent
- (The @kbd{I ^} command computes the @var{n}th root of a number.
- You could also type @kbd{& ^} to take the reciprocal of 9 and
- then raise the number to that power.)
- X
- @node List Answer 4, List Answer 5, List Answer 3, Answers to Exercises
- @subsection List Tutorial Exercise 4
- X
- @noindent
- A number @cite{j} is a divisor of @cite{n} if @c{$n \mathbin{\hbox{\code{\%}}} j = 0$}
- @samp{n % j = 0}. The first
- step is to get a vector that identifies the divisors.
- X
- @group
- @smallexample
- 2: 30 2: [0, 0, 0, 2, ...] 1: [1, 1, 1, 0, ...]
- 1: [1, 2, 3, 4, ...] 1: 0 .
- X . .
- X
- X 30 RET v x 30 RET s 1 V M % 0 V M a = s 2
- @end smallexample
- @end group
- X
- @noindent
- This vector has 1's marking divisors of 30 and 0's marking non-divisors.
- X
- The zeroth divisor function is just the total number of divisors.
- The first divisor function is the sum of the divisors.
- X
- @group
- @smallexample
- 1: 8 3: 8 2: 8 2: 8
- X 2: [1, 2, 3, 4, ...] 1: [1, 2, 3, 0, ...] 1: 72
- X 1: [1, 1, 1, 0, ...] . .
- X .
- X
- X V R + r 1 r 2 V M * V R +
- @end smallexample
- @end group
- X
- @noindent
- Once again, the last two steps just compute a dot product for which
- a simple @kbd{*} would have worked equally well.
- X
- @node List Answer 5, List Answer 6, List Answer 4, Answers to Exercises
- @subsection List Tutorial Exercise 5
- X
- @noindent
- The obvious first step is to obtain the list of factors with @kbd{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.
- X
- @group
- @smallexample
- 1: [3, 7, 7, 7, 19] 2: [3, 7, 7, 7, 19] 2: [3, 7, 7, 7, 19, 0]
- X . 1: [3, 7, 7, 7, 19, 0] 1: [0, 3, 7, 7, 7, 19]
- X . .
- X
- X 19551 k f RET 0 | TAB 0 TAB |
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: [0, 0, 1, 1, 0, 0] 1: 2 1: 0
- X . . .
- X
- X V M a = V R + 0 a =
- @end smallexample
- @end group
- X
- @noindent
- 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.
- X
- Incidentally, Calc provides the @c{\dfn{M\"obius} $\mu$}
- @dfn{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.
- X
- @node List Answer 6, List Answer 7, List Answer 5, Answers to Exercises
- @subsection List Tutorial Exercise 6
- X
- @noindent
- First use @kbd{v x 6 RET} to get a list of integers, then @kbd{V M v x}
- to get a list of lists of integers!
- X
- @node List Answer 7, List Answer 8, List Answer 6, Answers to Exercises
- @subsection List Tutorial Exercise 7
- X
- @noindent
- Here's one solution. First, compute the triangular list from the previous
- exercise and type @kbd{1 -} to subtract one from all the elements.
- X
- @group
- @smallexample
- 1: [ [0],
- X [0, 1],
- X [0, 1, 2],
- X @dots{}
- X
- X 1 -
- @end smallexample
- @end group
- X
- The numbers down the lefthand edge of the list we desire are called
- the ``triangular numbers'' (now you know why!). The @cite{n}th
- triangular number is the sum of the integers from 1 to @cite{n}, and
- can be computed directly by the formula @c{$n (n+1) \over 2$}
- @cite{n * (n+1) / 2}.
- X
- @group
- @smallexample
- 2: [ [0], [0, 1], ... ] 2: [ [0], [0, 1], ... ]
- 1: [0, 1, 2, 3, 4, 5] 1: [0, 1, 3, 6, 10, 15]
- X . .
- X
- X v x 6 RET 1 - V M ' $ ($+1)/2 RET
- @end smallexample
- @end group
- X
- @noindent
- Adding this list to the above list of lists produces the desired
- result:
- X
- @group
- @smallexample
- 1: [ [0],
- X [1, 2],
- X [3, 4, 5],
- X [6, 7, 8, 9],
- X [10, 11, 12, 13, 14],
- X [15, 16, 17, 18, 19, 20] ]
- X .
- X
- X V M +
- @end smallexample
- @end group
- X
- If we did not know the formula for triangular numbers, we could have
- computed them using a @kbd{V U +} command. We could also have
- gotten them the hard way by mapping a reduction across the original
- triangular list.
- X
- @group
- @smallexample
- 2: [ [0], [0, 1], ... ] 2: [ [0], [0, 1], ... ]
- 1: [ [0], [0, 1], ... ] 1: [0, 1, 3, 6, 10, 15]
- X . .
- X
- X RET V M V R +
- @end smallexample
- @end group
- X
- @noindent
- (This means ``map a @kbd{V R +} command across the vector,'' and
- since each element of the main vector is itself a small vector,
- @kbd{V R +} computes the sum of its elements.)
- X
- @node List Answer 8, List Answer 9, List Answer 7, Answers to Exercises
- @subsection List Tutorial Exercise 8
- X
- @noindent
- The first step is to build a list of values of @cite{x}.
- X
- @group
- @smallexample
- 1: [1, 2, 3, ..., 21] 1: [0, 1, 2, ..., 20] 1: [0, 0.25, 0.5, ..., 5]
- X . . .
- X
- X v x 21 RET 1 - 4 / s 1
- @end smallexample
- @end group
- X
- Next, we compute the Bessel function values.
- X
- @group
- @smallexample
- 1: [0., 0.124, 0.242, ..., -0.328]
- X .
- X
- X V M ' besJ(1,$) RET
- @end smallexample
- @end group
- X
- @noindent
- (Another way to do this would be @kbd{1 TAB V M f j}.)
- X
- A way to isolate the maximum value is to compute the maximum using
- @kbd{V R X}, then compare all the Bessel values with that maximum.
- X
- @group
- @smallexample
- 2: [0., 0.124, 0.242, ... ] 1: [0, 0, 0, ... ] 2: [0, 0, 0, ... ]
- 1: 0.5801562 . 1: 1
- X . .
- X
- X RET V R X V M a = RET V R + DEL
- @end smallexample
- @end group
- X
- @noindent
- It's a good idea to verify, as in the last step above, that only
- one value is equal to the maximum. (After all, a plot of @c{$\sin x$}
- @cite{sin(x)}
- might have many points all equal to the maximum value, 1.)
- X
- The vector we have now has a single 1 in the position that indicates
- the maximum value of @cite{x}. Now it is a simple matter to convert
- this back into the corresponding value itself.
- X
- @group
- @smallexample
- 2: [0, 0, 0, ... ] 1: [0, 0., 0., ... ] 1: 1.75
- 1: [0, 0.25, 0.5, ... ] . .
- X .
- X
- X r 1 V M * V R +
- @end smallexample
- @end group
- X
- If @kbd{a =} had produced more than one @cite{1} value, this method
- would have given the sum of all maximum @cite{x} values; not very
- useful! In this case we could have used @kbd{v m} (@code{calc-mask-vector})
- instead. This command deletes all elements of a ``data'' vector that
- correspond to zeros in a ``mask'' vector, leaving us with, in this
- example, a vector of maximum @cite{x} values.
- X
- The built-in @kbd{a X} command maximizes a function using more
- efficient methods. Just for illustration, let's use @kbd{a X}
- to maximize @samp{besJ(1,x)} over this same interval.
- X
- @group
- @smallexample
- 2: besJ(1, x) 1: [1.84115, 0.581865]
- 1: [0 .. 5] .
- X .
- X
- ' besJ(1,x), [0..5] RET a X x RET
- @end smallexample
- @end group
- X
- @noindent
- The output from @kbd{a X} is a vector containing the value of @cite{x}
- that maximizes the function, and the function's value at that maximum.
- As you can see, our simple search got quite close to the right answer.
- X
- @node List Answer 9, List Answer 10, List Answer 8, Answers to Exercises
- @subsection List Tutorial Exercise 9
- X
- @noindent
- Step one is to convert our integer into vector notation.
- X
- @group
- @smallexample
- 1: 25129925999 3: 25129925999
- X . 2: 10
- X 1: [11, 10, 9, ..., 1, 0]
- X .
- X
- X 25129925999 RET 10 RET 12 RET v x 12 RET -
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: 25129925999 1: [0, 2, 25, 251, 2512, ... ]
- 2: [100000000000, ... ] .
- X .
- X
- X V M ^ s 1 V M \
- @end smallexample
- @end group
- X
- @noindent
- (Recall, the @kbd{\} command computes an integer quotient.)
- X
- @group
- @smallexample
- 1: [0, 2, 5, 1, 2, 9, 9, 2, 5, 9, 9, 9]
- X .
- X
- X 10 V M % s 2
- @end smallexample
- @end group
- X
- Next we must increment this number. This involves adding one to
- the last digit, plus handling carries. There is a carry out of a
- digit to the left if that digit is a nine and all the digits to
- the right of it are nines.
- X
- @group
- @smallexample
- 1: [0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1] 1: [1, 1, 1, 0, 0, 1, ... ]
- X . .
- X
- X 9 V M a = v v
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: [1, 1, 1, 0, 0, 0, ... ] 1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]
- X . .
- X
- X V U * v v 1 |
- @end smallexample
- @end group
- X
- @noindent
- Accumulating @kbd{*} across a vector of ones and zeros will preserve
- only the initial run of ones. These are the carries into all digits
- except the rightmost digit. Concatenating a one on the right takes
- care of aligning the carries properly, and also adding one to the
- rightmost digit.
- X
- @group
- @smallexample
- 2: [0, 0, 0, 0, ... ] 1: [0, 0, 2, 5, 1, 2, 9, 9, 2, 6, 0, 0, 0]
- 1: [0, 0, 2, 5, ... ] .
- X .
- X
- X 0 r 2 | V M + 10 V M %
- @end smallexample
- @end group
- X
- @noindent
- Here we have concatenated 0 to the @emph{left} of the original number;
- this takes care of shifting the carries by one with respect to the
- digits that generated them.
- X
- Finally, we must convert this list back into an integer.
- X
- @group
- @smallexample
- 3: [0, 0, 2, 5, ... ] 2: [0, 0, 2, 5, ... ]
- 2: 1000000000000 1: [1000000000000, 100000000000, ... ]
- 1: [100000000000, ... ] .
- X .
- X
- X 10 RET 12 ^ r 1 |
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: [0, 0, 20000000000, 5000000000, ... ] 1: 25129926000
- X . .
- X
- X V M * V R +
- @end smallexample
- @end group
- X
- @noindent
- Another way to do this final step would be to reduce the formula
- @w{@cite{10 $$ + $}} across the vector of digits.
- X
- @group
- @smallexample
- 1: [0, 0, 2, 5, ... ] 1: 25129926000
- X . .
- X
- X V R ' 10 $$ + $ RET
- @end smallexample
- @end group
- X
- @node List Answer 10, List Answer 11, List Answer 9, Answers to Exercises
- @subsection List Tutorial Exercise 10
- X
- @noindent
- For the list @cite{[a, b, c, d]}, the result is @cite{((a = b) = c) = d},
- which will compare @cite{a} and @cite{b} to produce a 1 or 0, which is
- then compared with @cite{c} to produce another 1 or 0, which is then
- compared with @cite{d}. This is not at all what Joe wanted.
- X
- Here's a more correct method:
- X
- @group
- @smallexample
- 1: [7, 7, 7, 8, 7] 2: [7, 7, 7, 8, 7]
- X . 1: 7
- X .
- X
- X ' [7,7,7,8,7] RET RET v r 1 RET
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: [1, 1, 1, 0, 1] 1: 0
- X . .
- X
- X V M a = V R *
- @end smallexample
- @end group
- X
- @node List Answer 11, List Answer 12, List Answer 10, Answers to Exercises
- @subsection List Tutorial Exercise 11
- X
- @noindent
- The circle of unit radius consists of those points @cite{(x,y)} for which
- @cite{x^2 + y^2 < 1}. We start by generating a vector of @cite{x^2}
- and a vector of @cite{y^2}.
- X
- We can make this go a bit faster by using the @kbd{v .} and @kbd{t .}
- commands.
- X
- @group
- @smallexample
- 2: [2., 2., ..., 2.] 2: [2., 2., ..., 2.]
- 1: [2., 2., ..., 2.] 1: [1.16, 1.98, ..., 0.81]
- X . .
- X
- X v . t . 2. v b 100 RET RET V M k r
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 2: [2., 2., ..., 2.] 1: [0.026, 0.96, ..., 0.036]
- 1: [0.026, 0.96, ..., 0.036] 2: [0.53, 0.81, ..., 0.094]
- X . .
- X
- X 1 - 2 V M ^ TAB V M k r 1 - 2 V M ^
- @end smallexample
- @end group
- X
- Now we sum the @cite{x^2} and @cite{y^2} values, compare with 1 to
- get a vector of 1/0 truth values, then sum the truth values.
- X
- @group
- @smallexample
- 1: [0.56, 1.78, ..., 0.13] 1: [1, 0, ..., 1] 1: 84
- X . . .
- X
- X + 1 V M a < V R +
- @end smallexample
- @end group
- X
- @noindent
- The ratio @cite{84/100} should approximate the ratio @c{$\pi/4$}
- @cite{pi/4}.
- X
- @group
- @smallexample
- 1: 0.84 1: 3.36 2: 3.36 1: 1.0695
- X . . 1: 3.14159 .
- X
- X 100 / 4 * P /
- @end smallexample
- @end group
- X
- @noindent
- Our estimate, 3.36, is off by about 7%. We could get a better estimate
- by taking more points (say, 1000), but it's clear that this method is
- not very efficient!
- X
- (Naturally, since this example uses random numbers your own answer
- will be slightly different than the one shown here!)
- X
- If you typed @kbd{v .} and @kbd{t .} before, type them again to
- return to full-sized display of vectors.
- X
- @node List Answer 12, List Answer 13, List Answer 11, Answers to Exercises
- @subsection List Tutorial Exercise 12
- X
- @noindent
- This problem can be made a lot easier by taking advantage of some
- symmetries. First of all, after some thought it's clear that the
- @cite{y} axis can be ignored altogether. Just pick a random @cite{x}
- component for one end of the match, pick a random direction @c{$\theta$}
- @cite{theta},
- and see if @cite{x} and @c{$x + \cos \theta$}
- @cite{x + cos(theta)} (which is the @cite{x}
- coordinate of the other endpoint) cross a line. The lines are at
- integer coordinates, so this happens when the two numbers surround
- an integer.
- X
- Since the two endpoints are equivalent, we may as well choose the leftmost
- of the two endpoints as @cite{x}. Then @cite{theta} is an angle pointing
- to the right, in the range -90 to 90 degrees. (We could use radians, but
- it would feel like cheating to refer to @c{$\pi/2$}
- @cite{pi/2} radians while trying
- to estimate @c{$\pi$}
- @cite{pi}!)
- X
- In fact, since the field of lines is infinite we can choose the
- coordinates 0 and 1 for the lines on either side of the leftmost
- endpoint. The rightmost endpoint will be between 0 and 1 if the
- match does not cross a line, or between 1 and 2 if it does. So:
- Pick random @cite{x} and @c{$\theta$}
- @cite{theta}, compute @c{$x + \cos \theta$}
- @cite{x + cos(theta)},
- and count how many of the results are greater than one. Simple!
- X
- We can make this go a bit faster by using the @kbd{v .} and @kbd{t .}
- commands.
- X
- @group
- @smallexample
- 1: [0.52, 0.71, ..., 0.72] 2: [0.52, 0.71, ..., 0.72]
- X . 1: [78.4, 64.5, ..., -42.9]
- X .
- X
- v . t . 1. v b 100 RET V M k r 180. v b 100 RET V M k r 90 -
- @end smallexample
- @end group
- X
- @noindent
- (The next step may be slow, depending on the speed of your computer.)
- X
- @group
- @smallexample
- 2: [0.52, 0.71, ..., 0.72] 1: [0.72, 1.14, ..., 1.45]
- 1: [0.20, 0.43, ..., 0.73] .
- X .
- X
- X m d V M C +
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: [0, 1, ..., 1] 1: 0.64 1: 3.125
- X . . .
- X
- X 1 V M a > V R + 100 / 2 TAB /
- @end smallexample
- @end group
- X
- Let's try the third method, too. We'll use random integers up to
- one million. The @kbd{k r} command with an integer argument picks
- a random integer.
- X
- @group
- @smallexample
- 2: [1000000, 1000000, ..., 1000000] 2: [78489, 527587, ..., 814975]
- 1: [1000000, 1000000, ..., 1000000] 1: [324014, 358783, ..., 955450]
- X . .
- X
- X 1000000 v b 100 RET RET V M k r TAB V M k r
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: [1, 1, ..., 25] 1: [1, 1, ..., 0] 1: 0.56
- X . . .
- X
- X V M k g 1 V M a = V R + 100 /
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 1: 10.714 1: 3.273
- X . .
- X
- X 6 TAB / Q
- @end smallexample
- @end group
- X
- For a proof of this property of the GCD function, see section 4.5.2,
- exercise 10, of Knuth's @emph{Art of Computer Programming}, volume II.
- X
- If you typed @kbd{v .} and @kbd{t .} before, type them again to
- return to full-sized display of vectors.
- X
- @node List Answer 13, List Answer 14, List Answer 12, Answers to Exercises
- @subsection List Tutorial Exercise 13
- X
- @noindent
- First, we put the string on the stack as a vector of ASCII codes.
- X
- @group
- @smallexample
- 1: [84, 101, 115, ..., 51]
- X .
- X
- X "Testing, 1, 2, 3 RET
- @end smallexample
- @end group
- X
- @noindent
- Note that the @kbd{"} key, like @kbd{$}, initiates algebraic entry so
- there was no need to type an apostrophe. Also, Calc didn't mind that
- we omitted the closing @kbd{"}. (The same goes for all closing delimiters
- like @kbd{)} and @kbd{]} at the end of a formula.
- X
- We'll show two different approaches here. In the first, we note that
- if the input vector is @cite{[a, b, c, d]}, then the hash code is
- @cite{3 (3 (3a + b) + c) + d = 27a + 9b + 3c + d}. In other words,
- it's a sum of descending powers of three times the ASCII codes.
- X
- @group
- @smallexample
- 2: [84, 101, 115, ..., 51] 2: [84, 101, 115, ..., 51]
- 1: 16 1: [15, 14, 13, ..., 0]
- X . .
- X
- X RET v l v x 16 RET -
- X
- @end smallexample
- @end group
- @noindent
- @group
- @smallexample
- 2: [84, 101, 115, ..., 51] 1: 1960915098 1: 121
- 1: [14348907, ..., 1] . .
- X .
- X
- X 3 TAB V M ^ * 511 %
- @end smallexample
- @end group
- X
- @noindent
- Once again, @kbd{*} elegantly summarizes most of the computation.
- But there's an even more elegant approach: Reduce the formula
- @kbd{3 $$ + $} across the vector. Recall that this represents a
- function of two arguments that computes its first argument times three
- plus its second argument.
- X
- @group
- @smallexample
- 1: [84, 101, 115, ..., 51] 1: 1960915098
- X . .
- X
- X "Testing, 1, 2, 3 RET V R ' 3$$+$ RET
- @end smallexample
- @end group
- X
- @noindent
- If you did the decimal arithmetic exercise, this will be familiar.
- Basically, we're turning a base-3 vector of digits into an integer,
- except that our ``digits'' are much larger than real digits.
- X
- Instead of typing @kbd{511 %} again to reduce the result, we can be
- cleverer still and notice that rather than computing a huge integer
- and taking the modulo at the end, we can take the modulo at each step
- without affecting the result. While this means there are more
- arithmetic operations, the numbers we operate on remain small so
- the operations are faster.
- X
- @group
- @smallexample
- 1: [84, 101, 115, ..., 51] 1: 121
- X . .
- X
- X "Testing, 1, 2, 3 RET V R ' (3$$+$)%511 RET
- @end smallexample
- @end group
- X
- Why does this work? Think about a two-step computation:
- @w{@cite{3 (3a + b) + c}}. Taking a result modulo 511 basically means
- subtracting off enough 511's to put the result in the desired range.
- So the result when we take the modulo after every step is,
- X
- @ifinfo
- @example
- 3 (3 a + b - 511 m) + c - 511 n
- @end example
- @end ifinfo
- @tex
- \turnoffactive
- $$ 3 (3 a + b - 511 m) + c - 511 n $$
- @end tex
- X
- @noindent
- for some suitable integers @cite{m} and @cite{n}. Expanding out by
- the distributive law yields
- X
- @ifinfo
- @example
- 9 a + 3 b + c - 511*3 m - 511 n
- @end example
- @end ifinfo
- @tex
- \turnoffactive
- $$ 9 a + 3 b + c - 511\times3 m - 511 n $$
- @end tex
- X
- @noindent
- The @cite{m} term in the latter formula is redundant because any
- contribution it makes could just as easily be made by the @cite{n}
- term. So we can take it out to get an equivalent formula with
- @cite{n' = 3m + n},
- X
- @ifinfo
- @example
- 9 a + 3 b + c - 511 n'
- @end example
- @end ifinfo
- @tex
- \turnoffactive
- $$ 9 a + 3 b + c - 511 n' $$
- @end tex
- X
- @noindent
- which is just the formula for taking the modulo only at the end of
- the calculation. Therefore the two methods are essentially the same.
- X
- Later in the tutorial we will encounter @dfn{modulo forms}, which
- basically automate the idea of reducing every intermediate result
- modulo some value @i{M}.
- X
- @node List Answer 14, Types Answer 1, List Answer 13, Answers to Exercises
- @subsection List Tutorial Exercise 14
- X
- We want to use @kbd{H V U} to nest a function which adds a random
- step to an @cite{(x,y)} coordinate. The function is a bit long, but
- otherwise the problem is quite straightforward.
- X
- @group
- @smallexample
- 2: [0, 0] 1: [ [ 0, 0 ]
- 1: 50 [ 0.4288, -0.1695 ]
- X . [ -0.4787, -0.9027 ]
- X ...
- X
- X [0,0] 50 H V U ' <# + [random(2.0)-1, random(2.0)-1]> RET
- @end smallexample
- @end group
- X
- Just as the text recommended, we used @samp{< >} nameless function
- notation to keep the two @code{random} calls from being evaluated
- before nesting even begins.
- X
- We now have a vector of @cite{[x, y]} sub-vectors, which by Calc's
- rules acts like a matrix. We can transpose this matrix and unpack
- to get a pair of vectors, @cite{x} and @cite{y}, suitable for graphing.
- X
- @group
- @smallexample
- 2: [ 0, 0.4288, -0.4787, ... ]
- 1: [ 0, -0.1696, -0.9027, ... ]
- X .
- X
- X v t v u g f
- @end smallexample
- @end group
- X
- Incidentally, because the @cite{x} and @cite{y} are completely
- independent in this case, we could have done two separate commands
- to create our @cite{x} and @cite{y} vectors of numbers directly.
- X
- To make a random walk of unit steps, we note that @code{sincos} of
- a random direction exactly gives us a @cite{[x, y]} step of unit
- length; in fact, the new nesting function is even briefer, though
- we might want to lower the precision a bit for it.
- X
- @group
- @smallexample
- 2: [0, 0] 1: [ [ 0, 0 ]
- 1: 50 [ 0.1318, 0.9912 ]
- X . [ -0.5965, 0.3061 ]
- X ...
- X
- X [0,0] 50 m d p 6 RET H V U ' <# + sincos(random(360.0))> RET
- @end smallexample
- @end group
- X
- Another @kbd{v t v u g f} sequence will graph this new random walk.
- X
- An interesting twist on these random walk functions would be to use
- complex numbers instead of 2-vectors to represent points on the plane.
- In the first example, we'd use something like @samp{random + random*(0,1)},
- and in the second we could use polar complex numbers with random phase
- angles. (This exercise was first suggested in this form by Randal
- Schwartz.)
- X
- @node Types Answer 1, Types Answer 2, List Answer 14, Answers to Exercises
- @subsection Types Tutorial Exercise 1
- X
- @noindent
- If the number is the square root of @c{$\pi$}
- @cite{pi} times a rational number,
- then its square, divided by @c{$\pi$}
- @cite{pi}, should be a rational number.
- X
- @group
- @smallexample
- 1: 1.26508260337 1: 0.509433962268 1: 2486645810:4881193627
- X . . .
- X
- X 2 ^ P / c F
- @end smallexample
- @end group
- X
- @noindent
- Technically speaking this is a rational number, but not one that is
- likely to have arisen in the original problem. More likely, it just
- happens to be the fraction which most closely represents some
- irrational number to within 12 digits.
- X
- But perhaps our result was not quite exact. Let's reduce the
- precision slightly and try again:
- X
- @group
- @smallexample
- 1: 0.509433962268 1: 27:53
- X . .
- X
- X U p 10 RET c F
- @end smallexample
- @end group
- X
- @noindent
- Aha! It's unlikely that an irrational number would equal a fraction
- this simple to within ten digits, so our original number was probably
- @c{$\sqrt{27 \pi / 53}$}
- @cite{sqrt(27 pi / 53)}.
- X
- Notice that we didn't need to re-round the number when we reduced the
- precision. Remember, arithmetic operations always round their inputs
- to the current precision before starting.
- X
- @node Types Answer 2, Types Answer 3, Types Answer 1, Answers to Exercises
- @subsection Types Tutorial Exercise 2
- X
- @noindent
- @samp{inf / inf = nan}. Perhaps @samp{1} is the ``obvious'' answer.
- But if @w{@samp{17 inf = inf}}, then @samp{17 inf / inf = inf / inf = 17}, too.
- X
- @samp{exp(inf) = inf}. It's tempting to say that the exponential
- of infinity must be ``bigger'' than ``regular'' infinity, but as
- far as Calc is concerned all infinities are as just as big.
- In other words, as @cite{x} goes to infinity, @cite{e^x} also goes
- to infinity, but the fact the @cite{e^x} grows much faster than
- @cite{x} is not relevant here.
- X
- @samp{exp(-inf) = 0}. Here we have a finite answer even though
- the input is infinite.
- X
- @samp{sqrt(-inf) = (0, 1) inf}. Remember that @cite{(0, 1)}
- represents the imaginary number @cite{i}. Here's a derivation:
- @samp{sqrt(-inf) = @w{sqrt((-1) * inf)} = sqrt(-1) * sqrt(inf)}.
- The first part is, by definition, @cite{i}; the second is @code{inf}
- because, once again, all infinities are the same size.
- X
- @samp{sqrt(uinf) = uinf}. In fact, we do know something about the
- direction because @code{sqrt} is defined to return a value in the
- right half of the complex plane. But Calc has no notation for this,
- so it settles for the conservative answer @code{uinf}.
- X
- @samp{abs(uinf) = inf}. No matter which direction @cite{x} points,
- @samp{abs(x)} always points along the positive real axis.
- X
- @samp{ln(0) = -inf}. Here we have an infinite answer to a finite
- input. As in the @cite{1 / 0} case, Calc will only use infinities
- here if you have turned on ``infinite'' mode. Otherwise, it will
- treat @samp{ln(0)} as an error.
- X
- @node Types Answer 3, Types Answer 4, Types Answer 2, Answers to Exercises
- @subsection Types Tutorial Exercise 3
- X
- @noindent
- We can make @samp{inf - inf} be any real number we like, say,
- @cite{a}, just by claiming that we added @cite{a} to the first
- infinity but not to the second. This is just as true for complex
- values of @cite{a}, so @code{nan} can stand for a complex number.
- (And, similarly, @code{uinf} can stand for an infinity that points
- in any direction in the complex plane, such as @samp{(0, 1) inf}).
- X
- In fact, we can multiply the first @code{inf} by two. Surely
- @w{@samp{2 inf - inf = inf}}, but also @samp{2 inf - inf = inf - inf = nan}.
- So @code{nan} can even stand for infinity. Obviously it's just
- as easy to make it stand for minus infinity as for plus infinity.
- X
- The moral of this story is that ``infinity'' is a slippery fish
- indeed, and Calc tries to handle it by having a very simple model
- for infinities (only the direction counts, not the ``size''); but
- Calc is careful to write @code{nan} any time this simple model is
- unable to tell what the true answer is.
- X
- @node Types Answer 4, Types Answer 5, Types Answer 3, Answers to Exercises
- @subsection Types Tutorial Exercise 4
- X
- @group
- @smallexample
- 2: 0@@ 47' 26" 1: 0@@ 2' 47.411765"
- 1: 17 .
- X .
- X
- X 0@@ 47' 26" RET 17 /
- @end smallexample
- @end group
- X
- @noindent
- The average song length is two minutes and 47.4 seconds.
- X
- @group
- @smallexample
- 2: 0@@ 2' 47.411765" 1: 0@@ 3' 7.411765" 1: 0@@ 53' 6.000005"
- 1: 0@@ 0' 20" . .
- X .
- X
- X 20" + 17 *
- @end smallexample
- @end group
- X
- @noindent
- The album would be 53 minutes and 6 seconds long.
- X
- @node Types Answer 5, Types Answer 6, Types Answer 4, Answers to Exercises
- @subsection Types Tutorial Exercise 5
- X
- @noindent
- Let's suppose it's January 14, 1991. The easiest thing to do is
- to keep trying 13ths of months until Calc reports a Friday.
- We can do this by manually entering dates, or by using @kbd{t I}:
- X
- @group
- @smallexample
- 1: <Wed Feb 13, 1991> 1: <Wed Mar 13, 1991> 1: <Sat Apr 13, 1991>
- X . . .
- X
- X ' <2/13> RET DEL ' <3/13> RET t I
- @end smallexample
- @end group
- X
- @noindent
- (Calc assumes the current year if you don't say otherwise.)
- X
- This is getting tedious---we can keep advancing the date by typing
- @kbd{t I} over and over again, but let's automate the job by using
- vector mapping. The @kbd{t I} command actually takes a second
- ``how-many-months'' argument, which defaults to one. This
- argument is exactly what we want to map over:
- X
- @group
- @smallexample
- 2: <Sat Apr 13, 1991> 1: [<Mon May 13, 1991>, <Thu Jun 13, 1991>,
- 1: [1, 2, 3, 4, 5, 6] <Sat Jul 13, 1991>, <Tue Aug 13, 1991>,
- X . <Fri Sep 13, 1991>, <Sun Oct 13, 1991>]
- X .
- X
- X v x 6 RET V M t I
- @end smallexample
- @end group
- X
- @ifinfo
- @noindent
- Et voila, September 13, 1991 is a Friday.
- @end ifinfo
- @tex
- \noindent
- {\it Et voil{\accent"12 a}}, September 13, 1991 is a Friday.
- @end tex
- X
- @group
- @smallexample
- 1: 242
- X .
- X
- ' <sep 13> - <jan 14> RET
- @end smallexample
- @end group
- X
- @noindent
- And the answer to our original question: 242 days to go.
- X
- @node Types Answer 6, Types Answer 7, Types Answer 5, Answers to Exercises
- @subsection Types Tutorial Exercise 6
- X
- @noindent
- The full rule for leap years is that they occur in every year divisible
- SHAR_EOF
- true || echo 'restore of calc.texinfo failed'
- fi
- echo 'End of part 35'
- echo 'File calc.texinfo is continued in part 36'
- echo 36 > _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.
-