Lesson_5.red 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. COMMENT
  2. REDUCE INTERACTIVE LESSON NUMBER 5
  3. David R. Stoutemyer
  4. University of Hawaii
  5. COMMENT This is lesson 5 of 7 REDUCE lessons.
  6. There are at least two good reasons for wanting to save REDUCE
  7. expression assignments to a file:
  8. 1. So that one can logout, then resume computation at a later
  9. time.
  10. 2. So that needed main memory space can be cleared without
  11. irrecoverably losing the values of variables which are not
  12. needed in the next expression but will be needed later.
  13. Using trivial small expressions, the following statement sequence
  14. illustrates how this could be done:
  15. OFF NAT,
  16. OUT TEMP,
  17. F1 := (F + G)^2,
  18. G1 := G*F1,
  19. OUT T,
  20. CLEAR F1,
  21. H1 := H*G1,
  22. OUT TEMP,
  23. CLEAR G1,
  24. H2 := F*H1,
  25. CLEAR H1,
  26. SHUT TEMP,
  27. IN TEMP,
  28. F1,
  29. ON NAT,
  30. F1.
  31. ON NAT yields the natural output style with raised exponents, which is
  32. unsuitable for subsequent input.
  33. The OUT-statement causes subsequent output to be directed to the file
  34. named in the statement, until overridden by a different OUT-statement
  35. or until the file is closed by a SHUT-statement. File T is the
  36. terminal, and any other name designates a normal file. Such names
  37. must comply with the local file-naming conventions as well as with the
  38. REDUCE syntax. If the output is not of lasting importance, I find
  39. that including something like "TEMPORARY" or "SCRATCH" in the name
  40. helps remind me to delete it later.
  41. Successive OUT-statements to the same file will append rather than
  42. overwrite output if and only if there is no intervening SHUT-
  43. statement for that file. The SHUT-statement also has the effect of an
  44. implied OUT T.
  45. Note:
  46. 1. The generated output is the simplified expression rather than
  47. the raw form entered at the terminal.
  48. 2. Each output assignment automatically has a dollar-sign appended
  49. so that it is legal input and so that (perhaps lengthy) output
  50. will not unavoidably be generated at the terminal when the file
  51. is read in later.
  52. 3. Output cannot be sent simultaneously to 2 or more files.
  53. 4. Statements entered at the terminal which do not generate output
  54. -- such as declarations, LET rules, and procedure definitions
  55. -- do not appear in the output file.
  56. 5. One could get declarations, procedure definitions, rules, etc.
  57. written to a file from the terminal by typing statements such
  58. as
  59. WRITE "
  60. ALGEBRAIC PROCEDURE ...
  61. ... ".
  62. This could serve as a means of generating permanent copies of
  63. LET rules, procedures, etc., but it is quite awkward compared
  64. with the usual way, which is to generate a file containing the
  65. REDUCE program by using a text editor, then input the program
  66. by using the IN-statement. If you have refrained from learning
  67. to use a basic text editor (such as Windows Notepad), hesitate
  68. no longer. I suggest that your first text-editing exercise be
  69. to create an IN file for (re)defining the function
  70. FACTORIAL(n).
  71. 6. The reason I didn't actually execute the above statement
  72. sequence is that when the input to REDUCE comes from a file,
  73. both the input and output are sent to the output file (which is
  74. convenient for producing a file containing both the input and
  75. output of a demonstration.) Consequently, you would have seen
  76. none of the statements between the "OUT TEMP" and "OUT T" as
  77. well as between the second "OUT TEMP" and the "SHUT TEMP",
  78. until the IN-statement was executed. The example is confusing
  79. enough without having things scrambled from the order you would
  80. type them. To clarify all of this, I encourage you to actually
  81. execute the above statement sequence with an appropriately
  82. chosen file name and using semicolons instead of the commas and
  83. final period. Afterwards, to return to the lesson, type CONT.
  84. 7. It is often more natural to use a string (e.g. "less5.red")
  85. rather than an identifier (e.g. less5!.red) for a filename.
  86. REDUCE accepts both.;
  87. pause;
  88. COMMENT Suppose you and your colleagues developed or obtained a set of
  89. REDUCE files containing supplementary packages such as trigonometric
  90. simplification, Laplace transforms, etc. It would be a waste of time
  91. (and distracting) to have these files displayed every time they were
  92. input, so this output can be suppressed by inserting the statement
  93. "OFF ECHO" at the beginning of the file. (But don't forget to include
  94. the statement "ON ECHO" at the end of the file.)
  95. The lessons have amply demonstrated the PAUSE-statement, which is
  96. useful for insertion in input files at the top-level or within
  97. functions when input from the user is necessary or desired.
  98. It often happens that after generating an expression, one decides that
  99. it would be convenient to use it as the body of a function definition,
  100. with one or more of the indeterminates therein as parameters, which
  101. can be done as follows. (If you input code like this directly rather
  102. than from a file, you will need to agree to let REDUCE declare F to be
  103. an operator.);
  104. (1-(v/c)^2)^(1/2);
  105. for all v saveas f(v);
  106. f(5);
  107. COMMENT Here the indeterminate V became a parameter of F.
  108. Alternatively, we can save the previous expression to a variable.;
  109. saveas fof5;
  110. fof5;
  111. COMMENT I find this technique more convenient than referring to the
  112. special variable WS.;
  113. pause;
  114. COMMENT The FOR-loop provides a convenient way to form finite sums or
  115. products with specific integer index limits. However, this need is so
  116. ubiquitous that REDUCE provides even more convenient syntax of the
  117. forms
  118. FOR index := initial STEP increment UNTIL final SUM expression,
  119. FOR index := initial STEP increment UNTIL final PRODUCT expression.
  120. As before, ":" is an acceptable abbreviation for "STEP 1 UNTIL". As
  121. an example of their use, here is a very concise definition of a
  122. function which computes Taylor-series expansions of symbolic
  123. expressions:;
  124. algebraic procedure taylor(ex, x, pt, n);
  125. COMMENT This function returns the degree-N Taylor-series
  126. expansion of expression EX with respect to indeterminate X,
  127. expanded about expression PT. For a series-like appearance,
  128. display the answer under the influence of FACTOR X, ON RAT,
  129. and perhaps also ON DIV;
  130. sub(x=pt, ex) + for k:=1:n sum(sub(x=pt, df(ex,x,k))*(x-pt)^k
  131. / for j:=1:k product j);
  132. clear a, x; factor x; on rat, div;
  133. g1 := taylor(e^x, x, 0, 4);
  134. g2 := taylor(e^cos(x)*cos(sin(x)), x, 0, 3);
  135. % This illustrates the zero denominator limitation; continue anyway:
  136. taylor(log(x), x, 0, 4);
  137. COMMENT It would, of course, be more efficient to compute each
  138. derivative and factorial from the preceding one. (Similarly for
  139. (X-PT)^K if and only if PT NEQ 0).
  140. The Fourier series expansion of our example E^COS(X)*COS(SIN(X))
  141. is 1 + cos(x) + cos(2*x)/2 + cos(3*x)/(3*2) + ... .
  142. Use the above SUM and PRODUCT features to generate the partial sum of
  143. this series through terms of order COS(6*X);
  144. pause;
  145. COMMENT Closed-form solutions are often unobtainable for nontrivial
  146. problems, even using computer algebra. When this is the case,
  147. truncated symbolic series solutions are often worth trying before
  148. resorting to approximate numerical solutions.
  149. When we combine truncated series it is pointless (and worse yet,
  150. misleading) to retain terms of higher order than is justified by the
  151. constituents. For example, if we wish to multiply together the
  152. truncated series G1 and G2 generated above, there is no point in
  153. retaining terms higher than third degree in X. We can avoid even
  154. generating such terms as follows:;
  155. let x^4 = 0;
  156. g3 := g1*g2;
  157. COMMENT Replacing X^4 with 0 has the effect of also replacing all
  158. higher powers of X with 0. We could, of course, use our TAYLOR
  159. function to compute G3 directly, but differentiation is time consuming
  160. compared to truncated polynomial algebra. Moreover, our TAYLOR
  161. function requires a closed-form expression to begin with, whereas
  162. iterative techniques often permit us to construct symbolic series
  163. solutions even when we have no such closed form.
  164. Now consider the truncated series:;
  165. clear y; factor y;
  166. h1 := taylor(cos y, y, 0, 6);
  167. COMMENT Suppose we regard terms of order X^N in G1 as being comparable
  168. to terms of order Y^(2*N) in H1, and we want to form (G1*H1)^2. This
  169. can be done as follows:;
  170. let y^7 = 0;
  171. f1 := (g1*h1)^2;
  172. COMMENT Note however that any terms of the form C*X^M*Y^N with
  173. 2*M+N > 6 are inconsistent with the accuracy of the constituent
  174. series, and we have generated several such misleading terms by
  175. independently truncating powers of X and Y. To avoid generating such
  176. junk, we can specify that a term be replaced by 0 whenever a weighted
  177. sum of exponents of specified indeterminates and functional forms
  178. exceeds a specified weight level. In our example this is done as
  179. follows:;
  180. weight x=2, y=1;
  181. wtlevel 6;
  182. f1 := f1;
  183. COMMENT Variables not mentioned in a WEIGHT declaration have a weight
  184. of 0, and the default weight-level is 2.;
  185. pause;
  186. COMMENT Here is an example of how one might compute numerical
  187. approximations to the cosine function. (But note that REDUCE can
  188. already do this automatically!) One way is to provide a supplementary
  189. LET rule for numerical arguments. For example, since our TAYLOR
  190. function would reveal that the Taylor series for cos x is
  191. 1 - x^2/2! + x^4/4! - ...;
  192. for all x such that numberp x let abs(x) = x, abs(-x) = x;
  193. epsrecip := 1024$
  194. on rounded;
  195. while 1.0 + 1.0/epsrecip neq 1.0 do
  196. epsrecip := epsrecip + epsrecip;
  197. for all x such that numberp num x and numberp den x let cos x =
  198. begin COMMENT X is integer, real, or a rational number. This rule
  199. returns the Taylor-series approximation to COS X, truncated when
  200. the last included term is less than (1/EPSRECIP) of the returned
  201. answer. EPSRECIP is a global variable initialized to a value
  202. that is appropriate to the local floating-point precision.
  203. Arbitrarily larger values are justifiable when X is exact and
  204. ROUNDED is off. No angle reduction is performed, so this
  205. function is not recommended for ABS(X) >= about PI/2;
  206. integer k; scalar mxsq, term, ans;
  207. k := 1;
  208. mxsq := -x*x;
  209. term := mxsq/2;
  210. ans := term + 1;
  211. while abs(num term)*epsrecip*den(ans) - abs(num ans)*den(term) > 0 do
  212. << term := term*mxsq/k/(k+1);
  213. ans := term + ans;
  214. k := k+2 >>;
  215. return ans
  216. end;
  217. cos(f) + cos(1/2);
  218. off rounded;
  219. cos(1/2);
  220. COMMENT As an exercise, write a similar rule for the SIN or LOG, or
  221. replace the COS rule with an improved one which uses angle reduction
  222. so that angles outside a modest range are represented as equivalent
  223. angles within the range, before computing the Taylor series.;
  224. pause;
  225. COMMENT There is a REDUCE compiler, and you may wish to learn how to
  226. use it. However, even if rules such as the above ones are compiled,
  227. they will be slow compared to the implementation-dependent hand-coded
  228. ones used by most FORTRAN-like systems, so REDUCE provides a way to
  229. generate FORTRAN programs which can then be compiled and executed in a
  230. subsequent job step. This is useful when there is a lot of
  231. floating-point computation or when we wish to exploit an existing
  232. FORTRAN program. Suppose, for example, that we wish to utilize an
  233. existing FORTRAN subroutine which uses the Newton-Raphson iteration
  234. Xnew := Xold - SUB(X=Xold, F(X)/DF(F(X),X))
  235. to attempt an approximate solution to the equation F(X)=0. Most such
  236. subroutines require the user to provide a FORTRAN function or
  237. subroutine which, given Xold, returns F(X)/DF(F(X),X) evaluated at
  238. X=Xold. If F(X) is complicated, manual symbolic derivation of
  239. DF(F(X),X) is a tedious and error-prone process. We can get REDUCE to
  240. relieve us of this responsibility as is illustrated below for the
  241. trivial example F(X) = X*E^X - 1:
  242. ON FORT, ROUNDED,
  243. OUT FONDFFILE,
  244. WRITE " REAL FUNCTION FONDF(XOLD)",
  245. WRITE " REAL XOLD, F",
  246. F := XOLD*E^XOLD - 1.0,
  247. FONDF := F/DF(F,XOLD),
  248. WRITE " RETURN",
  249. WRITE " END",
  250. SHUT FONDFFILE.
  251. COMMENT Under the influence of ON FORT, the output generated by
  252. assignments is printed as valid FORTRAN assignment statements, using
  253. as many continuation lines as necessary up to the number specified by
  254. the global variable !*CARDNO, which is initially set to 20. The
  255. output generated by an expression which is not an assignment is a
  256. corresponding assignment to a variable named ANS. In either case,
  257. expressions which would otherwise exceed !*CARDNO continuation lines
  258. are evaluated piecewise, using ANS as an intermediate variable.
  259. Try executing the above statement sequence, using an appropriate
  260. filename and using semicolons instead of the commas and period at the
  261. end of the lines (only), then view the file after the lesson to see
  262. how it worked.;
  263. pause;
  264. off fort, rounded;
  265. COMMENT To make this technique usable by non-REDUCE programmers, we
  266. could write a more general REDUCE program which given merely the
  267. expression F by the user, outputs not only the function FONDF, but
  268. also any necessary job-control commands and an appropriate main
  269. program for calling the Newton-Raphson subroutine and printing the
  270. results.
  271. Sometimes it is desirable to modify or supplement the syntax of
  272. REDUCE. For example:
  273. 1. Electrical engineers may prefer to input J as the
  274. representation of (-1)^(1/2).
  275. 2. A user might prefer to input LOGE to denote natural
  276. logarithms. (Note that LN is already defined as a synonym for
  277. LOG.)
  278. 3. A user might prefer to use DERIV instead of DF to request
  279. differentiation.
  280. Such lexical macros can be established by the DEFINE declaration:;
  281. clear x, j;
  282. define j=i, loge=log, deriv=df;
  283. COMMENT Now watch!;
  284. g1 := sub(x=loge(j^3*x), deriv(x^2,x));
  285. COMMENT Each "equation" in a DEFINE declaration must be of the form
  286. "name = item", where each item is an expression, an operator, or a
  287. REDUCE-reserved word such as "FOR". Such replacements take place
  288. during the lexical scanning, before any evaluation, LET rules, or
  289. built-in simplification. Think of a good application for this
  290. facility, then try it.;
  291. pause;
  292. COMMENT When REDUCE is being run non-interactively, with input from a
  293. file rather than a terminal, it is preferable to have REDUCE make
  294. reasonable decisions and proceed when it encounters apparently
  295. undeclared operators, divisions by zero, etc. In interactive mode, it
  296. is preferable to pause and query the user. ON INT specifies the
  297. latter style, and OFF INT specifies the former. Under the influence
  298. of OFF INT, we can also have most error messages suppressed by
  299. specifying OFF MSG. This is sometimes useful when we expect abnormal
  300. conditions and do not want our output marred by the associated
  301. messages. INT is automatically turned off during input from a file in
  302. response to an IN-command from a terminal.;
  303. pause;
  304. COMMENT REDUCE provides a trace command for debugging, which employs
  305. the syntax
  306. TR functionname1, functionname2, ..., functionnameN.
  307. An analogous command named UNTR removes function names from trace
  308. status;
  309. pause;
  310. COMMENT REDUCE also provides an assignment-tracing command for
  311. debugging, which employs the syntax
  312. TRST functionname1, functionname2, ..., functionnameN.
  313. An analogous command named UNTRST removes functionnames from this
  314. status. All assignments in the designated functions are reported,
  315. except for assignments to array elements. Such functions must be
  316. uncompiled and must have a top-level BEGIN-block. To apply both TRST
  317. and TR to a function simultaneously, it is crucial to request them in
  318. that order, and it is necessary to relinquish the two kinds of tracing
  319. in the opposite order.;
  320. pause;
  321. COMMENT The REDUCE algebraic algorithms are written in a subset of
  322. REDUCE called RLISP. In turn, the more sophisticated features of
  323. RLISP are written in a small subset of RLISP, which is itself written
  324. in a simple dialect of LISP called Standard LISP.
  325. RLISP is ideal for implementing algebraic algorithms, but the RLISP
  326. environment is not most suitable for the routine use of these
  327. algorithms in the natural mathematical style of the preceding lessons.
  328. Accordingly, REDUCE is initially in a mode called ALGEBRAIC, which
  329. provides the user with the environment illustrated in the preceding
  330. lessons, while insulating him from accidental interaction with the
  331. numerous functions, global variables, etc. necessary for implementing
  332. the built-in algebra. In contrast, the underlying RLISP system
  333. together with all of the algebraic simplification algorithms written
  334. therein is called SYMBOLIC mode.
  335. As we have seen, algebraic-mode rules and procedures can be used to
  336. extend the built-in algebraic capabilities. However, some extensions
  337. can be accomplished most easily or efficiently by descending to
  338. SYMBOLIC mode.
  339. To make REDUCE operate in symbolic mode, we merely execute the top-
  340. level mode-declaration statement consisting of the word SYMBOLIC. We
  341. can subsequently switch back by executing the statement consisting of
  342. the word ALGEBRAIC.
  343. RLISP has the semantics of LISP with the syntax of our by-now-familiar
  344. algebraic-mode REDUCE, so RLISP provides a natural tool for many
  345. applications besides computer algebra, such as games, theorem-proving,
  346. natural-language translation, computer-aided instruction, and
  347. artificial intelligence in general. For this reason, it is possible
  348. to run RLISP without any of the symbolic-mode algebraic algorithms
  349. that are written in RLISP, and it is advisable to thus save space when
  350. the application does not involve computer algebra. (An RLISP system
  351. is a step in the process of building a complete REDUCE system, but is
  352. not distributed as an independent application, although one can be
  353. built from the source code available.)
  354. We have now discussed virtually every feature that is available in
  355. algebraic mode, so lesson 6 will deal solely with RLISP, and lesson 7
  356. will deal with communication between ALGEBRAIC and SYMBOLIC mode for
  357. mathematical purposes. However, I suggest that you proceed to those
  358. lessons only if and when:
  359. 1. You have consolidated and fully absorbed the information in
  360. lessons 1 through 5 by considerable practice beyond the
  361. exercises therein. (The exercises were intended to also
  362. suggest good related project ideas.)
  363. 2. You feel the need for a facility which you believe is
  364. impossible or quite awkward to implement solely in ALGEBRAIC
  365. mode.
  366. 3. You have read an introductory text about LISP, such as "A
  367. Concise Introduction to LISP" by David L. Matuszek, which is
  368. freely available at
  369. https://www.cis.upenn.edu/~matuszek/LispText/lisp.html.
  370. 4. You are familiar with the definition of Standard LISP, as
  371. described in the "Standard LISP Report" which was published in
  372. the October 1979 SIGPLAN Notices. [A copy is freely available
  373. via http://reduce-algebra.sourceforge.net/documentation.php.]
  374. Don't forget to view or print your newly generated FORTRAN file and to
  375. delete any temporary files created by this lesson.;
  376. ;end;