Comment: | icas-bundled (2020-03-13) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | descendants | master | trunk |
Files: | files | file ages | folders |
SHA3-256: |
f2c04ccdadaa02db6987161ce4382044 |
User & Date: | trnsz@pobox.com on 2021-03-03 07:48:17 |
Other Links: | manifest | tags |
2021-03-03
| ||
08:53:35 | Update documentation check-in: 0fe29732ce user: trnsz@pobox.com tags: master, trunk | |
07:48:17 | icas-bundled (2020-03-13) check-in: f2c04ccdad user: trnsz@pobox.com tags: master, trunk | |
Added .gitattributes version [4ad3c24f10].
> | 1 | *.red linguist-vendored |
Added .gitignore version [a7ffc6f8bf].
Added 10000_digits_of_Pi.red version [104b03fa1a].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | %%%%%%%%%%%%%%%%%%%%% % 10,000 DIGITS OF PI %%%%%%%%%%%%%%%%%%%%% % This file shows the power of iCAS % in computing PI to 10,000 digits % % NOTE WELL-- After computing % PI has finished, BE SURE to % scroll down to reset iCAS to % its standard settings (or else ALL % of your computations will be to % to 10,000 digits!) % % Use real arithmetic on rounded$ % Set precision to 10000 digits precision(10000)$ % Print Pi pi; % Set precision back to default (12) precision(12)$ % Restore precise arithmetic off rounded$ |
Added Algebra.red version [f655779106].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | %%%%%%%%%%%%%%%%%%%%% % ALGEBRA (SOLVE) %%%%%%%%%%%%%%%%%%%%% % Specify blue for echoed input color("Blue"); % Turn on fancy output fancy_output; % Turn input echo on on echo; % Solve quadratic equation solve(x^2+8x+15=0, x); % Solve for expression solve(a*log(sin(x+3))^2 - b, sin(x+3)); % Solve simultaneous equations solve({x+3y=7, y-x=1},{x,y}); % Solve a system with parameters solve({x=a*z+1, y=b*z},{z,x}); % Simplify expression ((((-r1*(1+k1))/(r2*(1+k2)))+((r1)/(r2)))/(((r1)/(r2)))); % Another solve example % Note the use of $ as the line termination % character to suppress output from % intermediate computations x1 := sqrt(h^2 + p1^2)$ x2 := sqrt((h/2)^2 + (p-p1)^2)$ x3 := x1 + x2$ dx := df(x3, p1)$ solve(dx, p1); % Suppose you are given the equation % x^2+x+1=0 and wish to determine the % value of x^3. The following simple % substitution achieves this. rule := solve(x^2+x+1=0,x)$ y := (x^3 where rule); % Then y=1, because % x^3=x*(x^2)=-x*(x+1)=-x^2-x=1. % Turn off echo off echo; |
Added Arbitrary_Precision.red version [f70b95dcaa].
> > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | %%%%%%%%%%%%%%%%%%%%% % ARBITRARY PRECISION %%%%%%%%%%%%%%%%%%%%% % Use real arithmetic on rounded$ % Set precision to 50 digits precision(50)$ % Print Pi pi; % Set precision back to default (12) precision(12)$ % Restore precise arithmetic off rounded$ |
Added Calculus.red version [b8b19fcbe2].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | %%%%%%%%%%%%%%%%%%%%% % CALCULUS %%%%%%%%%%%%%%%%%%%%% % Specify blue for echoed input color("Blue"); % Turn on fancy output fancy_output; % Turn input echo on on echo; % Differentiation % df/dx df(x^x,x); % Multivariate Differentiation % df/((dx)(dy^2)(dz)) df(x*exp(i*y)*log(z), x, 1, y, 2, z, 1); % Integration % indefinite integral with respect to x int(x^2 + x*sin(x), x); % SI(x) int(sin(x)/x,x); % Integral in interval [-oo, oo] int(exp(-x^2), x,-infinity,infinity); % Integral with logarithms int(log(log(x)),x); % Turn off echo off echo; |
Added GNUPLOT.red version [64ca1cbd55].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | ################################### # GNUPLOT PLOTTING ################################### # IMPORTANT: This file is for use in Plot # mode. reset unset title set label 1 "Kuen's Surface" at screen 0.6, 0.9 set output "Kuen's Surface" set label 1 font "frscript,25" set style line 3 linetype -1 linewidth 0.5 set pm3d depthorder hidden3d 3 set style fill transparent solid 0.65 border set palette set hidden3d set ticslevel 0 unset xtics unset ytics unset ztics unset border unset colorbox unset key set lmargin at screen 0.1 set bmargin at screen 0.1 set rmargin at screen 0.9 set tmargin at screen 0.9 set parametric set dummy u,v set urange [-4.5:4.5] set vrange [0.05:pi-0.05] set isosamples 51,51 set view 122, 357, 1.35, 1.08 a = 1.0 x(u,v) = 2.*a*(cos(u)+u*sin(u))*sin(v) / (1+u**2.*(sin(v))**2) y(u,v) = 2.*a*(sin(u)-u*cos(u))*sin(v) / (1+u**2.*(sin(v))**2) z(u,v) = a*log(tan(v/2.))+2.*cos(v)/(1+u**2.*(sin(v))**2) splot x(u,v), y(u,v), z(u,v) with pm3d reset unset surface set output "3D Log" set title "3D Log" set samples 30; set isosamples 30 set pm3d set style line 100 lt 5 lw 0.5 set pm3d hidden3d 100 set view 50,220 set xrange [-2:2] set yrange [-2:2] splot log(x*x*y*y) reset set title "Interlocking Torus" set output "3D Torus" set parametric set urange [-pi:pi] set vrange [-pi:pi] set isosamples 50,20 unset key unset xtics unset ytics unset ztics set border 0 set view 60, 30, 1.5, 0.9 set origin 0.0,-0.1 set size 0.9, 1.1 set colorbox vertical user origin 0.9, 0.15 size 0.02, 0.50 set format cb "%.1f" set pm3d depthorder splot cos(u)+.5*cos(u)*cos(v),sin(u)+.5*sin(u)*cos(v),.5*sin(v) with pm3d, 1+cos(u)+.5*cos(u)*cos(v),.5*sin(v),sin(u)+.5*sin(u)*cos(v) with pm3d reset unset surface set output "3D Cosh" set title "3D Cosh" set samples 30 set isosamples 30 set pm3d set style line 100 lt 5 lw 0.5 set pm3d hidden3d 100 set view 50,220 set xrange [-2:2] set yrange [-2:2] splot cosh(x)+cosh(y) reset unset surface set output "3D Exp" set title "3D Exp" set samples 30; set isosamples 30 set xrange [-2:2] set yrange [-2:2] set pm3d splot exp(-x*x)*exp(-y*y) reset unset surface set output "3D Sin" set title "3D Sin" set samples 30 set isosamples 30 set pm3d set style line 100 lt 5 lw 0.5 set pm3d hidden3d 100 set view 50,220 set xrange [-3:3] set yrange [-3:3] splot sin(x*x+y*y) # PM3D surfaces are not included in the calculation of hidden line removal. # However, you can approximate this by drawing the surface twice, # once "with pm3d" to produce the surface you want to show, and once # "with lines lt -2" to include the same surface in hidden3d calculations. # The "lt -2" makes the hidden3d copy of the surface invisible. # reset set hidden3d front set isosamples 25,25 set xyplane at 0 unset key set palette rgbformulae 31,-11,32 set style fill solid 0.5 set cbrange [-1:1] set title "Mixing pm3d surfaces with hidden-line plots" set output "Mixing pm3d surfaces with hidden-line plots" f(x,y) = sin(-sqrt((x+5)**2+(y-7)**2)*0.5) splot f(x,y) with pm3d, x*x-y*y with lines lt 1 lc rgb "#000000", f(x,y) with lines lt -2 notitle; |
Added Hypergeometry_and_MeijerG.red version [e56d65e361].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | %%%%%%%%%%%%%%%%%%%%% % HYPERGEOMETRY % & % MEIJERG %%%%%%%%%%%%%%%%%%%%% % Specify blue for echoed input color("Blue"); % Turn on fancy output fancy_output; % Turn input echo on on echo; % Load special functions 2 load_package specfn2$ % Load generalized hypergeometric package load_package ghyper$ % Hypergeometric function hypergeometric({1/2,1},{2},z); % Load meijerg package load_package meijerg$ % MeijerG function MeijerG({{}},{{5/4},1},x^2/2); % Turn off echo off echo; |
Added LICENSE version [a7ffc6f8bf].
Added Lesson_1.red version [ab530e162b].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | COMMENT REDUCE INTERACTIVE LESSON NUMBER 1 David R. Stoutemyer University of Hawaii COMMENT This is lesson 1 of 7 interactive lessons about the REDUCE system for computer symbolic mathematics. These lessons presume an acquaintance with elementary calculus, together with a previous exposure to some computer programming language. In REDUCE, any sequence of characters from the word "COMMENT" through the next semicolon or dollar-sign statement separator is an explanatory remark ignored by the system. In general, either separator signals the end of a statement, with the dollar sign suppressing any output that might otherwise automatically be produced by the statement. The typing of a carriage return initiates the immediate sequential execution of all statements which have been terminated on that line. When REDUCE is ready for more input, it will prompt you with a prompt number followed by a colon and a space at the left margin. Expressions can be formed using "^", "*", "/", "+", and "-" to indicate exponentiation, multiplication, division, addition, and subtraction or negation respectively. Assignments to variables can be done using the operator ":=". For example:; r2d2 := (987654321/15)^3; COMMENT The immediately preceding line, without a semicolon, is the computed output generated by the line with a semicolon which precedes it. Note that exact indefinite-precision rational arithmetic was used, in contrast to the limited-precision arithmetic of traditional programming languages. We can use the name R2D2 to represent its value in subsequent expressions such as; r2d2 := -r2d2/25 + 3*(13-5); COMMENT We could equally well write the name of this variable as R2D2, r2D2 or R2d2 since REDUCE is case-insensitive. Using this flexibility, in these lessons code discussed within the text will be written in upper case to make it stand out, but code to be actually executed by REDUCE will be written in lower case. Now I will give you an opportunity to try some analogous computations. To do so, type the letter n or N followed by a carriage return in response to the question "Cont?". (You could type y or Y if you wish to relinquish this opportunity, but I strongly recommend reinforced learning through active participation.) After trying an example or two, type the command "cont" (with any capitalization) terminated by a semicolon and carriage return when you wish to proceed with the rest of the lesson. To avoid interference with our examples, please don't assign anything to any variable names beginning with the letters E through I. To avoid lengthy delays, I recommend keeping all of your examples approximately as trivial as ours, saving your more ambitious experiments until after the lesson. If you happen to initiate a calculation requiring an undue amount of time to evaluate or display, you can abort that computation with an interrupt (Ctrl-C) to terminate REDUCE. Restart REDUCE, followed by the statement "in less1.red", followed by a semicolon and return, to restart the lesson at the beginning.; pause; COMMENT Now watch this example illustrating some more dramatic differences from traditional scientific programming systems:; e1 := 2*g + 3*g + h^3/h; COMMENT Note how we are allowed to use variables to which we have assigned no values! Note too how similar terms and similar factors are combined automatically. REDUCE also automatically expands products and powers of sums, together with placing expressions over common denominators, as illustrated by the examples:; e2 := e1*(f+g); e2 := e1^2; e1+1/e1; COMMENT Our last example also illustrates that there is no need to assign an expression if we do not plan to use its value later. Try some similar examples.; pause; COMMENT It is not always desirable to expand expressions over a common denominator, and we can use the OFF statement to turn off either or both computational switches which control these transformations. The switch named EXP controls EXPansion, and the switch named MCD controls the Making of Common Denominators; off exp, mcd; e2 := e1^2$ e2 := e2*(f+g) + 1/e1; COMMENT To turn these switches back on, we type:; on exp, mcd; COMMENT Try a few relevant examples with these switches turned off individually and jointly; pause; on exp; % Just in case you turned it off! COMMENT The "%" character is another way to introduce a comment that extends as far as the end of the line. Now consider the example:; e2 := (2*(f*h)^2 - f^2*g*h - (f*g)^2 - f*h^3 + f*h*g^2 - h^4 + g*h^3)/(f^2*h - f^2*g - f*h^2 + 2*f*g*h - f*g^2 - g*h^2 + g^2*h); COMMENT It is not obvious, but the numerator and denominator of this expression share a nontrivial common divisor which can be canceled. To make REDUCE automatically cancel greatest common divisors, we turn on the computational switch named GCD:; on gcd; e2; COMMENT The switch is not on by default because 1. It can consume a lot of time. 2. Often we know in advance the few places where a nontrivial GCD can occur in our problem. 3. Even without GCD cancellation, expansion and common denominators guarantee that any rational expression which is equivalent to zero simplifies to zero. 4. When the denominator is the greatest common divisor, such as for (X^2 - 2*X + 1)/(X - 1), REDUCE cancels the greatest common divisor even when GCD is OFF. 5. GCD cancellation sometimes makes expressions more complicated, such as with (F^10 - G^10)/(F^2 + F*G - 2*G^2). Try the examples mentioned in this comment, together with one or two other relevant ones.; pause; COMMENT Exact rational arithmetic can consume an alarming amount of computer time when the constituent integers have quite large magnitudes, and the results become awkward to interpret qualitatively. When this is the case and somewhat inexact numerical coefficients are acceptable, we can have the arithmetic done using floating point by turning on the computational switch ROUNDED. With this switch on, any non-integer rational numbers are approximated by floating-point numbers, and the result of any arithmetic operation is floating-point when any of its operands is floating point. For example:; on rounded; e1 := (12.3456789e3*f + 3*g)^2 + 1/2; COMMENT With ROUNDED off, any floating-point constants are automatically represented as explicit rational numbers:; off rounded; e1 := 12.35*g; pause; COMMENT A number of elementary functions, such as SIN, COS and LOG, are built into REDUCE. Moreover, the letter E represents the base of the natural logarithms, so the exponentiation operator enables us to represent the exponential function as well as fractional powers. For example:; e1:= sin(-f*g) + log(e) + (3*g^2*cos(-1))^(1/2); COMMENT What automatic simplifications can you identify in this example? Note that REDUCE never approximates the values of these functions, even for numerical arguments, and exact computations are generally impossible for non-trivial numerical arguments. Experimentally determine some other built-in simplifications for these functions.; pause; COMMENT Later you will learn how to introduce additional simplifications and additional functions. To compute numerical approximations for examples such as COS(1) simply turn on ROUNDED. Differentiation is also built-into REDUCE. For example, to differentiate E1 with respect to F:; e2 := df(e1,f); COMMENT To compute the second derivative of E2 with respect to G, we can type either DF(E2,G,2) or DF(E1,F,1,G,2) or DF(E1,F,G,2) or DF(E1,G,2,F,1) or; df(e1,g,2,f); COMMENT Surely you can't resist trying a few derivatives of your own! (Careful, high-order derivatives can be alarmingly complicated.); pause; COMMENT REDUCE uses the name I to represent (-1)^(1/2), incorporating some simplification rules such as replacing I^2 by -1. Here is an opportunity to experimentally determine other simplifications such as for I^3, 1/I^23, and (I^2-1)/(I-1).; pause; COMMENT Clearly it is inadvisable to use E or I as a variable. T is also inadvisable for reasons that will become clear later. The value of a variable is said to be "bound" to the variable. Any variable to which we have assigned a value is called a bound variable, and any variable to which we have not assigned a value is called an indeterminate. Occasionally it is desirable to make a bound variable into an indeterminate, and this can be done using the CLEAR command. For example:; clear r2d2, e1, e2; e2; COMMENT If you suspect that a degenerate assignment, such as E1:=E1, would suffice to clear a bound variable, try it on one of your own bound variables.; pause; COMMENT REDUCE also supports matrix algebra, as illustrated by the following:; matrix e1(4,1), f; e1; f; COMMENT This declaration establishes E1 as a matrix with 4 rows and 1 column, while establishing F as a matrix of unspecified size. To establish element values (and sizes if not already established in the MATRIX declaration), we can use the MAT function, as illustrated by the following example:; h := mat((log(g), g+3), (g, 5/7)); COMMENT Only after establishing the size of a matrix by declaring it or executing a matrix assignment can we refer to an individual element or to the matrix as a whole. For example to increase the last element of H by 1 then form twice the transpose of H, we can type:; h(2,2) := h(2,2) + 1; 2*tp(h); COMMENT To compute the determinant of H:; det(h); COMMENT To compute the trace of H:; trace(h); COMMENT To compute the inverse of H, we can use H^(-1) or 1/H. To compute the solution to the equation H*F = MAT((G),(2)), we can left-multiply the right-hand side by the inverse of H:; f := 1/h*mat((g),(2)); COMMENT Notes: 1. MAT((G),(2))/H would denote right-multiplication by the inverse, which is not what we want. 2. Solutions for a set of right-hand-side vectors are most efficiently computed simultaneously by collecting the right- hand sides together as the columns of a single multiple-column matrix. 3. Sub-expressions of the form 1/H*... or H^(-1)*... are computed more efficiently than if the inverse is computed separately in a previous statement, so separate computation of the inverse is advisable only if several solutions are desired and if they cannot be computed simultaneously. 4. MAT must have parentheses around each row of elements even if there is only one row or only one element per row. 5. References to individual matrix elements must have exactly two subscripts, even if the matrix has only one row or one column. Congratulations on completing lesson 1! I urge you to try a sequence of more ambitious examples for the various features that have been introduced, in order to gain some familiarity with the relationship between problem size and computing time for various operations. (The command "ON TIME" causes computing time to be output.) I also urge you to bring to the next lesson appropriate examples from textbooks, articles, or elsewhere, in order to experience the decisive learning reinforcement afforded by meaningful personal examples that are not arbitrarily contrived. To avoid the possibility of interference from assignments and declarations in lesson 1, it is wise to execute lesson 2 in a fresh REDUCE session, when you are ready. ;end; |
Added Lesson_2.red version [9c93fa0638].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | COMMENT REDUCE INTERACTIVE LESSON NUMBER 2 David R. Stoutemyer University of Hawaii COMMENT This is lesson 2 of 7 REDUCE lessons. Please refrain from using variables beginning with the letters F through H during the lesson. By now you have probably had the experience of generating an expression, and then having to repeat the calculation because you forgot to assign it to a variable or because you did not expect to want to use it later. REDUCE maintains a history of all inputs and computation during an interactive session. (Note, this is only for interactive sessions.) To use an input expression in a new computation, you can say INPUT(n) where n is the appropriate command number. The evaluated computations can be accessed through WS(n) or simply WS if you wish to refer to the last computation. WS stands for Work Space. As with all REDUCE expressions, these can also be used to create new expressions, e.g.: (INPUT(n1)/WS(n2))^2 Special characters can be used to make unique REDUCE variable names that reduce the chance of accidental interference with any other variables. In general, whenever you want to include an otherwise forbidden character such as * in a name, merely precede it by an exclamation point, which is called the escape character. However, pick a character other than "*", which is used for many internal REDUCE names. Otherwise, if most of us use "*" the purpose will be defeated.; g + !%h; ws; pause; COMMENT You can also name the expression in the workspace by using the command SAVEAS, for example:; saveas gplush; gplush; pause; COMMENT You may have noticed that REDUCE imposes its own order on the indeterminates and functional forms that appear in results, and that this ordering can strongly affect the intelligibility of the results. For example:; g1 := 2*h*g + e + f1 + f + f^2 + f2 + 5 + log(f1) + sin(f1); COMMENT The ORDER declaration permits us to order indeterminates and functional forms as we choose. For example, to order F2 before F1, and to order F1 before all remaining variables:; order f2, f1; g1; pause; COMMENT Now suppose we partially change our mind and decide to order LOG(F1) ahead of F1; order log(f1), f1; g1; COMMENT Note that any other indeterminates or functional forms under the influence of a previous ORDER declaration, such as F2, rank before those mentioned in the later declaration. Try to determine the default ordering algorithm used in your REDUCE implementation, and try to achieve some delicate rearrangements using the ORDER declaration.; pause; COMMENT You may have also noticed that REDUCE factors out any number, indeterminate, functional form, or the largest integer power thereof, which exactly divides every term of a result or every term of a parenthesized sub-expression of a result. For example:; on exp, mcd; g1 := f^2*(g^2 + 2*g) + f*(g^2 + h)/(2*f1); COMMENT This process usually leads to more compact expressions and reveals important structural information. However, the process can yield results which are difficult to interpret if the resulting parentheses are nested more than about two levels, and it is often desirable to see a fully expanded result to facilitate direct comparison of all terms. To suppress this monomial factoring, we can turn off an output control switch named ALLFAC; off allfac; g1; pause; COMMENT The ALLFAC monomial-factorization process is strongly dependent upon the ordering. We can achieve a more selective monomial factorization by using the FACTOR declaration, which declares a variable to have FACTOR status. If any indeterminates or functional forms occurring in an expression are in FACTOR status when the expression is output, terms having the same powers of the indeterminates or functional forms are collected together, and the power is factored out. Terms containing two or more indeterminates or functional forms under FACTOR status are not included in this monomial factorization process. For example:; off allfac; factor f; g1; factor g; g1; pause; COMMENT We can use the REMFAC command to remove items from factor status:; remfac f; g1; COMMENT ALLFAC can still have an effect on the coefficients of the monomials that have been factored out under the influence of FACTOR:; on allfac; g1; pause; COMMENT It is often desirable to distribute denominators over all factored sub-expressions generated under the influence of a FACTOR declaration, such as when we wish to view a result as a polynomial or as a power series in the factored indeterminates or functional forms, with coefficients which are rational functions of any other indeterminates or functional forms. (A mnemonic aid is: think RAT for RATional-function coefficients.) For example:; on rat; g1; pause; COMMENT RAT has no effect on expressions which have no indeterminates or functional forms under the influence of FACTOR. The related but different DIV switch permits us to distribute numerical and monomial factors of the denominator over every term of the numerator, expressing these distributed portions as rational-number coefficients and negative power factors respectively. (A mnemonic aid: DIV DIVides by monomials.) The overall effect can also depend strongly on whether the RAT switch is on or off. Series and polynomials are often most attractive with RAT and DIV both on; on div, rat; g1; off rat; g1; pause; remfac g; g1; pause; COMMENT With a very complicated result, detailed study of the result is often facilitated by having each new term begin on a new line, which can be accomplished using the LIST switch:; on list; g1; pause; COMMENT In various combinations, ORDER, FACTOR, the computational switches EXP, MCD, GCD, and ROUNDED, together with the output control switches ALLFAC, RAT, DIV, and LIST provide a variety of output alternatives. With experience, it is usually possible to use these tools to produce a result in the desired form, or at least in a form which is far more acceptable than the one produced by the default settings. I encourage you to experiment with various combinations while this information is fresh in your mind; pause; off list, rat, div, gcd, rounded; on allfac, mcd, exp; COMMENT You may have wondered whether or not an assignment to a variable, say F1, automatically updates the value of a bound variable, say G1, which was previously assigned an expression containing F1. The answer is: 1. If F1 was a bound variable in the expression when it was set to G1, then subsequent changes to the value of F1 have no effect on G1 because all traces of F1 in G1 disappeared after F1 contributed its value to the formation of G1. 2. If F1 was an indeterminate in an expression previously assigned to G1, then for each subsequent use of G1, F1 contributes its current value at the time of that use. These phenomena are illustrated by the following sequence:; pause; f2 := f; g1 := f1 + f2; f2 := g; g1; f1 := g; f1 := h; g1; f1 := g; g1; COMMENT Experience indicates that it is well worth studying this sequence and experimenting with others until these phenomena are thoroughly understood. You might, for example, mimic the above example, but with another level of evaluation included by inserting a statement analogous to "Q9:=G1" after "F2:=G", and inserting an expression analogous to "Q9" at the end, to compare with G1.; pause; COMMENT Note also, that if an indeterminate is used directly, or indirectly through another expression, in evaluating itself, this will lead to an infinite recursion. For example, the following expression results in infinite recursion at the first evaluation of H1, so REDUCE will detect it as an error. H1 := H1 + 1 You may experiment with this problem later at your own risk. It is often desirable to make an assignment to an indeterminate in a previously established expression have a permanent effect, as if the assignment were done before forming the expression. This can be done by using the substitute function, SUB.; g1 := f1 + f2; h1 := sub(f1=h, g1); f1 := g; h1; COMMENT Note the use of "=" rather than ":=" in SUB. This function is also valuable for achieving the effect of a local assignment within a sub-expression, without binding the involved indeterminate or functional form in the rest of the expression or wherever else it occurs. More generally the SUB function can have any number of equations of the form "indeterminate or functional form = expression", separated by commas, before the expression which is its last argument. Try devising a set of examples which reveals whether such multiple substitutions are done left to right, right to left, in parallel, or unpredictably. This is the end of lesson 2. To execute lesson 3, start a fresh REDUCE session. ;end; |
Added Lesson_3.red version [7d13a0474a].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | COMMENT REDUCE INTERACTIVE LESSON NUMBER 3 David R. Stoutemyer University of Hawaii Update for REDUCE 3.4 Herbert Melenk Konrad-Zuse-Zentrum Berlin 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, you can augment or even override these definitions depending on the needs of a given problem. For example, if you wished to write COT(F) in terms of TAN, you 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:; let cot(~f) => 1/tan(f); g1; COMMENT Any variable preceded by a tilde 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. The leftmost occurrence of a dummy variable in a rule must be marked with a tilde. The arguments to LET are either single rules or lists (explicitly enclosed in {..} or as variables with list values). All elements of a list have to be rules (i.e., expressions written in terms of the operator "=>") or names of other rule lists. So we could have written the above command either as LET COT(~F) => 1/TAN(F) or as the command sequence RS := {COT(~F) => 1/TAN(F)} LET RS The CLEARRULES command clears one or more rules. They have to be entered in the same form as for LET -- otherwise REDUCE is unable to identify them.; clearrules cot(~f) => 1/tan(f); cot(g+5); COMMENT Alternative forms would have been CLEARRULES {COT(~F) => 1/TAN(F)} or with the above value of RS CLEARRULES RS Note that CLEAR RS would not remove the rule(s) from the system -- it would only remove the list value from the variable RS.; pause; COMMENT The arguments of a functional form on the left-hand side of a rule can be more complicated than mere indeterminates. For example, we may wish to inform REDUCE how to differentiate expressions involving a symbolic function P, whose derivative is expressed in terms of another function Q.; operator p, q; let df(p(~x), x) => q(x)^2; df(3*p(f*g), g); COMMENT Also, REDUCE obviously knows the chain rule.; pause; COMMENT As another example, suppose that we wish to employ the angle-sum identities for SIN and COS:; 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 written as a list. 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 sub-expression F-G in our example, there was no need to make rules for the difference of two angles, because sub-expressions 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 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 a product of such powers and/or indeterminates or functional forms. For example, we can have the rule SIN(~X)^2 => 1 - COS(~X)^2 or we can have the rule:; let cos(~x)^2 => 1 - sin(~x)^2; g1 := cos(f)^3 + cos(g); pause; COMMENT Note that a replacement takes place wherever the 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 "SIN(~X)^2 + COS(X)^2 => 1" is not permitted. We can get around the restriction against a top-level "+" on the left-hand side though, at the minor nuisance of having to employ an operator whenever we want the rule applied to an expression:; clearrules cos(~x)^2 => 1 - sin(~x)^2; operator trigsimp; trigsimp_rules := { 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, trigsimp(~x) => x }$ g1 := f*cos(g)^2 + f*sin(g)^2 + g*sin(g)^2 + g*cos(g)^2 + 5; g1 := trigsimp(g1) where trigsimp_rules; pause; COMMENT Here we use another syntactical paradigm: the rule list is assigned to a name (here TRIGSIMP_RULES) and it is activated only locally for one evaluation, using the WHERE clause. Why doesn't our rule TRIGSIMP(~X) => X defeat the other more specific ones? The reason is that rules inside a list are applied in the order they are written, 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 they can. For such reasons we usually write rules for an operator in an order which proceeds from the most specific to the most general 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 Rules do not need to have free variables. For example, we could introduce the simplification rule to replace all subsequent instances of M*C^2 by ENERGY:; clear m, c, energy; g1 := (3*m^2*c^2 + m*c^3 + c^2 + m + m*c + m1*c1^2) where m*c^2 => energy; pause; COMMENT Suppose that instead we wish to replace M by ENERGY/C^2:; g1 where m => energy/c^2; COMMENT You may wonder how a rule of the trivial form "indeterminate => ..." differs from the corresponding assignment "indeterminate := ...". The difference is this: 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 "X => X + 1" would cause infinite recursion at the first subsequent occurrence of X, as would the pair of rules "{X => Y, Y => X}". (Try it! -- After the lesson.) To illustrate point 1 above, compare the following command sequence with the analogous earlier one in lesson 2, which used 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. (Without it, the following code will not work correctly!); 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, nminusone; zero := e^(n*i*x) - e^(nminusone*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 NMINUSONE 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:; cos(~n*~x) => cos(x)*cos((n-1)*x) - sin(x)*sin((n-1)*x) when fixp n and n>1; COMMENT Note: 1. In a conditional rule, any dummy variables should appear in the left-hand side of the replacement with a tilde. 2. FIXP, standing for FIX Predicate, is a built-in function which yields true if and only if its argument is an integer. Other useful predicates are NUMBERP, which is true if its argument represents a numeric value, that is an integer, a rational number or a rounded (floating point) number, and EVENP, which is true if its argument is an integer multiple of 2. 3. Arbitrarily-complicated true-false conditions can be composed using the relational operators =, NEQ, <, >, <=, >=, together with the logical operators "AND", "OR", "NOT". 4. The operators < , >, <=, and >= work only when both sides are numbers. 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 expressions 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 expressions 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; let integrate(~x^~p, x) => x^(p+1)/(p+1) when df(p, x) = 0; integrate(f^5, f); integrate(g^g, g); integrate(f^g, f); pause; 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 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 consider 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), but we can add additional rules for such cases:; let { integrate(1/~x^~p, x) => x^(1-p)/(1-p) when df(p, x) = 0, 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:; let integrate(~x^-1, x) => log(x); integrate(1/x, x); pause; COMMENT We now collect the integration rules so far into one list according to the law that within a rule set a more specific rule should precede the more general one:; integrate_rules := { integrate(1, ~x) => x, integrate(~x, x) => x^2/2, integrate(~x^-1, x) => log(x), integrate(1/~x^~p, x) => x^(1-p)/(1-p) when df(p, x) = 0, integrate(~x^~p, x) => x^(p+1)/(p+1) when df(p, x) = 0 }$ COMMENT Note that there are more elegant ways to match special cases in which variables have the values 0 or 1 by using "double tilde variables" -- see "Advanced use of rule lists" in section 11.3 of the REDUCE User's Manual. This is the end of lesson 3. We leave it as an intriguing exercise to extend this integrator. ;end; |
Added Lesson_4.red version [4e85ac460d].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 | COMMENT REDUCE INTERACTIVE LESSON NUMBER 4 David R. Stoutemyer University of Hawaii COMMENT This is lesson 4 of 7 REDUCE lessons. As before, please refrain from using variables beginning with the letters F through H during the lesson. In theory, assignments and LET statements are sufficient to accomplish anything that any other practical computing mechanism is capable of doing. However, it is more convenient for some purposes to use function procedures which can employ branch selection and iteration as do most traditional programming languages. As a trivial example, if we invariably wanted to replace cotangents with the corresponding tangents, we could input:; algebraic procedure cotan(x); 1/tan(x); COMMENT As an example of the use of this function, we have; cotan(log(f)); pause; COMMENT Note: 1. The procedure definition automatically declares the procedure name as an operator. 2. A procedure can be executed any time after its definition, until it is cleared. 3. Any parameters are dummy variables that are distinct from any other variables with the same name outside the procedure definition, and the corresponding arguments can be arbitrary expressions. 4. The value returned by a procedure is the value of the expression following the procedure statement. 5. The function COT is already defined in REDUCE and should not be redefined. We can replace this definition with a different one:; algebraic procedure cotan(y); cos(y)/sin(y); g1 := cotan(log(f)); COMMENT In place of the word ALGEBRAIC, we can optionally use the word INTEGER when a function always returns an integer value, or we can optionally use the word REAL when a function always returns a floating-point value. (ALGEBRAIC can also be omitted, since it is the default procedure type.) Try writing a procedure definition for the sine in terms of the cosine, then type G1.; pause; COMMENT Here is a more complicated function which introduces the notion of a conditional expression:; algebraic procedure sumcheck(aj, j, m, n, s); COMMENT J is an indeterminate and the other parameters are expressions. This function returns the global variable named PROVED if the function can inductively verify that S equals the sum of AJ for J going from M through N, returning the global variable named UNPROVED otherwise. For the best chance of proving a correct sum, the function should be executed under the influence of ON EXP, ON MCD, and any other user-supplied simplification rules relevant to the expression classes of AJ and S; if sub(j=m,aj) - sub(n=m,s) neq 0 or s + sub(j=n+1,aj) - sub(n=n+1,s) neq 0 then unproved else proved; on exp, mcd; clear x, j, n; sumcheck(j, j, 1, n, n*(n+1)/2); sumcheck(x^j, j, 0, n, (x^(n+1)-1)/(x-1)); COMMENT Within procedures of this sort a global variable is any variable which is not one of the parameters, and a global variable has the value, if any, which is current for that name at the point from where the procedure is used.; pause; COMMENT Conditional expressions have the form IF condition THEN expression1 ELSE expression2. There are generally several equivalent ways of writing a conditional expression. For example, the body of the above procedure could have been written IF SUB(J=M,AJ) - SUB(N=M,S) = 0 AND S + SUB(J=N+1,AJ) - SUB(N=N+1,S) = 0 THEN PROVED ELSE UNPROVED. Note how we compare a difference with 0, rather than comparing two nonzero expressions, for reasons explained in lesson 3. As an exercise, write a procedure analogous to SUMCHECK for proving closed-form product formulas, then test it on the valid formula that COS(N*X) equals the product of COS(J*X)/COS(J*X-X) for J ranging from 1 through N. You do not need to include prefatory comments describing parameters and the returned value until you learn how to use a text editor.; pause; COMMENT Most REDUCE statements are also expressions because they have a value. The value is usually 0 if nothing else makes sense, but I will mention the value only if it is useful. The value of an assignment statement is the assigned value. Thus a multiple assignment, performed right to left, can be achieved by a sequence of the form variable1 := variable2 := ... := variableN := expression. Moreover, assignments can be inserted within ordinary expressions such as X*(Y:=5). Such assignments must usually be parenthesized because of the low precedence of the assignment operator, and excessive use of this construct tends to make programs confusing.; pause; COMMENT REDUCE treats as a single expression any sequence of statements preceded by the pair of adjacent characters << and followed by the pair >>. The value of such a group expression is the value of the last statement in the group. Group expressions facilitate the implementation of tasks that are most easily stated as a sequence of operations. However, such sequences often utilize temporary variables to count, hold intermediate results, etc., and it is hazardous to use global variables for that purpose. If a top-level REDUCE statement or another function directly or indirectly uses that variable name, then its value or its virgin indeterminate status there might be damaged by our use as a temporary variable. In large programs or programs which rely on the work of others, such interference has a non-negligible probability, even if all programmers agree to the convention that all such temporary variables should begin with the function name as a prefix and all programmers attempt to comply with the convention. For this reason, REDUCE provides another expression-valued sequence called a BEGIN-block, which permits the declaration of local variables that are distinct from any other variables outside the block having the same name. Another advantage of using local variables for temporary variables is that the perhaps large amount of storage occupied by their values can be reclaimed after leaving their block.; pause; COMMENT A BEGIN-block consists of the word BEGIN, followed by optional declarations, followed by a sequence of statements, followed by the word END. Within BEGIN-blocks, it is often convenient to return control and possibly a value from someplace other than the end of the block. Control and a value may be returned via a RETURN-statement of the form RETURN expression or RETURN, 0 being returned in the latter case. A BEGIN-block does not return the value of the last statement. If a value is to be returned then RETURN must be used. These features and others are illustrated by the following function:; pause; algebraic procedure limit(ex, indet, pnt); begin COMMENT This function uses up through 4 iterations of L'Hospital's rule to attempt determination of the limit of expression EX as indeterminate INDET approaches expression PNT. This function is intended for the case where SUB(INDET=PNT, EX) yields 0/0, provoking a zero-divide message. This function returns the global variable named UNDEFINED when the limit is 0 dividing an expression which did not simplify to 0, and this function returns the global variable named UNKNOWN when it cannot determine the limit. Otherwise this function returns an expression which is the limit. For best results, this function should be executed under the influence of ON EXP, ON MCD, and any user-supplied simplification rules appropriate to the expression classes of EX and PNT; integer iteration; scalar n, d, nlim, dlim; iteration := 0; n := num(ex); d := den(ex); nlim := sub(indet=pnt, n); dlim := sub(indet=pnt, d); while nlim=0 and dlim=0 and iteration<5 do << n := df(n, indet); d := df(d, indet); nlim := sub(indet=pnt, n); dlim := sub(indet=pnt, d); iteration := iteration + 1 >>; return (if nlim=0 then if dlim=0 then unknown else 0 else if dlim=0 then undefined else nlim/dlim) end; % Examples follow... pause; g1 := (e^x-1)/x; % Evaluation at 0 causes a zero denominator error at top level but % continue anyway. sub(x=0, g1); limit(g1, x, 0); g1:= ((1-x)/log(x))^2; % Evaluation at 1 causes a zero denominator error at top level but % continue anyway. sub(x=1, g1); limit(g1, x, 1); COMMENT Note: 1. The idea behind L'Hospital's rule is that as long as the numerator and denominator are both zero at the limit point, we can replace them by their derivatives without altering the limit of the quotient. 2. Assignments within groups and BEGIN-blocks do not automatically cause output. 3. Local variables are declared INTEGER, REAL, or SCALAR, the latter corresponding to the same most general class denoted by ALGEBRAIC in a procedure statement. All local variables are initialized to zero, so they cannot serve as indeterminates. Moreover, if we attempted to overcome this by clearing them, we would clear all variables with their names. 4. We do not declare the attributes of parameters. 5. The NUM and DEN functions respectively extract the numerator and denominator of their arguments. (With OFF MCD, the denominator of 1+1/X would be 1.) 6. The WHILE-loop has the general form WHILE condition DO statement. REDUCE also has a "GO TO" statement, and using commas rather than semicolons to prevent termination of this comment, the above general form of a WHILE-loop is equivalent to BEGIN GO TO TEST, LOOP: statement, TEST: IF condition THEN GO TO LOOP, RETURN 0 END. A GOTO statement is permitted only within a block, and the GOTO statement cannot refer to a label outside the same block or to a label inside a block that the GOTO statement is not also within. Actually, 99.99% of REDUCE BEGIN-blocks are less confusing if written entirely without GOTOs, and I mention them primarily to explain WHILE-loops in terms of a more primitive notion.; pause; COMMENT 7. The LIMIT function provides a good illustration of nested conditional expressions. Proceeding sequentially through such nests, each ELSE clause is matched with the nearest preceding unmatched THEN clause in the group or block. In order to help reveal their structure, I have consistently indented nested conditional statements, continuations of multi-line statements and loop-bodies according to one of the many staunchly defended indentation styles. (If you have an instructor, I also urge you to humor him by adopting his style for the duration of the course.) 8. C and Java programmers take note: "IF ... THEN ... ELSE ..." is regarded as one expression, and semicolons are used to separate rather than terminate statements. Moreover, BEGIN and END are brackets rather than statements, so a semicolon is never needed immediately after BEGIN, and a semicolon is necessary immediately preceding END only if the END is intended as a labeled destination for a GOTO. Within conditional expressions, an inappropriate semicolon after an END, a >>, or an ELSE-clause is likely to be one of your most prevalent mistakes.; pause; COMMENT The next exercise is based on the above LIMIT function: For the sum of positive expressions AJ for J ranging from some finite initial value to infinity, the infinite series converges if the limit of the ratio SUB(J=J+1,AJ)/AJ is less than 1 as J approaches infinity. The series diverges if this limit exceeds 1, and the test is inconclusive if the limit is 1. To convert the problem to the form required by the above LIMIT program, we can replace J by 1/!*FOO in the ratio, then take the limit as the indeterminate !*FOO approaches zero. (Since an indeterminate is necessary here, I picked the weird name !*FOO to make the chance of conflict negligible.) After writing such a function to perform the ratio test, test it on the examples AJ=J/2^J, AJ=1/J^2, AJ=2^J/J^10, and AJ=1/J. (The first two converge and the second two diverge.); pause; COMMENT Groups or blocks can be used wherever any arbitrary expression is allowed, including the right-hand side of a LET rule. The need for loops with an integer index variable running from a given initial value through a given final value by a given increment is so prevalent that REDUCE offers a convenient special way of accomplishing it via a FOR-loop, which has the general form FOR index := initial STEP increment UNTIL final DO statement. Except for the use of commas as statement separators, this construct is equivalent to BEGIN INTEGER index, index := initial, IF increment>0 THEN WHILE index <= final DO << statement, index := index + increment >> ELSE WHILE index >= final DO << statement, index := index + increment >>, RETURN 0 END; pause; COMMENT Note: 1. The index variable is automatically declared local to the FOR- loop. 2. "initial", "increment", and "final" must have integer values. 3. FORTRAN programmers take note: the body of the loop is not automatically executed at least once. 4. An abbreviation for "STEP 1 UNTIL" is ":". 5. Since the WHILE-loop and the FOR-loop have implied BEGIN- blocks, a RETURN statement within their bodies cannot transfer control further than the point following the loops. Another frequent need is to produce output from within a group or block, because such output is not automatically produced. This can be done using the WRITE-statement, which has the form WRITE expression1, expression2, ..., expressionN. Beginning a new line with expression1, the expressions are printed immediately adjacent to each other, split over line boundaries if necessary. The value of the WRITE-statement is the value of its last expression, and any of the expressions can be a character-string of the form "character1 character2 ... characterM". Inserting the word "WRITE" on a separate line before an assignment is convenient for debugging, because the word is then easily deleted afterward. These features and others are illustrated by the following equation solver:; pause; operator solvefor, soln; for all x, lhs, rhs let solvefor(x, lhs, rhs) = solvefor(x, lhs-rhs); COMMENT LHS and RHS are expressions such that P=NUM(LHS-RHS) is a polynomial of degree at most 2 in the indeterminate or functional form X. Otherwise an error message is printed. As a convenience, RHS can be omitted if it is 0. If P is quadratic in X, the two values of X which satisfy P=0 are stored as the values of the functional forms SOLN(1) and SOLN(2). If P is a first-degree polynomial in X, SOLN(1) is set to the one solution. If P simplifies to 0, SOLN(1) is set to the identifier ARBITRARY. If P is an expression which does not simplify to zero but does not contain X, SOLN(1) is set to the identifier NONE. In all other cases, SOLN(1) is set to the identifier UNKNOWN. The function then returns the number of SOLN forms which were set. This function prints a well deserved warning message if the denominator of LHS-RHS contains X. If LHS-RHS is not polynomial in X, it is wise to execute this function under the influence of ON GCD.; pause; for all x, lhsmrhs let solvefor(x, lhsmrhs) = begin integer hipow; scalar temp, cflist, cf0, cf1, cf2; if lhsmrhs = 0 then << soln(1) := arbitrary; return 1 >>; cflist := coeff(lhsmrhs, x); hipow := hipow!*; if hipow = 0 then << soln(1) := none; return 1 >>; if hipow > 2 then << soln(1) := unknown; return 1 >>; if hipow = 1 then << soln(1) := first(cflist)/second(cflist); if df(sub(x=!*foo, soln(1)), !*foo) neq 0 then soln(1) := unknown; return 1 >>; cf0 := first(cflist)/third(cflist); cf1 := -second(cflist)/third(cflist)/2; if df(sub(x=!*foo, cf0), !*foo) neq 0 or df(sub(x=!*foo, cf1), !*foo) neq 0 then << soln(1) := unknown; return 1 >>; temp := (cf1^2 - cf0)^(1/2); soln(1) := cf1 + temp; soln(2) := cf1 - temp; return 2 end; COMMENT And some examples:; pause; for k:=1:solvefor(x, a*x^2, -b*x-c) do write soln(k) := soln(k); for k:=1:solvefor(log(x), 5*log(x)-7) do write soln(k) := soln(k); for k:=1:solvefor(x, x, x) do write soln(k) := soln(k); for k:= 1:solvefor(x, 5) do write soln(k) := soln(k); for k:=1:solvefor(x, x^3+x+1) do write soln(k) := soln(k); for k:=1:solvefor(x, x*e^x, 1) do write soln(k) := soln(k); g1 := x/(e^x-1); % Results in 'invalid as polynomial' error, continue anyway:; for k:=1:solvefor(x, g1) do write soln(k) := soln(k); sub(x=soln(1), g1); limit(g1, x, soln(1)); pause; COMMENT Here we have used LET rules to permit the user the convenience of omitting default arguments. (Function definitions have to have a fixed number of parameters.) Array elements are designated by the same syntax as matrix elements, namely as functional forms having integer arguments. Here are some desiderata that may help you decide which of these alternatives is most appropriate for a particular application: 1. The lower bound of each array subscript is 0 vs. 1 for matrices vs. unrestricted for functional forms. 2. The upper bound of each array subscript must have a specific integer value at the time the array is declared, as must the upper bounds of matrix subscripts when a matrix is first referred to, on the left side of a matrix assignment. In contrast, functional forms never require a commitment to a specific upper bound. 3. An array can have any fixed number of subscripts, a matrix must have exactly 2, and a functional form can have a varying arbitrary number. 4. Matrix operations, such as transpose and inverse, are built-in only for matrices. 5. For most implementations, access to array elements requires time approximately proportional to the number of subscripts, whereas access to matrix elements takes time approximately proportional to the sum of the two subscript values, whereas access to functional forms takes average time approximately proportional to the number of bound functional forms having that name. 6. Only functional forms permit the effect of a subscripted indeterminate such as having an answer be "A(M,N) + B(3,4)". 7. Only functional forms can be used alone in the LHS of LET substitutions.; pause; COMMENT 8. All arrays, matrices, and operators are global regardless of where they are declared, so declaring them within a BEGIN-block does not afford the protection and automatic storage recovery of local variables. Moreover, clearing them within a BEGIN-block will clear them globally, and normal functions cannot return an array or a matrix value. Furthermore, REDUCE parameters are referenced by value, which means that an assignment to a parameter has no effect on the corresponding argument. Thus, matrix or array results cannot be transmitted back to an argument either. 9. It is often advantageous to use two or more of these alternatives to represent a set of quantities at different times in the same program. For example, to get the general form of the inverse of a 3-by-3 matrix, we could write MATRIX AA(3,3), OPERATOR A, FOR J:=1:3 DO FOR K:=1:3 DO AA(J,K) := A(J,K), AA^-1. As another example, we might use an array to receive some polynomial coefficients, then transfer the values to a matrix for inversion.; pause; COMMENT The COEFF function is the remaining new feature in our SOLVEFOR example. The first argument is a polynomial expression in the indeterminate or functional form which is the second argument. The polynomial coefficients of the integer powers of the indeterminate are returned as a LIST, with the independent coefficient first. The highest and lowest non-zero powers are placed in the variables HIPOW!* and LOWPOW!* respectively. A LIST is a kind of data structure, just as matrices and arrays are. It is represented as a comma-separated sequence of elements enclosed in braces. The elements can be accessed with the functions FIRST, SECOND, THIRD, PART(i) which returns the i-th element, and REST, which returns a list of all but the first element. For example:; clear x; coeff(x^5+2, x); lowpow!*; hipow!*; pause; COMMENT COEFF does not check to make sure that the coefficients do not contain its second argument within a functional form, so that is the reason we differentiated. The reason we first substituted the indeterminate !*FOO for the second argument is that differentiation does not work with respect to a functional form. The last exercise is to rewrite the last rule so that we can solve equations which simplify to the form a*x^(m+2*l) + b*x^(m+l) + c*x^m = 0, where m >= 0 and l >= 1. The solutions are 0, with multiplicity m, x1*E^(2*j*I*pi/l), x2*E^(2*j*I*pi/l), with j = 0, 1, ..., l-1, where x1 and x2 are the solutions to the quadratic equation a*x^2 + b*x + c = 0. As a convenience to the user, you might also wish to have a global switch named SOLVEPRINT, such that when it is nonzero, the solutions are automatically printed. This is the end of lesson 4. When you are ready to run lesson 5, start a new REDUCE session. ;end; |
Added Lesson_5.red version [e2416f954e].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 | COMMENT REDUCE INTERACTIVE LESSON NUMBER 5 David R. Stoutemyer University of Hawaii COMMENT This is lesson 5 of 7 REDUCE lessons. There are at least two good reasons for wanting to save REDUCE expression assignments to a file: 1. So that one can logout, then resume computation at a later time. 2. So that needed main memory space can be cleared without irrecoverably losing the values of variables which are not needed in the next expression but will be needed later. Using trivial small expressions, the following statement sequence illustrates how this could be done: OFF NAT, OUT TEMP, F1 := (F + G)^2, G1 := G*F1, OUT T, CLEAR F1, H1 := H*G1, OUT TEMP, CLEAR G1, H2 := F*H1, CLEAR H1, SHUT TEMP, IN TEMP, F1, ON NAT, F1. ON NAT yields the natural output style with raised exponents, which is unsuitable for subsequent input. The OUT-statement causes subsequent output to be directed to the file named in the statement, until overridden by a different OUT-statement or until the file is closed by a SHUT-statement. File T is the terminal, and any other name designates a normal file. Such names must comply with the local file-naming conventions as well as with the REDUCE syntax. If the output is not of lasting importance, I find that including something like "TEMPORARY" or "SCRATCH" in the name helps remind me to delete it later. Successive OUT-statements to the same file will append rather than overwrite output if and only if there is no intervening SHUT- statement for that file. The SHUT-statement also has the effect of an implied OUT T. Note: 1. The generated output is the simplified expression rather than the raw form entered at the terminal. 2. Each output assignment automatically has a dollar-sign appended so that it is legal input and so that (perhaps lengthy) output will not unavoidably be generated at the terminal when the file is read in later. 3. Output cannot be sent simultaneously to 2 or more files. 4. Statements entered at the terminal which do not generate output -- such as declarations, LET rules, and procedure definitions -- do not appear in the output file. 5. One could get declarations, procedure definitions, rules, etc. written to a file from the terminal by typing statements such as WRITE " ALGEBRAIC PROCEDURE ... ... ". This could serve as a means of generating permanent copies of LET rules, procedures, etc., but it is quite awkward compared with the usual way, which is to generate a file containing the REDUCE program by using a text editor, then input the program by using the IN-statement. If you have refrained from learning to use a basic text editor (such as Windows Notepad), hesitate no longer. I suggest that your first text-editing exercise be to create an IN file for (re)defining the function FACTORIAL(n). 6. The reason I didn't actually execute the above statement sequence is that when the input to REDUCE comes from a file, both the input and output are sent to the output file (which is convenient for producing a file containing both the input and output of a demonstration.) Consequently, you would have seen none of the statements between the "OUT TEMP" and "OUT T" as well as between the second "OUT TEMP" and the "SHUT TEMP", until the IN-statement was executed. The example is confusing enough without having things scrambled from the order you would type them. To clarify all of this, I encourage you to actually execute the above statement sequence with an appropriately chosen file name and using semicolons instead of the commas and final period. Afterwards, to return to the lesson, type CONT. 7. It is often more natural to use a string (e.g. "less5.red") rather than an identifier (e.g. less5!.red) for a filename. REDUCE accepts both.; pause; COMMENT Suppose you and your colleagues developed or obtained a set of REDUCE files containing supplementary packages such as trigonometric simplification, Laplace transforms, etc. It would be a waste of time (and distracting) to have these files displayed every time they were input, so this output can be suppressed by inserting the statement "OFF ECHO" at the beginning of the file. (But don't forget to include the statement "ON ECHO" at the end of the file.) The lessons have amply demonstrated the PAUSE-statement, which is useful for insertion in input files at the top-level or within functions when input from the user is necessary or desired. It often happens that after generating an expression, one decides that it would be convenient to use it as the body of a function definition, with one or more of the indeterminates therein as parameters, which can be done as follows. (If you input code like this directly rather than from a file, you will need to agree to let REDUCE declare F to be an operator.); (1-(v/c)^2)^(1/2); for all v saveas f(v); f(5); COMMENT Here the indeterminate V became a parameter of F. Alternatively, we can save the previous expression to a variable.; saveas fof5; fof5; COMMENT I find this technique more convenient than referring to the special variable WS.; pause; COMMENT The FOR-loop provides a convenient way to form finite sums or products with specific integer index limits. However, this need is so ubiquitous that REDUCE provides even more convenient syntax of the forms FOR index := initial STEP increment UNTIL final SUM expression, FOR index := initial STEP increment UNTIL final PRODUCT expression. As before, ":" is an acceptable abbreviation for "STEP 1 UNTIL". As an example of their use, here is a very concise definition of a function which computes Taylor-series expansions of symbolic expressions:; algebraic procedure taylor(ex, x, pt, n); COMMENT This function returns the degree-N Taylor-series expansion of expression EX with respect to indeterminate X, expanded about expression PT. For a series-like appearance, display the answer under the influence of FACTOR X, ON RAT, and perhaps also ON DIV; sub(x=pt, ex) + for k:=1:n sum(sub(x=pt, df(ex,x,k))*(x-pt)^k / for j:=1:k product j); clear a, x; factor x; on rat, div; g1 := taylor(e^x, x, 0, 4); g2 := taylor(e^cos(x)*cos(sin(x)), x, 0, 3); % This illustrates the zero denominator limitation; continue anyway: taylor(log(x), x, 0, 4); COMMENT It would, of course, be more efficient to compute each derivative and factorial from the preceding one. (Similarly for (X-PT)^K if and only if PT NEQ 0). The Fourier series expansion of our example E^COS(X)*COS(SIN(X)) is 1 + cos(x) + cos(2*x)/2 + cos(3*x)/(3*2) + ... . Use the above SUM and PRODUCT features to generate the partial sum of this series through terms of order COS(6*X); pause; COMMENT Closed-form solutions are often unobtainable for nontrivial problems, even using computer algebra. When this is the case, truncated symbolic series solutions are often worth trying before resorting to approximate numerical solutions. When we combine truncated series it is pointless (and worse yet, misleading) to retain terms of higher order than is justified by the constituents. For example, if we wish to multiply together the truncated series G1 and G2 generated above, there is no point in retaining terms higher than third degree in X. We can avoid even generating such terms as follows:; let x^4 = 0; g3 := g1*g2; COMMENT Replacing X^4 with 0 has the effect of also replacing all higher powers of X with 0. We could, of course, use our TAYLOR function to compute G3 directly, but differentiation is time consuming compared to truncated polynomial algebra. Moreover, our TAYLOR function requires a closed-form expression to begin with, whereas iterative techniques often permit us to construct symbolic series solutions even when we have no such closed form. Now consider the truncated series:; clear y; factor y; h1 := taylor(cos y, y, 0, 6); COMMENT Suppose we regard terms of order X^N in G1 as being comparable to terms of order Y^(2*N) in H1, and we want to form (G1*H1)^2. This can be done as follows:; let y^7 = 0; f1 := (g1*h1)^2; COMMENT Note however that any terms of the form C*X^M*Y^N with 2*M+N > 6 are inconsistent with the accuracy of the constituent series, and we have generated several such misleading terms by independently truncating powers of X and Y. To avoid generating such junk, we can specify that a term be replaced by 0 whenever a weighted sum of exponents of specified indeterminates and functional forms exceeds a specified weight level. In our example this is done as follows:; weight x=2, y=1; wtlevel 6; f1 := f1; COMMENT Variables not mentioned in a WEIGHT declaration have a weight of 0, and the default weight-level is 2.; pause; COMMENT Here is an example of how one might compute numerical approximations to the cosine function. (But note that REDUCE can already do this automatically!) One way is to provide a supplementary LET rule for numerical arguments. For example, since our TAYLOR function would reveal that the Taylor series for cos x is 1 - x^2/2! + x^4/4! - ...; for all x such that numberp x let abs(x) = x, abs(-x) = x; epsrecip := 1024$ on rounded; while 1.0 + 1.0/epsrecip neq 1.0 do epsrecip := epsrecip + epsrecip; for all x such that numberp num x and numberp den x let cos x = begin COMMENT X is integer, real, or a rational number. This rule returns the Taylor-series approximation to COS X, truncated when the last included term is less than (1/EPSRECIP) of the returned answer. EPSRECIP is a global variable initialized to a value that is appropriate to the local floating-point precision. Arbitrarily larger values are justifiable when X is exact and ROUNDED is off. No angle reduction is performed, so this function is not recommended for ABS(X) >= about PI/2; integer k; scalar mxsq, term, ans; k := 1; mxsq := -x*x; term := mxsq/2; ans := term + 1; while abs(num term)*epsrecip*den(ans) - abs(num ans)*den(term) > 0 do << term := term*mxsq/k/(k+1); ans := term + ans; k := k+2 >>; return ans end; cos(f) + cos(1/2); off rounded; cos(1/2); COMMENT As an exercise, write a similar rule for the SIN or LOG, or replace the COS rule with an improved one which uses angle reduction so that angles outside a modest range are represented as equivalent angles within the range, before computing the Taylor series.; pause; COMMENT There is a REDUCE compiler, and you may wish to learn how to use it. However, even if rules such as the above ones are compiled, they will be slow compared to the implementation-dependent hand-coded ones used by most FORTRAN-like systems, so REDUCE provides a way to generate FORTRAN programs which can then be compiled and executed in a subsequent job step. This is useful when there is a lot of floating-point computation or when we wish to exploit an existing FORTRAN program. Suppose, for example, that we wish to utilize an existing FORTRAN subroutine which uses the Newton-Raphson iteration Xnew := Xold - SUB(X=Xold, F(X)/DF(F(X),X)) to attempt an approximate solution to the equation F(X)=0. Most such subroutines require the user to provide a FORTRAN function or subroutine which, given Xold, returns F(X)/DF(F(X),X) evaluated at X=Xold. If F(X) is complicated, manual symbolic derivation of DF(F(X),X) is a tedious and error-prone process. We can get REDUCE to relieve us of this responsibility as is illustrated below for the trivial example F(X) = X*E^X - 1: ON FORT, ROUNDED, OUT FONDFFILE, WRITE " REAL FUNCTION FONDF(XOLD)", WRITE " REAL XOLD, F", F := XOLD*E^XOLD - 1.0, FONDF := F/DF(F,XOLD), WRITE " RETURN", WRITE " END", SHUT FONDFFILE. COMMENT Under the influence of ON FORT, the output generated by assignments is printed as valid FORTRAN assignment statements, using as many continuation lines as necessary up to the number specified by the global variable !*CARDNO, which is initially set to 20. The output generated by an expression which is not an assignment is a corresponding assignment to a variable named ANS. In either case, expressions which would otherwise exceed !*CARDNO continuation lines are evaluated piecewise, using ANS as an intermediate variable. Try executing the above statement sequence, using an appropriate filename and using semicolons instead of the commas and period at the end of the lines (only), then view the file after the lesson to see how it worked.; pause; off fort, rounded; COMMENT To make this technique usable by non-REDUCE programmers, we could write a more general REDUCE program which given merely the expression F by the user, outputs not only the function FONDF, but also any necessary job-control commands and an appropriate main program for calling the Newton-Raphson subroutine and printing the results. Sometimes it is desirable to modify or supplement the syntax of REDUCE. For example: 1. Electrical engineers may prefer to input J as the representation of (-1)^(1/2). 2. A user might prefer to input LOGE to denote natural logarithms. (Note that LN is already defined as a synonym for LOG.) 3. A user might prefer to use DERIV instead of DF to request differentiation. Such lexical macros can be established by the DEFINE declaration:; clear x, j; define j=i, loge=log, deriv=df; COMMENT Now watch!; g1 := sub(x=loge(j^3*x), deriv(x^2,x)); COMMENT Each "equation" in a DEFINE declaration must be of the form "name = item", where each item is an expression, an operator, or a REDUCE-reserved word such as "FOR". Such replacements take place during the lexical scanning, before any evaluation, LET rules, or built-in simplification. Think of a good application for this facility, then try it.; pause; COMMENT When REDUCE is being run non-interactively, with input from a file rather than a terminal, it is preferable to have REDUCE make reasonable decisions and proceed when it encounters apparently undeclared operators, divisions by zero, etc. In interactive mode, it is preferable to pause and query the user. ON INT specifies the latter style, and OFF INT specifies the former. Under the influence of OFF INT, we can also have most error messages suppressed by specifying OFF MSG. This is sometimes useful when we expect abnormal conditions and do not want our output marred by the associated messages. INT is automatically turned off during input from a file in response to an IN-command from a terminal.; pause; COMMENT REDUCE provides a trace command for debugging, which employs the syntax TR functionname1, functionname2, ..., functionnameN. An analogous command named UNTR removes function names from trace status; pause; COMMENT REDUCE also provides an assignment-tracing command for debugging, which employs the syntax TRST functionname1, functionname2, ..., functionnameN. An analogous command named UNTRST removes functionnames from this status. All assignments in the designated functions are reported, except for assignments to array elements. Such functions must be uncompiled and must have a top-level BEGIN-block. To apply both TRST and TR to a function simultaneously, it is crucial to request them in that order, and it is necessary to relinquish the two kinds of tracing in the opposite order.; pause; COMMENT The REDUCE algebraic algorithms are written in a subset of REDUCE called RLISP. In turn, the more sophisticated features of RLISP are written in a small subset of RLISP, which is itself written in a simple dialect of LISP called Standard LISP. RLISP is ideal for implementing algebraic algorithms, but the RLISP environment is not most suitable for the routine use of these algorithms in the natural mathematical style of the preceding lessons. Accordingly, REDUCE is initially in a mode called ALGEBRAIC, which provides the user with the environment illustrated in the preceding lessons, while insulating him from accidental interaction with the numerous functions, global variables, etc. necessary for implementing the built-in algebra. In contrast, the underlying RLISP system together with all of the algebraic simplification algorithms written therein is called SYMBOLIC mode. As we have seen, algebraic-mode rules and procedures can be used to extend the built-in algebraic capabilities. However, some extensions can be accomplished most easily or efficiently by descending to SYMBOLIC mode. To make REDUCE operate in symbolic mode, we merely execute the top- level mode-declaration statement consisting of the word SYMBOLIC. We can subsequently switch back by executing the statement consisting of the word ALGEBRAIC. RLISP has the semantics of LISP with the syntax of our by-now-familiar algebraic-mode REDUCE, so RLISP provides a natural tool for many applications besides computer algebra, such as games, theorem-proving, natural-language translation, computer-aided instruction, and artificial intelligence in general. For this reason, it is possible to run RLISP without any of the symbolic-mode algebraic algorithms that are written in RLISP, and it is advisable to thus save space when the application does not involve computer algebra. (An RLISP system is a step in the process of building a complete REDUCE system, but is not distributed as an independent application, although one can be built from the source code available.) We have now discussed virtually every feature that is available in algebraic mode, so lesson 6 will deal solely with RLISP, and lesson 7 will deal with communication between ALGEBRAIC and SYMBOLIC mode for mathematical purposes. However, I suggest that you proceed to those lessons only if and when: 1. You have consolidated and fully absorbed the information in lessons 1 through 5 by considerable practice beyond the exercises therein. (The exercises were intended to also suggest good related project ideas.) 2. You feel the need for a facility which you believe is impossible or quite awkward to implement solely in ALGEBRAIC mode. 3. You have read an introductory text about LISP, such as "A Concise Introduction to LISP" by David L. Matuszek, which is freely available at https://www.cis.upenn.edu/~matuszek/LispText/lisp.html. 4. You are familiar with the definition of Standard LISP, as described in the "Standard LISP Report" which was published in the October 1979 SIGPLAN Notices. [A copy is freely available via http://reduce-algebra.sourceforge.net/documentation.php.] Don't forget to view or print your newly generated FORTRAN file and to delete any temporary files created by this lesson.; ;end; |
Added Lesson_6.red version [4d7217d89c].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | COMMENT REDUCE INTERACTIVE LESSON NUMBER 6 David R. Stoutemyer University of Hawaii COMMENT This is lesson 6 of 7 REDUCE lessons. A prerequisite is to read an introductory text about LISP, such as "A Concise Introduction to LISP" by David L. Matuszek, which is freely available at https://www.cis.upenn.edu/~matuszek/LispText/lisp.html. Then familiarize yourself with the Standard Lisp Report, which is freely available via http://reduce-algebra.sourceforge.net/documentation.php. To avoid confusion between RLISP and the SYMBOLIC-mode algebraic algorithms, this lesson will treat only RLISP. Lesson 7 deals with how the REDUCE algebraic mode is implemented in RLISP and how the user can interact directly with that implementation. That is why I suggested that you run this lesson in RLISP rather than full REDUCE. If you forgot or do not have a locally available separate RLISP, then please switch now to symbolic mode by typing the statement SYMBOLIC.; symbolic; pause; COMMENT Your most frequent mistakes are likely to be forgetting to quote data examples, using commas as separators within lists, and not putting enough levels of parentheses in your data examples. Having learnt from reading the Standard Lisp Report about the built-in RLISP functions CAR, CDR, CONS, ATOM, EQ, NULL, LIST, APPEND, REVERSE, DELETE, MAPLIST, MAPCON, LAMBDA, FLAG, FLAGP, PUT, GET, DEFLIST, NUMBERP, ZEROP, ONEP, AND, EVAL, PLUS, TIMES, CAAR, CADR, etc., here is an opportunity to reinforce the learning by practice. Write expressions using CAR, CDR, CDDR, etc. (which are defined only through 4 letters between C and R) to individually extract each atom from F, where:; f := '((john . doe) (1147 hotel street) honolulu); pause; COMMENT My solutions are CAAR F, CDAR F, CAADR F, CADADR F, CADDR CADR F, and CADDR F. Although commonly the "." is only mentioned in conjunction with data, we can also use it as an infix alias for CONS. Do this to build from F and from the data 'MISTER the s-expression consisting of F with MISTER inserted before JOHN.DOE; pause; COMMENT My solution is ('MISTER . CAR F) . CDR F. Enough of these inane exercises -- let's get on to something useful! Let's develop a collection of functions for operating on finite sets. We will let the elements be arbitrary s-expressions, and we will represent a set as a list of its elements in arbitrary order, without duplicates. Here is a function which determines whether its first argument is a member of the set which is its second element; symbolic procedure memberp(elem, set1); COMMENT Returns T if s-expression ELEM is a top-level element of list SET1, returning NIL otherwise; if null set1 then nil else if elem = car set1 then t else memberp(elem, cdr set1); memberp('blue, '(red blue green)); COMMENT This function illustrates several convenient techniques for writing functions which process lists: 1. To avoid the errors of taking the CAR or the CDR of an atom, and to build self confidence while it is not immediately apparent how to completely solve the problem, treat the trivial cases first. For an s-expression or list argument, the most trivial cases are generally when one or more of the arguments are NIL, and a slightly less trivial case is when one or more is an atom. (Note that we will get an error message if we use MEMBERP with a second argument which is not a list. We could check for this, but in the interest of brevity, I will not strive to make our set-package give set-oriented error messages.) 2. Use CAR to extract the first element and use CDR to refer to the remainder of the list. 3. Use recursion to treat more complicated cases by extracting the first element and using the same functions on smaller arguments.; pause; COMMENT To make MEMBERP into an infix operator we make the declaration:; infix memberp; '(john.doe) memberp '((fig.newton) fonzo (santa claus)); COMMENT Infix operators associate left, meaning expressions of the form (operand1 operator operand2 operator ... operator operandN) are interpreted left-to-right as ((...(operand1 operator operand2) operator ...) operator operandN). Operators may also be flagged RIGHT by FLAG ('(op1 op2 ...), 'RIGHT). to give the interpretation (operand1 operator (operand2 operator (... operandN))...). Of the built-in operators, only ".", "*=", "+", and "*" associate right. If we had made the infix declaration before the function definition, the latter could have begun with the more natural statement SYMBOLIC PROCEDURE ELEM MEMBERP SET. Infix functions can also be referred to by functional notation if one desires. Actually, an analogous infix operator named MEMBER is already built-into RLISP, so we will use MEMBER rather than MEMBERP from here on. (But note that MEMBER returns the sublist beginning with the first argument rather than T.); member(1147, cadr f); COMMENT Inspired by the simple yet elegant definition of MEMBERP, write a function named SETP which uses MEMBER to check for a duplicate element in its list argument, thus determining whether or not the argument of SETP is a set; pause; COMMENT My solution is; symbolic procedure setp candidate; COMMENT Returns T if list CANDIDATE is a set, returning NIL otherwise; if null candidate then t else if car candidate member cdr candidate then nil else setp cdr candidate; setp '(kermit, (cookie monster)); setp '(dog cat dog); COMMENT If you used a BEGIN-block, local variables, loops, etc., then your solution is surely more awkward than mine. For the duration of the lesson, try to do everything without groups, BEGIN-blocks, local variables, assignments, and loops. Everything can be done using function composition, conditional expressions, and recursion. It will be a mind-expanding experience -- more so than transcendental meditation, psilopsybin, and EST. Afterward, you can revert to your old ways if you disagree. Thus endeth the sermon. Incidentally, to make the above definition of SETP work for non-list arguments all we have to do is insert "ELSE IF ATOM CANDIDATE THEN NIL" below "IF NULL CANDIDATE THEN T". Now try to write an infix procedure named SUBSETOF, such that SET1 SUBSETOF SET2 returns NIL if SET1 contains an element that SET2 does not, returning T otherwise. You are always encouraged, by the way, to use any functions that are already builtin, or that we have previously defined, or that you define later as auxiliary functions.; pause; COMMENT My solution is; infix subsetof; symbolic procedure set1 subsetof set2; if null set1 then t else if car set1 member set2 then cdr set1 subsetof set2 else nil; '(roof door) subsetof '(window door floor roof); '(apple banana) subsetof '((apple cobbler) (banana creme pie)); COMMENT Two sets are equal when they have identical elements, not necessarily in the same order. Write an infix procedure named EQSETP which returns T if its two operands are equal sets, returning NIL otherwise.; pause; COMMENT The following solution introduces the PRECEDENCE declaration:; infix eqsetp; precedence eqsetp, =; precedence subsetof, eqsetp; symbolic procedure set1 eqsetp set2; set1 subsetof set2 and set2 subsetof set1; '(ballet tap) eqsetp '(tap ballet); '(pine fir aspen) eqsetp '(pine fir palm); COMMENT The precedence declarations make SUBSETOF have a higher precedence than EQSETP and make the latter have higher precedence than "=", which is higher than "AND". Consequently, these declarations enabled me to omit parentheses around "SET1 SUBSUBSETOF SET2" and around "SET2 SUBSETOF SET1". All prefix operators have higher precedence than any infix operator, and to inspect the ordering among the latter, we merely inspect the value of the global variable named; preclis!*; COMMENT Now see if you can write a REDUCE infix function named PROPERSUBSETOF, which determines if its left operand is a proper subset of its right operand, meaning it is a subset which is not equal to the right operand.; pause; COMMENT All of the above exercises have been predicates. In contrast, the next exercise is to write a function called MAKESET, which returns a list which is a copy of its argument, omitting duplicates.; pause; COMMENT How about:; symbolic procedure makeset lis; if null lis then nil else if car lis member cdr lis then makeset cdr lis else car lis . makeset cdr lis; COMMENT As you may have guessed, the next exercise is to implement an operator named INTERSECT, which returns the intersection of its set operands.; pause; COMMENT Here is my solution:; infix intersect; precedence intersect, subsetof; symbolic procedure set1 intersect set2; if null set1 then nil else if car set1 member set2 then car set1 . cdr set1 intersect set2 else cdr set1 intersect set2; COMMENT Symbolic-mode REDUCE has a built-in function named SETDIFF, which returns the set of elements which are in its first argument but not the second. See if you can write an infix definition of a similar function named DIFFSET.; pause; COMMENT Presenting --:; infix diffset; precedence diffset, intersect; symbolic procedure left diffset right; if null left then nil else if car left member right then cdr left diffset right else car left . (cdr left diffset right); '(seagull wren condor) diffset '(wren lark); COMMENT The symmetric difference of two sets is the set of all elements which are in only one of the two sets. Implement a corresponding infix function named SYMDIFF. Look for the easy way! There is almost always one for examinations and instructional exercises.; pause; COMMENT Presenting --:; infix symdiff; precedence symdiff, intersect; symbolic procedure set1 symdiff set2; append(set1 diffset set2, set2 diffset set1); '(seagull wren condor) symdiff '(wren lark); COMMENT We can use APPEND because the two set differences are disjoint. The above set of exercises (exercises of set?) have all returned set results. The cardinality, size, or length of a set is the number of elements in the set. More generally, it is useful to have a function which returns the length of its list argument, and such a function is built-into RLISP. See if you can write a similar function named SIZEE.; pause; COMMENT Presenting --:; symbolic procedure sizee lis; if null lis then 0 else 1 + sizee cdr lis; sizee '(how marvelously concise); sizee '(); COMMENT Literal atoms, meaning atoms which are not numbers, are stored uniquely in LISP and in RLISP, so comparison for equality of literal atoms can be implemented by comparing their addresses, which is significantly more efficient than a character-by-character comparison of their names. The comparison operator "EQ" compares addresses, so it is the most efficient choice when comparing only literal atoms. The assignments N2 := N1 := 987654321, S2 := S1 := '(FROG (SALAMANDER.NEWT)), make N2 have the same address as N1 and make S2 have the same address as S1, but if N1 and N2 were constructed independently, they would not generally have the same address, and similarly for S1 vs. S2. The comparison operator "=", which is an alias for "EQUAL", does a general test for identical s-expressions, which need not be merely two pointers to the same address. Since "=" is built-in, compiled, and crucial, I will define my own differently-named version denoted "..=" as follows:; pause; newtok '((!. !. !=) myequal); infix eqatom, myequal; precedence myequal, equal; precedence eqatom, eq; symbolic procedure s1 myequal s2; if atom s1 then if atom s2 then s1 eqatom s2 else nil else if atom s2 then nil else car s1 myequal car s2 and cdr s1 myequal cdr s2; symbolic procedure a1 eqatom a2; if numberp a1 then if numberp a2 then zerop(a1-a2) else nil else if numberp a2 then nil else a1 eq a2; COMMENT Here I introduced a help function named EQATOM, because I was beginning to become confused by detail when I got to the line which uses EQATOM. Consequently, I procrastinated on attending to some fine detail by relegating it to a help function which I was confident could be successfully written later. After completing MYEQUAL, I was confident that it would work provided EQATOM worked, so I could then turn my attention entirely to EQATOM, freed of further distraction by concern about the more ambitious overall goal. It turns out that EQATOM is a rather handy utility function anyway, and practice helps develop good judgement about where best to so subdivide tasks. This psychological divide-and-conquer programming technique is important in most other programming languages too. "..=" is different from our previous examples in that "..=" recurses down the CAR as well as down the CDR of an s-expression.; pause; COMMENT If a list has n elements, our function named MEMBERP or the equivalent built-in function named MEMBER requires on the order of n "=" tests. Consequently, the above definitions of SETP and MAKESET, which require on the order of n membership tests, will require on the order of n^2 "=" tests. Similarly, if the two operands have m and n elements, the above definitions of SUBSETOF, EQSETP, INTERSECT, DIFFSET, and SYMDIFF require on the order of m*n "=" tests. We could decrease the growth rates to order of n and order of m+n respectively by sorting the elements before giving lists to these functions. The best algorithms sort a list of n elements in the order of n*log(n) element comparisons, and this need be done only once per input set. To do so we need a function which returns T if the first argument is "=" to the second argument or should be placed to the left of the second argument. Such a function, named ORDP, is already built-into symbolic-mode REDUCE, based on the following rules: 1. Any number orders left of NIL. 2. Larger numbers order left of smaller numbers. 4. Literal atoms order left of numbers. 3. Literal atoms order among themselves by address, as determined by the built-in RLISP function named ORDERP. 5. Non-atoms order left of atoms. 6. Non-atoms order among themselves according to ORDP of their CARs, with ties broken according to ORDP of their CDRs. Try writing an analogous function named MYORD, and, if you are in REDUCE rather than RLISP, test its behavior in comparison to ORDP.; pause; COMMENT Whether or not we use sorted sets, we can reduce the proportionality constant associated with the growth rate by replacing "=" by "EQ" if the set elements are restricted to literal atoms. However, with such elements we can use property-lists to achieve the growth rates of the sorted algorithms without any need to sort the sets. On any LISP system that is efficient enough to support REDUCE with acceptable performance, the time required to access a property of an atom is modest and very insensitive to the number of distinct atoms in the program and data. Consequently, the basic technique for any of our set operations is: 1. Scan the list argument or one of the two list arguments, flagging each element as "SEEN". 2. During the first scan, or during a second scan of the same list, or during a scan of the second list, check each element to see whether or not it has already been flagged, and act accordingly. 3. Make a final pass through all elements which were flagged to remove the flag "SEEN". (Otherwise, we may invalidate later set operations which utilize any of the same atoms.) We could use indicators rather than flags, but the latter are slightly more efficient when an indicator would have only one value (such as having "SEEN" as the value of an indicator named "SEENORNOT"). As an example, here is INTERSECT defined using this technique; symbolic procedure intersect(s1, s2); begin scalar ans, set2; flag(s1, 'seen); set2 := s2; while set2 do << if flagp(car set2, 'seen) then ans := car set2 . ans; set2 := cdr set2 >>; remflag(s1, 'seen); return ans end; COMMENT Perhaps you noticed that, having used a BEGIN-block, group, loop, and assignments, I have not practiced what I preached about using only function composition, conditional expressions, and recursion during this lesson. Well, now that you have had some exposure to both extremes, I think you should always fairly consider both together with appropriate compromises, in each case choosing whatever is most clear, concise, and natural. For set operations based on the property-list approach, I find the style exemplified immediately above most natural. As your last exercise for this lesson, develop a file containing a package for set operations based upon either property-lists or sorting. This is the end of lesson 6. When you are ready to run the final lesson 7, load a fresh copy of REDUCE. ;end; |
Added Lesson_7.red version [c7bc5ffce9].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | COMMENT REDUCE INTERACTIVE LESSON NUMBER 7 David R. Stoutemyer University of Hawaii COMMENT This is lesson 7 of 7 REDUCE lessons. Sometimes it is desired to have a certain facility available to algebraic mode, no such facility is described in the REDUCE User's Manual, and there is no easy way to implement the facility directly in algebraic mode. The possibilities are: 1. The facility exists for algebraic mode, but is undocumented. 2. The facility exists, but is available only in symbolic mode. 3. The facility is not built-in for either mode. Perusal of the REDUCE source code (see https://sourceforge.net/p/reduce-algebra/code/HEAD/tree/trunk/packages/ -- alg contains the core algebra facilities), together with experimentation can reveal which of these alternatives is true. (Even in case 3, an inquiry via the REDUCE Project Forum or Mailing List -- see https://sourceforge.net/projects/reduce-algebra/support -- may reveal that someone else has already implemented the supplementary facility and can provide the code.); pause; COMMENT A type of statement is available to both modes if its leading keyword appears in either of the equivalent statements PUT (..., 'STAT, ...) or DEFLIST('(...), 'STAT). A symbolic-mode global variable is available to algebraic mode and vice-versa if the name of the variable appears in either of the equivalent statements SHARE ..., or FLAG('(...), 'SHARE). A function defined in symbolic mode is directly available to algebraic mode if the function name appears in one of the statements SYMBOLIC OPERATOR ..., PUT(..., 'SIMPFN, ...), DEFLIST('(...), 'SIMPFN), FLAG('(...), 'OPFN). In addition, if you want a function to be used as a predicate in IF or WHILE statements, it should be flagged BOOLEAN, as in FLAG('(...), 'BOOLEAN); pause; COMMENT Other functions which are used but not defined in RLISP are the built-in LISP functions. See a description of the underlying LISP system (normally either PSL or CSL) for documentation on these functions. All Standard Lisp functions should be available. Particularly notable built-in features available only to symbolic mode include 1. A function named SPACES, which outputs the number of blanks indicated by its integer argument. 2. A function named REDERR, which provokes an error interrupt after outputting its arguments. 3. A predicate named KERNP, which returns NIL if its argument is not an indeterminate or a functional form. 4. A function named MATHPRINT, which outputs its argument in natural mathematical notation, beginning on a new line. 5. A function named MAPRIN, which is like MATHPRINT, but does not automatically start or end a new line. 6. A function named TERPRI!*, which ends the current output-line. Thus, for example, all that we have to do to make the predicate KERNP and the function SPACES available to algebraic mode is to type FLAG('(KERNP), 'BOOLEAN), SYMBOLIC OPERATOR SPACES. When such simple remedies are unavailable, we can introduce our own statements or write our own SYMBOLIC-mode variables and procedures, then use these techniques to make them available to algebraic mode. In order to do so, it is usually necessary to understand how REDUCE represents and simplifies algebraic expressions.; pause; COMMENT One of the REDUCE representations is called Cambridge Prefix. An expression is either an atom or a list consisting of a literal atom, denoting a function or operator name, followed by arguments which are Cambridge Prefix expressions. The most common unary operator names are MINUS, LOG, SIN, and COS. The most common binary operator names are DIFFERENCE, QUOTIENT, and EXPT. The most common nary operator names are PLUS and TIMES. Thus, for example, the expression 3*x^2*y + x^(1/2) + e^(-x) could be represented as '(PLUS (TIMES 3 (EXPT X 2) Y) (EXPT X (QUOTIENT 1 2)) (EXPT E (MINUS X)) The parser produces an unsimplified Cambridge Prefix version of algebraic-mode expressions typed by the user, then the simplifier returns a simplified prefix version. When a symbolic procedure that has been declared a symbolic operator is invoked from algebraic mode, the procedure is given simplified Cambridge Prefix versions of the arguments. To illustrate these ideas, here is an infix function named ISFREEOF, which determines whether its left argument is free of the indeterminate, function name, or literal sub-expression which is the right argument. ISFREEOF is similar to the REDUCE FREEOF function but less general.; pause; flag('(isfreeof), 'boolean); infix isfreeof; symbolic procedure campre1 isfreeof campre2; if campre1=campre2 then nil else if atom campre1 then t else (car campre1 isfreeof campre2) and (cdr campre1 isfreeof campre2); algebraic if log(5+x+cos(y)) isfreeof sin(z-7) then write "WORKS ONE WAY"; algebraic if not(log(5+x+cos(y)) isfreeof cos(y)) then write "WORKS OTHER WAY TOO"; COMMENT Conceivably we might wish to distinguish when CAMPRE2 is a literal atom occurring as a function name from the case when CAMPRE2 is a literal atom and occurs as an indeterminate. Accordingly, see if you can write two such more specialized infix predicates named ISFREEOFINDET and ISFREEOFFUNCTION.; pause; COMMENT When writing a symbolic-mode function, it is often desired to invoke the algebraic simplifier from within the function. This can be done by using the function named REVAL, which returns a simplified Cambridge Prefix version of its prefix argument. Usually, REDUCE uses and produces a different representation, which I call REDUCE prefix. The symbolic function AEVAL returns a simplified REDUCE-prefix version of its prefix argument. Both REVAL and AEVAL can take either type of prefix argument. A REDUCE-prefix expression is an integer, a floating-point number, an indeterminate, or an expression of the form ('!*SQ standardquotient . !*SQVAR!*). !*SQVAR!* is a global variable which is set to T when the REDUCE- prefix expression is originally formed. The value of !*SQVAR!* is reset to NIL if subsequent LET, MATCH, or computational ON statements could change the environment is such a way that the expression might require resimplification next time it is used.; pause; COMMENT Standard quotients are neither Cambridge nor REDUCE prefix, so the purpose of the atom '!*SQ is to make the value of all algebraic- mode variables always be some type of prefix form at the top level. A standard quotient is a unit-normal dotted pair of 2 standard forms, and a standard form is the REDUCE representation for a polynomial. Unit-normal means that the leading coefficient of the denominator is positive. REDUCE has a built-in symbolic function SIMP!*, which returns the simplified standard quotient representation of its argument, which can be either Cambridge or REDUCE prefix. REDUCE also has symbolic functions named NEGSQ, INVSQ, ADDSQ, MULTSQ, DIVSQ, DIFFSQ, and CANONSQ which respectively negate, reciprocate, add, multiply, divide, differentiate, and unit-normalize standard quotients. There is also a function named ABSQ, which negates a standard quotient if the leading coefficient of its numerator is negative, and there is a function named EXPTSQ which raises a standard quotient to an integer power. Finally, there is a function named MK!*SQ, which returns a REDUCE prefix version of its standard-quotient argument, and there is also a function named PREPSQ which returns a Cambridge prefix version of its standard-quotient argument. If there is a sequence of operations, rather than converting from prefix to standard quotient and back at each step, it is usually more efficient to do the operations on standard quotients, then use MK!*SQ to make the final result be REDUCE prefix. Also it is often more efficient to work with polynomials rather than rational functions during the intermediate steps.; pause; COMMENT The coefficient domain of polynomials is floating-point numbers, integers, integers modulo an arbitrary integer modulus, or rational numbers. However, zero is represented as NIL. The polynomial variables are called kernels, which can be indeterminates or uniquely-stored fully simplified Cambridge-prefix functional forms. The latter alternative permits the representation of expressions which could not otherwise be represented as the ratio of two expanded polynomials, such as 1. sub-expressions of the form LOG(...) or SIN(...), 2. sub-expressions of the form indeterminate^noninteger, 3. unexpanded polynomials, each polynomial factor being represented as a functional form, 4. rational expressions not placed over a common denominator, each quotient sub-expression being represented as a functional form. A polynomial is represented as a list of its nonzero terms in decreasing order of the degree of the leading "variable". Each term is represented as a standard power dotted with its coefficient, which is a standard form in the remaining variables. A standard power is represented as a variable dotted with a positive integer degree.; pause; COMMENT Letting ::= denote "is defined as" and letting | denote "or", we can summarize the REDUCE data representations as follows: reduceprefix ::= ('!*SQ standardquotient . !*SQVAR!*) standardquotient ::= NUMR(standardquotient) ./ DENR(standardquotient) NUMR(standardquotient) ::= standardform DENR(standardquotient) ::= unitnormalstandardform domainelement ::= NIL | nonzerointeger | nonzerofloat | nonzerointeger . positiveinteger standardform ::= domainelement | LT(standardform) .+ RED(standardform) RED(standardform) ::= standardform LT(standardform) := LPOW(standardform) .* LC(standardform) LPOW(standardform) := MVAR(standardform) .^ LDEG(standardform) LC(standardform) ::= standardform MVAR(standardform) ::= kernel kernel ::= indeterminate | functionalform functionalform ::= (functionname Cambridgeprefix1 Cambridgeprefix2 ...) Cambridgeprefix ::= integer | float | indeterminate | functionalform LC(unitnormalstandardform) ::= positivedomainelement | unitnormalstandardform I have taken this opportunity to also introduce the major REDUCE selector macros named NUMR, DENR, LT, RED, LPOW, LC, MVAR, and LDEG, together with the major constructor macros named ./, .+, .*, and .^ . The latter are just mnemonic aliases for ".". A comparison of my verbal and more formal definitions also reveals that the selectors are respectively just aliases for CAR, CDR, CAR, CDR, CAAR, CDAR, CAAAR, and CDAAR. Since these selectors and constructors are macros rather than functions, they afford a more readable and modifiable programming style at no cost in ultimate efficiency. Thus you are encouraged to use them and to invent your own when convenient. As an example of how this can be done, here is the macro definition for extracting the main variable of a standard term:; % symbolic smacro procedure tvar trm; caar trm; pause; COMMENT It turns out that there are already built-in selectors named TC, TPOW, and TDEG, which respectively extract the coefficient, leading power, and leading degree of a standard term. There are also built-in constructors named !*P2F, !*K2F, !*K2Q, and !*T2Q, which respectively make a power into a standard form, a kernel into a standard form, a kernel into a standard quotient, and a term into a standard quotient. See the REDUCE User's Manual for a complete list. The unary functions NEGF and ABSF respectively negate, and unit- normalize their standard-form arguments. The binary functions ADDF, MULTF, QUOTF, SUBF, EXPTF, and GCDF respectively add, multiply, divide, substitute into, raise to a positive integer power, and determine the greatest common divisor of standard forms. See if you can use them to define a macro which subtracts standard forms.; pause; COMMENT The best way to become adept at working with standard forms and standard quotients is to study the corresponding portions of the REDUCE source listing. The listing of ADDF and its subordinates is particularly instructive. As an exercise, see if you can write a function named ISFREEOFKERN which determines whether or not its left argument is free of the kernel which is the right argument, using REDUCE prefix rather than Cambridge prefix for the left argument.; pause; COMMENT As a final example of the interaction between modes, here is a function which produces simple character-based plots. Note that, to keep the implementation as simple as possible, values of the indeterminate ("x") increase downwards and values of the expression plotted ("y") increase to the right. This is the conventional orientation rotated clockwise through 90 degrees!; share ncols; ncols := 66; symbolic operator plot; symbolic procedure plot(ex, xinit, dx, ndx, yinit, dy); begin COMMENT This procedure produces a character-plot of univariate expression EX where, XINIT is the initial value of the indeterminate, DX is the increment per line of the indeterminate, NDX is the number of lines plotted, YINIT is the value represented at the left edge, DY is incremental value per column. The shared variable NCOLS, initially 66, is the number of columns used. Points are plotted using "*", except "<" and ">" are used at the left and right edges to indicate out of bounds points.; scalar x, f, y; integer col, ncolsminus1; ncolsminus1 := ncols - 1; write "Starting the plot of ",ex; x := listofvars ex; % find indeterminates; if length x > 1 then rederr "ERROR: PLOT expression can have at most 1 indeterminate"; if null x then << write "ERROR: no indeterminates in ", ex; rederr "" >> else x := car x; write " in variable ", x; terpri(); COMMENT Convert args from algebraic to symbolic values; xinit := revalx xinit; dx := revalx dx; yinit := revalx yinit; dy := revalx dy; for j:= 0:ndx do << % generate expression with current value substituted for x f := subst(xinit + j*dx, x, ex); y := eval(f); % eval expression col := rnd((y - yinit)/dy); % scale and round for cols if col<0 then write "<" else if col > ncolsminus1 then << spaces(ncolsminus1); prin2 ">"; terpri() >> else << spaces(col); prin2 "*"; terpri() >> >> ; if null y then rederr "ERROR: UNABLE TO PERFORM FLOATING-POINT EVALUATION OF 1ST ARG" end; pause; symbolic procedure listofvars campre; if null campre or numberp campre then nil else if atom campre then list campre else varsinargs cdr campre; symbolic procedure varsinargs listofcampre; if null listofcampre then nil else union(listofvars car listofcampre, varsinargs cdr listofcampre); symbolic procedure rnd x; begin scalar ans; ans := revalx x; if not numberp x then redderr "RND GIVEN NON-NUMERIC ARGUMENT"; if ans >=0 then ans := fix(ans+00.5) else ans:= fix(ans-0.5); return ans end; symbolic procedure revalx u; % MAKE SURE WE GET TRUE FLOATS IN SYMBOLIC MODE. if eqcar(u,'!:rd!:) then rdprepx u else u; symbolic procedure rdprepx u; if floatp cdr u then cdr u else bf2flr u; pause; on rounded; plot(y^2, 0, 0.25, 10, 0, 0.25); pause; plot((a+1)^2, 0, 0.25, 10, 0, 0.25); pause; b := a*2; plot(a*b, 0, 0.25, 10, 0, 0.25); pause; COMMENT We leave it as an exercise to write a more elaborate plot procedure which offers amenities such as automatic scaling, numbered ordinates, etc. Good luck with these exercises, with REDUCE, with computer algebra and with all of your endeavors. ;end; |
Added Linear_Algebra.red version [fe561f5c75].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | %%%%%%%%%%%%%%%%%%%%% % LINEAR ALGEBRA %%%%%%%%%%%%%%%%%%%%% % Enable fancy output for easier viewing of % matrix output fancy_output$ % Load linear algebra package load_package linalg$ % Define a complex 3x3 matrix m1 := mat((1+i*3, 2-i*5, 7-i), (4-i*2, 6+i*9,-8+i*4), (-3-i*7, 3+i*2, -1+i*6)); % Determinant of matrix write "|m1| = ", det(m1)$ % Trace of matrix write "trace(m1) = ", trace(m1)$ % Characteristic polynomial write "characteristic polynomial of m1:"; char_poly(m1,eta); % Enable real arithmetic on rounded$ % Singular value decomposition of a matrix. a := mat((1,3),(-4,3)); write "Singular Value Decomposition of a:"$ svd(a); |
Added Plotting.red version [1b663a7db2].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | %%%%%%%%%%%%%%%%%%%%% % PLOTTING %%%%%%%%%%%%%%%%%%%%% % Load gnuplot package load_package gnuplot$ % Plot of sine and cosine plot(sin(x), title="sin(x) and cos(x)", output="Sine and Cosine"); plot(cos(x), title="sin(x) and cos(x)"); % Superposition of polynomials plot((x^2+y^2-9)*x*y=0, title="Polynomials", output="Polynomials"); % 3D surface plot plot(cos sqrt(x**2+y**2),x=(-10 .. 10),y=(-10 .. 10),hidden3d, title="cos sqrt(x^2+y^2)", points=50, output="3D Plot"); % Super-Ellipsoid on rounded; ax:=3$ ay:=3$ az:=4$ ns:=4/5$ ew:=1$ for all w,m let c(w,m) = sign(cos(w))*abs(cos(w))**m$ for all w,m let s(w,m) = sign(sin(w))*abs(sin(w))**m$ for all u,v let x(u,v) =ax * c(v, ns)*c(u, ew)$ for all u,v let y(u,v) =ay * c(v, ns)*s(u, ew)$ for all u,v let z(u,v) =az * s(v, ns)$ dd:=pi/15$ w:=for u:=-pi step dd until pi collect for v:=-pi/2 step dd until pi/2 collect {x(u,v),y(u,v),z(u,v)}$ gnuplot(set, ticslevel, 0)$ gnuplot(set, xtics, -4, 1, 4)$ gnuplot(set, ytics, -4, 1, 4)$ gnuplot(set, ztics, -4, 1, 4)$ plot (w, hidden3d, title="Super-Ellipsoid", output="Super-Ellipsoid")$ % 3D surface plot with gradients using the % CAS mode gnuplot operator of the gnuplot % package. The same plot could be created % using direct gnuplot commands in Plot % mode. plotreset$ gnuplot("unset hidden3d"); gnuplot("unset hidden"); gnuplot("unset surface"); gnuplot("set output ""3D Log"""); gnuplot("set title ""3D Log"""); gnuplot("set samples 30; set isosamples 30"); gnuplot("set pm3d"); gnuplot("set style line 100 lt 5 lw 0.5"); gnuplot("set pm3d hidden3d 100"); gnuplot("set view 57,220"); gnuplot("set xrange [-2:2]"); gnuplot("set yrange [-2:2]"); gnuplot("splot log(x*x*y*y)"); plotshow; % 3D Torus % Again, the same plot could be generated % with direct gnuplot commands in Plot % mode. plotreset$ gnuplot("set title ""Interlocking Torus"""); gnuplot("set output ""Torus"""); gnuplot("set parametric"); gnuplot("set urange [-pi:pi]"); gnuplot("set vrange [-pi:pi]"); gnuplot("set isosamples 50,20"); gnuplot("unset key"); gnuplot("unset xtics"); gnuplot("unset ytics"); gnuplot("unset ztics"); gnuplot("set border 0"); gnuplot("set view 60, 30, 1.5, 0.9"); gnuplot("set origin 0.0,-0.075"); gnuplot("set size 0.9, 1.1"); gnuplot("set colorbox vertical user origin 0.9, 0.15 size 0.02, 0.50"); gnuplot("set format cb ""%.1f"""); gnuplot("set pm3d depthorder"); gnuplot("splot cos(u)+.5*cos(u)*cos(v),sin(u)+.5*sin(u)*cos(v),.5*sin(v) with pm3d, 1+cos(u)+.5*cos(u)*cos(v),.5*sin(v),sin(u)+.5*sin(u)*cos(v) with pm3d"); plotshow; |
Added Programming.red version [61ad17dfc9].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | %%%%%%%%%%%%%%%%%%%%% % PROGRAMMING %%%%%%%%%%%%%%%%%%%%% % Define number to factorize x:=42; % Factorize x and write out each individual % factor factors:=factorize(fix(x))$ x:=0$ for i:=1:length(factors) do begin q:=part(factors,i); for j:=1:part(q,2) do begin x:=x+1; write "factor ", x, ": ", part(q,1); end; end; % Procedure to calculate Legendre polynomial % using recursion procedure p(n,x); if n<0 then rederr "Invalid argument to p(n,x)" else if n=0 then 1 else if n=1 then x else ((2*n-1)*x*p(n-1,x)-(n-1)*p(n-2,x))/n$ % Enable fancy output fancy_output$ % Calculate p(2,w) write "P(2,w) = ", p(2,w); % Incidentally, p(n,x) can be calculated more % efficiently as follows procedure p(n,x); sub(y=0,df(1/(y^2-2*x*y+1)^(1/2),y,n))/(for i:=1:n product i)$ write "P(3,w) = ", p(3,w); |
Added README.md version [3d3bb6261c].
> | 1 | # icas-bundled |
Added REDUCE_Commands.red version [cb5b4d2471].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | Excerpted from the REDUCE Manual Version 3.8 COMMANDS & IDENTIFIERS We list here all identifiers that are normally reserved in REDUCE including names of commands, operators and switches initially in the system. Excluded are words that are reserved in specific implementations of the system. Commands ALGEBRAIC ANTISYMMETRIC ARRAY BYE CLEAR CLEARRULES COMMENT CONT DECOMPOSE DEFINE DEPEND DISPLAY ED EDITDEF END EVEN FACTOR FOR FORALL FOREACH GO GOTO IF IN INDEX INFIX INPUT INTEGER KORDER LET LINEAR LISP LISTARGP LOAD LOAD PACKAGE MASS MATCH MATRIX MSHELL NODEPEND NONCOM NONZERO NOSPUR ODD OFF ON OPERATOR ORDER OUT PAUSE PRECEDENCE PRINT PRECISION PROCEDURE QUIT REAL REMFAC REMIND RETRY RETURN SAVEAS SCALAR SETMOD SHARE SHOWTIME SHUT SPUR SYMBOLIC SYMMETRIC VECDIM VECTOR WEIGHT WRITE WTLEVEL Boolean Operators EVENP FIXP FREEOF NUMBERP ORDP PRIMEP Infix Operators := = >= > <= < => + - * / ˆ ** . WHERE SETQ OR AND MEMBER MEMQ EQUAL NEQ EQ GEQ GREATERP LEQ LESSP PLUS DIFFERENCE MINUS TIMES QUOTIENT EXPT CONS Numerical Operators ABS ACOS ACOSH ACOT ACOTH ACSC ACSCH ASEC ASECH ASIN ASINH ATAN ATANH ATAN2 COS COSH COT COTH CSC CSCH EXP FACTORIAL FIX FLOOR HYPOT LN LOG LOGB LOG10 NEXTPRIME ROUND SEC SECH SIN SINH SQRT TAN TANH Prefix Operators APPEND ARGLENGTH CEILING COEFF COEFFN COFACTOR CONJ DEG DEN DET DF DILOG EI EPS ERF FACTORIZE FIRST GCD G IMPART INT INTERPOL LCM LCOF LENGTH LHS LINELENGTH LTERM MAINVAR MAT MATEIGEN MAX MIN MKID NULLSPACE NUM PART PF PRECISION PROD RANDOM RANDOM NEW SEED RANK REDERR REDUCT REMAINDER REPART REST RESULTANT REVERSE RHS SECOND SET SHOWRULES SIGN SOLVE STRUCTR SUB SUM THIRD TP TRACE VARNAME Reserved Variables CARD NO E EVAL MODE FORT WIDTH HIGH POW I INFINITY K!* LOW POW NIL PI ROOT MULTIPLICITIES T Switches ADJPREC ALGINT ALLBRANCH ALLFAC BALANCE MOD BFSPACE COMBINEEXPT COMBINELOGS COMP COMPLEX CRAMER CREF DEFN DEMO DIV ECHO ERRCONT EVALLHSEQP EXP EXPANDLOGS EZGCD FACTOR FORT FULLROOTS GCD IFACTOR INT INTSTR LCM LIST LISTARGS MCD MODULAR MSG MULTIPLICITIES NAT NERO NOSPLIT OUTPUT PERIOD PRECISE PRET PRI RAT RATARG RATIONAL RATIONALIZE RATPRI REVPRI RLISP88 ROUNDALL ROUNDBF ROUNDED SAVESTRUCTR SOLVESINGULAR TIME TRA TRFAC TRIGFORM TRINT Other Reserved Ids BEGIN DO EXPR FEXPR INPUT LAMBDA LISP MACRO PRODUCT REPEAT SMACRO SUM UNTIL WHEN WHILE WS |
Added Special_Functions.red version [c0b3ce1144].
> > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | %%%%%%%%%%%%%%%%%%%%% % SPECIAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%% % Load special functions load_package specfn$ % Gamma function Gamma(0.5); % Enable real arithmetic on rounded$ % Zeta function Zeta(3/2); % Bessel function of the first kind and order 3 besselj(3, 0.5); |
Added Welcome.red version [c6ade7a4de].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 | %%%%%%%%%%%%%%%%%%%%%% % WELCOME TO iCAS % % The core of iCAS is based on REDUCE, a % powerful CAS system with comparable % capabilities to Maple and Mathematica % with a track record spanning over 40 years % in academic and research institutions. % iCAS brings all the capabilities of % REDUCE and the embedded gnuplot % plotting engine to your iPhone or iPod % touch. % % Best of all, iCAS is entirely self-contained % and runs natively on your iPhone or iPod % touch so no internet connection is required % to harness its power. % % This file is written as a short tutorial % to walk you through some simple examples % to become familiar with the app and help % you get started. % %%%%%%%%%%%%%%%%%%%%%% % BASIC USAGE % % Enter the desired command or operation % and press return to execute the command or % operation. Try it by tapping to the right of % the semicolon on the line below and then % tapping return. 6 * 7; % If fancy output is enabled, the results can be % viewed in a typeset format by tapping a % translucent button that appears on the upper % right hand corner of this view when there is % fancy output or when iCAS detects LaTeX % content. The output view can be zoomed % using the standard pinch gestures. % % Fancy output can be globally enabled with % the "Create Fancy Output" setting or on a % case by case basis using the fancy switch. % If fancy output is enabled and the % "Automatically Show" option is enabled, % iCAS will automatically show the rendered % fancy output when it is generated. % % Execute the following lines (i.e. place the % cursor to the right of the semicolon and tap % the return key) to see the difference % between plain and fancy output. df(x^x,x); on fancy; df(x^x,x); % Notice the pseudo-LaTeX output format % and the "TeX" translucent button that % appeared on the top right of the window. % Tapping the "TeX" button generates a % typeset version of the file that can be % optionally emailed as a LaTeX source file % for publishing, presentation, and/or sharing % with colleagues. % % Fancy output works best with a line length % of 80 or more. iCAS sets the linelength to % the optimal width for plain output when a % CAS session is started based on the font % style and size settings. Therefore, we % recommend setting the linelength to 80 % when using fancy output. iCAS provides a % convenience command called fancy_output % that sets the fancy switch and sets the % linelength to 80 characters. Note that % turning the fancy switch off does not % affect the linelength so you may need to % set the linelength to an appropriate value % after using fancy output. The linelength % is reset when a new CAS session is % initiated (e.g. by using either the "bye" % or "quit" command). % %%%%%%%%%%%%%%%%%%%%%% % KEYBOARD USAGE % % By default, iCAS uses the system keyboard. % A user configurable macro keyboard and a % numerical keyboard are also optionally % available. The enabled keyboards and the % default keyboard can be configured in the % app Settings. The app Settings can be % accessed either through the global Settings % app or by tapping the Settings button on % the top right corner of the screen. % % To switch between the enabled keyboards, % use a horizontal swipe gesture in the text % area when a keyboard is active. % % To dismiss the keyboard, tap the center of % the top bar where "Welcome" is currently % displayed) or tap the "dismiss" keyboard % button above the keyboard if the "Arrow % Keys" setting is enabled. This restores % access to the toolbar butons. % % By default, tapping a button other than % the "CLEAR" or "BATCH" buttons on the % macro keyboard causes the active keyboard % to automatically switch to the system % keyboard to allow entry of variables, % parameters, arguments, etc. This behavior % can be enabled/disabled using the "Auto % Hide Macros" setting. % % Tap the clear line below to active the % keyboard and swipe from right to left to % reveal the macro keyboard. Now tap the % "integral" button. % Now double tap "function" and replace it % with some function of x, say x, to keep it % quick and simple. Then execute the line. % Unless you've disabled fancy output, iCAS % will have output a pseudo-LaTeX output % that you can view by tapping the "TeX" % button at the top right. Go ahead and tap it % to see the output in the LaTeX viewer. % % Tapping return on the system keyboard % can be configured to automatically switch % to the macro keyboard to enable the entry % of other CAS commands. This is controlled % by the "Return Shows Macros" setting. % % To edit the contents of a macro button, tap % and hold down the button for 1 second or % longer. % % Instances of \n in macros get automatically % converted into new lines. This makes it % possible to create macros with text % spanning multiple lines. % % Assigning \r to a macro button turns that % button into a silent return key. That is, % it inserts a new line character without % processing the contents of the line. % % Assigning \b to a macro button turns that % button into a backspace/delete key. % % Assigning \c to a macro button turns that % button into a clear key. % % Assigning \cb to a macro button turns that % button into a clear batch output key. The % macro has no effect if there is no batch % output. % % The cursor placement within a macro can be % optionally specified by including \^ in % the macro where the cursor should be after % the macro is inserted. For example, the % macro “(\^)” will cause the cursor to be % placed between the two parentheses. % % The macro buttons can be optionally % labelled by including the desired label % surrounded by the # character in the macro % text. For example, if a macro contains % #LABEL# in its definition, the button will % display LABEL in a larger font instead of % the actual contents of the macro. % % The following labels (in uppercase) are % automatically displayed with the % mathematical symbol for the corresponding % CAS operator/constant: DF, E, I, % INFINITY, INT, PI, PROD, and SUM. % % The default integral, derivative, pi, and % infinity buttons are examples that utilize % these features. % %%%%%%%%%%%%%%%%%%%%%% % PLOTTING % % iCAS includes a full implementation of % gnuplot that can be accessed in CAS mode % using the gnuplot package or directly in % plot mode (more on modes later). By % default, iCAS loads the gnuplot package so % unless you changed the "Always Load % gnuplot" setting, it should already be % loaded. % % By default, iCAS automatically shows % newly generated or updated plots. This % behavior can be disabled in the global % settings. % % Plots can be magnified using the standard % pinch gestures. iCAS supports landscape % orientations in all its views so plots can be % viewed in either portrait or landscape % orientations. Execute the line below to % see plotting in action and use the pinch % gesture to zoom in/out and swipe gestures % to pan around the plot while zoomed in. plot(sin(x)); % Unless specified, iCAS uses the title "iCAS % Plot" and the file name "CASPlot" for plot % files. The default plot title can be changed % in the app Settings and can also be set % on a per plot basis. Execute the below line % to see an example. plot(cos(x), title="cos(x)", output="cos(x)"); % Plot files can be accessed by tapping the % "folder" button on the right side of the % bottom toolbar. Go ahead and dismiss the % keyboard (tap "Welcome" above) and tap % the button now. % % The files organizer picker has four wheels. % One for text files such as this one, one for % plot files, one for REDUCE inout files, and % one for macro keyboard files. Aim the left % picker wheel to view the corresponding % files. Files can be deleted, emailed, or % viewed/selected with the buttons above the % picker wheels. % % The displayed contents can be emailed, % copied, or printed by tapping the "send" % button button on the right side of the bottom % toolbar. Text files are emailed using the % active font style. The ont style, font size, % and colors can be configured using the styles % panel revealed by tapping the "styles" button % on the left of the bottom toolbar. The % available font styles are "Helvetica", % "Times", and "Courier". Although not the % prettiest, Courier can be optimal as it is % the closest to a monospace font on iOS % devices. % % Plots can be emailed in SVG format which % is a resolution independent format % supported by major browsers including % Safari and FireFox. % %%%%%%%%%%%%%%%%%%%%%% % OPERATION MODES % % iCAS supports three operation modes. % % • CAS Mode % • Plot Mode % • Text Editor Mode % % By default, the application's color theme % changes to indicate the active mode. This % color feedback behavior can be disabled in % the app Settings, if desired. % % In CAS mode (the current mode unless % you've changed the mode with the mode % controls switch in the middle of the % toolbar), iCAS behaves as a terminal % interface to the CAS engine. % % In Plot mode, iCAS behaves as a direct % terminal interface to the gnuplot engine. % Go ahead and dismiss the keyboard and tap % the "plot" mode button (the button with a % graph) to switch to Plot mode. Then % execute each of the following lines in % sequence. This is an example straight from % the gnuplot demonstration samples web % page. set output "3D Log" set title "3D Log" set samples 30; set isosamples 30 set hidden3d set pm3d set surface set view 50,220 set xrange [-2:2] set yrange [-2:2] splot log(x*x*y*y) % As you can see, iCAS accepts gnuplot % commands directly. % % In Text Editor mode, iCAS behaves as a % plain text editor. Pressing return does not % invoke either CAS or plot operations. This % mode is useful for general-purpose text % editing, to create input files for batch % execution (described below), to % create/preview LaTeX documents, etc. % % The active file is automatically saved when % the application is quit/placed in the % background or when a new file is opened. % % There may be times when you need to abort % the active CAS session. To abort a CAS % session that is idle, simply use the % REDUCE "bye" or "quit" command. A % new session will be automatically restarted. % To abort a CAS session that is busy, tap % the "Abort" button that replaces the % "Settings" button while iCAS is busy. Set % the mode to CAS mode using the mode % buttons and go ahead and abort the CAS % session using the following example that % intentionally invokes a very long for-loop. for i:=0:10000000 do j:=i; %%%%%%%%%%%%%%%%%%%%%% % BATCH OPERATION % % In addition to the interactive operation % that we've just used, iCAS supports batch % execution of entire file contents. That % is, iCAS can process the entire contents % of the active file either in CAS mode or % Plot mode. To do so, use the special % "BATCH" macro keyboard button. Unlike % interactive results which are output at the % current cursor location, CAS mode batch % execution results are appended to the end % of the file surrounded by "%%% Begin Batch % Results" and "%%% End Batch Results" so % they can be easily located with a quick % search. % % Plot mode results are of course the creation % of plot files. Note that plot files are % not automatically shown when they are % generated in batch mode. To view batch % generated plot files, please use the files % picker. % % Now, this file contains interactive output % from the examples that we've run so if you % process this file in batch mode, it will % result in errors. Therefore, please try % batch execution using one of the example % files. % %%%%%%%%%%%%%%%%%%%%%% % FOR MORE INFORMATION % % We hope that you found this tutorial % helpful. You'll find more examples for % various areas in the files picker. You % will also find more information in the % iCAS FAQ at the following URL. % % http://alsoftiphone.com/iCAS/faq % % Last but not least, if you have any questions % or feedback, please don't hesitate to contact % us at support@alsoftiphone.com. You can % quickly do so by tapping the "Contact % Support"button at the bottom of the app % Settings. % % We hope that you will find iCAS a useful % companion for your computation needs. % % Best Regards, % AL Software % %%%%%%%%%%%%%%%%%%%%%% |
Added Welcome_iPad.red version [116ddf461d].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % WELCOME TO iCAS % % The core of iCAS is based on REDUCE, a powerful CAS system with comparable capabilities % to Maple and Mathematica with a track record spanning over 40 years in academic and research % institutions. iCAS brings all the capabilities of REDUCE and the embedded gnuplot plotting % engine to your iPad. Best of all, iCAS is entirely self-contained and runs natively on your iPad % so no internet connection is required to harness its power. % % This file is written as a short tutorial to walk you through some simple examples to become % familiar with the app and help you get started. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % BASIC USAGE % % Enter the desired command or operation and press return to execute the command or operation. % Try it by tapping to the right of the semicolon on the line below and then tapping return. 6 * 7; % If fancy output is enabled, the results can be viewed in a typeset format by tapping a translucent % button that appears on the upper right hand corner of this view when there is fancy output or % iCAS detects LaTeX content. The output view can be zoomed using the standard pinch gestures. % % Fancy output can be globally enabled with the "Create Fancy Output" option or on a case by case % basis using the fancy switch. If fancy output is enabled and the "Automatically Show" option is % enabled, iCAS will automatically show the rendered fancy output when it is generated. % % Execute the following lines (i.e. place the cursor to the right of the semicolon and tap the return % key) to see the difference between plain and fancy output. df(x^x,x); on fancy; df(x^x,x); % Notice the pseudo-LaTeX output format and the "TeX" translucent button that appeared on the % top right of the window. Tapping the "TeX" button generates a typeset version of the file that % can be optionally emailed as a LaTeX source file for publishing, presentation, and/or sharing with % colleagues. % % Fancy output works best with a line length of 80 or more. iCAS sets the linelength to the optimal % width for plain output when a CAS session is started based on the font style and size settings. % Therefore, we recommend setting the linelength to 80 when using fancy output. iCAS provides a % convenience command called fancy_output that sets the fancy switch and sets the linelength to 80 % characters. Note that turning the fancy switch off does not affect the linelength so you may need % to set the linelength to an appropriate value after using fancy output. The linelength is reset when % a new CAS session is initiated (e.g. by using either the "bye" or "quit" command). % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % KEYBOARD USAGE % % By default, iCAS uses the system keyboard. A user configurable macro keyboard and a % numerical keyboard are also optionally available. The enabled keyboards and the default % keyboard can be configured in the app Settings. The app Settings can be accessed either through the % global Settings app or by tapping the Settings button on the top right corner of the screen. % % To switch between the enabled keyboards, use a horizontal swipe gesture in the text area when a % keyboard is active. % % By default, tapping a button other than the "CLEAR" or "BATCH" buttons on the macro % keyboard causes the active keyboard to automatically switch to the system keyboard to allow % entry of variables, parameters, arguments, etc. This behavior can be enabled/disabled using the % "Auto Hide Macros" setting. % % Tap the clear line below to active the keyboard and swipe from right to left to reveal the macro % keyboard. Now tap the "integral" button. % Now double tap "function" and replace it with some function of x, say x, to keep it quick and % simple. Then execute the line. Unless you've disabled fancy output, iCAS will have output a % pseudo-LaTeX output that you can view by tapping the "TeX" button at the top right. Go ahead % and tap it to see the output in the LaTeX viewer. % % Tapping return on the system keyboard can be configured to automatically switch to the macro % keyboard to enable the entry of other CAS commands. This is controlled by the "Return Shows % Macros" setting. % % To edit the contents of a macro button, tap and hold down the button for 1 second or longer. % % Instances of \n in macros get automatically converted into new lines. This makes it possible to % create macros with text spanning multiple lines. % % Assigning \r to a macro button turns that button into a silent return key. That is, it inserts a % new line character without processing the contents of the line. % % Assigning \b to a macro button turns that button into a backspace/delete key. % % Assigning \c to a macro button turns that button into a clear key. % % Assigning \cb to a macro button turns that button into a clear batch output key. The macro has % no effect if there is no batch output. % % The cursor placement within a macro can be optionally specified by including \^ in the macro where % the cursor should be after the macro is inserted. For example, the macro “(\^)” will cause the % cursor to be placed between the two parentheses. % % The macro buttons can be optionally labelled by including the desired label surrounded by the # % character in the macro text. For example, if a macro contains #LABEL#, the button will display % LABEL in a larger font instead of the actual contents of the macro. % % The following labels (in uppercase) are automatically displayed with the mathematical symbol for % the corresponding CAS operator/constant: DF, E, I, INFINITY, INT, PI, PROD, and SUM. % % The default integral, derivative, pi, and infinity buttons are examples that utilize these features. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % PLOTTING % % iCAS includes a full implementation of gnuplot that can be accessed in CAS mode using the % gnuplot package or directly in plot mode (more on modes later). By default, iCAS loads the % gnuplot package so unless you changed the "Always Load gnuplot" setting, it should already be % loaded. % % By default, iCAS automatically shows newly generated or updated plots. This behavior can be % disabled in the global settings. % % Plots can be magnified using the standard pinch gestures. iCAS supports landscape orientations % in all its views so plots can be viewed in either portrait or landscape orientations. Execute the % line below to see plotting in action and use the pinch gesture to zoom in/out and swipe gestures % to pan around the plot while zoomed in. plot(sin(x)); % Unless specified, iCAS uses the title "iCAS Plot" and the file name "CASPlot" for plot files. The % default plot title can be changed in the global settings and can also be set on a per plot basis. % Execute the below line to see an example. plot(cos(x), title="cos(x)", output="cos(x)"); % Plot files can be accessed by tapping the "folder" button on the right side of the menu bar. Go % ahead and tap the button now. % % The files organizer picker has four wheels. One for text files such as this one, one for plot files, % one for REDUCE inout files, and one for macro keyboard files. Aim the left picker wheel to view the % corresponding files. Files can be deleted, mailed, or viewed/selected with the buttons above the % picker wheels. % % The displayed contents can be emailed, copied, or printed by tapping the "send" button button on % the right side of the bottom toolbar. Text files are emailed using the active font style. The % font style, font size, and colors can be configured using the styles panel revealed by tapping the % "styles" button on the left of the bottom toolbar. The available font styles are "Helvetica", "Times", % and "Courier". Although not the prettiest, Courier can be optimal as it is the closest to a monospace % font on iOS devices. % % Plots can be emailed in SVG format which is a resolution independent format supported by major % major browsers including Safari and FireFox. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % OPERATION MODES % % iCAS supports three operation modes. % % • CAS Mode % • Plot Mode % • Text Editor Mode % % By default, the application's color theme changes to indicate the active mode. This color feedback % behavior can be disabled in the app Settings, if desired. % % In CAS mode (the current mode unless you've changed the mode with the mode controls switch % in the middle of the toolbar), iCAS behaves as a terminal interface to the CAS engine. % % In Plot mode, iCAS behaves as a direct terminal interface to the gnuplot engine. Go ahead and % dismiss the keyboard and tap the "plot" mode button (the button with a graph) to switch to Plot % mode. Then execute each of the following lines in sequence. This is an example straight from the % gnuplot demonstration samples web page. set output "3D Log" set title "3D Log" set samples 30; set isosamples 30 set hidden3d set pm3d set surface set view 50,220 set xrange [-2:2] set yrange [-2:2] splot log(x*x*y*y) % As you can see, iCAS accepts gnuplot commands directly. % % In Text Editor mode, iCAS behaves as a plain text editor. Pressing return does not invoke either % CAS or plot operations. This mode is useful for general-purpose text editing, to create input files % for batch execution (described below), to create/preview LaTeX documents, etc. % % The active file is automatically saved when the application is quit/placed in the background or % when a new file is opened. % % There may be times when you need to abort the active CAS session. To abort a CAS session that is % idle, simply use the REDUCE "bye" or "quit" command. A new session will be automatically % restarted. To abort a CAS session that is busy, tap the "Abort" button that replaces the % "Settings" button while iCAS is busy. Set the mode to CAS mode using the mode buttons and go % ahead and abort the CAS session using the following example that intentionally invokes a very long % for-loop. for i:=0:10000000 do j:=i; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % BATCH OPERATION % % In addition to the interactive operation that we've just used, iCAS supports batch execution of % entire file contents. That is, iCAS can process the entire contents of the active file either in CAS % mode or Plot mode. To do so, use the special "BATCH" macro keyboard button. Unlike % interactive results which are output at the current cursor location, CAS mode batch execution % results are appended to the end of the file surrounded by "%%% Begin Batch Results" and % "%%% End Batch Results" so they can be easily located with a quick search. % % Plot mode results are of course the creation of plot files. Note that plot files are not % automatically shown when they are generated in batch mode. To view batch generated plot % files, please use the files picker. % % Now, this file contains interactive output from the examples that we've run so if you process this % file in batch mode, it will result in errors. Therefore, please try batch execution using one of the % example files. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % FOR MORE INFORMATION % % We hope that you found this tutorial helpful. You'll find more examples for various areas in the % files picker. You will also find more information in the iCAS FAQ at the following URL. % % http://alsoftiphone.com/iCAS/faq % % Last but not least, if you have any questions or feedback, please don't hesitate to contact us at % support@alsoftiphone.com. You can quickly do so by either tapping the "i" button on the bottom % right corner and then tapping the "Feedback" button or by tapping the "Contact Support" button at % the bottom of the app Settings. % % We hope that you will find iCAS a useful companion for your computation needs. % % Best Regards, % AL Software % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |