Merge branch 'rtoy-wrap-option-args'
[maxima.git] / doc / info / Numerical.texi
blobe66407ae3d13f5afde464e226aac83a2ea2d271d
1 @menu
2 * Introduction to fast Fourier transform::                     
3 * Functions and Variables for fast Fourier transform::
4 * Functions and Variables for FFTPACK5::
5 * Functions for numerical solution of equations::
6 * Introduction to numerical solution of differential equations::
7 * Functions for numerical solution of differential equations::
8 @end menu
10 @c -----------------------------------------------------------------------------
11 @node Introduction to fast Fourier transform, Functions and Variables for fast Fourier transform, , Numerical
12 @section Introduction to fast Fourier transform
13 @c -----------------------------------------------------------------------------
15 The @code{fft} package comprises functions for the numerical (not symbolic)
16 computation of the fast Fourier transform.  This is limited to
17 sequences whit length that is a power of two.  For more general
18 lengths, consider the @code{fftpack5} package that supports sequences
19 of any length, but is most efficient if the length is a product of
20 small primes.
23 @opencatbox{Categories:}
24 @category{Fourier transform}
25 @category{Numerical methods}
26 @category{Share packages}
27 @category{Package fft}
28 @closecatbox
30 @c end concepts Numerical
32 @c -----------------------------------------------------------------------------
33 @node Functions and Variables for fast Fourier transform, Functions and Variables for FFTPACK5, Introduction to fast Fourier transform, Numerical
34 @section Functions and Variables for fft
35 @c -----------------------------------------------------------------------------
37 @c -----------------------------------------------------------------------------
38 @anchor{polartorect}
39 @deffn {Function} polartorect (@var{r}, @var{t})
41 Translates complex values of the form @code{r %e^(%i t)} to the form
42 @code{a + b %i}, where @var{r} is the magnitude and @var{t} is the phase.
43 @var{r} and @var{t} are 1-dimensional arrays of the same size.
44 The array size need not be a power of 2.
46 The original values of the input arrays are
47 replaced by the real and imaginary parts, @code{a} and @code{b}, on return.
48 The outputs are calculated as
50 @example
51 a = r cos(t)
52 b = r sin(t)
53 @end example
55 @mref{polartorect} is the inverse function of @mrefdot{recttopolar}
57 @code{load("fft")} loads this function.  See also @mrefdot{fft}
59 @opencatbox{Categories:}
60 @category{Package fft}
61 @category{Complex variables}
62 @closecatbox
63 @end deffn
65 @c -----------------------------------------------------------------------------
66 @anchor{recttopolar}
67 @deffn {Function} recttopolar (@var{a}, @var{b})
69 Translates complex values of the form @code{a + b %i} to the form
70 @code{r %e^(%i t)}, where @var{a} is the real part and @var{b} is the imaginary
71 part.  @var{a} and @var{b} are 1-dimensional arrays of the same size.
72 The array size need not be a power of 2.
74 The original values of the input arrays are
75 replaced by the magnitude and angle, @code{r} and @code{t}, on return.
76 The outputs are calculated as
78 @example
79 r = sqrt(a^2 + b^2)
80 t = atan2(b, a)
81 @end example
83 The computed angle is in the range @code{-%pi} to @code{%pi}.
85 @code{recttopolar} is the inverse function of @mrefdot{polartorect}
87 @code{load("fft")} loads this function.  See also @mrefdot{fft}
89 @opencatbox{Categories:}
90 @category{Package fft}
91 @category{Complex variables}
92 @closecatbox
93 @end deffn
95 @c -----------------------------------------------------------------------------
96 @anchor{inverse_fft}
97 @deffn {Function} inverse_fft (@var{y})
99 Computes the inverse complex fast Fourier transform.
100 @var{y} is a list or array (named or unnamed) which contains the data to
101 transform.  The number of elements must be a power of 2.
102 The elements must be literal numbers (integers, rationals, floats, or bigfloats)
103 or symbolic constants,
104 or expressions @code{a + b*%i} where @code{a} and @code{b} are literal numbers
105 or symbolic constants.
107 @code{inverse_fft} returns a new object of the same type as @var{y},
108 which is not modified.
109 Results are always computed as floats
110 or expressions @code{a + b*%i} where @code{a} and @code{b} are floats.
111 If bigfloat precision is needed the function @mref{bf_inverse_fft} can
112 be used instead as a drop-in replacement of @code{inverse_fft} that is
113 slower, but supports bfloats. 
115 The inverse discrete Fourier transform is defined as follows.
116 Let @code{x} be the output of the inverse transform.
117 Then for @code{j} from 0 through @code{n - 1},
119 @example
120 x[j] = sum(y[k] exp(-2 %i %pi j k / n), k, 0, n - 1)
121 @end example
123 As there are various sign and normalization conventions possible,
124 this definition of the transform may differ from that used by other mathematical software.
126 @code{load("fft")} loads this function.
128 See also @mref{fft} (forward transform), @mrefcomma{recttopolar} and
129 @mrefdot{polartorect}
131 Examples:
133 Real data.
135 @c ===beg===
136 @c load ("fft") $
137 @c fpprintprec : 4 $
138 @c L : [1, 2, 3, 4, -1, -2, -3, -4] $
139 @c L1 : inverse_fft (L);
140 @c L2 : fft (L1);
141 @c lmax (abs (L2 - L));
142 @c ===end===
143 @example
144 (%i1) load ("fft") $
145 (%i2) fpprintprec : 4 $
146 (%i3) L : [1, 2, 3, 4, -1, -2, -3, -4] $
147 (%i4) L1 : inverse_fft (L);
148 (%o4) [0.0, 14.49 %i - .8284, 0.0, 2.485 %i + 4.828, 0.0, 
149                        4.828 - 2.485 %i, 0.0, - 14.49 %i - .8284]
150 (%i5) L2 : fft (L1);
151 (%o5) [1.0, 2.0 - 2.168L-19 %i, 3.0 - 7.525L-20 %i, 
152 4.0 - 4.256L-19 %i, - 1.0, 2.168L-19 %i - 2.0, 
153 7.525L-20 %i - 3.0, 4.256L-19 %i - 4.0]
154 (%i6) lmax (abs (L2 - L));
155 (%o6)                       3.545L-16
156 @end example
158 Complex data.
160 @c ===beg===
161 @c load ("fft") $
162 @c fpprintprec : 4 $
163 @c L : [1, 1 + %i, 1 - %i, -1, -1, 1 - %i, 1 + %i, 1] $
164 @c L1 : inverse_fft (L);
165 @c L2 : fft (L1);
166 @c lmax (abs (L2 - L));
167 @c ===end===
168 @example
169 (%i1) load ("fft") $
170 (%i2) fpprintprec : 4 $                 
171 (%i3) L : [1, 1 + %i, 1 - %i, -1, -1, 1 - %i, 1 + %i, 1] $
172 (%i4) L1 : inverse_fft (L);
173 (%o4) [4.0, 2.711L-19 %i + 4.0, 2.0 %i - 2.0, 
174 - 2.828 %i - 2.828, 0.0, 5.421L-20 %i + 4.0, - 2.0 %i - 2.0, 
175 2.828 %i + 2.828]
176 (%i5) L2 : fft (L1);
177 (%o5) [4.066E-20 %i + 1.0, 1.0 %i + 1.0, 1.0 - 1.0 %i, 
178 1.55L-19 %i - 1.0, - 4.066E-20 %i - 1.0, 1.0 - 1.0 %i, 
179 1.0 %i + 1.0, 1.0 - 7.368L-20 %i]
180 (%i6) lmax (abs (L2 - L));                    
181 (%o6)                       6.841L-17
182 @end example
184 @opencatbox{Categories:}
185 @category{Package fft}
186 @closecatbox
187 @end deffn
189 @c -----------------------------------------------------------------------------
190 @anchor{fft}
191 @deffn {Function} fft (@var{x})
193 Computes the complex fast Fourier transform.
194 @var{x} is a list or array (named or unnamed) which contains the data to
195 transform.  The number of elements must be a power of 2.
196 The elements must be literal numbers (integers, rationals, floats, or bigfloats)
197 or symbolic constants,
198 or expressions @code{a + b*%i} where @code{a} and @code{b} are literal numbers
199 or symbolic constants.
201 @code{fft} returns a new object of the same type as @var{x},
202 which is not modified.
203 Results are always computed as floats
204 or expressions @code{a + b*%i} where @code{a} and @code{b} are floats.
205 If bigfloat precision is needed the function @mref{bf_fft} can be used
206 instead as a drop-in replacement of @code{fft} that is slower, but
207 supports bfloats. In addition if it is known that the input consists
208 of only real values (no imaginary parts), @mref{real_fft} can be used
209 which is potentially faster.
211 The discrete Fourier transform is defined as follows.
212 Let @code{y} be the output of the transform.
213 Then for @code{k} from 0 through @code{n - 1},
215 @example
216 y[k] = (1/n) sum(x[j] exp(+2 %i %pi j k / n), j, 0, n - 1)
217 @end example
219 As there are various sign and normalization conventions possible,
220 this definition of the transform may differ from that used by other mathematical software.
222 When the data @var{x} are real,
223 real coefficients @code{a} and @code{b} can be computed such that
225 @example
226 x[j] = sum(a[k]*cos(2*%pi*j*k/n)+b[k]*sin(2*%pi*j*k/n), k, 0, n/2)
227 @end example
229 with
231 @example
232 a[0] = realpart (y[0])
233 b[0] = 0
234 @end example
236 and, for k from 1 through n/2 - 1,
238 @example
239 a[k] = realpart (y[k] + y[n - k])
240 b[k] = imagpart (y[n - k] - y[k])
241 @end example
245 @example
246 a[n/2] = realpart (y[n/2])
247 b[n/2] = 0
248 @end example
250 @code{load("fft")} loads this function.
252 See also @mref{inverse_fft} (inverse transform),
253 @mrefcomma{recttopolar} and @mrefdot{polartorect}. See @mref{real_fft}
254 for FFTs of a real-valued input, and @mref{bf_fft} and
255 @mref{bf_real_fft} for operations on bigfloat values.  Finally, for
256 transforms of any size (but limited to float values), see
257 @mref{fftpack5_fft} and @mref{fftpack5_real_fft}.
259 Examples:
261 Real data.
263 @c ===beg===
264 @c load ("fft") $
265 @c fpprintprec : 4 $
266 @c L : [1, 2, 3, 4, -1, -2, -3, -4] $
267 @c L1 : fft (L);
268 @c L2 : inverse_fft (L1);
269 @c lmax (abs (L2 - L));
270 @c ===end===
271 @example
272 (%i1) load ("fft") $
273 (%i2) fpprintprec : 4 $
274 (%i3) L : [1, 2, 3, 4, -1, -2, -3, -4] $
275 (%i4) L1 : fft (L);
276 (%o4) [0.0, 1.811 %i - .1036, 0.0, 0.3107 %i + .6036, 0.0, 
277                          0.6036 - 0.3107 %i, 0.0, (- 1.811 %i) - 0.1036]
278 (%i5) L2 : inverse_fft (L1);
279 (%o5) [1.0, 2.168L-19 %i + 2.0, 7.525L-20 %i + 3.0, 
280 4.256L-19 %i + 4.0, - 1.0, - 2.168L-19 %i - 2.0, 
281 - 7.525L-20 %i - 3.0, - 4.256L-19 %i - 4.0]
282 (%i6) lmax (abs (L2 - L));
283 (%o6)                       3.545L-16
284 @end example
286 Complex data.
288 @c ===beg===
289 @c load ("fft") $
290 @c fpprintprec : 4 $
291 @c L : [1, 1 + %i, 1 - %i, -1, -1, 1 - %i, 1 + %i, 1] $
292 @c L1 : fft (L);
293 @c L2 : inverse_fft (L1);
294 @c lmax (abs (L2 - L));
295 @c ===end===
296 @example
297 (%i1) load ("fft") $
298 (%i2) fpprintprec : 4 $
299 (%i3) L : [1, 1 + %i, 1 - %i, -1, -1, 1 - %i, 1 + %i, 1] $
300 (%i4) L1 : fft (L);
301 (%o4) [0.5, 0.5, 0.25 %i - 0.25, (- 0.3536 %i) - 0.3536, 0.0, 0.5, 
302                                         (- 0.25 %i) - 0.25, 0.3536 %i + 0.3536]
303 (%i5) L2 : inverse_fft (L1);
304 (%o5) [1.0, 1.0 %i + 1.0, 1.0 - 1.0 %i, - 1.0, - 1.0, 1.0 - 1.0 %i, 
305                                                              1.0 %i + 1.0, 1.0]
306 (%i6) lmax (abs (L2 - L));
307 (%o6)                       0.0
308 @end example
310 Computation of sine and cosine coefficients.
312 @c ===beg===
313 @c load ("fft") $
314 @c fpprintprec : 4 $
315 @c L : [1, 2, 3, 4, 5, 6, 7, 8] $
316 @c n : length (L) $
317 @c x : make_array (any, n) $
318 @c fillarray (x, L) $
319 @c y : fft (x) $
320 @c a : make_array (any, n/2 + 1) $
321 @c b : make_array (any, n/2 + 1) $
322 @c a[0] : realpart (y[0]) $
323 @c b[0] : 0 $
324 @c for k : 1 thru n/2 - 1 do
325 @c    (a[k] : realpart (y[k] + y[n - k]),
326 @c     b[k] : imagpart (y[n - k] - y[k]));
327 @c a[n/2] : y[n/2] $
328 @c b[n/2] : 0 $
329 @c listarray (a);
330 @c listarray (b);
331 @c f(j) := sum (a[k] * cos (2*%pi*j*k / n) + b[k] * sin (2*%pi*j*k / n), k, 0, n/2) $
332 @c makelist (float (f (j)), j, 0, n - 1);
333 @c ===end===
334 @example
335 (%i1) load ("fft") $
336 (%i2) fpprintprec : 4 $
337 (%i3) L : [1, 2, 3, 4, 5, 6, 7, 8] $
338 (%i4) n : length (L) $
339 (%i5) x : make_array (any, n) $
340 (%i6) fillarray (x, L) $
341 (%i7) y : fft (x) $
342 (%i8) a : make_array (any, n/2 + 1) $
343 (%i9) b : make_array (any, n/2 + 1) $
344 (%i10) a[0] : realpart (y[0]) $
345 (%i11) b[0] : 0 $
346 (%i12) for k : 1 thru n/2 - 1 do
347    (a[k] : realpart (y[k] + y[n - k]),
348     b[k] : imagpart (y[n - k] - y[k]));
349 (%o12)                        done
350 (%i13) a[n/2] : y[n/2] $
351 (%i14) b[n/2] : 0 $
352 (%i15) listarray (a);
353 (%o15)          [4.5, - 1.0, - 1.0, - 1.0, - 0.5]
354 (%i16) listarray (b);
355 (%o16)           [0, - 2.414, - 1.0, - .4142, 0]
356 (%i17) f(j) := sum (a[k]*cos(2*%pi*j*k/n) + b[k]*sin(2*%pi*j*k/n), 
357                     k, 0, n/2) $
358 (%i18) makelist (float (f (j)), j, 0, n - 1);
359 (%o18)      [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
360 @end example
362 @opencatbox{Categories:}
363 @category{Package fft}
364 @closecatbox
365 @end deffn
367 @c -----------------------------------------------------------------------------
368 @anchor{real_fft}
369 @deffn {Function} real_fft (@var{x})
371 Computes the fast Fourier transform of a real-valued sequence
372 @var{x}.  This is equivalent to performing @code{fft(x)}, except that
373 only the first @code{N/2+1} results are returned, where @code{N} is
374 the length of @var{x}.  @code{N} must be power of two.
376 No check is made that @var{x} contains only real values.
378 The symmetry properties of the Fourier transform of real sequences to
379 reduce he complexity.  In particular the first and last output values
380 of @code{real_fft} are purely real.  For larger sequences, @code{real_fft}
381 may be computed more quickly than @code{fft}.
383 Since the output length is short, the normal @mref{inverse_fft} cannot
384 be directly used.  Use @mref{inverse_real_fft} to compute the inverse.
385 @opencatbox{Categories:}
386 @category{Package fft}
387 @closecatbox
388 @end deffn
390 @c -----------------------------------------------------------------------------
391 @anchor{inverse_real_fft}
392 @deffn {Function} inverse_real_fft (@var{y})
393 Computes the inverse Fourier transform of @var{y}, which must have a
394 length of @code{N/2+1} where @code{N} is a power of two.  That is, the
395 input @var{x} is expected to be the output of @code{real_fft}.
397 No check is made to ensure that the input has the correct format.
398 (The first and last elements must be purely real.)
400 @opencatbox{Categories:}
401 @category{Package fft}
402 @closecatbox
403 @end deffn
405 @c -----------------------------------------------------------------------------
406 @anchor{bf_inverse_fft}
407 @deffn {Function} bf_inverse_fft (@var{y})
409 Computes the inverse complex fast Fourier transform.  This is the
410 bigfloat version of @mref{inverse_fft} that converts the input to
411 bigfloats and returns a bigfloat result.
412 @opencatbox{Categories:}
413 @category{Package fft}
414 @closecatbox
415 @end deffn
417 @anchor{bf_fft}
418 @deffn {Function} bf_fft (@var{y})
420 Computes the forward complex fast Fourier transform.  This is the
421 bigfloat version of @mref{fft} that converts the input to
422 bigfloats and returns a bigfloat result.
423 @opencatbox{Categories:}
424 @category{Package fft}
425 @closecatbox
426 @end deffn
428 @anchor{bf_real_fft}
429 @deffn {Function} bf_real_fft (@var{x})
431 Computes the forward fast Fourier transform of a real-valued input
432 returning a bigfloat result.  This is the bigfloat version of
433 @code{real_fft}.
435 @opencatbox{Categories:}
436 @category{Package fft}
437 @closecatbox
438 @end deffn
440 @anchor{bf_inverse_real_fft}
441 @deffn {Function} bf_inverse_real_fft (@var{y})
442 Computes the inverse fast Fourier transform with a real-valued
443 bigfloat output.  This is the bigfloat version of @code{inverse_real_fft}.
445 @opencatbox{Categories:}
446 @category{Package fft}
447 @closecatbox
448 @end deffn
450 @c -----------------------------------------------------------------------------
451 @node Functions and Variables for FFTPACK5, Functions for numerical solution of equations, Functions and Variables for fast Fourier transform, Numerical
452 @section Functions and Variables for FFTPACK5
453 @c -----------------------------------------------------------------------------
455 @code{FFTPACK5} provides several routines to compute Fourier
456 transforms for both real and complex sequences and their inverses.
457 The forward transform is defined the same as for @code{fft}.  The
458 major difference is the length of the sequence is not constrained to
459 be a power of two.  In fact, any length is supported, but it is most
460 efficient when the length has the form @math{2^r*3^s*5^t}.
462 @code{load("fftpack5")} loads this function.
464 @anchor{fftpack5_fft}
465 @deffn {Function} fftpack5_fft (@var{x})
467 Like @code{fft} (@mref{fft}), this computes the fast Fourier transform
468 of a complex sequence.  However, the length of @var{x} is not limited
469 to a power of 2.  
471 @code{load("fftpack5")} loads this function.
473 Examples:
475 Real data.
477 @example
478 (%i1) load("fftpack5") $
479 (%i2) fpprintprec : 4 $
480 (%i3) L : [1, 2, 3, 4, -1, -2 ,-3, -4] $
481 (%i4) L1 : fftpack5_fft(L);
482 (%o4) [0.0, 1.811 %i - 0.1036, 0.0, 0.3107 %i + 0.6036, 0.0, 
483                                 0.6036 - 0.3107 %i, 0.0, (- 1.811 %i) - 0.1036]
484 (%i5) L2 : fftpack5_inverse_fft(L1);
485 (%o5) [1.0, 4.441e-16 %i + 2.0, 1.837e-16 %i + 3.0, 4.0 - 4.441e-16 %i, 
486      - 1.0, (- 4.441e-16 %i) - 2.0, (- 1.837e-16 %i) - 3.0, 4.441e-16
487        %i - 4.0]
488 (%i6) lmax (abs (L2-L));
489 (%o6)                       4.441e-16
490 (%i7) L : [1, 2, 3, 4, 5, 6]$
491 (%i8) L1 : fftpack5_fft(L);
492 (%o8) [3.5, (- 0.866 %i) - 0.5, (- 0.2887 %i) - 0.5, (- 1.48e-16 %i) - 0.5, 
493                                                0.2887 %i - 0.5, 0.866
494                                                       %%i - 0.5]
495 (%i9) L2 : fftpack5_inverse_fft (L1);
496 (%o9) [1.0 - 1.48e-16 %i, 3.701e-17 %i + 2.0, 3.0 - 1.48e-16 %i, 
497                      4.0 - 1.811e-16 %i, 5.0 - 1.48e-16 %i, 5.881e-16
498                            %i + 6.0]
499 (%i10) lmax (abs (L2-L));
500 (%o10)                             9.064e-16
501 @end example
503 Complex data.
505 @example
506 (%i1) load("fftpack5") $
507 (%i2) fpprintprec : 4 $
508 (%i3) L : [1, 1 + %i, 1 - %i, -1, -1, 1 - %i, 1 + %i, 1] $
509 (%i4) L1 : fftpack5_inverse_fft (L);
510 (%o4) [4.0, 2.828 %i + 2.828, (- 2.0 %i) - 2.0, 4.0, 0.0, 
511                                        (- 2.828 %i) - 2.828, 2.0 %i - 2.0, 4.0]
512 (%i5) L2 : fftpack5_fft(L1);
513 (%o5) [1.0, 1.0 %i + 1.0, 1.0 - 1.0 %i, (- 2.776e-17 %i) - 1.0, - 1.0, 
514                                 1.0 - 1.0 %i, 1.0 %i + 1.0, 1.0 -
515                                           %2.776e-17 %i]
516 (%i6) lmax(abs(L2-L));
517 (%o6)                              1.11e-16
518 @end example
520 @opencatbox{Categories:}
521 @category{Package fftpack5}
522 @closecatbox
523 @end deffn
525 @anchor{fftpack5_inverse_fft}
526 @deffn {Function} fftpack5_inverse_fft (@var{y})
528 Computes the inverse complex Fourier transform, like
529 @code{inverse_fft}, but is not constrained to be a power of two.
531 @opencatbox{Categories:}
532 @category{Package fftpack5}
533 @closecatbox
534 @end deffn
536 @anchor{fftpack5_real_fft}
537 @deffn {Function} fftpack5_real_fft (@var{x})
539 Computes the fast Fourier transform of a real-valued sequence @var{x},
540 just like @code{real_fft}, except the length is not constrained to be
541 a power of two.
543 Examples:
545 @example
546 (%i1) fpprintprec : 4 $
547 (%i2) L : [1, 2, 3, 4, 5, 6] $
548 (%i3) L1 : fftpack5_real_fft(L);
549 (%o3)       [3.5, (- 0.866 %i) - 0.5, (- 0.2887 %i) - 0.5, - 0.5]
550 (%i4) L2 : fftpack5_inverse_real_fft(L1, 6);
551 (%o4)                  [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
552 (%i5) lmax(abs(L2-L));
553 (%o5)                            1.332e-15
554 (%i6) fftpack5_inverse_real_fft(L1, 7);
555 (%o6)            [0.5, 2.083, 2.562, 3.7, 4.3, 5.438, 5.917] 
556 @end example
558 The last example shows how important it to set the length correctly
559 for @code{fftpack5_inverse_real_fft}.
561 @opencatbox{Categories:}
562 @category{Package fftpack5}
563 @closecatbox
564 @end deffn
566 @anchor{fftpack5_inverse_real_fft}
567 @deffn {Function} fftpack5_inverse_real_fft (@var{y}, @var{n})
569 Computes the inverse Fourier transform of @var{y}, which must have a
570 length of @code{floor(n/2) + 1}.  The length of sequence produced by the
571 inverse transform must be specified by @var{n}.  This is required
572 because the length of @var{y} does not uniquely determine @var{n}.
573 The last element of @var{y} is always real if @var{n} is even, but it
574 can be complex when @var{n} is odd.
576 @opencatbox{Categories:}
577 @category{Package fftpack5}
578 @closecatbox
579 @end deffn
581 @c -----------------------------------------------------------------------------
582 @node Functions for numerical solution of equations, Introduction to numerical solution of differential equations, Functions and Variables for FFTPACK5, Numerical
583 @section Functions for numerical solution of equations
584 @c -----------------------------------------------------------------------------
586 @anchor{horner}
587 @deffn  {Function} horner @
588 @fname{horner} (@var{expr}, @var{x}) @
589 @fname{horner} (@var{expr})
591 Returns a rearranged representation of @var{expr} as in Horner's rule, using
592 @var{x} as the main variable if it is specified.  @code{x} may be omitted in
593 which case the main variable of the canonical rational expression form of
594 @var{expr} is used.
596 @code{horner} sometimes improves stability if @code{expr} is
597 to be numerically evaluated.  It is also useful if Maxima is used to
598 generate programs to be run in Fortran.  See also @mrefdot{stringout}
600 @c ===beg===
601 @c expr: 1e-155*x^2 - 5.5*x + 5.2e155;
602 @c expr2: horner (%, x), keepfloat: true;
603 @c ev (expr, x=1e155);
604 @c ev (expr2, x=1e155);
605 @c ===end===
606 @example
607 (%i1) expr: 1e-155*x^2 - 5.5*x + 5.2e155;
608                            2
609 (%o1)             1.e-155 x  - 5.5 x + 5.2e+155
610 (%i2) expr2: horner (%, x), keepfloat: true;
611 (%o2)         1.0 ((1.e-155 x - 5.5) x + 5.2e+155)
612 (%i3) ev (expr, x=1e155);
613 Maxima encountered a Lisp error:
615  arithmetic error FLOATING-POINT-OVERFLOW signalled
617 Automatically continuing.
618 To enable the Lisp debugger set *debugger-hook* to nil.
619 (%i4) ev (expr2, x=1e155);
620 (%o4)                 7.00000000000001e+154
621 @end example
623 @opencatbox{Categories:}
624 @category{Numerical methods}
625 @closecatbox
626 @end deffn
628 @c -----------------------------------------------------------------------------
629 @anchor{find_root}
630 @anchor{bf_find_root}
631 @anchor{find_root_error}
632 @anchor{find_root_abs}
633 @anchor{find_root_rel}
634 @deffn  {Function} find_root (@var{expr}, @var{x}, @var{a}, @var{b}, [@var{abserr}, @var{relerr}])
635 @deffnx {Function} find_root (@var{f}, @var{a}, @var{b}, [@var{abserr}, @var{relerr}])
636 @deffnx {Function} bf_find_root (@var{expr}, @var{x}, @var{a}, @var{b}, [@var{abserr}, @var{relerr}])
637 @deffnx {Function} bf_find_root (@var{f}, @var{a}, @var{b}, [@var{abserr}, @var{relerr}])
638 @deffnx {Option variable} find_root_error
639 @deffnx {Option variable} find_root_abs
640 @deffnx {Option variable} find_root_rel
642 Finds a root of the expression @var{expr} or the function @var{f} over the
643 closed interval @math{[@var{a}, @var{b}]}.  The expression @var{expr} may be an
644 equation, in which case @mref{find_root} seeks a root of
645 @code{lhs(@var{expr}) - rhs(@var{expr})}.
647 Given that Maxima can evaluate @var{expr} or @var{f} over
648 @math{[@var{a}, @var{b}]} and that @var{expr} or @var{f} is continuous,
649 @code{find_root} is guaranteed to find the root,
650 or one of the roots if there is more than one.
652 @code{find_root} initially applies binary search.
653 If the function in question appears to be smooth enough,
654 @code{find_root} applies linear interpolation instead.
656 @code{bf_find_root} is a bigfloat version of @code{find_root}.  The
657 function is computed using bigfloat arithmetic and a bigfloat result
658 is returned.  Otherwise, @code{bf_find_root} is identical to
659 @code{find_root}, and the following description is equally applicable
660 to @code{bf_find_root}.
662 The accuracy of @code{find_root} is governed by @code{abserr} and
663 @code{relerr}, which are optional keyword arguments to
664 @code{find_root}.  These keyword arguments take the form
665 @code{key=val}.  The keyword arguments are
667 @table @code
668 @item abserr
669 Desired absolute error of function value at root.  Default is
670 @code{find_root_abs}.
671 @item relerr
672 Desired relative error of root.  Default is @code{find_root_rel}.
673 @end table
675 @code{find_root} stops when the function in question evaluates to
676 something less than or equal to @code{abserr}, or if successive
677 approximants @var{x_0}, @var{x_1} differ by no more than @code{relerr
678 * max(abs(x_0), abs(x_1))}.  The default values of
679 @code{find_root_abs} and @code{find_root_rel} are both zero.
681 @code{find_root} expects the function in question to have a different sign at
682 the endpoints of the search interval.
683 When the function evaluates to a number at both endpoints
684 and these numbers have the same sign,
685 the behavior of @code{find_root} is governed by @code{find_root_error}.
686 When @code{find_root_error} is @code{true},
687 @code{find_root} prints an error message.
688 Otherwise @code{find_root} returns the value of @code{find_root_error}.
689 The default value of @code{find_root_error} is @code{true}.
691 If @var{f} evaluates to something other than a number at any step in the search
692 algorithm, @code{find_root} returns a partially-evaluated @code{find_root}
693 expression.
695 The order of @var{a} and @var{b} is ignored; the region in which a root is
696 sought is @math{[min(@var{a}, @var{b}), max(@var{a}, @var{b})]}.
698 Examples:
700 @c PREVIOUS EXAMPLE STUFF -- MAY WANT TO BRING TRANSLATE BACK INTO THE EXAMPLE
701 @c f(x):=(mode_declare(x,float),sin(x)-x/2.0);
702 @c interpolate(sin(x)-x/2,x,0.1,%pi)       time= 60 msec
703 @c interpolate(f(x),x,0.1,%pi);            time= 68 msec
704 @c translate(f);
705 @c interpolate(f(x),x,0.1,%pi);            time= 26 msec
706 @c interpolate(f,0.1,%pi);                 time=  5 msec
708 @c ===beg===
709 @c f(x) := sin(x) - x/2;
710 @c find_root (sin(x) - x/2, x, 0.1, %pi);
711 @c find_root (sin(x) = x/2, x, 0.1, %pi);
712 @c find_root (f(x), x, 0.1, %pi);
713 @c find_root (f, 0.1, %pi);
714 @c find_root (exp(x) = y, x, 0, 100);
715 @c find_root (exp(x) = y, x, 0, 100), y = 10;
716 @c log (10.0);
717 @c fpprec:32;
718 @c 32;
719 @c bf_find_root (exp(x) = y, x, 0, 100), y = 10;
720 @c log(10b0);
721 @c ===end===
722 @example
723 (%i1) f(x) := sin(x) - x/2;
724                                         x
725 (%o1)                  f(x) := sin(x) - -
726                                         2
727 (%i2) find_root (sin(x) - x/2, x, 0.1, %pi);
728 (%o2)                   1.895494267033981
729 (%i3) find_root (sin(x) = x/2, x, 0.1, %pi);
730 (%o3)                   1.895494267033981
731 (%i4) find_root (f(x), x, 0.1, %pi);
732 (%o4)                   1.895494267033981
733 (%i5) find_root (f, 0.1, %pi);
734 (%o5)                   1.895494267033981
735 (%i6) find_root (exp(x) = y, x, 0, 100);
736                             x
737 (%o6)           find_root(%e  = y, x, 0.0, 100.0)
738 (%i7) find_root (exp(x) = y, x, 0, 100), y = 10;
739 (%o7)                   2.302585092994046
740 (%i8) log (10.0);
741 (%o8)                   2.302585092994046
742 (%i9) fpprec:32;
743 (%o9)                           32
744 (%i10) bf_find_root (exp(x) = y, x, 0, 100), y = 10;
745 (%o10)                  2.3025850929940456840179914546844b0
746 (%i11) log(10b0);
747 (%o11)                  2.3025850929940456840179914546844b0
748 @end example
750 @opencatbox{Categories:}
751 @category{Algebraic equations}
752 @category{Numerical methods}
753 @closecatbox
754 @end deffn
756 @c -----------------------------------------------------------------------------
757 @anchor{newton}
758 @deffn {Function} newton (@var{expr}, @var{x}, @var{x_0}, @var{eps})
760 Returns an approximate solution of @code{@var{expr} = 0} by Newton's method,
761 considering @var{expr} to be a function of one variable, @var{x}.
762 The search begins with @code{@var{x} = @var{x_0}}
763 and proceeds until @code{abs(@var{expr}) < @var{eps}}
764 (with @var{expr} evaluated at the current value of @var{x}).
766 @code{newton} allows undefined variables to appear in @var{expr},
767 so long as the termination test @code{abs(@var{expr}) < @var{eps}} evaluates
768 to @code{true} or @code{false}.
769 Thus it is not necessary that @var{expr} evaluate to a number.
771 @code{load("newton1")} loads this function.
773 See also @mrefcomma{realroots} @mrefcomma{allroots} @mref{find_root} and
774 @mrefdot{mnewton}
776 Examples:
778 @c ===beg===
779 @c load ("newton1");
780 @c newton (cos (u), u, 1, 1/100);
781 @c ev (cos (u), u = %);
782 @c assume (a > 0);
783 @c newton (x^2 - a^2, x, a/2, a^2/100);
784 @c ev (x^2 - a^2, x = %);
785 @c ===end===
786 @example
787 (%i1) load ("newton1");
788 (%o1)  /maxima/share/numeric/newton1.mac
789 (%i2) newton (cos (u), u, 1, 1/100);
790 (%o2)                   1.570675277161251
791 (%i3) ev (cos (u), u = %);
792 (%o3)                 1.2104963335033529e-4
793 (%i4) assume (a > 0);
794 (%o4)                        [a > 0]
795 (%i5) newton (x^2 - a^2, x, a/2, a^2/100);
796 (%o5)                  1.00030487804878 a
797 (%i6) ev (x^2 - a^2, x = %);
798                                            2
799 (%o6)                6.098490481853958e-4 a
800 @end example
802 @opencatbox{Categories:}
803 @category{Algebraic equations}
804 @category{Numerical methods}
805 @closecatbox
806 @end deffn
808 @c -----------------------------------------------------------------------------
809 @node Introduction to numerical solution of differential equations, Functions for numerical solution of differential equations, Functions for numerical solution of equations, Numerical
810 @section Introduction to numerical solution of differential equations
811 @c -----------------------------------------------------------------------------
813 The Ordinary Differential Equations (ODE) solved by the functions in this
814 section should have the form,
815 @ifnottex
816 @example
817        dy
818        -- = F(x,y)
819        dx
820 @end example
821 @end ifnottex
822 @tex
823 $${{dy}\over{dx}} = F(x,y)$$
824 @end tex
825 which is a first-order ODE. Higher order differential equations of order
826 @var{n} must be written as a system of @var{n} first-order equations of that
827 kind. For instance, a second-order ODE should be written as a system of two
828 equations
829 @ifnottex
830 @example
831        dx               dy
832        -- = G(x,y,t)    -- = F(x,y,t) 
833        dt               dt
834 @end example
835 @end ifnottex
836 @tex
837 $${{dx}\over{dt}} = G(x,y,t) \qquad {{dy}\over{dt}} = F(x,y,t)$$
838 @end tex
840 The first argument in the functions will be a list with the expressions on
841 the right-side of the ODE's. The variables whose derivatives are represented
842 by those expressions should be given in a second list. In the case above those
843 variables are @var{x} and @var{y}. The independent variable, @var{t} in the
844 examples above, might be given in a separated option. If the expressions
845 given do not depend on that independent variable, the system is called
846 autonomous.
848 @opencatbox{Categories:}
849 @category{Differential equations}
850 @category{Numerical methods}
851 @category{Plotting}
852 @closecatbox
855 @c -----------------------------------------------------------------------------
856 @node Functions for numerical solution of differential equations,  , Introduction to numerical solution of differential equations, Numerical
857 @section Functions for numerical solution of differential equations
858 @c -----------------------------------------------------------------------------
859 @anchor{plotdf}
860 @deffn {Function} plotdf @
861 @fname{plotdf} (@var{dydx}, options@dots{}) @
862 @fname{plotdf} (@var{dvdu}, [@var{u},@var{v}], options@dots{}) @
863 @fname{plotdf} ([@var{dxdt},c@var{dydt}], options@dots{}) @
864 @fname{plotdf} ([@var{dudt},c@var{dvdt}], [@var{u},c@var{v}], options@dots{})
866 The function @code{plotdf} creates a two-dimensional plot of the direction
867 field (also called slope field) for a first-order Ordinary Differential
868 Equation (ODE) or a system of two autonomous first-order ODE's.
870 Plotdf requires Xmaxima, even if its run from a Maxima session in
871 a console, since the plot will be created by the Tk scripts in Xmaxima.
872 If Xmaxima is not installed plotdf will not work.
874 @var{dydx}, @var{dxdt} and @var{dydt} are expressions that depend on
875 @var{x} and @var{y}. @var{dvdu}, @var{dudt} and @var{dvdt} are
876 expressions that depend on @var{u} and @var{v}. In addition to those two
877 variables, the expressions can also depend on a set of parameters, with
878 numerical values given with the @code{parameters} option (the option
879 syntax is given below), or with a range of allowed values specified by a
880 @var{sliders} option.
882 Several other options can be given within the command, or selected in
883 the menu. Integral curves can be obtained by clicking on the plot, or
884 with the option @code{trajectory_at}. The direction of the integration
885 can be controlled with the @code{direction} option, which can have
886 values of @emph{forward}, @emph{backward} or @emph{both}. The number of
887 integration steps is given by @code{nsteps}; at each integration
888 step the time increment will be adjusted automatically to produce
889 displacements much smaller than the size of the plot window. The
890 numerical method used is 4th order Runge-Kutta with variable time steps.
892 @b{Plot window menu:}
894 The menu bar of the plot window has the following seven icons:
896 An X. Can be used to close the plot window.
898 A wrench and a screwdriver. Opens the configuration menu with several
899 fields that show the ODE(s) in use and various other settings. If a pair
900 of coordinates are entered in the field @emph{Trajectory at} and the
901 @key{enter} key is pressed, a new integral curve will be shown, in
902 addition to the ones already shown.
904 Two arrows following a circle. Replots the direction field with the
905 new settings defined in the configuration menu and replots only the last
906 integral curve that was previously plotted.
908 Hard disk drive with an arrow. Used to save a copy of the
909 plot, in Postscript format, in the file specified in a field of the
910 box that appears when that icon is clicked.
912 Magnifying glass with a plus sign. Zooms in the plot.
914 Magnifying glass with a minus sign. Zooms out the plot. The plot can be
915 displaced by holding down the right mouse button while the mouse is
916 moved.
918 Icon of a plot. Opens another window with a plot of the two variables
919 in terms of time, for the last integral curve that was plotted.
921 @b{Plot options:}
923 Options can also be given within the @code{plotdf} itself, each one being
924 a list of two or more elements. The first element in each option is the name
925 of the option, and the remainder is the value or values assigned to the
926 option.
928 The options which are recognized by @code{plotdf} are the following:
930 @itemize @bullet
931 @item
932 @dfn{nsteps} defines the number of steps that will be used for the
933 independent variable, to compute an integral curve. The default value is
934 100.
936 @item
937 @dfn{direction} defines the direction of the independent
938 variable that will be followed to compute an integral curve. Possible
939 values are @code{forward}, to make the independent variable increase
940 @code{nsteps} times, with increments @code{tstep}, @code{backward}, to
941 make the independent variable decrease, or @code{both} that will lead to
942 an integral curve that extends @code{nsteps} forward, and @code{nsteps}
943 backward. The keywords @code{right} and @code{left} can be used as
944 synonyms for @code{forward} and @code{backward}.
945 The default value is @code{both}.
947 @item
948 @dfn{tinitial} defines the initial value of variable @var{t} used
949 to compute integral curves. Since the differential equations are
950 autonomous, that setting will only appear in the plot of the curves as
951 functions of @var{t}. 
952 The default value is 0.
954 @item
955 @dfn{versus_t} is used to create a second plot window, with a
956 plot of an integral curve, as two functions @var{x}, @var{y}, of the
957 independent variable @var{t}. If @code{versus_t} is given any value
958 different from 0, the second plot window will be displayed. The second
959 plot window includes another menu, similar to the menu of the main plot
960 window.
961 The default value is 0.
963 @item
964 @dfn{trajectory_at} defines the coordinates @var{xinitial} and
965 @var{yinitial} for the starting point of an integral curve.
966 The option is empty by default.
968 @item
969 @dfn{parameters} defines a list of parameters, and their
970 numerical values, used in the definition of the differential
971 equations. The name and values of the parameters must be given in a
972 string with a comma-separated sequence of pairs @code{name=value}.
974 @item
975 @dfn{sliders} defines a list of parameters that will be changed
976 interactively using slider buttons, and the range of variation of those
977 parameters. The names and ranges of the parameters must be given in a
978 string with a comma-separated sequence of elements @code{name=min:max}
980 @item
981 @dfn{xfun} defines a string with semi-colon-separated sequence
982 of functions of @var{x} to be displayed, on top of the direction field.
983 Those functions will be parsed by Tcl and not by Maxima.
985 @item
986 @dfn{x} should be followed by two numbers, which will set up the minimum
987 and maximum values shown on the horizontal axis. If the variable on the
988 horizontal axis is not @var{x}, then this option should have the name of
989 the variable on the horizontal axis.
990 The default horizontal range is from -10 to 10.
992 @item
993 @dfn{y} should be followed by two numbers, which will set up the minimum
994 and maximum values shown on the vertical axis. If the variable on the
995 vertical axis is not @var{y}, then this option should have the name of
996 the variable on the vertical axis.
997 The default vertical range is from -10 to 10.
999 @item
1000 @dfn{xaxislabel} will be used to identify the horizontal axis. Its default value is the name of the first state variable.
1002 @item
1003 @dfn{yaxislabel} will be used to identify the vertical axis. Its default value is the name of the second state variable.
1005 @item
1006 @dfn{number_of_arrows} should be set to a square number and defines the approximate
1007 density of the arrows being drawn. The default value is 225.
1008 @end itemize
1010 @strong{Examples:}
1012 @itemize @bullet
1013 @item
1014 To show the direction field of the differential equation @math{y' = exp(-x) + y} and the solution that goes through @math{(2, -0.1)}:
1015 @c ===beg===
1016 @c plotdf(exp(-x)+y,[trajectory_at,2,-0.1])$
1017 @c ===end===
1018 @example
1019 (%i1) plotdf(exp(-x)+y,[trajectory_at,2,-0.1])$
1020 @end example
1022 @ifnotinfo
1023 @image{figures/plotdf1,8cm}
1024 @end ifnotinfo
1026 @item
1027 To obtain the direction field for the equation @math{diff(y,x) = x - y^2} and the solution with initial condition @math{y(-1) = 3}, we can use the command:
1028 @c ===beg===
1029 @c plotdf(x-y^2,[xfun,"sqrt(x);-sqrt(x)"],
1030 @c          [trajectory_at,-1,3], [direction,forward],
1031 @c          [y,-5,5], [x,-4,16])$
1032 @c ===end===
1033 @example
1034 @group
1035 (%i1) plotdf(x-y^2,[xfun,"sqrt(x);-sqrt(x)"],
1036          [trajectory_at,-1,3], [direction,forward],
1037          [y,-5,5], [x,-4,16])$
1038 @end group
1039 @end example
1041 The graph also shows the function @math{y = sqrt(x)}. 
1043 @ifnotinfo
1044 @image{figures/plotdf2,8cm}
1045 @end ifnotinfo
1047 @item
1048 The following example shows the direction field of a harmonic oscillator,
1049 defined by the two equations @math{dz/dt = v} and @math{dv/dt = -k*z/m},
1050 and the integral curve through @math{(z,v) = (6,0)}, with a slider that
1051 will allow you to change the value of @math{m} interactively (@math{k} is
1052 fixed at 2):
1053 @c ===beg===
1054 @c plotdf([v,-k*z/m], [z,v], [parameters,"m=2,k=2"],
1055 @c            [sliders,"m=1:5"], [trajectory_at,6,0])$
1056 @c ===end===
1057 @example
1058 @group
1059 (%i1) plotdf([v,-k*z/m], [z,v], [parameters,"m=2,k=2"],
1060            [sliders,"m=1:5"], [trajectory_at,6,0])$
1061 @end group
1062 @end example
1064 @ifnotinfo
1065 @image{figures/plotdf3,8cm}
1066 @end ifnotinfo
1068 @item
1069 To plot the direction field of the Duffing equation, @math{m*x''+c*x'+k*x+b*x^3 = 0}, we introduce the variable @math{y=x'} and use:
1070 @c ===beg===
1071 @c plotdf([y,-(k*x + c*y + b*x^3)/m],
1072 @c              [parameters,"k=-1,m=1.0,c=0,b=1"],
1073 @c              [sliders,"k=-2:2,m=-1:1"],[tstep,0.1])$
1074 @c ===end===
1075 @example
1076 @group
1077 (%i1) plotdf([y,-(k*x + c*y + b*x^3)/m],
1078              [parameters,"k=-1,m=1.0,c=0,b=1"],
1079              [sliders,"k=-2:2,m=-1:1"],[tstep,0.1])$
1080 @end group
1081 @end example
1083 @ifnotinfo
1084 @image{figures/plotdf4,8cm}
1085 @end ifnotinfo
1087 @item
1088 The direction field for a damped pendulum, including the
1089 solution for the given initial conditions, with a slider that
1090 can be used to change the value of the mass @math{m}, and with a plot of
1091 the two state variables as a function of time:
1093 @c ===beg===
1094 @c plotdf([w,-g*sin(a)/l - b*w/m/l], [a,w],
1095 @c         [parameters,"g=9.8,l=0.5,m=0.3,b=0.05"],
1096 @c         [trajectory_at,1.05,-9],[tstep,0.01],
1097 @c         [a,-10,2], [w,-14,14], [direction,forward],
1098 @c         [nsteps,300], [sliders,"m=0.1:1"], [versus_t,1])$
1099 @c ===end===
1100 @example
1101 @group
1102 (%i1) plotdf([w,-g*sin(a)/l - b*w/m/l], [a,w],
1103         [parameters,"g=9.8,l=0.5,m=0.3,b=0.05"],
1104         [trajectory_at,1.05,-9],[tstep,0.01],
1105         [a,-10,2], [w,-14,14], [direction,forward],
1106         [nsteps,300], [sliders,"m=0.1:1"], [versus_t,1])$
1107 @end group
1108 @end example
1110 @ifnotinfo
1111 @image{figures/plotdf5,8cm}@image{figures/plotdf6,8cm}
1112 @end ifnotinfo
1114 @end itemize
1116 @opencatbox{Categories:}
1117 @category{Differential equations}
1118 @category{Plotting}
1119 @category{Numerical methods}
1120 @closecatbox
1122 @end deffn
1124 @deffn {Function} ploteq (@var{exp}, ...options...)
1126 Plots equipotential curves for @var{exp}, which should be an expression
1127 depending on two variables. The curves are obtained by integrating the
1128 differential equation that define the orthogonal trajectories to the solutions
1129 of the autonomous system obtained from the gradient of the expression given.
1130 The plot can also show the integral curves for that gradient system (option
1131 fieldlines).
1133 This program also requires Xmaxima, even if its run from a Maxima session in
1134 a console, since the plot will be created by the Tk scripts in Xmaxima.
1135 By default, the plot region will be empty until the user clicks in a point
1136 (or gives its coordinate with in the set-up menu or via the trajectory_at option).
1138 Most options accepted by plotdf can also be used for ploteq and the plot
1139 interface is the same that was described in plotdf.
1141 Example:
1143 @c ===beg===
1144 @c V: 900/((x+1)^2+y^2)^(1/2)-900/((x-1)^2+y^2)^(1/2)$
1145 @c ploteq(V,[x,-2,2],[y,-2,2],[fieldlines,"blue"])$
1146 @c ===end===
1147 @example
1148 (%i1) V: 900/((x+1)^2+y^2)^(1/2)-900/((x-1)^2+y^2)^(1/2)$
1149 (%i2) ploteq(V,[x,-2,2],[y,-2,2],[fieldlines,"blue"])$
1150 @end example
1152 Clicking on a point will plot the equipotential curve that passes by that point
1153 (in red) and the orthogonal trajectory (in blue).
1155 @opencatbox{Categories:}
1156 @category{Differential equations}
1157 @category{Plotting}
1158 @category{Numerical methods}
1159 @closecatbox
1161 @end deffn
1163 @anchor{rk}
1164 @deffn {Function} rk @
1165 @fname{rk} (@var{ODE}, @var{var}, @var{initial}, @var{domain}) @
1166 @fname{rk} ([@var{ODE1}, @dots{}, @var{ODEm}], [@var{v1}, @dots{}, @var{vm}], [@var{init1}, @dots{}, @var{initm}], @var{domain})
1168 The first form solves numerically one first-order ordinary differential
1169 equation, and the second form solves a system of m of those equations,
1170 using the 4th order Runge-Kutta method. @var{var} represents the dependent
1171 variable. @var{ODE} must be an expression that depends only on the independent
1172 and dependent variables and defines the derivative of the dependent
1173 variable with respect to the independent variable.
1175 The independent variable is specified with @code{domain}, which must be a
1176 list of four elements as, for instance:
1177 @example
1178 [t, 0, 10, 0.1]
1179 @end example
1180 the first element of the list identifies the independent variable, the
1181 second and third elements are the initial and final values for that
1182 variable, and the last element sets the increments that should be used
1183 within that interval.
1185 If @var{m} equations are going to be solved, there should be @var{m}
1186 dependent variables @var{v1}, @var{v2}, ..., @var{vm}. The initial values
1187 for those variables will be @var{init1}, @var{init2}, ..., @var{initm}.
1188 There will still be just one independent variable defined by @code{domain},
1189 as in the previous case. @var{ODE1}, ..., @var{ODEm} are the expressions
1190 that define the derivatives of each dependent variable in
1191 terms of the independent variable. The only variables that may appear in
1192 those expressions are the independent variable and any of the dependent
1193 variables. It is important to give the derivatives @var{ODE1}, ...,
1194 @var{ODEm} in the list in exactly the same order used for the dependent
1195 variables; for instance, the third element in the list will be interpreted
1196 as the derivative of the third dependent variable.
1198 The program will try to integrate the equations from the initial value
1199 of the independent variable until its last value, using constant
1200 increments. If at some step one of the dependent variables takes an
1201 absolute value too large, the integration will be interrupted at that
1202 point. The result will be a list with as many elements as the number of
1203 iterations made. Each element in the results list is itself another list
1204 with @var{m}+1 elements: the value of the independent variable, followed
1205 by the values of the dependent variables corresponding to that point.
1207 See also @mrefcomma{drawdf} @mref{desolve} and @mrefdot{ode2}
1209 Examples:
1211 To solve numerically the differential equation
1213 @ifnottex
1214 @example
1215           dx/dt = t - x^2
1216 @end example
1217 @end ifnottex
1218 @tex
1219 $${{dx}\over{dt}} = t - x^2$$ 
1220 @end tex
1222 With initial value x(t=0) = 1, in the interval of t from 0 to 8 and with
1223 increments of 0.1 for t, use:
1225 @c ===beg===
1226 @c results: rk(t-x^2,x,1,[t,0,8,0.1])$
1227 @c plot2d ([discrete, results])$
1228 @c ===end===
1229 @example
1230 (%i1) results: rk(t-x^2,x,1,[t,0,8,0.1])$
1231 (%i2) plot2d ([discrete, results])$
1232 @end example
1234 the results will be saved in the list @code{results} and the plot will show the solution obtained, with @var{t} on the horizontal axis and @var{x} on the vertical axis.
1236 To solve numerically the system:
1238 @ifnottex
1239 @example
1240         dx/dt = 4-x^2-4*y^2     dy/dt = y^2-x^2+1
1241 @end example
1242 @end ifnottex
1243 @tex
1244 $$\cases{{\displaystyle{dx}\over\displaystyle{dt}} = 4-x^2-4y^2 &\cr &\cr {\displaystyle{dy}\over\displaystyle{dt}} = y^2-x^2+1}$$
1245 @end tex
1247 for t between 0 and 4, and with values of -1.25 and 0.75 for x and y at t=0:
1249 @c ===beg===
1250 @c sol: rk([4-x^2-4*y^2, y^2-x^2+1], [x, y], [-1.25, 0.75],
1251 @c               [t,0,4,0.02])$
1252 @c plot2d([discrete, makelist([p[1], p[3]], p, sol)], [xlabel, "t"],
1253 @c              [ylabel, "y"])$
1254 @c ===end===
1255 @example
1256 (%i1) sol: rk([4-x^2-4*y^2, y^2-x^2+1], [x, y], [-1.25, 0.75],
1257               [t, 0, 4, 0.02])$
1258 (%i2) plot2d([discrete, makelist([p[1], p[3]], p, sol)], [xlabel, "t"],
1259              [ylabel, "y"])$
1260 @end example
1262 The plot will show the solution for variable @var{y} as a function of @var{t}.
1264 @opencatbox{Categories:}
1265 @category{Differential equations}
1266 @category{Numerical methods}
1267 @closecatbox
1269 @end deffn