123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- COMMENT
- REDUCE INTERACTIVE LESSON NUMBER 3
- David R. Stoutemyer
- University of Hawaii
- COMMENT This is lesson 3 of 7 REDUCE lessons. Please refrain from
- using variables beginning with the letters F through H during the
- lesson.
- Mathematics is replete with many named elementary and not-so-
- elementary functions besides the set built into REDUCE such as SIN,
- COS, and LOG, and it is often convenient to utilize expressions
- containing a functional form such as f(x) to denote an unknown
- function or a class of functions. Functions are called operators in
- REDUCE, and by merely declaring their names as such, we are free to
- use them for functional forms. For example;
- OPERATOR F;
- G1 := F(F(COT(F)), F());
- COMMENT Note that
- 1. We can use the same name for both a variable and an operator.
- (However, this practice often leads to confusion.)
- 2. We can use the same operator for any number of arguments --
- including zero arguments such as for F().
- 3. We can assign values to specific instances of functional
- forms;
- PAUSE;
- COMMENT COT is one of the functions already defined in REDUCE
- together with a few of its properties. However, the user can augment
- or even override these definitions depending on the needs of a given
- problem. For example, if one wished to write COT(F) in terms of TAN,
- one could say;
- COT(F) := 1/TAN(F);
- G1 := G1 + COT(H+1);
- PAUSE;
- COMMENT Naturally, our assignment for COT(F) did not affect
- COT(H+1) in our example above. However, we can use a LET rule to
- make all cotangents automatically be replaced by the reciprocal of
- the corresponding tangents:;
- FOR ALL F LET COT(F) = 1/TAN(F);
- G1;
- COMMENT Any variable designated "FOR ALL" is a dummy variable which
- is distinct from any other previously or subsequently introduced
- indeterminate, variable, or dummy variable having the same name
- outside the rule.
- To clear a LET rule having dummy variables, the CLEAR command must
- employ the same dummy variables;
- FOR ALL F CLEAR COT(F);
- COT(G+5);
- PAUSE;
- COMMENT The arguments of a functional form on the left-hand side of a
- LET rule can be more complicated than mere indeterminates. For
- example, we may wish to inform REDUCE how to differentiate
- expressions involving SEC, which is not defined in the basic system;
- OPERATOR SEC;
- FOR ALL G1 LET
- DF(SEC(G1),G1) = SEC(G1)*TAN(G1);
- DF(3*SEC(F*G), G);
- COMMENT Also, REDUCE obviously knows the chain rule because otherwise we
- would have had to type
- FOR ALL Y,X LET DF(SEC(Y),X)=SEC(Y)*TAN(Y)*DF(Y,X);
- PAUSE;
- COMMENT As another example, suppose that we wish to employ the
- angle-sum identities for SIN and COS;
- FOR ALL X, Y LET
- SIN(X+Y) = SIN(X)*COS(Y) + SIN(Y)*COS(X),
- COS(X+Y) = COS(X)*COS(Y) - SIN(X)*SIN(Y);
- COS(5+F-G);
- COMMENT Note that:
- 1. LET can have any number of replacement rules separated by commas.
- 2. There was no need for rules with 3 or more addends, because
- the above rules were automatically employed recursively, with
- two of the three addends 5, F, and -G grouped together as one
- of the dummy variables the first time through.
- 3. Despite the subexpression F-G in our example, there was no
- need to make rules for the difference of two angles, because
- subexpressions of the form X-Y are treated as X+(-Y).
- 4. Built-in rules were employed to convert expressions of the
- form SIN(-X) or COS(-X) to -SIN(X) or COS(X) respectively.
- As an exercise, try to implement rules which transform the logarithms
- of products and quotients respectively to sums and differences of
- logarithms, while converting the logarithm of a power of a quantity to
- the power times the logarithm of the quantity; PAUSE;
- COMMENT Actually, the left-hand side of a LET rule also can be
- somewhat more general than a functional form. The left-hand side can
- be a power of an indeterminate or of a functional form, or the left-
- hand side can be a product of such powers and/or indeterminates or
- functional forms. For example, we can have the rule "FOR ALL X LET
- SIN(X)**2=1-COS(X)**2", or we can have the rule;
- FOR ALL X LET COS(X)**2 = 1 - SIN(X)**2;
- G1 := COS(F)**3 + COS(G);
- PAUSE;
- COMMENT Note that a replacement takes place wherever a left-hand side of
- a rule divides a term. With a rule replacing SIN(X)**2 and a rule
- replacing COS(X)**2 simultaneously in effect, an expression which uses
- either one will lead to an infinite recursion that eventually exhausts
- the available storage. (Try it if you wish -- after the lesson). We are
- also permitted to employ a more symmetric rule using a top level "+"
- provided that no free variables appear in the rule. However, a rule
- such as "FOR ALL X LET SIN(X)**2+COS(X)**2=1" is not permitted. We can
- get around the restriction against a top-level "+" on the left side
- though, at the minor nuisance of having to employ an operator whenever
- we want the rule applied to an expression:;
- FOR ALL X CLEAR COS(X)**2;
- OPERATOR TRIGSIMP;
- FOR ALL A, C, X LET
- TRIGSIMP(X) = X,
- TRIGSIMP(A*SIN(X)**2 + A*COS(X)**2 + C) = A + TRIGSIMP(C),
- TRIGSIMP(A*SIN(X)**2 + A*COS(X)**2) = A,
- TRIGSIMP(SIN(X)**2 + COS(X)**2 + C) = 1 + TRIGSIMP(C),
- TRIGSIMP(SIN(X)**2 + COS(X)**2) = 1;
- G1 := F*COS(G)**2 + F*SIN(G)**2 + G*SIN(G)**2 + G*COS(G)**2 + 5;
- G1 := TRIGSIMP(G1);
- PAUSE;
- COMMENT Why doesn't our rule TRIGSIMP(X)=X defeat the other more
- specific ones? The reason is that rules are applied in a
- last-in-first-applied order, with the whole process immediately
- restarted whenever any rule succeeds. Thus the rule TRIGSIMP(X)=X,
- intended to make the operator TRIGSIMP eventually evaporate, is tried
- only after all of the genuine simplification rules have done all that
- they can. For such reasons we usually write rules for an operator in
- an order which proceeds from the most general to the most specific
- cases. Experimentation will reveal that TRIGSIMP will not simplify
- higher powers of sine and cosine, such as COS(X)**4 +
- 2*COS(X)**2*SIN(X)**2 + SIN(X)**4, and that TRIGSIMP will not
- necessarily work when there are more than 6 terms. This latter
- restriction is not fundamental but is a practical one imposed to keep
- the combinatorial searching associated with the current algorithm
- under reasonable control. As an exercise, see if you can generalize
- the rules sufficiently so that 5*COS(H)**2+6*SIN(H)**2 simplifies to
- 5 + SIN(H)**2 or to 6-COS(H)**2;
- PAUSE;
- COMMENT LET rules do not need to have a "FOR ALL" prefix. For
- example, we could introduce the simplification rule "LET
- E**(I*PI)=-1". As another example, we might wish to replace all
- subsequent instances of M*C**2 by ENERGY;
- CLEAR M, C, ENERGY;
- LET M*C**2 = ENERGY;
- G1 := 3*M**2*C**2 + M*C**3 + C**2 + M + M*C + M1*C1**2;
- PAUSE;
- COMMENT Suppose that instead we wish to replace M by ENERGY/C**2:;
- CLEAR M*C**2;
- LET M = ENERGY/C**2;
- G1;
- COMMENT Without the CLEAR M*C**2, the subsequent statements would
- have produced an infinite recursion. You may wonder how a LET rule
- of the trivial form "LET indeterminate = ..." differs from the
- corresponding assignment "indeterminate := ...". The difference is
- 1. The LET rule does not replace any contained bound variables
- with their values until the rule is actually used for a
- replacement.
- 2. The LET rule performs the evaluation of any contained bound
- variables every time the rule is used.
- Thus, the rule "LET X = X + 1" would cause infinite recursion at the
- first subsequent occurrence of X, as would the pair of rules "LET X=Y"
- and "LET Y=X". (Try it! -- after the lesson.) To illustrate point 1
- above, compare the following sequence with the analogous earlier one in
- lesson 2 using assignments throughout;
- CLEAR E1, F;
- E2:= F;
- LET F1 = E1 + E2;
- F1;
- E2 := G;
- F1;
- PAUSE;
- COMMENT For a subsequent example, we need to replace E**(I*X) by
- COS(X)**2 + I*SIN(X)**2 for all X. See if you can successfully
- introduce this rule;
- PAUSE;
- E**I;
- COMMENT REDUCE does not match I as an instance of the pattern I*X
- with X=1, so if you neglected to include a rule for this degenerate
- case, do so now;
- PAUSE;
- CLEAR X, N, NMINUS1;
- ZERO := E**(N*I*X) - E**(NMINUS1*I*X)*E**(I*X);
- REALZERO := SUB(I=0, ZERO);
- IMAGZERO := SUB(I=0, -I*ZERO);
- COMMENT Regarding the last two assignments as equations, we can solve
- them to get recurrence relations defining SIN(N*X) and COS(N*X) in
- terms of angles having lower multiplicity.
- Can you figure out why I didn't use N-1 rather than NMINUS1 above?
- Can you devise a similar technique to derive the angle-sum identities
- that we previously implemented?;
- PAUSE;
- COMMENT To implement a set of trigonometric multiple-angle expansion
- rules, we need to match the patterns SIN(N*X) and COS(N*X) only when N
- is an integer exceeding 1. We can implement one of the necessary rules
- as follows;
- FOR ALL N,X SUCH THAT NUMBERP N AND N>1
- LET COS(N*X) = COS(X)*COS((N-1)*X) - SIN(X)*SIN((N-1)*X);
- COMMENT Note:
- 1. In a conditional LET statement, any dummy variables should
- appear in the preceding FOR ALL clause.
- 2. NUMBERP, standing for NUMBER Predicate, is a built-in function
- which yields true if and only if its argument is an integer or
- a floating-point number. In lesson 6 we will learn how to
- write such a function exclusively for integers, so until then
- our multiple-angle rules should not be used under the
- influence of ON FLOAT.
- 3. Arbitrarily-complicated true-false conditions can be composed
- using the relational operators =, NEQ, <, >, <=, >=, together
- with the logical operators "AND", "OR", "NOT".
- 4. Operators < and > work only when both sides are integers or
- floating-point numbers. Moreover, = together with NEQ check
- only whether or not the two sides appear identical under the
- influence of whatever rules and computational flags are in
- effect. For example, (X-1)/(X+1)=(X**2-2*X+1)/(X**2-1) will
- yield false under the influence of OFF GCD. Operator <=
- works only in circumstances where < or = would work, and
- similarly for >=. Consequently, it is usually advisable to
- compare the difference in two expressions with 0, which forces
- a certain amount of algebraic simplification.
- 5. The relational operators have higher precedence than "NOT",
- which has higher precedence than "AND", which has higher
- precedence than "OR".
- 6. In a sequence of items joined by "AND" operators, testing is
- done left to right, and testing is discontinued after the
- first item which is false.
- 7. In a sequence of items joined by "OR" operators, testing is
- done left to right, and testing is discontinued after the
- first item which is true.
- 8. We didn't actually need the "AND N>1" part in the above rule
- Can you guess why?
- Your mission is to complete the set of multiple-angle rules and to
- test them on the example COS(4*X) + COS(X/3) + COS(F*X);
- PAUSE;
- COMMENT Now suppose that we wish to write a set of rules for doing
- symbolic integration, such that expressions of the form
- INTEGRATE(X**P,X) are replaced by X**(P+1)/(P+1) for arbitrary X and
- P, provided P is independent of X. This will of course be less
- complete that the analytic integration package available with REDUCE,
- but for specific classes of integrals it is often a reasonable way to
- do such integration. Noting that DF(P,X) is 0 if P is independent of
- X, we can accomplish this as follows;
- OPERATOR INTEGRATE;
- FOR ALL P,X SUCH THAT DF(P,X)=0
- LET INTEGRATE(X**P,X) = X**(P+1)/(P+1);
- INTEGRATE(F**5,F);
- INTEGRATE(G**G, G);
- INTEGRATE(F**G,F);
- G1 := INTEGRATE(G*F**5,F) + INTEGRATE(F**5+F**G,F);
- COMMENT The last example indicates that we must incorporate rules
- which distribute integrals over sums and extract factors which are
- independent of the second argument of INTEGRATE. Can you think of LET
- rules which accomplish this? It is a good exercise, but this
- particular pair of properties of INTEGRATE is so prevalent in
- mathematics that operators with these properties are called linear,
- and a corresponding declaration is built into REDUCE;
- LINEAR INTEGRATE;
- G1;
- G1:= INTEGRATE(F+1,F) + INTEGRATE(1/F**5,F);
- PAUSE;
- COMMENT We overcame one difficulty and uncovered 3 others. Clearly
- REDUCE does not regard F to match the pattern F**P as F**1, or 1 to
- match the pattern as F**0, or 1/F**5 to match the pattern as F**(-1),
- so we can add additional rules for such cases;
- FOR ALL P,X SUCH THAT DF(P,X)=0
- LET INTEGRATE(1/X**P,X) = X**(1-P)/(1-P);
- FOR ALL X LET
- INTEGRATE(X,X) = X**2/2,
- INTEGRATE(1,X) = X;
- G1;
- COMMENT A remaining problem is that INTEGRATE(X**-1,X) will lead to
- X**0/(-1+1), which simplifies to 1/0, which will cause a zero-divide
- error message. Consequently, we should also include the correct rule
- for this special case;
- FOR ALL X LET INTEGRATE(X**-1,X) = LOG(X);
- INTEGRATE(1/X,X);
- COMMENT This is the end of lesson 3. We leave it as an intriguing
- exercise to extend this integrator.
- ;END;
|