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

f2c04ccdad 2021-03-03    1: COMMENT
f2c04ccdad 2021-03-03    2: 
f2c04ccdad 2021-03-03    3:                   REDUCE INTERACTIVE LESSON NUMBER 3
f2c04ccdad 2021-03-03    4: 
f2c04ccdad 2021-03-03    5:                          David R. Stoutemyer
f2c04ccdad 2021-03-03    6:                          University of Hawaii
f2c04ccdad 2021-03-03    7: 
f2c04ccdad 2021-03-03    8:                         Update for REDUCE 3.4
f2c04ccdad 2021-03-03    9:                             Herbert Melenk
f2c04ccdad 2021-03-03   10:                       Konrad-Zuse-Zentrum Berlin
f2c04ccdad 2021-03-03   11:                                    
f2c04ccdad 2021-03-03   12: 
f2c04ccdad 2021-03-03   13: COMMENT This is lesson 3 of 7 REDUCE lessons.  Please refrain from
f2c04ccdad 2021-03-03   14: using variables beginning with the letters F through H during the
f2c04ccdad 2021-03-03   15: lesson.
f2c04ccdad 2021-03-03   16: 
f2c04ccdad 2021-03-03   17: Mathematics is replete with many named elementary and not-so-
f2c04ccdad 2021-03-03   18: elementary functions besides the set built into REDUCE such as SIN,
f2c04ccdad 2021-03-03   19: COS, and LOG, and it is often convenient to utilize expressions
f2c04ccdad 2021-03-03   20: containing a functional form such as F(X) to denote an unknown
f2c04ccdad 2021-03-03   21: function or a class of functions.  Functions are called operators in
f2c04ccdad 2021-03-03   22: REDUCE, and by merely declaring their names as such, we are free to
f2c04ccdad 2021-03-03   23: use them for functional forms.  For example:;
f2c04ccdad 2021-03-03   24: 
f2c04ccdad 2021-03-03   25: operator f;
f2c04ccdad 2021-03-03   26: g1 := f(f(cot(f)), f());
f2c04ccdad 2021-03-03   27: 
f2c04ccdad 2021-03-03   28: COMMENT Note that
f2c04ccdad 2021-03-03   29: 
f2c04ccdad 2021-03-03   30:    1.  We can use the same name for both a variable and an operator.
f2c04ccdad 2021-03-03   31:        (However, this practice often leads to confusion.)
f2c04ccdad 2021-03-03   32:    2.  We can use the same operator for any number of arguments --
f2c04ccdad 2021-03-03   33:        including zero arguments such as for F().
f2c04ccdad 2021-03-03   34:    3.  We can assign values to specific instances of functional
f2c04ccdad 2021-03-03   35:        forms.;
f2c04ccdad 2021-03-03   36: 
f2c04ccdad 2021-03-03   37: pause;
f2c04ccdad 2021-03-03   38: 
f2c04ccdad 2021-03-03   39: COMMENT COT is one of the functions already defined in REDUCE together
f2c04ccdad 2021-03-03   40: with a few of its properties.  However, you can augment or even
f2c04ccdad 2021-03-03   41: override these definitions depending on the needs of a given problem.
f2c04ccdad 2021-03-03   42: For example, if you wished to write COT(F) in terms of TAN, you could
f2c04ccdad 2021-03-03   43: say:;
f2c04ccdad 2021-03-03   44: 
f2c04ccdad 2021-03-03   45: cot(f) := 1/tan(f);
f2c04ccdad 2021-03-03   46: g1 := g1 + cot(h+1);
f2c04ccdad 2021-03-03   47: 
f2c04ccdad 2021-03-03   48: pause;
f2c04ccdad 2021-03-03   49: 
f2c04ccdad 2021-03-03   50: COMMENT Naturally, our assignment for COT(F) did not affect COT(H+1)
f2c04ccdad 2021-03-03   51: in our example above.  However, we can use a LET rule to make all
f2c04ccdad 2021-03-03   52: cotangents automatically be replaced by the reciprocal of the
f2c04ccdad 2021-03-03   53: corresponding tangents:;
f2c04ccdad 2021-03-03   54: 
f2c04ccdad 2021-03-03   55: let cot(~f) => 1/tan(f);
f2c04ccdad 2021-03-03   56: g1;
f2c04ccdad 2021-03-03   57: 
f2c04ccdad 2021-03-03   58: COMMENT Any variable preceded by a tilde is a dummy variable which is
f2c04ccdad 2021-03-03   59: distinct from any other previously or subsequently introduced
f2c04ccdad 2021-03-03   60: indeterminate, variable, or dummy variable having the same name
f2c04ccdad 2021-03-03   61: outside the rule.  The leftmost occurrence of a dummy variable in a
f2c04ccdad 2021-03-03   62: rule must be marked with a tilde.
f2c04ccdad 2021-03-03   63: 
f2c04ccdad 2021-03-03   64: The arguments to LET are either single rules or lists (explicitly
f2c04ccdad 2021-03-03   65: enclosed in {..} or as variables with list values).  All elements of a
f2c04ccdad 2021-03-03   66: list have to be rules (i.e., expressions written in terms of the
f2c04ccdad 2021-03-03   67: operator "=>") or names of other rule lists.  So we could have written
f2c04ccdad 2021-03-03   68: the above command either as
f2c04ccdad 2021-03-03   69: 
f2c04ccdad 2021-03-03   70:       LET COT(~F) => 1/TAN(F)
f2c04ccdad 2021-03-03   71: 
f2c04ccdad 2021-03-03   72: or as the command sequence
f2c04ccdad 2021-03-03   73: 
f2c04ccdad 2021-03-03   74:       RS := {COT(~F) => 1/TAN(F)}
f2c04ccdad 2021-03-03   75:       LET RS
f2c04ccdad 2021-03-03   76: 
f2c04ccdad 2021-03-03   77: The CLEARRULES command clears one or more rules.  They have to be
f2c04ccdad 2021-03-03   78: entered in the same form as for LET -- otherwise REDUCE is unable to
f2c04ccdad 2021-03-03   79: identify them.;
f2c04ccdad 2021-03-03   80: 
f2c04ccdad 2021-03-03   81: clearrules cot(~f) => 1/tan(f);
f2c04ccdad 2021-03-03   82: cot(g+5);
f2c04ccdad 2021-03-03   83: 
f2c04ccdad 2021-03-03   84: COMMENT Alternative forms would have been
f2c04ccdad 2021-03-03   85: 
f2c04ccdad 2021-03-03   86:      CLEARRULES {COT(~F) => 1/TAN(F)}
f2c04ccdad 2021-03-03   87: 
f2c04ccdad 2021-03-03   88:    or with the above value of RS
f2c04ccdad 2021-03-03   89: 
f2c04ccdad 2021-03-03   90:      CLEARRULES RS
f2c04ccdad 2021-03-03   91: 
f2c04ccdad 2021-03-03   92: Note that CLEAR RS would not remove the rule(s) from the system -- it
f2c04ccdad 2021-03-03   93: would only remove the list value from the variable RS.;
f2c04ccdad 2021-03-03   94: 
f2c04ccdad 2021-03-03   95: pause;
f2c04ccdad 2021-03-03   96: 
f2c04ccdad 2021-03-03   97: COMMENT The arguments of a functional form on the left-hand side of a
f2c04ccdad 2021-03-03   98: rule can be more complicated than mere indeterminates.  For example,
f2c04ccdad 2021-03-03   99: we may wish to inform REDUCE how to differentiate expressions
f2c04ccdad 2021-03-03  100: involving a symbolic function P, whose derivative is expressed in
f2c04ccdad 2021-03-03  101: terms of another function Q.;
f2c04ccdad 2021-03-03  102: 
f2c04ccdad 2021-03-03  103: operator p, q;
f2c04ccdad 2021-03-03  104: let df(p(~x), x) => q(x)^2;
f2c04ccdad 2021-03-03  105: 
f2c04ccdad 2021-03-03  106: df(3*p(f*g), g);
f2c04ccdad 2021-03-03  107: 
f2c04ccdad 2021-03-03  108: COMMENT Also, REDUCE obviously knows the chain rule.;
f2c04ccdad 2021-03-03  109: 
f2c04ccdad 2021-03-03  110: pause;
f2c04ccdad 2021-03-03  111: 
f2c04ccdad 2021-03-03  112: COMMENT As another example, suppose that we wish to employ the
f2c04ccdad 2021-03-03  113: angle-sum identities for SIN and COS:;
f2c04ccdad 2021-03-03  114: 
f2c04ccdad 2021-03-03  115: let {sin(~x+~y) => sin(x)*cos(y) + sin(y)*cos(x),
f2c04ccdad 2021-03-03  116:      cos(~x+~y) => cos(x)*cos(y) - sin(x)*sin(y)};
f2c04ccdad 2021-03-03  117: cos(5 + f - g);
f2c04ccdad 2021-03-03  118: 
f2c04ccdad 2021-03-03  119: COMMENT Note that:
f2c04ccdad 2021-03-03  120: 
f2c04ccdad 2021-03-03  121:    1.  LET can have any number of replacement rules written as a list.
f2c04ccdad 2021-03-03  122:    2.  There was no need for rules with 3 or more addends, because the
f2c04ccdad 2021-03-03  123:        above rules were automatically employed recursively, with two
f2c04ccdad 2021-03-03  124:        of the three addends 5, F, and -G grouped together as one of
f2c04ccdad 2021-03-03  125:        the dummy variables the first time through.
f2c04ccdad 2021-03-03  126:    3.  Despite the sub-expression F-G in our example, there was no
f2c04ccdad 2021-03-03  127:        need to make rules for the difference of two angles, because
f2c04ccdad 2021-03-03  128:        sub-expressions of the form X-Y are treated as X+(-Y).
f2c04ccdad 2021-03-03  129:    4.  Built-in rules were employed to convert expressions of the form
f2c04ccdad 2021-03-03  130:        SIN(-X) or COS(-X) to -SIN(X) or COS(X) respectively.
f2c04ccdad 2021-03-03  131: 
f2c04ccdad 2021-03-03  132: As an exercise, try to implement rules which transform the logarithms
f2c04ccdad 2021-03-03  133: of products and quotients respectively to sums and differences of
f2c04ccdad 2021-03-03  134: logarithms, while converting the logarithm of a power of a quantity to
f2c04ccdad 2021-03-03  135: the power times the logarithm of the quantity.;
f2c04ccdad 2021-03-03  136: 
f2c04ccdad 2021-03-03  137: pause;
f2c04ccdad 2021-03-03  138: 
f2c04ccdad 2021-03-03  139: COMMENT Actually, the left-hand side of a rule also can be somewhat
f2c04ccdad 2021-03-03  140: more general than a functional form.  The left-hand side can be a
f2c04ccdad 2021-03-03  141: power of an indeterminate or of a functional form, or a product of
f2c04ccdad 2021-03-03  142: such powers and/or indeterminates or functional forms.  For example,
f2c04ccdad 2021-03-03  143: we can have the rule
f2c04ccdad 2021-03-03  144: 
f2c04ccdad 2021-03-03  145:        SIN(~X)^2 => 1 - COS(~X)^2
f2c04ccdad 2021-03-03  146: 
f2c04ccdad 2021-03-03  147: or we can have the rule:;
f2c04ccdad 2021-03-03  148: 
f2c04ccdad 2021-03-03  149: let cos(~x)^2 => 1 - sin(~x)^2;
f2c04ccdad 2021-03-03  150: g1 := cos(f)^3 + cos(g);
f2c04ccdad 2021-03-03  151: pause;
f2c04ccdad 2021-03-03  152: 
f2c04ccdad 2021-03-03  153: COMMENT Note that a replacement takes place wherever the left-hand
f2c04ccdad 2021-03-03  154: side of a rule divides a term.  With a rule replacing SIN(X)^2 and a
f2c04ccdad 2021-03-03  155: rule replacing COS(X)^2 simultaneously in effect, an expression which
f2c04ccdad 2021-03-03  156: uses either one will lead to an infinite recursion that eventually
f2c04ccdad 2021-03-03  157: exhausts the available storage.  (Try it if you wish -- after the
f2c04ccdad 2021-03-03  158: lesson).  We are also permitted to employ a more symmetric rule using
f2c04ccdad 2021-03-03  159: a top level "+" provided that no free variables appear in the rule.
f2c04ccdad 2021-03-03  160: However, a rule such as "SIN(~X)^2 + COS(X)^2 => 1" is not permitted.
f2c04ccdad 2021-03-03  161: We can get around the restriction against a top-level "+" on the
f2c04ccdad 2021-03-03  162: left-hand side though, at the minor nuisance of having to employ an
f2c04ccdad 2021-03-03  163: operator whenever we want the rule applied to an expression:;
f2c04ccdad 2021-03-03  164: 
f2c04ccdad 2021-03-03  165: clearrules cos(~x)^2 => 1 - sin(~x)^2;
f2c04ccdad 2021-03-03  166: operator trigsimp;
f2c04ccdad 2021-03-03  167: trigsimp_rules := {
f2c04ccdad 2021-03-03  168:    trigsimp(~a*sin(~x)^2 + a*cos(x)^2 + ~c) => a + trigsimp(c),
f2c04ccdad 2021-03-03  169:    trigsimp(~a*sin(~x)^2 + a*cos(x)^2) => a,
f2c04ccdad 2021-03-03  170:    trigsimp(sin(~x)^2 + cos(x)^2 + ~c) => 1 + trigsimp(c),
f2c04ccdad 2021-03-03  171:    trigsimp(sin(~x)^2 + cos(x)^2) => 1,
f2c04ccdad 2021-03-03  172:    trigsimp(~x) => x }$
f2c04ccdad 2021-03-03  173: g1 := f*cos(g)^2 + f*sin(g)^2 + g*sin(g)^2 + g*cos(g)^2 + 5;
f2c04ccdad 2021-03-03  174: g1 := trigsimp(g1) where trigsimp_rules;
f2c04ccdad 2021-03-03  175: pause;
f2c04ccdad 2021-03-03  176: 
f2c04ccdad 2021-03-03  177: COMMENT Here we use another syntactical paradigm: the rule list is
f2c04ccdad 2021-03-03  178: assigned to a name (here TRIGSIMP_RULES) and it is activated only
f2c04ccdad 2021-03-03  179: locally for one evaluation, using the WHERE clause.
f2c04ccdad 2021-03-03  180: 
f2c04ccdad 2021-03-03  181: Why doesn't our rule TRIGSIMP(~X) => X defeat the other more specific
f2c04ccdad 2021-03-03  182: ones?  The reason is that rules inside a list are applied in the order
f2c04ccdad 2021-03-03  183: they are written, with the whole process immediately restarted
f2c04ccdad 2021-03-03  184: whenever any rule succeeds.  Thus the rule TRIGSIMP(X) = X, intended
f2c04ccdad 2021-03-03  185: to make the operator TRIGSIMP eventually evaporate, is tried only
f2c04ccdad 2021-03-03  186: after all of the genuine simplification rules have done all they can.
f2c04ccdad 2021-03-03  187: For such reasons we usually write rules for an operator in an order
f2c04ccdad 2021-03-03  188: which proceeds from the most specific to the most general cases.
f2c04ccdad 2021-03-03  189: Experimentation will reveal that TRIGSIMP will not simplify higher
f2c04ccdad 2021-03-03  190: powers of sine and cosine, such as COS(X)^4 + 2*COS(X)^2*SIN(X)^2 +
f2c04ccdad 2021-03-03  191: SIN(X)^4, and that TRIGSIMP will not necessarily work when there are
f2c04ccdad 2021-03-03  192: more than 6 terms.  This latter restriction is not fundamental but is
f2c04ccdad 2021-03-03  193: a practical one imposed to keep the combinatorial searching associated
f2c04ccdad 2021-03-03  194: with the current algorithm under reasonable control.  As an exercise,
f2c04ccdad 2021-03-03  195: see if you can generalize the rules sufficiently so that 5*COS(H)^2 +
f2c04ccdad 2021-03-03  196: 6*SIN(H)^2 simplifies to 5 + SIN(H)^2 or to 6 - COS(H)^2.;
f2c04ccdad 2021-03-03  197: 
f2c04ccdad 2021-03-03  198: pause;
f2c04ccdad 2021-03-03  199: 
f2c04ccdad 2021-03-03  200: COMMENT Rules do not need to have free variables.  For example, we
f2c04ccdad 2021-03-03  201: could introduce the simplification rule to replace all subsequent
f2c04ccdad 2021-03-03  202: instances of M*C^2 by ENERGY:;
f2c04ccdad 2021-03-03  203: 
f2c04ccdad 2021-03-03  204: clear m, c, energy;
f2c04ccdad 2021-03-03  205: g1 := (3*m^2*c^2 + m*c^3 + c^2 + m + m*c + m1*c1^2)
f2c04ccdad 2021-03-03  206:               where m*c^2 => energy;
f2c04ccdad 2021-03-03  207: pause;
f2c04ccdad 2021-03-03  208: 
f2c04ccdad 2021-03-03  209: COMMENT Suppose that instead we wish to replace M by ENERGY/C^2:;
f2c04ccdad 2021-03-03  210: 
f2c04ccdad 2021-03-03  211: g1 where m => energy/c^2;
f2c04ccdad 2021-03-03  212: 
f2c04ccdad 2021-03-03  213: COMMENT You may wonder how a rule of the trivial form 
f2c04ccdad 2021-03-03  214: "indeterminate => ..." differs from the corresponding assignment 
f2c04ccdad 2021-03-03  215: "indeterminate := ...".  The difference is this:
f2c04ccdad 2021-03-03  216: 
f2c04ccdad 2021-03-03  217:    1.  The LET rule does not replace any contained bound
f2c04ccdad 2021-03-03  218:        variables with their values until the rule is actually used for
f2c04ccdad 2021-03-03  219:        a replacement.
f2c04ccdad 2021-03-03  220:    2.  The LET rule performs the evaluation of any contained bound
f2c04ccdad 2021-03-03  221:        variables every time the rule is used.
f2c04ccdad 2021-03-03  222: 
f2c04ccdad 2021-03-03  223: Thus, the rule "X => X + 1" would cause infinite recursion at the
f2c04ccdad 2021-03-03  224: first subsequent occurrence of X, as would the pair of rules "{X => Y,
f2c04ccdad 2021-03-03  225: Y => X}".  (Try it! -- After the lesson.)  To illustrate point 1
f2c04ccdad 2021-03-03  226: above, compare the following command sequence with the analogous
f2c04ccdad 2021-03-03  227: earlier one in lesson 2, which used assignments throughout:;
f2c04ccdad 2021-03-03  228: 
f2c04ccdad 2021-03-03  229: clear e1, f;
f2c04ccdad 2021-03-03  230: e2 := f;
f2c04ccdad 2021-03-03  231: let f1 => e1 + e2;
f2c04ccdad 2021-03-03  232: f1;
f2c04ccdad 2021-03-03  233: e2 := g;
f2c04ccdad 2021-03-03  234: f1;
f2c04ccdad 2021-03-03  235: pause;
f2c04ccdad 2021-03-03  236: 
f2c04ccdad 2021-03-03  237: COMMENT For a subsequent example, we need to replace E^(I*X) by
f2c04ccdad 2021-03-03  238: COS(X)^2 + I*SIN(X)^2 for all X.  See if you can successfully
f2c04ccdad 2021-03-03  239: introduce this rule.  (Without it, the following code will not work
f2c04ccdad 2021-03-03  240: correctly!);
f2c04ccdad 2021-03-03  241: 
f2c04ccdad 2021-03-03  242: pause;
f2c04ccdad 2021-03-03  243: e^i;
f2c04ccdad 2021-03-03  244: 
f2c04ccdad 2021-03-03  245: COMMENT REDUCE does not match I as an instance of the pattern I*X with
f2c04ccdad 2021-03-03  246: X = 1, so if you neglected to include a rule for this degenerate case,
f2c04ccdad 2021-03-03  247: do so now.;
f2c04ccdad 2021-03-03  248: 
f2c04ccdad 2021-03-03  249: pause;
f2c04ccdad 2021-03-03  250: clear x, n, nminusone;
f2c04ccdad 2021-03-03  251: zero := e^(n*i*x) - e^(nminusone*i*x)*e^(i*x);
f2c04ccdad 2021-03-03  252: realzero := sub(i=0, zero);
f2c04ccdad 2021-03-03  253: imagzero := sub(i=0, -i*zero);
f2c04ccdad 2021-03-03  254: 
f2c04ccdad 2021-03-03  255: COMMENT Regarding the last two assignments as equations, we can solve
f2c04ccdad 2021-03-03  256: them to get recurrence relations defining SIN(N*X) and COS(N*X) in
f2c04ccdad 2021-03-03  257: terms of angles having lower multiplicity.
f2c04ccdad 2021-03-03  258: 
f2c04ccdad 2021-03-03  259: Can you figure out why I didn't use N-1 rather than NMINUSONE above?
f2c04ccdad 2021-03-03  260: 
f2c04ccdad 2021-03-03  261: Can you devise a similar technique to derive the angle-sum identities
f2c04ccdad 2021-03-03  262: that we previously implemented?;
f2c04ccdad 2021-03-03  263: 
f2c04ccdad 2021-03-03  264: pause;
f2c04ccdad 2021-03-03  265: 
f2c04ccdad 2021-03-03  266: COMMENT To implement a set of trigonometric multiple-angle expansion
f2c04ccdad 2021-03-03  267: rules, we need to match the patterns SIN(N*X) and COS(N*X) only when N
f2c04ccdad 2021-03-03  268: is an integer exceeding 1.  We can implement one of the necessary
f2c04ccdad 2021-03-03  269: rules as follows:;
f2c04ccdad 2021-03-03  270: 
f2c04ccdad 2021-03-03  271:    cos(~n*~x) => cos(x)*cos((n-1)*x) - sin(x)*sin((n-1)*x)
f2c04ccdad 2021-03-03  272:              when fixp n and n>1;
f2c04ccdad 2021-03-03  273: 
f2c04ccdad 2021-03-03  274: COMMENT Note:
f2c04ccdad 2021-03-03  275: 
f2c04ccdad 2021-03-03  276:    1.  In a conditional rule, any dummy variables should appear in the
f2c04ccdad 2021-03-03  277:        left-hand side of the replacement with a tilde.
f2c04ccdad 2021-03-03  278:    2.  FIXP, standing for FIX Predicate, is a built-in function which
f2c04ccdad 2021-03-03  279:        yields true if and only if its argument is an integer.  Other
f2c04ccdad 2021-03-03  280:        useful predicates are NUMBERP, which is true if its argument
f2c04ccdad 2021-03-03  281:        represents a numeric value, that is an integer, a rational
f2c04ccdad 2021-03-03  282:        number or a rounded (floating point) number, and EVENP, which
f2c04ccdad 2021-03-03  283:        is true if its argument is an integer multiple of 2.
f2c04ccdad 2021-03-03  284:    3.  Arbitrarily-complicated true-false conditions can be composed
f2c04ccdad 2021-03-03  285:        using the relational operators =, NEQ, <, >, <=, >=, together
f2c04ccdad 2021-03-03  286:        with the logical operators "AND", "OR", "NOT".
f2c04ccdad 2021-03-03  287:    4.  The operators < , >, <=, and >= work only when both sides are
f2c04ccdad 2021-03-03  288:        numbers.
f2c04ccdad 2021-03-03  289:    5.  The relational operators have higher precedence than "NOT",
f2c04ccdad 2021-03-03  290:        which has higher precedence than "AND", which has higher
f2c04ccdad 2021-03-03  291:        precedence than "OR".
f2c04ccdad 2021-03-03  292:    6.  In a sequence of expressions joined by "AND" operators, testing
f2c04ccdad 2021-03-03  293:        is done left to right, and testing is discontinued after the
f2c04ccdad 2021-03-03  294:        first item which is false.
f2c04ccdad 2021-03-03  295:    7.  In a sequence of expressions joined by "OR" operators, testing
f2c04ccdad 2021-03-03  296:        is done left to right, and testing is discontinued after the
f2c04ccdad 2021-03-03  297:        first item which is true.
f2c04ccdad 2021-03-03  298:    8.  We didn't actually need the "AND N>1" part in the above rule.
f2c04ccdad 2021-03-03  299:        Can you guess why?
f2c04ccdad 2021-03-03  300: 
f2c04ccdad 2021-03-03  301: Your mission is to complete the set of multiple-angle rules and to
f2c04ccdad 2021-03-03  302: test them on the example COS(4*X) + COS(X/3) + COS(F*X).;
f2c04ccdad 2021-03-03  303: 
f2c04ccdad 2021-03-03  304: pause;
f2c04ccdad 2021-03-03  305: 
f2c04ccdad 2021-03-03  306: COMMENT Now suppose that we wish to write a set of rules for doing
f2c04ccdad 2021-03-03  307: symbolic integration, such that expressions of the form
f2c04ccdad 2021-03-03  308: INTEGRATE(X^P, X) are replaced by X^(P+1)/(P+1) for arbitrary X and P,
f2c04ccdad 2021-03-03  309: provided P is independent of X.  This will of course be less complete
f2c04ccdad 2021-03-03  310: that the analytic integration package available with REDUCE, but for
f2c04ccdad 2021-03-03  311: specific classes of integrals it is often a reasonable way to do such
f2c04ccdad 2021-03-03  312: integration.  Noting that DF(P,X) is 0 if P is independent of X, we
f2c04ccdad 2021-03-03  313: can accomplish this as follows:;
f2c04ccdad 2021-03-03  314: 
f2c04ccdad 2021-03-03  315: operator integrate;
f2c04ccdad 2021-03-03  316: let integrate(~x^~p, x) => x^(p+1)/(p+1) when df(p, x) = 0;
f2c04ccdad 2021-03-03  317: integrate(f^5, f);
f2c04ccdad 2021-03-03  318: integrate(g^g, g);
f2c04ccdad 2021-03-03  319: integrate(f^g, f);
f2c04ccdad 2021-03-03  320: pause;
f2c04ccdad 2021-03-03  321: 
f2c04ccdad 2021-03-03  322: g1 := integrate(g*f^5, f) + integrate(f^5+f^g, f);
f2c04ccdad 2021-03-03  323: 
f2c04ccdad 2021-03-03  324: COMMENT The last example indicates that we must incorporate rules
f2c04ccdad 2021-03-03  325: which distribute integrals over sums and extract factors which are
f2c04ccdad 2021-03-03  326: independent of the second argument of INTEGRATE.  Can you think of
f2c04ccdad 2021-03-03  327: rules which accomplish this?  It is a good exercise, but this
f2c04ccdad 2021-03-03  328: particular pair of properties of INTEGRATE is so prevalent in
f2c04ccdad 2021-03-03  329: mathematics that operators with these properties are called linear,
f2c04ccdad 2021-03-03  330: and a corresponding declaration is built into REDUCE:;
f2c04ccdad 2021-03-03  331: 
f2c04ccdad 2021-03-03  332: linear integrate;
f2c04ccdad 2021-03-03  333: g1;
f2c04ccdad 2021-03-03  334: g1 := integrate(f+1, f) + integrate(1/f^5, f);
f2c04ccdad 2021-03-03  335: pause;
f2c04ccdad 2021-03-03  336: 
f2c04ccdad 2021-03-03  337: COMMENT We overcame one difficulty and uncovered 3 others.  Clearly
f2c04ccdad 2021-03-03  338: REDUCE does not consider F to match the pattern F^P as F^1, or 1 to
f2c04ccdad 2021-03-03  339: match the pattern as F^0, or 1/F^5 to match the pattern as F^(-1), but
f2c04ccdad 2021-03-03  340: we can add additional rules for such cases:;
f2c04ccdad 2021-03-03  341: 
f2c04ccdad 2021-03-03  342: let {
f2c04ccdad 2021-03-03  343:    integrate(1/~x^~p, x) => x^(1-p)/(1-p) when df(p, x) = 0,
f2c04ccdad 2021-03-03  344:    integrate(~x, x) => x^2/2,
f2c04ccdad 2021-03-03  345:    integrate(1, ~x) => x }$
f2c04ccdad 2021-03-03  346: g1;
f2c04ccdad 2021-03-03  347: 
f2c04ccdad 2021-03-03  348: COMMENT A remaining problem is that INTEGRATE(X^-1, X) will lead to
f2c04ccdad 2021-03-03  349: X^0/(-1+1), which simplifies to 1/0, which will cause a zero-divide
f2c04ccdad 2021-03-03  350: error message.  Consequently, we should also include the correct rule
f2c04ccdad 2021-03-03  351: for this special case:;
f2c04ccdad 2021-03-03  352: 
f2c04ccdad 2021-03-03  353: let integrate(~x^-1, x) => log(x);
f2c04ccdad 2021-03-03  354: integrate(1/x, x);
f2c04ccdad 2021-03-03  355: pause;
f2c04ccdad 2021-03-03  356:  
f2c04ccdad 2021-03-03  357: COMMENT We now collect the integration rules so far into one list
f2c04ccdad 2021-03-03  358: according to the law that within a rule set a more specific rule
f2c04ccdad 2021-03-03  359: should precede the more general one:;
f2c04ccdad 2021-03-03  360:  
f2c04ccdad 2021-03-03  361: integrate_rules := {
f2c04ccdad 2021-03-03  362:   integrate(1, ~x) => x,
f2c04ccdad 2021-03-03  363:   integrate(~x, x) => x^2/2,
f2c04ccdad 2021-03-03  364:   integrate(~x^-1, x) => log(x),
f2c04ccdad 2021-03-03  365:   integrate(1/~x^~p, x) => x^(1-p)/(1-p) when df(p, x) = 0,
f2c04ccdad 2021-03-03  366:   integrate(~x^~p, x) => x^(p+1)/(p+1) when df(p, x) = 0 }$
f2c04ccdad 2021-03-03  367: 
f2c04ccdad 2021-03-03  368: COMMENT Note that there are more elegant ways to match special cases
f2c04ccdad 2021-03-03  369: in which variables have the values 0 or 1 by using "double tilde
f2c04ccdad 2021-03-03  370: variables" -- see "Advanced use of rule lists" in section 11.3 of the
f2c04ccdad 2021-03-03  371: REDUCE User's Manual.
f2c04ccdad 2021-03-03  372: 
f2c04ccdad 2021-03-03  373: This is the end of lesson 3.  We leave it as an intriguing exercise to
f2c04ccdad 2021-03-03  374: extend this integrator.
f2c04ccdad 2021-03-03  375: 
f2c04ccdad 2021-03-03  376: ;end;

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