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::
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
23 @opencatbox{Categories:}
24 @category{Fourier transform}
25 @category{Numerical methods}
26 @category{Share packages}
27 @category{Package fft}
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 -----------------------------------------------------------------------------
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
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}
65 @c -----------------------------------------------------------------------------
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
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}
95 @c -----------------------------------------------------------------------------
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},
120 x[j] = sum(y[k] exp(-2 %i %pi j k / n), k, 0, n - 1)
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}
138 @c L : [1, 2, 3, 4, -1, -2, -3, -4] $
139 @c L1 : inverse_fft (L);
141 @c lmax (abs (L2 - L));
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]
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));
163 @c L : [1, 1 + %i, 1 - %i, -1, -1, 1 - %i, 1 + %i, 1] $
164 @c L1 : inverse_fft (L);
166 @c lmax (abs (L2 - L));
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,
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));
184 @opencatbox{Categories:}
185 @category{Package fft}
189 @c -----------------------------------------------------------------------------
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},
216 y[k] = (1/n) sum(x[j] exp(+2 %i %pi j k / n), j, 0, n - 1)
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
226 x[j] = sum(a[k]*cos(2*%pi*j*k/n)+b[k]*sin(2*%pi*j*k/n), k, 0, n/2)
232 a[0] = realpart (y[0])
236 and, for k from 1 through n/2 - 1,
239 a[k] = realpart (y[k] + y[n - k])
240 b[k] = imagpart (y[n - k] - y[k])
246 a[n/2] = realpart (y[n/2])
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}.
266 @c L : [1, 2, 3, 4, -1, -2, -3, -4] $
268 @c L2 : inverse_fft (L1);
269 @c lmax (abs (L2 - L));
273 (%i2) fpprintprec : 4 $
274 (%i3) L : [1, 2, 3, 4, -1, -2, -3, -4] $
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));
291 @c L : [1, 1 + %i, 1 - %i, -1, -1, 1 - %i, 1 + %i, 1] $
293 @c L2 : inverse_fft (L1);
294 @c lmax (abs (L2 - L));
298 (%i2) fpprintprec : 4 $
299 (%i3) L : [1, 1 + %i, 1 - %i, -1, -1, 1 - %i, 1 + %i, 1] $
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,
306 (%i6) lmax (abs (L2 - L));
310 Computation of sine and cosine coefficients.
315 @c L : [1, 2, 3, 4, 5, 6, 7, 8] $
317 @c x : make_array (any, n) $
318 @c fillarray (x, L) $
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]) $
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]));
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);
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) $
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]) $
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]));
350 (%i13) a[n/2] : y[n/2] $
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),
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]
362 @opencatbox{Categories:}
363 @category{Package fft}
367 @c -----------------------------------------------------------------------------
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}
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}
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}
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}
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
435 @opencatbox{Categories:}
436 @category{Package fft}
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}
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
471 @code{load("fftpack5")} loads this function.
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
488 (%i6) lmax (abs (L2-L));
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
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
499 (%i10) lmax (abs (L2-L));
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 -
516 (%i6) lmax(abs(L2-L));
520 @opencatbox{Categories:}
521 @category{Package fftpack5}
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}
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
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));
554 (%i6) fftpack5_inverse_real_fft(L1, 7);
555 (%o6) [0.5, 2.083, 2.562, 3.7, 4.3, 5.438, 5.917]
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}
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}
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 -----------------------------------------------------------------------------
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
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}
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);
607 (%i1) expr: 1e-155*x^2 - 5.5*x + 5.2e155;
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
623 @opencatbox{Categories:}
624 @category{Numerical methods}
628 @c -----------------------------------------------------------------------------
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
669 Desired absolute error of function value at root. Default is
670 @code{find_root_abs}.
672 Desired relative error of root. Default is @code{find_root_rel}.
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}
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})]}.
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
705 @c interpolate(f(x),x,0.1,%pi); time= 26 msec
706 @c interpolate(f,0.1,%pi); time= 5 msec
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;
719 @c bf_find_root (exp(x) = y, x, 0, 100), y = 10;
723 (%i1) f(x) := sin(x) - x/2;
725 (%o1) f(x) := sin(x) - -
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);
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
741 (%o8) 2.302585092994046
744 (%i10) bf_find_root (exp(x) = y, x, 0, 100), y = 10;
745 (%o10) 2.3025850929940456840179914546844b0
747 (%o11) 2.3025850929940456840179914546844b0
750 @opencatbox{Categories:}
751 @category{Algebraic equations}
752 @category{Numerical methods}
756 @c -----------------------------------------------------------------------------
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
780 @c newton (cos (u), u, 1, 1/100);
781 @c ev (cos (u), u = %);
783 @c newton (x^2 - a^2, x, a/2, a^2/100);
784 @c ev (x^2 - a^2, x = %);
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);
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 = %);
799 (%o6) 6.098490481853958e-4 a
802 @opencatbox{Categories:}
803 @category{Algebraic equations}
804 @category{Numerical methods}
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,
823 $${{dy}\over{dx}} = F(x,y)$$
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
832 -- = G(x,y,t) -- = F(x,y,t)
837 $${{dx}\over{dt}} = G(x,y,t) \qquad {{dy}\over{dt}} = F(x,y,t)$$
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
848 @opencatbox{Categories:}
849 @category{Differential equations}
850 @category{Numerical methods}
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 -----------------------------------------------------------------------------
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
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.
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
928 The options which are recognized by @code{plotdf} are the following:
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
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}.
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.
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
961 The default value is 0.
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.
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}.
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}
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.
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.
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.
1000 @dfn{xaxislabel} will be used to identify the horizontal axis. Its default value is the name of the first state variable.
1003 @dfn{yaxislabel} will be used to identify the vertical axis. Its default value is the name of the second state variable.
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.
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)}:
1016 @c plotdf(exp(-x)+y,[trajectory_at,2,-0.1])$
1019 (%i1) plotdf(exp(-x)+y,[trajectory_at,2,-0.1])$
1023 @image{figures/plotdf1,8cm}
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:
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])$
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])$
1041 The graph also shows the function @math{y = sqrt(x)}.
1044 @image{figures/plotdf2,8cm}
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
1054 @c plotdf([v,-k*z/m], [z,v], [parameters,"m=2,k=2"],
1055 @c [sliders,"m=1:5"], [trajectory_at,6,0])$
1059 (%i1) plotdf([v,-k*z/m], [z,v], [parameters,"m=2,k=2"],
1060 [sliders,"m=1:5"], [trajectory_at,6,0])$
1065 @image{figures/plotdf3,8cm}
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:
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])$
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])$
1084 @image{figures/plotdf4,8cm}
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:
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])$
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])$
1111 @image{figures/plotdf5,8cm}@image{figures/plotdf6,8cm}
1116 @opencatbox{Categories:}
1117 @category{Differential equations}
1119 @category{Numerical methods}
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
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.
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"])$
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"])$
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}
1158 @category{Numerical methods}
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:
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}
1211 To solve numerically the differential equation
1219 $${{dx}\over{dt}} = t - x^2$$
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:
1226 @c results: rk(t-x^2,x,1,[t,0,8,0.1])$
1227 @c plot2d ([discrete, results])$
1230 (%i1) results: rk(t-x^2,x,1,[t,0,8,0.1])$
1231 (%i2) plot2d ([discrete, results])$
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:
1240 dx/dt = 4-x^2-4*y^2 dy/dt = y^2-x^2+1
1244 $$\cases{{\displaystyle{dx}\over\displaystyle{dt}} = 4-x^2-4y^2 &\cr &\cr {\displaystyle{dy}\over\displaystyle{dt}} = y^2-x^2+1}$$
1247 for t between 0 and 4, and with values of -1.25 and 0.75 for x and y at t=0:
1250 @c sol: rk([4-x^2-4*y^2, y^2-x^2+1], [x, y], [-1.25, 0.75],
1252 @c plot2d([discrete, makelist([p[1], p[3]], p, sol)], [xlabel, "t"],
1256 (%i1) sol: rk([4-x^2-4*y^2, y^2-x^2+1], [x, y], [-1.25, 0.75],
1258 (%i2) plot2d([discrete, makelist([p[1], p[3]], p, sol)], [xlabel, "t"],
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}