123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- module odesolve$ % Header for ordinary differential equation solver
- % Authors: F. J. Wright and M. A. H. MacCallum
- % Maintainer: F.J.Wright@maths.qmw.ac.uk, Time-stamp: <14 August 2001>
- algebraic ODESolve_version := "ODESolve 1.065"$
- global '(ODESolve!-subpackages!*)$
- % Build needs repeating if this list is changed!
- ODESolve!-subpackages!* := '(
- odeintfc % User interface and condition code (FJW)
- odetop % Top level ODESolve routines (FJW / MAHM)
- odelin % Simple linear ODE solvers (MAHM / FJW)
- odespcfn % Linear special function ODEs (FJW)
- odenon1 % Special form nonlinear ODEs of order 1 (MAHM / FJW)
- odenonn % Special form nonlinear ODEs of order > 1 (FJW)
- odepatch % Temporary REDUCE patches and extensions (FJW)
- )$
- create!-package('odesolve . ODESolve!-subpackages!*, nil)$
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Common variable type declarations and macro definitions
- % Switches to select solution form where possible -- off by default.
- % Can also be set locally by options to odesolve.
- switch odesolve_explicit$ % fully explicit
- switch odesolve_expand$ % expand roots of unity
- switch odesolve_full$ % fully explicit and expanded
- switch odesolve_implicit$ % not parametric
- switch odesolve_noint$ % turn off selected integrations
- switch noint$ % turn off integration globally
- switch odesolve_verbose$ % display ode & conditions
- switch odesolve_basis$ % output basis as linear ODE solution
- switch odesolve_noswap$ % do not swap variables
- switch odesolve_norecurse$ % no recursion => noswap
- % The `noswap' and `norecurse' switches are mainly for debugging.
- switch odesolve_fast$ % no heuristics => norecurse
- % The `fast' switch disables all non-deterministic solution techniques
- % (including most of those for nonlinear ODEs of order > 1). it is
- % useful if ODESolve is used as a service routine, including calling
- % it recursively in a hook. It makes ODESolve 1+ behave like the
- % odesolve distributed with REDUCE versions up to and including 3.7,
- % and so does not affect the odesolve.tst file.
- switch odesolve_check$ % check solution
- %% switch odesolve_load_specfn$ !*odesolve_load_specfn := t$
- % If on (the default) then autoload the specfn package if a solution
- % is returned that involves special functions. It can be turned off
- % to save resources if ODE solutions will not be further manipulated,
- % e.g. if conditions will NOT be imposed.
- % Switches controlled by ODESolve:
- fluid '(!*evallhseqp !*multiplicities !*div !*intstr
- !*exp !*mcd !*factor !*ifactor !*precise !*fullroots !*trigform)$
- % REDUCE global variables manipulated by ODESolve:
- fluid '(kord!* depl!*)$
- % Common global ODESolve variables:
- fluid '(!*odesolve!-solvable!-xy)$
- symbolic operator member, delete, !*eqn2a, depends, smember, gensym$
- symbolic smacro procedure eqnp u;
- eqcar(u, 'equal)$
- symbolic smacro procedure ODESolve!-basisp soln;
- rlistp cadr soln and not eqnp cadadr soln$
- % The following two statements are needed in case SOLVE has not been
- % loaded before compiling this package.
- global '(multiplicities!*)$ share multiplicities!*$
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Tracing support
- switch trode$ % trace the algorithms used
- % Assign a numerical value to !*trode for extra algorithm tracing:
- share !*trode$
- % rlistat is not flagged eval, so for faslout ...
- deflist('((traceode rlis) (traceode!* rlis) (traceode1 rlis)), 'stat)$
- global '(TraceOde!-InputList)$
- symbolic procedure traceode!-print u;
- %% Print sequence of elements and terminate line with linefeed.
- %% Returns nil.
- begin scalar alg; % non-nil if any algebraic elements to print
- alg := u := revlis nconc(TraceOde!-InputList, u);
- TraceOde!-InputList := nil;
- while alg and atom car alg do alg := cdr alg;
- if alg then <<
- terpri!* t;
- for each el in u do maprin el;
- terpri!* t
- >> else <<
- for each el in u do prin2 el;
- terpri()
- >>
- end$
- symbolic procedure traceode u;
- %% Print sequence of elements and terminate line with linefeed.
- %% Returns nil.
- if !*trode then traceode!-print u$
- symbolic procedure traceode!* u;
- %% Print line WITHOUT linefeed:
- %% Returns nil.
- if !*trode then
- %% Assignment necessary when TraceOde!-InputList is null:
- begin TraceOde!-InputList := nconc(TraceOde!-InputList, u) end$
- symbolic procedure traceode1 u;
- %% Extra tracing -- print line with linefeed:
- %% Returns nil.
- if !*trode = 1 then traceode!-print u$
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Arbitrary constants in solutions:
- algebraic operator arbconst$
- algebraic (!!arbconst := 0)$
- algebraic procedure newarbconst();
- arbconst(!!arbconst := !!arbconst + 1)$
- % General utilities:
- algebraic procedure ode!-int(y, x);
- %% Currently used only in `ODESolve!-PI' in module `odelin', but
- %% should probably be used more widely, so moved here!
- int(trigsimp y, x)$
- algebraic procedure ODESolve!-multi!-int(y, x, m);
- %% Integate y wrt x m times:
- %% REVISE TO INTEGRATE JUST ONCE (cf. trivial n'th order ODEs)?
- if m > 0 then ODESolve!-multi!-int(int(y,x), x, m-1) else y$
- %% algebraic procedure odefailure(ode);
- %% <<
- %% %% This message moved to ODESolve!-nonlinear:
- %% %% traceode "This version of ODESOLVE cannot solve ",
- %% %% "equations of the type given.";
- %% {ode=0}
- %% >>$
- algebraic operator odesolve!-df$
- endmodule$
- end$
|