Origin for each line in Lesson_5.red from check-in f2c04ccdad:

f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:                   REDUCE INTERACTIVE LESSON NUMBER 5
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:                          David R. Stoutemyer
f2c04ccdad 2021-03-03 trnsz@pobox.c:                          University of Hawaii
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT This is lesson 5 of 7 REDUCE lessons.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: There are at least two good reasons for wanting to save REDUCE
f2c04ccdad 2021-03-03 trnsz@pobox.c: expression assignments to a file:
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    1.  So that one can logout, then resume computation at a later
f2c04ccdad 2021-03-03 trnsz@pobox.c:        time.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    2.  So that needed main memory space can be cleared without
f2c04ccdad 2021-03-03 trnsz@pobox.c:        irrecoverably losing the values of variables which are not
f2c04ccdad 2021-03-03 trnsz@pobox.c:        needed in the next expression but will be needed later.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: Using trivial small expressions, the following statement sequence
f2c04ccdad 2021-03-03 trnsz@pobox.c: illustrates how this could be done:
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    OFF NAT,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    OUT TEMP,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    F1 := (F + G)^2,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    G1 := G*F1,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    OUT T,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    CLEAR F1,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    H1 := H*G1,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    OUT TEMP,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    CLEAR G1,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    H2 := F*H1,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    CLEAR H1,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    SHUT TEMP,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    IN TEMP,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    F1,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    ON NAT,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    F1.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: ON NAT yields the natural output style with raised exponents, which is
f2c04ccdad 2021-03-03 trnsz@pobox.c: unsuitable for subsequent input.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: The OUT-statement causes subsequent output to be directed to the file
f2c04ccdad 2021-03-03 trnsz@pobox.c: named in the statement, until overridden by a different OUT-statement
f2c04ccdad 2021-03-03 trnsz@pobox.c: or until the file is closed by a SHUT-statement.  File T is the
f2c04ccdad 2021-03-03 trnsz@pobox.c: terminal, and any other name designates a normal file.  Such names
f2c04ccdad 2021-03-03 trnsz@pobox.c: must comply with the local file-naming conventions as well as with the
f2c04ccdad 2021-03-03 trnsz@pobox.c: REDUCE syntax.  If the output is not of lasting importance, I find
f2c04ccdad 2021-03-03 trnsz@pobox.c: that including something like "TEMPORARY" or "SCRATCH" in the name
f2c04ccdad 2021-03-03 trnsz@pobox.c: helps remind me to delete it later.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: Successive OUT-statements to the same file will append rather than
f2c04ccdad 2021-03-03 trnsz@pobox.c: overwrite output if and only if there is no intervening SHUT-
f2c04ccdad 2021-03-03 trnsz@pobox.c: statement for that file.  The SHUT-statement also has the effect of an
f2c04ccdad 2021-03-03 trnsz@pobox.c: implied OUT T.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: Note:
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    1.  The generated output is the simplified expression rather than
f2c04ccdad 2021-03-03 trnsz@pobox.c:        the raw form entered at the terminal.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    2.  Each output assignment automatically has a dollar-sign appended
f2c04ccdad 2021-03-03 trnsz@pobox.c:        so that it is legal input and so that (perhaps lengthy) output
f2c04ccdad 2021-03-03 trnsz@pobox.c:        will not unavoidably be generated at the terminal when the file
f2c04ccdad 2021-03-03 trnsz@pobox.c:        is read in later.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    3.  Output cannot be sent simultaneously to 2 or more files.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    4.  Statements entered at the terminal which do not generate output
f2c04ccdad 2021-03-03 trnsz@pobox.c:        -- such as declarations, LET rules, and procedure definitions
f2c04ccdad 2021-03-03 trnsz@pobox.c:        -- do not appear in the output file.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    5.  One could get declarations, procedure definitions, rules, etc.
f2c04ccdad 2021-03-03 trnsz@pobox.c:        written to a file from the terminal by typing statements such
f2c04ccdad 2021-03-03 trnsz@pobox.c:        as
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:           WRITE "
f2c04ccdad 2021-03-03 trnsz@pobox.c:           ALGEBRAIC PROCEDURE ...
f2c04ccdad 2021-03-03 trnsz@pobox.c:              ... ".
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:        This could serve as a means of generating permanent copies of
f2c04ccdad 2021-03-03 trnsz@pobox.c:        LET rules, procedures, etc., but it is quite awkward compared
f2c04ccdad 2021-03-03 trnsz@pobox.c:        with the usual way, which is to generate a file containing the
f2c04ccdad 2021-03-03 trnsz@pobox.c:        REDUCE program by using a text editor, then input the program
f2c04ccdad 2021-03-03 trnsz@pobox.c:        by using the IN-statement.  If you have refrained from learning
f2c04ccdad 2021-03-03 trnsz@pobox.c:        to use a basic text editor (such as Windows Notepad), hesitate
f2c04ccdad 2021-03-03 trnsz@pobox.c:        no longer.  I suggest that your first text-editing exercise be
f2c04ccdad 2021-03-03 trnsz@pobox.c:        to create an IN file for (re)defining the function
f2c04ccdad 2021-03-03 trnsz@pobox.c:        FACTORIAL(n).
f2c04ccdad 2021-03-03 trnsz@pobox.c:    6.  The reason I didn't actually execute the above statement
f2c04ccdad 2021-03-03 trnsz@pobox.c:        sequence is that when the input to REDUCE comes from a file,
f2c04ccdad 2021-03-03 trnsz@pobox.c:        both the input and output are sent to the output file (which is
f2c04ccdad 2021-03-03 trnsz@pobox.c:        convenient for producing a file containing both the input and
f2c04ccdad 2021-03-03 trnsz@pobox.c:        output of a demonstration.)  Consequently, you would have seen
f2c04ccdad 2021-03-03 trnsz@pobox.c:        none of the statements between the "OUT TEMP" and "OUT T" as
f2c04ccdad 2021-03-03 trnsz@pobox.c:        well as between the second "OUT TEMP" and the "SHUT TEMP",
f2c04ccdad 2021-03-03 trnsz@pobox.c:        until the IN-statement was executed.  The example is confusing
f2c04ccdad 2021-03-03 trnsz@pobox.c:        enough without having things scrambled from the order you would
f2c04ccdad 2021-03-03 trnsz@pobox.c:        type them.  To clarify all of this, I encourage you to actually
f2c04ccdad 2021-03-03 trnsz@pobox.c:        execute the above statement sequence with an appropriately
f2c04ccdad 2021-03-03 trnsz@pobox.c:        chosen file name and using semicolons instead of the commas and
f2c04ccdad 2021-03-03 trnsz@pobox.c:        final period.  Afterwards, to return to the lesson, type CONT.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    7.  It is often more natural to use a string (e.g. "less5.red")
f2c04ccdad 2021-03-03 trnsz@pobox.c:        rather than an identifier (e.g. less5!.red) for a filename.
f2c04ccdad 2021-03-03 trnsz@pobox.c:        REDUCE accepts both.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Suppose you and your colleagues developed or obtained a set of
f2c04ccdad 2021-03-03 trnsz@pobox.c: REDUCE files containing supplementary packages such as trigonometric
f2c04ccdad 2021-03-03 trnsz@pobox.c: simplification, Laplace transforms, etc.  It would be a waste of time
f2c04ccdad 2021-03-03 trnsz@pobox.c: (and distracting) to have these files displayed every time they were
f2c04ccdad 2021-03-03 trnsz@pobox.c: input, so this output can be suppressed by inserting the statement
f2c04ccdad 2021-03-03 trnsz@pobox.c: "OFF ECHO" at the beginning of the file.  (But don't forget to include
f2c04ccdad 2021-03-03 trnsz@pobox.c: the statement "ON ECHO" at the end of the file.)
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: The lessons have amply demonstrated the PAUSE-statement, which is
f2c04ccdad 2021-03-03 trnsz@pobox.c: useful for insertion in input files at the top-level or within
f2c04ccdad 2021-03-03 trnsz@pobox.c: functions when input from the user is necessary or desired.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: It often happens that after generating an expression, one decides that
f2c04ccdad 2021-03-03 trnsz@pobox.c: it would be convenient to use it as the body of a function definition,
f2c04ccdad 2021-03-03 trnsz@pobox.c: with one or more of the indeterminates therein as parameters, which
f2c04ccdad 2021-03-03 trnsz@pobox.c: can be done as follows.  (If you input code like this directly rather
f2c04ccdad 2021-03-03 trnsz@pobox.c: than from a file, you will need to agree to let REDUCE declare F to be
f2c04ccdad 2021-03-03 trnsz@pobox.c: an operator.);
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: (1-(v/c)^2)^(1/2);
f2c04ccdad 2021-03-03 trnsz@pobox.c: for all v saveas f(v);
f2c04ccdad 2021-03-03 trnsz@pobox.c: f(5);
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Here the indeterminate V became a parameter of F.
f2c04ccdad 2021-03-03 trnsz@pobox.c: Alternatively, we can save the previous expression to a variable.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: saveas fof5;
f2c04ccdad 2021-03-03 trnsz@pobox.c: fof5;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT I find this technique more convenient than referring to the
f2c04ccdad 2021-03-03 trnsz@pobox.c: special variable WS.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT The FOR-loop provides a convenient way to form finite sums or
f2c04ccdad 2021-03-03 trnsz@pobox.c: products with specific integer index limits.  However, this need is so
f2c04ccdad 2021-03-03 trnsz@pobox.c: ubiquitous that REDUCE provides even more convenient syntax of the
f2c04ccdad 2021-03-03 trnsz@pobox.c: forms
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:   FOR index := initial STEP increment UNTIL final SUM expression,
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:   FOR index := initial STEP increment UNTIL final PRODUCT expression.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: As before, ":" is an acceptable abbreviation for "STEP 1 UNTIL".  As
f2c04ccdad 2021-03-03 trnsz@pobox.c: an example of their use, here is a very concise definition of a
f2c04ccdad 2021-03-03 trnsz@pobox.c: function which computes Taylor-series expansions of symbolic
f2c04ccdad 2021-03-03 trnsz@pobox.c: expressions:;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: algebraic procedure taylor(ex, x, pt, n);
f2c04ccdad 2021-03-03 trnsz@pobox.c:    COMMENT This function returns the degree-N Taylor-series
f2c04ccdad 2021-03-03 trnsz@pobox.c:       expansion of expression EX with respect to indeterminate X,
f2c04ccdad 2021-03-03 trnsz@pobox.c:       expanded about expression PT.  For a series-like appearance,
f2c04ccdad 2021-03-03 trnsz@pobox.c:       display the answer under the influence of FACTOR X, ON RAT,
f2c04ccdad 2021-03-03 trnsz@pobox.c:       and perhaps also ON DIV;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    sub(x=pt, ex) + for k:=1:n sum(sub(x=pt, df(ex,x,k))*(x-pt)^k
f2c04ccdad 2021-03-03 trnsz@pobox.c:                  / for j:=1:k product j);
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: clear a, x;  factor x;  on rat, div;
f2c04ccdad 2021-03-03 trnsz@pobox.c: g1 := taylor(e^x, x, 0, 4);
f2c04ccdad 2021-03-03 trnsz@pobox.c: g2 := taylor(e^cos(x)*cos(sin(x)), x, 0, 3);
f2c04ccdad 2021-03-03 trnsz@pobox.c: % This illustrates the zero denominator limitation; continue anyway:
f2c04ccdad 2021-03-03 trnsz@pobox.c: taylor(log(x), x, 0, 4);
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT It would, of course, be more efficient to compute each
f2c04ccdad 2021-03-03 trnsz@pobox.c: derivative and factorial from the preceding one.  (Similarly for
f2c04ccdad 2021-03-03 trnsz@pobox.c: (X-PT)^K if and only if PT NEQ 0).
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: The Fourier series expansion of our example E^COS(X)*COS(SIN(X))
f2c04ccdad 2021-03-03 trnsz@pobox.c: is  1 + cos(x) + cos(2*x)/2 + cos(3*x)/(3*2) + ... .
f2c04ccdad 2021-03-03 trnsz@pobox.c: Use the above SUM and PRODUCT features to generate the partial sum of
f2c04ccdad 2021-03-03 trnsz@pobox.c: this series through terms of order COS(6*X);
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Closed-form solutions are often unobtainable for nontrivial
f2c04ccdad 2021-03-03 trnsz@pobox.c: problems, even using computer algebra.  When this is the case,
f2c04ccdad 2021-03-03 trnsz@pobox.c: truncated symbolic series solutions are often worth trying before
f2c04ccdad 2021-03-03 trnsz@pobox.c: resorting to approximate numerical solutions.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: When we combine truncated series it is pointless (and worse yet,
f2c04ccdad 2021-03-03 trnsz@pobox.c: misleading) to retain terms of higher order than is justified by the
f2c04ccdad 2021-03-03 trnsz@pobox.c: constituents.  For example, if we wish to multiply together the
f2c04ccdad 2021-03-03 trnsz@pobox.c: truncated series G1 and G2 generated above, there is no point in
f2c04ccdad 2021-03-03 trnsz@pobox.c: retaining terms higher than third degree in X.  We can avoid even
f2c04ccdad 2021-03-03 trnsz@pobox.c: generating such terms as follows:;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: let x^4 = 0;
f2c04ccdad 2021-03-03 trnsz@pobox.c: g3 := g1*g2;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Replacing X^4 with 0 has the effect of also replacing all
f2c04ccdad 2021-03-03 trnsz@pobox.c: higher powers of X with 0.  We could, of course, use our TAYLOR
f2c04ccdad 2021-03-03 trnsz@pobox.c: function to compute G3 directly, but differentiation is time consuming
f2c04ccdad 2021-03-03 trnsz@pobox.c: compared to truncated polynomial algebra.  Moreover, our TAYLOR
f2c04ccdad 2021-03-03 trnsz@pobox.c: function requires a closed-form expression to begin with, whereas
f2c04ccdad 2021-03-03 trnsz@pobox.c: iterative techniques often permit us to construct symbolic series
f2c04ccdad 2021-03-03 trnsz@pobox.c: solutions even when we have no such closed form.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: Now consider the truncated series:;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: clear y;  factor y;
f2c04ccdad 2021-03-03 trnsz@pobox.c: h1 := taylor(cos y, y, 0, 6);
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Suppose we regard terms of order X^N in G1 as being comparable
f2c04ccdad 2021-03-03 trnsz@pobox.c: to terms of order Y^(2*N) in H1, and we want to form (G1*H1)^2.  This
f2c04ccdad 2021-03-03 trnsz@pobox.c: can be done as follows:;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: let y^7 = 0;
f2c04ccdad 2021-03-03 trnsz@pobox.c: f1 := (g1*h1)^2;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Note however that any terms of the form C*X^M*Y^N with
f2c04ccdad 2021-03-03 trnsz@pobox.c: 2*M+N > 6 are inconsistent with the accuracy of the constituent
f2c04ccdad 2021-03-03 trnsz@pobox.c: series, and we have generated several such misleading terms by
f2c04ccdad 2021-03-03 trnsz@pobox.c: independently truncating powers of X and Y.  To avoid generating such
f2c04ccdad 2021-03-03 trnsz@pobox.c: junk, we can specify that a term be replaced by 0 whenever a weighted
f2c04ccdad 2021-03-03 trnsz@pobox.c: sum of exponents of specified indeterminates and functional forms
f2c04ccdad 2021-03-03 trnsz@pobox.c: exceeds a specified weight level.  In our example this is done as
f2c04ccdad 2021-03-03 trnsz@pobox.c: follows:;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: weight x=2, y=1;
f2c04ccdad 2021-03-03 trnsz@pobox.c: wtlevel 6;
f2c04ccdad 2021-03-03 trnsz@pobox.c: f1 := f1;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Variables not mentioned in a WEIGHT declaration have a weight
f2c04ccdad 2021-03-03 trnsz@pobox.c: of 0, and the default weight-level is 2.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Here is an example of how one might compute numerical
f2c04ccdad 2021-03-03 trnsz@pobox.c: approximations to the cosine function.  (But note that REDUCE can
f2c04ccdad 2021-03-03 trnsz@pobox.c: already do this automatically!)  One way is to provide a supplementary
f2c04ccdad 2021-03-03 trnsz@pobox.c: LET rule for numerical arguments.  For example, since our TAYLOR
f2c04ccdad 2021-03-03 trnsz@pobox.c: function would reveal that the Taylor series for cos x is
f2c04ccdad 2021-03-03 trnsz@pobox.c: 1 - x^2/2! + x^4/4! - ...;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: for all x such that numberp x let abs(x) = x, abs(-x) = x;
f2c04ccdad 2021-03-03 trnsz@pobox.c: epsrecip := 1024$
f2c04ccdad 2021-03-03 trnsz@pobox.c: on rounded;
f2c04ccdad 2021-03-03 trnsz@pobox.c: while 1.0 + 1.0/epsrecip neq 1.0 do
f2c04ccdad 2021-03-03 trnsz@pobox.c:    epsrecip := epsrecip + epsrecip;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: for all x such that numberp num x and numberp den x let cos x =
f2c04ccdad 2021-03-03 trnsz@pobox.c:    begin COMMENT X is integer, real, or a rational number.  This rule
f2c04ccdad 2021-03-03 trnsz@pobox.c:       returns the Taylor-series approximation to COS X, truncated when
f2c04ccdad 2021-03-03 trnsz@pobox.c:       the last included term is less than (1/EPSRECIP) of the returned
f2c04ccdad 2021-03-03 trnsz@pobox.c:       answer.  EPSRECIP is a global variable initialized to a value
f2c04ccdad 2021-03-03 trnsz@pobox.c:       that is appropriate to the local floating-point precision.
f2c04ccdad 2021-03-03 trnsz@pobox.c:       Arbitrarily larger values are justifiable when X is exact and
f2c04ccdad 2021-03-03 trnsz@pobox.c:       ROUNDED is off.  No angle reduction is performed, so this
f2c04ccdad 2021-03-03 trnsz@pobox.c:       function is not recommended for ABS(X) >= about PI/2;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    integer k;  scalar mxsq, term, ans;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    k := 1;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    mxsq := -x*x;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    term := mxsq/2;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    ans := term + 1;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    while abs(num term)*epsrecip*den(ans) - abs(num ans)*den(term) > 0 do
f2c04ccdad 2021-03-03 trnsz@pobox.c:       << term := term*mxsq/k/(k+1);
f2c04ccdad 2021-03-03 trnsz@pobox.c:          ans := term + ans;
f2c04ccdad 2021-03-03 trnsz@pobox.c:          k := k+2 >>;
f2c04ccdad 2021-03-03 trnsz@pobox.c:    return ans
f2c04ccdad 2021-03-03 trnsz@pobox.c:    end;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: cos(f) + cos(1/2);
f2c04ccdad 2021-03-03 trnsz@pobox.c: off rounded;
f2c04ccdad 2021-03-03 trnsz@pobox.c: cos(1/2);
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT As an exercise, write a similar rule for the SIN or LOG, or
f2c04ccdad 2021-03-03 trnsz@pobox.c: replace the COS rule with an improved one which uses angle reduction
f2c04ccdad 2021-03-03 trnsz@pobox.c: so that angles outside a modest range are represented as equivalent
f2c04ccdad 2021-03-03 trnsz@pobox.c: angles within the range, before computing the Taylor series.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT There is a REDUCE compiler, and you may wish to learn how to
f2c04ccdad 2021-03-03 trnsz@pobox.c: use it.  However, even if rules such as the above ones are compiled,
f2c04ccdad 2021-03-03 trnsz@pobox.c: they will be slow compared to the implementation-dependent hand-coded
f2c04ccdad 2021-03-03 trnsz@pobox.c: ones used by most FORTRAN-like systems, so REDUCE provides a way to
f2c04ccdad 2021-03-03 trnsz@pobox.c: generate FORTRAN programs which can then be compiled and executed in a
f2c04ccdad 2021-03-03 trnsz@pobox.c: subsequent job step.  This is useful when there is a lot of
f2c04ccdad 2021-03-03 trnsz@pobox.c: floating-point computation or when we wish to exploit an existing
f2c04ccdad 2021-03-03 trnsz@pobox.c: FORTRAN program.  Suppose, for example, that we wish to utilize an
f2c04ccdad 2021-03-03 trnsz@pobox.c: existing FORTRAN subroutine which uses the Newton-Raphson iteration
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    Xnew := Xold - SUB(X=Xold, F(X)/DF(F(X),X))
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: to attempt an approximate solution to the equation F(X)=0.  Most such
f2c04ccdad 2021-03-03 trnsz@pobox.c: subroutines require the user to provide a FORTRAN function or
f2c04ccdad 2021-03-03 trnsz@pobox.c: subroutine which, given Xold, returns F(X)/DF(F(X),X) evaluated at
f2c04ccdad 2021-03-03 trnsz@pobox.c: X=Xold.  If F(X) is complicated, manual symbolic derivation of
f2c04ccdad 2021-03-03 trnsz@pobox.c: DF(F(X),X) is a tedious and error-prone process.  We can get REDUCE to
f2c04ccdad 2021-03-03 trnsz@pobox.c: relieve us of this responsibility as is illustrated below for the
f2c04ccdad 2021-03-03 trnsz@pobox.c: trivial example F(X) = X*E^X - 1:
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    ON FORT, ROUNDED,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    OUT FONDFFILE,
f2c04ccdad 2021-03-03 trnsz@pobox.c:    WRITE "      REAL FUNCTION FONDF(XOLD)",
f2c04ccdad 2021-03-03 trnsz@pobox.c:    WRITE "      REAL XOLD, F",
f2c04ccdad 2021-03-03 trnsz@pobox.c:                 F := XOLD*E^XOLD - 1.0,
f2c04ccdad 2021-03-03 trnsz@pobox.c:                 FONDF := F/DF(F,XOLD),
f2c04ccdad 2021-03-03 trnsz@pobox.c:    WRITE "      RETURN",
f2c04ccdad 2021-03-03 trnsz@pobox.c:    WRITE "      END",
f2c04ccdad 2021-03-03 trnsz@pobox.c:    SHUT FONDFFILE.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Under the influence of ON FORT, the output generated by
f2c04ccdad 2021-03-03 trnsz@pobox.c: assignments is printed as valid FORTRAN assignment statements, using
f2c04ccdad 2021-03-03 trnsz@pobox.c: as many continuation lines as necessary up to the number specified by
f2c04ccdad 2021-03-03 trnsz@pobox.c: the global variable !*CARDNO, which is initially set to 20.  The
f2c04ccdad 2021-03-03 trnsz@pobox.c: output generated by an expression which is not an assignment is a
f2c04ccdad 2021-03-03 trnsz@pobox.c: corresponding assignment to a variable named ANS.  In either case,
f2c04ccdad 2021-03-03 trnsz@pobox.c: expressions which would otherwise exceed !*CARDNO continuation lines
f2c04ccdad 2021-03-03 trnsz@pobox.c: are evaluated piecewise, using ANS as an intermediate variable.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: Try executing the above statement sequence, using an appropriate
f2c04ccdad 2021-03-03 trnsz@pobox.c: filename and using semicolons instead of the commas and period at the
f2c04ccdad 2021-03-03 trnsz@pobox.c: end of the lines (only), then view the file after the lesson to see
f2c04ccdad 2021-03-03 trnsz@pobox.c: how it worked.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: off fort, rounded;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT To make this technique usable by non-REDUCE programmers, we
f2c04ccdad 2021-03-03 trnsz@pobox.c: could write a more general REDUCE program which given merely the
f2c04ccdad 2021-03-03 trnsz@pobox.c: expression F by the user, outputs not only the function FONDF, but
f2c04ccdad 2021-03-03 trnsz@pobox.c: also any necessary job-control commands and an appropriate main
f2c04ccdad 2021-03-03 trnsz@pobox.c: program for calling the Newton-Raphson subroutine and printing the
f2c04ccdad 2021-03-03 trnsz@pobox.c: results.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: Sometimes it is desirable to modify or supplement the syntax of
f2c04ccdad 2021-03-03 trnsz@pobox.c: REDUCE.  For example:
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    1.  Electrical engineers may prefer to input J as the
f2c04ccdad 2021-03-03 trnsz@pobox.c:        representation of (-1)^(1/2).
f2c04ccdad 2021-03-03 trnsz@pobox.c:    2.  A user might prefer to input LOGE to denote natural
f2c04ccdad 2021-03-03 trnsz@pobox.c:        logarithms.  (Note that LN is already defined as a synonym for
f2c04ccdad 2021-03-03 trnsz@pobox.c:        LOG.)
f2c04ccdad 2021-03-03 trnsz@pobox.c:    3.  A user might prefer to use DERIV instead of DF to request
f2c04ccdad 2021-03-03 trnsz@pobox.c:        differentiation.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: Such lexical macros can be established by the DEFINE declaration:;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: clear x, j;
f2c04ccdad 2021-03-03 trnsz@pobox.c: define j=i, loge=log, deriv=df;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Now watch!;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: g1 := sub(x=loge(j^3*x), deriv(x^2,x));
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT Each "equation" in a DEFINE declaration must be of the form
f2c04ccdad 2021-03-03 trnsz@pobox.c: "name = item", where each item is an expression, an operator, or a
f2c04ccdad 2021-03-03 trnsz@pobox.c: REDUCE-reserved word such as "FOR".  Such replacements take place
f2c04ccdad 2021-03-03 trnsz@pobox.c: during the lexical scanning, before any evaluation, LET rules, or
f2c04ccdad 2021-03-03 trnsz@pobox.c: built-in simplification.  Think of a good application for this
f2c04ccdad 2021-03-03 trnsz@pobox.c: facility, then try it.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT When REDUCE is being run non-interactively, with input from a
f2c04ccdad 2021-03-03 trnsz@pobox.c: file rather than a terminal, it is preferable to have REDUCE make
f2c04ccdad 2021-03-03 trnsz@pobox.c: reasonable decisions and proceed when it encounters apparently
f2c04ccdad 2021-03-03 trnsz@pobox.c: undeclared operators, divisions by zero, etc.  In interactive mode, it
f2c04ccdad 2021-03-03 trnsz@pobox.c: is preferable to pause and query the user.  ON INT specifies the
f2c04ccdad 2021-03-03 trnsz@pobox.c: latter style, and OFF INT specifies the former.  Under the influence
f2c04ccdad 2021-03-03 trnsz@pobox.c: of OFF INT, we can also have most error messages suppressed by
f2c04ccdad 2021-03-03 trnsz@pobox.c: specifying OFF MSG.  This is sometimes useful when we expect abnormal
f2c04ccdad 2021-03-03 trnsz@pobox.c: conditions and do not want our output marred by the associated
f2c04ccdad 2021-03-03 trnsz@pobox.c: messages.  INT is automatically turned off during input from a file in
f2c04ccdad 2021-03-03 trnsz@pobox.c: response to an IN-command from a terminal.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT REDUCE provides a trace command for debugging, which employs
f2c04ccdad 2021-03-03 trnsz@pobox.c: the syntax
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    TR functionname1, functionname2, ..., functionnameN.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: An analogous command named UNTR removes function names from trace
f2c04ccdad 2021-03-03 trnsz@pobox.c: status;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT REDUCE also provides an assignment-tracing command for
f2c04ccdad 2021-03-03 trnsz@pobox.c: debugging, which employs the syntax
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    TRST functionname1, functionname2, ..., functionnameN.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: An analogous command named UNTRST removes functionnames from this
f2c04ccdad 2021-03-03 trnsz@pobox.c: status.  All assignments in the designated functions are reported,
f2c04ccdad 2021-03-03 trnsz@pobox.c: except for assignments to array elements.  Such functions must be
f2c04ccdad 2021-03-03 trnsz@pobox.c: uncompiled and must have a top-level BEGIN-block.  To apply both TRST
f2c04ccdad 2021-03-03 trnsz@pobox.c: and TR to a function simultaneously, it is crucial to request them in
f2c04ccdad 2021-03-03 trnsz@pobox.c: that order, and it is necessary to relinquish the two kinds of tracing
f2c04ccdad 2021-03-03 trnsz@pobox.c: in the opposite order.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: pause;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: COMMENT The REDUCE algebraic algorithms are written in a subset of
f2c04ccdad 2021-03-03 trnsz@pobox.c: REDUCE called RLISP.  In turn, the more sophisticated features of
f2c04ccdad 2021-03-03 trnsz@pobox.c: RLISP are written in a small subset of RLISP, which is itself written
f2c04ccdad 2021-03-03 trnsz@pobox.c: in a simple dialect of LISP called Standard LISP.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: RLISP is ideal for implementing algebraic algorithms, but the RLISP
f2c04ccdad 2021-03-03 trnsz@pobox.c: environment is not most suitable for the routine use of these
f2c04ccdad 2021-03-03 trnsz@pobox.c: algorithms in the natural mathematical style of the preceding lessons.
f2c04ccdad 2021-03-03 trnsz@pobox.c: Accordingly, REDUCE is initially in a mode called ALGEBRAIC, which
f2c04ccdad 2021-03-03 trnsz@pobox.c: provides the user with the environment illustrated in the preceding
f2c04ccdad 2021-03-03 trnsz@pobox.c: lessons, while insulating him from accidental interaction with the
f2c04ccdad 2021-03-03 trnsz@pobox.c: numerous functions, global variables, etc. necessary for implementing
f2c04ccdad 2021-03-03 trnsz@pobox.c: the built-in algebra.  In contrast, the underlying RLISP system
f2c04ccdad 2021-03-03 trnsz@pobox.c: together with all of the algebraic simplification algorithms written
f2c04ccdad 2021-03-03 trnsz@pobox.c: therein is called SYMBOLIC mode.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: As we have seen, algebraic-mode rules and procedures can be used to
f2c04ccdad 2021-03-03 trnsz@pobox.c: extend the built-in algebraic capabilities.  However, some extensions
f2c04ccdad 2021-03-03 trnsz@pobox.c: can be accomplished most easily or efficiently by descending to
f2c04ccdad 2021-03-03 trnsz@pobox.c: SYMBOLIC mode.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: To make REDUCE operate in symbolic mode, we merely execute the top-
f2c04ccdad 2021-03-03 trnsz@pobox.c: level mode-declaration statement consisting of the word SYMBOLIC.  We
f2c04ccdad 2021-03-03 trnsz@pobox.c: can subsequently switch back by executing the statement consisting of
f2c04ccdad 2021-03-03 trnsz@pobox.c: the word ALGEBRAIC.
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: RLISP has the semantics of LISP with the syntax of our by-now-familiar
f2c04ccdad 2021-03-03 trnsz@pobox.c: algebraic-mode REDUCE, so RLISP provides a natural tool for many
f2c04ccdad 2021-03-03 trnsz@pobox.c: applications besides computer algebra, such as games, theorem-proving,
f2c04ccdad 2021-03-03 trnsz@pobox.c: natural-language translation, computer-aided instruction, and
f2c04ccdad 2021-03-03 trnsz@pobox.c: artificial intelligence in general.  For this reason, it is possible
f2c04ccdad 2021-03-03 trnsz@pobox.c: to run RLISP without any of the symbolic-mode algebraic algorithms
f2c04ccdad 2021-03-03 trnsz@pobox.c: that are written in RLISP, and it is advisable to thus save space when
f2c04ccdad 2021-03-03 trnsz@pobox.c: the application does not involve computer algebra.  (An RLISP system
f2c04ccdad 2021-03-03 trnsz@pobox.c: is a step in the process of building a complete REDUCE system, but is
f2c04ccdad 2021-03-03 trnsz@pobox.c: not distributed as an independent application, although one can be
f2c04ccdad 2021-03-03 trnsz@pobox.c: built from the source code available.)
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: We have now discussed virtually every feature that is available in
f2c04ccdad 2021-03-03 trnsz@pobox.c: algebraic mode, so lesson 6 will deal solely with RLISP, and lesson 7
f2c04ccdad 2021-03-03 trnsz@pobox.c: will deal with communication between ALGEBRAIC and SYMBOLIC mode for
f2c04ccdad 2021-03-03 trnsz@pobox.c: mathematical purposes.  However, I suggest that you proceed to those
f2c04ccdad 2021-03-03 trnsz@pobox.c: lessons only if and when:
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c:    1.  You have consolidated and fully absorbed the information in
f2c04ccdad 2021-03-03 trnsz@pobox.c:        lessons 1 through 5 by considerable practice beyond the
f2c04ccdad 2021-03-03 trnsz@pobox.c:        exercises therein.  (The exercises were intended to also
f2c04ccdad 2021-03-03 trnsz@pobox.c:        suggest good related project ideas.)
f2c04ccdad 2021-03-03 trnsz@pobox.c:    2.  You feel the need for a facility which you believe is
f2c04ccdad 2021-03-03 trnsz@pobox.c:        impossible or quite awkward to implement solely in ALGEBRAIC
f2c04ccdad 2021-03-03 trnsz@pobox.c:        mode.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    3.  You have read an introductory text about LISP, such as "A
f2c04ccdad 2021-03-03 trnsz@pobox.c:        Concise Introduction to LISP" by David L. Matuszek, which is
f2c04ccdad 2021-03-03 trnsz@pobox.c:        freely available at
f2c04ccdad 2021-03-03 trnsz@pobox.c:        https://www.cis.upenn.edu/~matuszek/LispText/lisp.html.
f2c04ccdad 2021-03-03 trnsz@pobox.c:    4.  You are familiar with the definition of Standard LISP, as
f2c04ccdad 2021-03-03 trnsz@pobox.c:        described in the "Standard LISP Report" which was published in
f2c04ccdad 2021-03-03 trnsz@pobox.c:        the October 1979 SIGPLAN Notices.  [A copy is freely available
f2c04ccdad 2021-03-03 trnsz@pobox.c:        via http://reduce-algebra.sourceforge.net/documentation.php.]
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: Don't forget to view or print your newly generated FORTRAN file and to
f2c04ccdad 2021-03-03 trnsz@pobox.c: delete any temporary files created by this lesson.;
f2c04ccdad 2021-03-03 trnsz@pobox.c: 
f2c04ccdad 2021-03-03 trnsz@pobox.c: ;end;

iCAS Bundled REDUCE Scripts
Homepage | GitHub Mirror | SourceHut Mirror | NotABug Mirror | Chisel Mirror | Chisel RSS ]