less3 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. COMMENT
  2. REDUCE INTERACTIVE LESSON NUMBER 3
  3. David R. Stoutemyer
  4. University of Hawaii
  5. COMMENT This is lesson 3 of 7 REDUCE lessons. Please refrain from
  6. using variables beginning with the letters F through H during the
  7. lesson.
  8. Mathematics is replete with many named elementary and not-so-
  9. elementary functions besides the set built into REDUCE such as SIN,
  10. COS, and LOG, and it is often convenient to utilize expressions
  11. containing a functional form such as f(x) to denote an unknown
  12. function or a class of functions. Functions are called operators in
  13. REDUCE, and by merely declaring their names as such, we are free to
  14. use them for functional forms. For example;
  15. OPERATOR F;
  16. G1 := F(F(COT(F)), F());
  17. COMMENT Note that
  18. 1. We can use the same name for both a variable and an operator.
  19. (However, this practice often leads to confusion.)
  20. 2. We can use the same operator for any number of arguments --
  21. including zero arguments such as for F().
  22. 3. We can assign values to specific instances of functional
  23. forms;
  24. PAUSE;
  25. COMMENT COT is one of the functions already defined in REDUCE
  26. together with a few of its properties. However, the user can augment
  27. or even override these definitions depending on the needs of a given
  28. problem. For example, if one wished to write COT(F) in terms of TAN,
  29. one could say;
  30. COT(F) := 1/TAN(F);
  31. G1 := G1 + COT(H+1);
  32. PAUSE;
  33. COMMENT Naturally, our assignment for COT(F) did not affect
  34. COT(H+1) in our example above. However, we can use a LET rule to
  35. make all cotangents automatically be replaced by the reciprocal of
  36. the corresponding tangents:;
  37. FOR ALL F LET COT(F) = 1/TAN(F);
  38. G1;
  39. COMMENT Any variable designated "FOR ALL" is a dummy variable which
  40. is distinct from any other previously or subsequently introduced
  41. indeterminate, variable, or dummy variable having the same name
  42. outside the rule.
  43. To clear a LET rule having dummy variables, the CLEAR command must
  44. employ the same dummy variables;
  45. FOR ALL F CLEAR COT(F);
  46. COT(G+5);
  47. PAUSE;
  48. COMMENT The arguments of a functional form on the left-hand side of a
  49. LET rule can be more complicated than mere indeterminates. For
  50. example, we may wish to inform REDUCE how to differentiate
  51. expressions involving SEC, which is not defined in the basic system;
  52. OPERATOR SEC;
  53. FOR ALL G1 LET
  54. DF(SEC(G1),G1) = SEC(G1)*TAN(G1);
  55. DF(3*SEC(F*G), G);
  56. COMMENT Also, REDUCE obviously knows the chain rule because otherwise we
  57. would have had to type
  58. FOR ALL Y,X LET DF(SEC(Y),X)=SEC(Y)*TAN(Y)*DF(Y,X);
  59. PAUSE;
  60. COMMENT As another example, suppose that we wish to employ the
  61. angle-sum identities for SIN and COS;
  62. FOR ALL X, Y LET
  63. SIN(X+Y) = SIN(X)*COS(Y) + SIN(Y)*COS(X),
  64. COS(X+Y) = COS(X)*COS(Y) - SIN(X)*SIN(Y);
  65. COS(5+F-G);
  66. COMMENT Note that:
  67. 1. LET can have any number of replacement rules separated by commas.
  68. 2. There was no need for rules with 3 or more addends, because
  69. the above rules were automatically employed recursively, with
  70. two of the three addends 5, F, and -G grouped together as one
  71. of the dummy variables the first time through.
  72. 3. Despite the subexpression F-G in our example, there was no
  73. need to make rules for the difference of two angles, because
  74. subexpressions of the form X-Y are treated as X+(-Y).
  75. 4. Built-in rules were employed to convert expressions of the
  76. form SIN(-X) or COS(-X) to -SIN(X) or COS(X) respectively.
  77. As an exercise, try to implement rules which transform the logarithms
  78. of products and quotients respectively to sums and differences of
  79. logarithms, while converting the logarithm of a power of a quantity to
  80. the power times the logarithm of the quantity; PAUSE;
  81. COMMENT Actually, the left-hand side of a LET rule also can be
  82. somewhat more general than a functional form. The left-hand side can
  83. be a power of an indeterminate or of a functional form, or the left-
  84. hand side can be a product of such powers and/or indeterminates or
  85. functional forms. For example, we can have the rule "FOR ALL X LET
  86. SIN(X)**2=1-COS(X)**2", or we can have the rule;
  87. FOR ALL X LET COS(X)**2 = 1 - SIN(X)**2;
  88. G1 := COS(F)**3 + COS(G);
  89. PAUSE;
  90. COMMENT Note that a replacement takes place wherever a left-hand side of
  91. a rule divides a term. With a rule replacing SIN(X)**2 and a rule
  92. replacing COS(X)**2 simultaneously in effect, an expression which uses
  93. either one will lead to an infinite recursion that eventually exhausts
  94. the available storage. (Try it if you wish -- after the lesson). We are
  95. also permitted to employ a more symmetric rule using a top level "+"
  96. provided that no free variables appear in the rule. However, a rule
  97. such as "FOR ALL X LET SIN(X)**2+COS(X)**2=1" is not permitted. We can
  98. get around the restriction against a top-level "+" on the left side
  99. though, at the minor nuisance of having to employ an operator whenever
  100. we want the rule applied to an expression:;
  101. FOR ALL X CLEAR COS(X)**2;
  102. OPERATOR TRIGSIMP;
  103. FOR ALL A, C, X LET
  104. TRIGSIMP(X) = X,
  105. TRIGSIMP(A*SIN(X)**2 + A*COS(X)**2 + C) = A + TRIGSIMP(C),
  106. TRIGSIMP(A*SIN(X)**2 + A*COS(X)**2) = A,
  107. TRIGSIMP(SIN(X)**2 + COS(X)**2 + C) = 1 + TRIGSIMP(C),
  108. TRIGSIMP(SIN(X)**2 + COS(X)**2) = 1;
  109. G1 := F*COS(G)**2 + F*SIN(G)**2 + G*SIN(G)**2 + G*COS(G)**2 + 5;
  110. G1 := TRIGSIMP(G1);
  111. PAUSE;
  112. COMMENT Why doesn't our rule TRIGSIMP(X)=X defeat the other more
  113. specific ones? The reason is that rules are applied in a
  114. last-in-first-applied order, with the whole process immediately
  115. restarted whenever any rule succeeds. Thus the rule TRIGSIMP(X)=X,
  116. intended to make the operator TRIGSIMP eventually evaporate, is tried
  117. only after all of the genuine simplification rules have done all that
  118. they can. For such reasons we usually write rules for an operator in
  119. an order which proceeds from the most general to the most specific
  120. cases. Experimentation will reveal that TRIGSIMP will not simplify
  121. higher powers of sine and cosine, such as COS(X)**4 +
  122. 2*COS(X)**2*SIN(X)**2 + SIN(X)**4, and that TRIGSIMP will not
  123. necessarily work when there are more than 6 terms. This latter
  124. restriction is not fundamental but is a practical one imposed to keep
  125. the combinatorial searching associated with the current algorithm
  126. under reasonable control. As an exercise, see if you can generalize
  127. the rules sufficiently so that 5*COS(H)**2+6*SIN(H)**2 simplifies to
  128. 5 + SIN(H)**2 or to 6-COS(H)**2;
  129. PAUSE;
  130. COMMENT LET rules do not need to have a "FOR ALL" prefix. For
  131. example, we could introduce the simplification rule "LET
  132. E**(I*PI)=-1". As another example, we might wish to replace all
  133. subsequent instances of M*C**2 by ENERGY;
  134. CLEAR M, C, ENERGY;
  135. LET M*C**2 = ENERGY;
  136. G1 := 3*M**2*C**2 + M*C**3 + C**2 + M + M*C + M1*C1**2;
  137. PAUSE;
  138. COMMENT Suppose that instead we wish to replace M by ENERGY/C**2:;
  139. CLEAR M*C**2;
  140. LET M = ENERGY/C**2;
  141. G1;
  142. COMMENT Without the CLEAR M*C**2, the subsequent statements would
  143. have produced an infinite recursion. You may wonder how a LET rule
  144. of the trivial form "LET indeterminate = ..." differs from the
  145. corresponding assignment "indeterminate := ...". The difference is
  146. 1. The LET rule does not replace any contained bound variables
  147. with their values until the rule is actually used for a
  148. replacement.
  149. 2. The LET rule performs the evaluation of any contained bound
  150. variables every time the rule is used.
  151. Thus, the rule "LET X = X + 1" would cause infinite recursion at the
  152. first subsequent occurrence of X, as would the pair of rules "LET X=Y"
  153. and "LET Y=X". (Try it! -- after the lesson.) To illustrate point 1
  154. above, compare the following sequence with the analogous earlier one in
  155. lesson 2 using assignments throughout;
  156. CLEAR E1, F;
  157. E2:= F;
  158. LET F1 = E1 + E2;
  159. F1;
  160. E2 := G;
  161. F1;
  162. PAUSE;
  163. COMMENT For a subsequent example, we need to replace E**(I*X) by
  164. COS(X)**2 + I*SIN(X)**2 for all X. See if you can successfully
  165. introduce this rule;
  166. PAUSE;
  167. E**I;
  168. COMMENT REDUCE does not match I as an instance of the pattern I*X
  169. with X=1, so if you neglected to include a rule for this degenerate
  170. case, do so now;
  171. PAUSE;
  172. CLEAR X, N, NMINUS1;
  173. ZERO := E**(N*I*X) - E**(NMINUS1*I*X)*E**(I*X);
  174. REALZERO := SUB(I=0, ZERO);
  175. IMAGZERO := SUB(I=0, -I*ZERO);
  176. COMMENT Regarding the last two assignments as equations, we can solve
  177. them to get recurrence relations defining SIN(N*X) and COS(N*X) in
  178. terms of angles having lower multiplicity.
  179. Can you figure out why I didn't use N-1 rather than NMINUS1 above?
  180. Can you devise a similar technique to derive the angle-sum identities
  181. that we previously implemented?;
  182. PAUSE;
  183. COMMENT To implement a set of trigonometric multiple-angle expansion
  184. rules, we need to match the patterns SIN(N*X) and COS(N*X) only when N
  185. is an integer exceeding 1. We can implement one of the necessary rules
  186. as follows;
  187. FOR ALL N,X SUCH THAT NUMBERP N AND N>1
  188. LET COS(N*X) = COS(X)*COS((N-1)*X) - SIN(X)*SIN((N-1)*X);
  189. COMMENT Note:
  190. 1. In a conditional LET statement, any dummy variables should
  191. appear in the preceding FOR ALL clause.
  192. 2. NUMBERP, standing for NUMBER Predicate, is a built-in function
  193. which yields true if and only if its argument is an integer or
  194. a floating-point number. In lesson 6 we will learn how to
  195. write such a function exclusively for integers, so until then
  196. our multiple-angle rules should not be used under the
  197. influence of ON FLOAT.
  198. 3. Arbitrarily-complicated true-false conditions can be composed
  199. using the relational operators =, NEQ, <, >, <=, >=, together
  200. with the logical operators "AND", "OR", "NOT".
  201. 4. Operators < and > work only when both sides are integers or
  202. floating-point numbers. Moreover, = together with NEQ check
  203. only whether or not the two sides appear identical under the
  204. influence of whatever rules and computational flags are in
  205. effect. For example, (X-1)/(X+1)=(X**2-2*X+1)/(X**2-1) will
  206. yield false under the influence of OFF GCD. Operator <=
  207. works only in circumstances where < or = would work, and
  208. similarly for >=. Consequently, it is usually advisable to
  209. compare the difference in two expressions with 0, which forces
  210. a certain amount of algebraic simplification.
  211. 5. The relational operators have higher precedence than "NOT",
  212. which has higher precedence than "AND", which has higher
  213. precedence than "OR".
  214. 6. In a sequence of items joined by "AND" operators, testing is
  215. done left to right, and testing is discontinued after the
  216. first item which is false.
  217. 7. In a sequence of items joined by "OR" operators, testing is
  218. done left to right, and testing is discontinued after the
  219. first item which is true.
  220. 8. We didn't actually need the "AND N>1" part in the above rule
  221. Can you guess why?
  222. Your mission is to complete the set of multiple-angle rules and to
  223. test them on the example COS(4*X) + COS(X/3) + COS(F*X);
  224. PAUSE;
  225. COMMENT Now suppose that we wish to write a set of rules for doing
  226. symbolic integration, such that expressions of the form
  227. INTEGRATE(X**P,X) are replaced by X**(P+1)/(P+1) for arbitrary X and
  228. P, provided P is independent of X. This will of course be less
  229. complete that the analytic integration package available with REDUCE,
  230. but for specific classes of integrals it is often a reasonable way to
  231. do such integration. Noting that DF(P,X) is 0 if P is independent of
  232. X, we can accomplish this as follows;
  233. OPERATOR INTEGRATE;
  234. FOR ALL P,X SUCH THAT DF(P,X)=0
  235. LET INTEGRATE(X**P,X) = X**(P+1)/(P+1);
  236. INTEGRATE(F**5,F);
  237. INTEGRATE(G**G, G);
  238. INTEGRATE(F**G,F);
  239. G1 := INTEGRATE(G*F**5,F) + INTEGRATE(F**5+F**G,F);
  240. COMMENT The last example indicates that we must incorporate rules
  241. which distribute integrals over sums and extract factors which are
  242. independent of the second argument of INTEGRATE. Can you think of LET
  243. rules which accomplish this? It is a good exercise, but this
  244. particular pair of properties of INTEGRATE is so prevalent in
  245. mathematics that operators with these properties are called linear,
  246. and a corresponding declaration is built into REDUCE;
  247. LINEAR INTEGRATE;
  248. G1;
  249. G1:= INTEGRATE(F+1,F) + INTEGRATE(1/F**5,F);
  250. PAUSE;
  251. COMMENT We overcame one difficulty and uncovered 3 others. Clearly
  252. REDUCE does not regard F to match the pattern F**P as F**1, or 1 to
  253. match the pattern as F**0, or 1/F**5 to match the pattern as F**(-1),
  254. so we can add additional rules for such cases;
  255. FOR ALL P,X SUCH THAT DF(P,X)=0
  256. LET INTEGRATE(1/X**P,X) = X**(1-P)/(1-P);
  257. FOR ALL X LET
  258. INTEGRATE(X,X) = X**2/2,
  259. INTEGRATE(1,X) = X;
  260. G1;
  261. COMMENT A remaining problem is that INTEGRATE(X**-1,X) will lead to
  262. X**0/(-1+1), which simplifies to 1/0, which will cause a zero-divide
  263. error message. Consequently, we should also include the correct rule
  264. for this special case;
  265. FOR ALL X LET INTEGRATE(X**-1,X) = LOG(X);
  266. INTEGRATE(1/X,X);
  267. COMMENT This is the end of lesson 3. We leave it as an intriguing
  268. exercise to extend this integrator.
  269. ;END;