odesolve.red 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. module odesolve$ % Header for ordinary differential equation solver
  2. % Authors: F. J. Wright and M. A. H. MacCallum
  3. % Maintainer: F.J.Wright@maths.qmw.ac.uk, Time-stamp: <14 August 2001>
  4. algebraic ODESolve_version := "ODESolve 1.065"$
  5. global '(ODESolve!-subpackages!*)$
  6. % Build needs repeating if this list is changed!
  7. ODESolve!-subpackages!* := '(
  8. odeintfc % User interface and condition code (FJW)
  9. odetop % Top level ODESolve routines (FJW / MAHM)
  10. odelin % Simple linear ODE solvers (MAHM / FJW)
  11. odespcfn % Linear special function ODEs (FJW)
  12. odenon1 % Special form nonlinear ODEs of order 1 (MAHM / FJW)
  13. odenonn % Special form nonlinear ODEs of order > 1 (FJW)
  14. odepatch % Temporary REDUCE patches and extensions (FJW)
  15. )$
  16. create!-package('odesolve . ODESolve!-subpackages!*, nil)$
  17. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  18. % Common variable type declarations and macro definitions
  19. % Switches to select solution form where possible -- off by default.
  20. % Can also be set locally by options to odesolve.
  21. switch odesolve_explicit$ % fully explicit
  22. switch odesolve_expand$ % expand roots of unity
  23. switch odesolve_full$ % fully explicit and expanded
  24. switch odesolve_implicit$ % not parametric
  25. switch odesolve_noint$ % turn off selected integrations
  26. switch noint$ % turn off integration globally
  27. switch odesolve_verbose$ % display ode & conditions
  28. switch odesolve_basis$ % output basis as linear ODE solution
  29. switch odesolve_noswap$ % do not swap variables
  30. switch odesolve_norecurse$ % no recursion => noswap
  31. % The `noswap' and `norecurse' switches are mainly for debugging.
  32. switch odesolve_fast$ % no heuristics => norecurse
  33. % The `fast' switch disables all non-deterministic solution techniques
  34. % (including most of those for nonlinear ODEs of order > 1). it is
  35. % useful if ODESolve is used as a service routine, including calling
  36. % it recursively in a hook. It makes ODESolve 1+ behave like the
  37. % odesolve distributed with REDUCE versions up to and including 3.7,
  38. % and so does not affect the odesolve.tst file.
  39. switch odesolve_check$ % check solution
  40. %% switch odesolve_load_specfn$ !*odesolve_load_specfn := t$
  41. % If on (the default) then autoload the specfn package if a solution
  42. % is returned that involves special functions. It can be turned off
  43. % to save resources if ODE solutions will not be further manipulated,
  44. % e.g. if conditions will NOT be imposed.
  45. % Switches controlled by ODESolve:
  46. fluid '(!*evallhseqp !*multiplicities !*div !*intstr
  47. !*exp !*mcd !*factor !*ifactor !*precise !*fullroots !*trigform)$
  48. % REDUCE global variables manipulated by ODESolve:
  49. fluid '(kord!* depl!*)$
  50. % Common global ODESolve variables:
  51. fluid '(!*odesolve!-solvable!-xy)$
  52. symbolic operator member, delete, !*eqn2a, depends, smember, gensym$
  53. symbolic smacro procedure eqnp u;
  54. eqcar(u, 'equal)$
  55. symbolic smacro procedure ODESolve!-basisp soln;
  56. rlistp cadr soln and not eqnp cadadr soln$
  57. % The following two statements are needed in case SOLVE has not been
  58. % loaded before compiling this package.
  59. global '(multiplicities!*)$ share multiplicities!*$
  60. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  61. % Tracing support
  62. switch trode$ % trace the algorithms used
  63. % Assign a numerical value to !*trode for extra algorithm tracing:
  64. share !*trode$
  65. % rlistat is not flagged eval, so for faslout ...
  66. deflist('((traceode rlis) (traceode!* rlis) (traceode1 rlis)), 'stat)$
  67. global '(TraceOde!-InputList)$
  68. symbolic procedure traceode!-print u;
  69. %% Print sequence of elements and terminate line with linefeed.
  70. %% Returns nil.
  71. begin scalar alg; % non-nil if any algebraic elements to print
  72. alg := u := revlis nconc(TraceOde!-InputList, u);
  73. TraceOde!-InputList := nil;
  74. while alg and atom car alg do alg := cdr alg;
  75. if alg then <<
  76. terpri!* t;
  77. for each el in u do maprin el;
  78. terpri!* t
  79. >> else <<
  80. for each el in u do prin2 el;
  81. terpri()
  82. >>
  83. end$
  84. symbolic procedure traceode u;
  85. %% Print sequence of elements and terminate line with linefeed.
  86. %% Returns nil.
  87. if !*trode then traceode!-print u$
  88. symbolic procedure traceode!* u;
  89. %% Print line WITHOUT linefeed:
  90. %% Returns nil.
  91. if !*trode then
  92. %% Assignment necessary when TraceOde!-InputList is null:
  93. begin TraceOde!-InputList := nconc(TraceOde!-InputList, u) end$
  94. symbolic procedure traceode1 u;
  95. %% Extra tracing -- print line with linefeed:
  96. %% Returns nil.
  97. if !*trode = 1 then traceode!-print u$
  98. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  99. % Arbitrary constants in solutions:
  100. algebraic operator arbconst$
  101. algebraic (!!arbconst := 0)$
  102. algebraic procedure newarbconst();
  103. arbconst(!!arbconst := !!arbconst + 1)$
  104. % General utilities:
  105. algebraic procedure ode!-int(y, x);
  106. %% Currently used only in `ODESolve!-PI' in module `odelin', but
  107. %% should probably be used more widely, so moved here!
  108. int(trigsimp y, x)$
  109. algebraic procedure ODESolve!-multi!-int(y, x, m);
  110. %% Integate y wrt x m times:
  111. %% REVISE TO INTEGRATE JUST ONCE (cf. trivial n'th order ODEs)?
  112. if m > 0 then ODESolve!-multi!-int(int(y,x), x, m-1) else y$
  113. %% algebraic procedure odefailure(ode);
  114. %% <<
  115. %% %% This message moved to ODESolve!-nonlinear:
  116. %% %% traceode "This version of ODESOLVE cannot solve ",
  117. %% %% "equations of the type given.";
  118. %% {ode=0}
  119. %% >>$
  120. algebraic operator odesolve!-df$
  121. endmodule$
  122. end$