PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/R2008-02-16/extra/ode/inst/ode23.m

#
MATLAB | 180 lines | 82 code | 9 blank | 89 comment | 9 complexity | e17eba8441cfa042e97f9f142749416e MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, GPL-3.0, LGPL-3.0
  1. % Copyright (C) 2001, 2000 Marc Compere
  2. %
  3. % This program is free software; you can redistribute it and/or modify it
  4. % under the terms of the GNU General Public License as published by
  5. % the Free Software Foundation; either version 2, or (at your option)
  6. % any later version.
  7. %
  8. % This program is distributed in the hope that it will be useful, but
  9. % WITHOUT ANY WARRANTY; without even the implied warranty of
  10. % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. % General Public License for more details at www.gnu.org/copyleft/gpl.html.
  12. %
  13. % This file is intended for use with this software.
  14. % --------------------------------------------------------------------
  15. %
  16. % ode23 (v1.14) Integrates a system of ordinary differential equations using
  17. % 2nd & 3rd order Runge-Kutta formulas. This particular 3rd-order method reduces
  18. % to Simpson's 1/3 rule and uses the 3rd order estimate for xout.
  19. %
  20. % 3rd-order accurate RK methods have local and global errors of O(h^4) and O(h^3),
  21. % respectively and yield exact results when the solution is a cubic.
  22. %
  23. % The order of the RK method is the order of the local *truncation* error, d,
  24. % which is the principle error term in the portion of the Taylor series
  25. % expansion that gets dropped, or intentionally truncated. This is different
  26. % from the local error which is the difference between the estimated solution
  27. % and the actual, or true solution. The local error is used in stepsize
  28. % selection and may be approximated by the difference between two estimates of
  29. % different order, l(h) = x_(O(h+1)) - x_(O(h)). With this definition, the
  30. % local error will be as large as the error in the lower order method.
  31. % The local truncation error is within the group of terms that gets multipled
  32. % by h when solving for a solution from the general RK method. Therefore, the
  33. % order-p solution created by the RK method will be roughly accurate to O(h^(p+1))
  34. % since the local truncation error shows up in the solution as h*d, which is
  35. % h times an O(h^(p)) term, or rather O(h^(p+1)).
  36. % Summary: For an order-p accurate RK method,
  37. % - the local truncation error is O(h^p)
  38. % - the local error used for stepsize adjustment and that
  39. % is actually realized in a solution is O(h^(p+1))
  40. %
  41. % This requires 3 function evaluations per integration step.
  42. %
  43. % Relevant discussion on step size choice can be found on pp.90,91 in
  44. % U.M. Ascher, L.R. Petzold, Computer Methods for Ordinary Differential Equations
  45. % and Differential-Agebraic Equations, Society for Industrial and Applied Mathematics
  46. % (SIAM), Philadelphia, 1998
  47. %
  48. % The error estimate formula and slopes are from
  49. % Numerical Methods for Engineers, 2nd Ed., Chapra & Canale, McGraw-Hill, 1985
  50. %
  51. % Usage:
  52. % [tout, xout] = ode23(FUN,tspan,x0,ode_fcn_format,tol,trace,count,hmax)
  53. %
  54. % INPUT:
  55. % FUN - String containing name of user-supplied problem description.
  56. % Call: xprime = fun(t,x) where FUN = 'fun'.
  57. % t - Time (scalar).
  58. % x - Solution column-vector.
  59. % xprime - Returned derivative COLUMN-vector; xprime(i) = dx(i)/dt.
  60. % tspan - [ tstart, tfinal ]
  61. % x0 - Initial value COLUMN-vector.
  62. % ode_fcn_format - this specifies if the user-defined ode function is in
  63. % the form: xprime = fun(t,x) (ode_fcn_format=0, default)
  64. % or: xprime = fun(x,t) (ode_fcn_format=1)
  65. % Matlab's solvers comply with ode_fcn_format=0 while
  66. % Octave's lsode() and sdirk4() solvers comply with ode_fcn_format=1.
  67. % tol - The desired accuracy. (optional, default: tol = 1.e-6).
  68. % trace - If nonzero, each step is printed. (optional, default: trace = 0).
  69. % count - if nonzero, variable 'rhs_counter' is initalized, made global
  70. % and counts the number of state-dot function evaluations
  71. % 'rhs_counter' is incremented in here, not in the state-dot file
  72. % simply make 'rhs_counter' global in the file that calls ode23
  73. % hmax - limit the maximum stepsize to be less than or equal to hmax
  74. %
  75. % OUTPUT:
  76. % tout - Returned integration time points (column-vector).
  77. % xout - Returned solution, one solution column-vector per tout-value.
  78. %
  79. % The result can be displayed by: plot(tout, xout).
  80. %
  81. % Marc Compere
  82. % CompereM@asme.org
  83. % created : 06 October 1999
  84. % modified: 27 June 2001
  85. function [tout,xout] = ode23(FUN,tspan,x0,ode_fcn_format,tol,trace,count,hmax)
  86. if nargin < 8, hmax = (tspan(2) - tspan(1))/2.5; end
  87. if nargin < 7, count = 0; end
  88. if nargin < 6, trace = 0; end
  89. if nargin < 5, tol = 1.e-3; end
  90. if nargin < 4, ode_fcn_format = 0; end
  91. pow = 1/4; % see p.91 in the Ascher & Petzold reference for more infomation.
  92. % The 2(3) coefficients:
  93. a(1,1)=0;
  94. a(2,1)=1/2;
  95. a(3,1)=-1; a(3,2)=2;
  96. % 2nd order b-coefficients
  97. b2(1)=0; b2(2)=1;
  98. % 5th order b-coefficients
  99. b3(1)=1/6; b3(2)=2/3; b3(3)=1/6;
  100. for i=1:3
  101. c(i)=sum(a(i,:));
  102. end
  103. % Initialization
  104. t0 = tspan(1);
  105. tfinal = tspan(2);
  106. t = t0;
  107. hmin = (tfinal - t)/1e12;
  108. h = min((tfinal - t)/200,hmax); % initial guess at a step size
  109. x = x0(:); % this always creates a column vector, x
  110. tout = t; % first output time
  111. xout = x.'; % first output solution
  112. if count==1,
  113. global rhs_counter
  114. if ~exist('rhs_counter'),rhs_counter=0; end
  115. end % if count
  116. if trace
  117. clc, t, h, x
  118. end
  119. % The main loop
  120. while (t < tfinal) & (h >= hmin)
  121. if t + h > tfinal, h = tfinal - t; end
  122. % compute the slopes
  123. if (ode_fcn_format==0), % (default)
  124. k(:,1)=feval(FUN,t,x);
  125. k(:,2)=feval(FUN,t+c(2)*h,x+h*(a(2,1)*k(:,1)));
  126. k(:,3)=feval(FUN,t+c(3)*h,x+h*(a(3,1)*k(:,1)+a(3,2)*k(:,2)));
  127. else, % ode_fcn_format==1
  128. k(:,1)=feval(FUN,x,t);
  129. k(:,2)=feval(FUN,x+h*(a(2,1)*k(:,1)),t+c(2)*h);
  130. k(:,3)=feval(FUN,x+h*(a(3,1)*k(:,1)+a(3,2)*k(:,2)),t+c(3)*h);
  131. end % if (ode_fcn_format==1)
  132. % increment rhs_counter
  133. if count==1, rhs_counter = rhs_counter + 3; end
  134. % compute the 2nd order estimate
  135. x2=x + h*b2(2)*k(:,2);
  136. % compute the 3rd order estimate
  137. x3=x + h*(b3(1)*k(:,1) + b3(2)*k(:,2) + b3(3)*k(:,3));
  138. % estimate the local truncation error
  139. gamma1 = x3 - x2;
  140. % Estimate the error and the acceptable error
  141. delta = norm(gamma1,'inf');
  142. tau = tol*max(norm(x,'inf'),1.0);
  143. % Update the solution only if the error is acceptable
  144. if delta <= tau
  145. t = t + h;
  146. x = x3; % <-- using the higher order estimate is called 'local extrapolation'
  147. tout = [tout; t];
  148. xout = [xout; x.'];
  149. end
  150. if trace
  151. home, t, h, x
  152. end
  153. % Update the step size
  154. if delta == 0.0
  155. delta = 1e-16;
  156. end
  157. h = min(hmax, 0.8*h*(tau/delta)^pow);
  158. end;
  159. if (t < tfinal)
  160. disp('Step size grew too small.')
  161. t, h, x
  162. end