odeex.red 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. % A SIMPLE PROGRAM FOR COMPUTING SOLUTIONS OF ODES BY TAYLOR SERIES.
  2. % Author: Andreas Strotmann <strotmann@rrz.uni-koeln.de>.
  3. algebraic;
  4. % 1. The simplest case.
  5. % Compute the first N terms of the Taylor series of the solution of
  6. % the explicit ordinary first order differential equation
  7. % y' = f(x,y)
  8. % in a neighborhood of x0 *if* f is holomorphic in x and y at (x0,y0).
  9. PROCEDURE detaylor(f,x,y,x0,y0,N);
  10. begin scalar wj, pot;
  11. wj:=f; pot:=x-x0;
  12. return ( y0+sub({x=x0,y=y0},f)*(x-x0) +
  13. for j:=2:n sum
  14. << wj:= df(wj,x)+f*df(wj,y);
  15. pot := pot*(x-x0)/j;
  16. sub({x=x0,y=y0},wj)*pot>>);
  17. end;
  18. % Example: y'=xy
  19. detaylor(x*y,x,y,0,1,5);
  20. % 2. The general case.
  21. % Vectors (= systems of ODEs) are encoded as lists.
  22. % 2.1 Auxiliaries.
  23. infix lplusl;
  24. precedence lplusl,+;
  25. procedure x lplusl y; % vector + vector
  26. begin scalar auxy;
  27. auxy:= y;
  28. return
  29. foreach xi in x collect <<auxy:= rest auxy; s>>
  30. where s= first auxy+ xi;
  31. end;
  32. infix ltimesl;
  33. precedence ltimesl,*;
  34. procedure x ltimesl y; % vector * vector -> scalar
  35. begin scalar auxy;
  36. auxy:= y;
  37. return
  38. foreach xi in x sum <<auxy:= rest auxy; s>> where s=first auxy* xi;
  39. end;
  40. infix ltimess;
  41. precedence ltimess,*;
  42. procedure x ltimess y; % vector * scalar -> vector
  43. foreach xi in x collect y*xi;
  44. % 2.2 The central procedure.
  45. % Compute the first N terms of the Taylor series of the solution of
  46. % the initial value problem
  47. % (y1,...,yn)'=(f1(x,y1,...,yn), ... , fn(x,y1,...,yn))
  48. % such that y1(x0)=y10, ..., yn(x0)=yn0
  49. % for a system of explicit ordinary first order differential equations
  50. % in a neighborhood of x0 *if* f is holomorphic in x and all the yi at
  51. % (x0, y10,....,yn0).
  52. %
  53. % Input format: flis={f1,...,fn},
  54. % Anfangswerte={x=x0, y1=y10,..., yn=yn0}
  55. %
  56. % NOTE: none of the yi may DEPEND on x (i.e., be symbols declared to
  57. % do so).
  58. % The yi MUST be symbols so DF can handle them.
  59. procedure odetaylor(flis,Anfangswerte,N);
  60. begin scalar pot,x,y,x0,y0,wj,res;
  61. % Split args (see comment above for format):
  62. x:= lhs first Anfangswerte;
  63. x0:= rhs first Anfangswerte;
  64. y:= for each gl in rest Anfangswerte collect lhs gl;
  65. y0:= for each gl in rest Anfangswerte collect rhs gl;
  66. % Initialisations (= degree one of the taylor polynomial)
  67. res:= y0 lplusl (sub(Anfangswerte,flis) ltimess (x-x0));
  68. pot:= x-x0;
  69. wj:= flis;
  70. % Main loop:
  71. for j:=2:n do
  72. << wj:= foreach wij in wj
  73. collect df(wij,x) + (flis ltimesl
  74. foreach yk in y % one row of the
  75. % Jacobian
  76. collect df(wij,yk)); %of wj wrt y
  77. % The above DFs should be PARTDFs, really. In REDUCE 3.4, maybe they
  78. % can...
  79. pot := pot*(x-x0)/j;
  80. res:= res lplusl (sub(Anfangswerte,wj) ltimess pot);
  81. %should be sub...
  82. >>;
  83. % DONE:
  84. return res;
  85. end;
  86. % Examples:
  87. factor x;
  88. % y''=-y.
  89. odetaylor({yprime,-y}, {x=0,y=0,yprime=1}, 4);
  90. % And something wild just for fun:
  91. odetaylor({sin y2, cos(x*y1*y2)}, {x=0,y1=pi/2, y2=pi*7/4}, 4);
  92. end;