Lesson_3.red 14 KB

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