Mercurial > octave-nkf
comparison scripts/ode/private/runge_kutta_45_dorpri.m @ 20572:72cd24aa5f7a
Clean up and vetorize Dormant&Prince RK timestepper
* scripts/ode/private/runge_kutta_45_dorpri: cleanup and vectorize.
author | Carlo de Falco <carlo.defalco@polimi.it> |
---|---|
date | Fri, 02 Oct 2015 17:48:58 +0200 |
parents | 6256f6e366ac |
children | 3339c9bdfe6a |
comparison
equal
deleted
inserted
replaced
20571:d0f886a030b7 | 20572:72cd24aa5f7a |
---|---|
1 ## Copyright (C) 2013, Roberto Porcu' <roberto.porcu@polimi.it> | 1 ## Copyright (C) 2013, Roberto Porcu' <roberto.porcu@polimi.it> |
2 ## Copyright (C) 2015, Carlo de Falco | |
2 ## | 3 ## |
3 ## This file is part of Octave. | 4 ## This file is part of Octave. |
4 ## | 5 ## |
5 ## Octave is free software; you can redistribute it and/or modify it | 6 ## Octave is free software; you can redistribute it and/or modify it |
6 ## under the terms of the GNU General Public License as published by | 7 ## under the terms of the GNU General Public License as published by |
62 ## | 63 ## |
63 ## @seealso{odepkg} | 64 ## @seealso{odepkg} |
64 | 65 |
65 function varargout = runge_kutta_45_dorpri (f, t, x, dt, varargin) | 66 function varargout = runge_kutta_45_dorpri (f, t, x, dt, varargin) |
66 | 67 |
67 options = varargin{1}; | 68 persistent a = [0 0 0 0 0 0; |
68 k = zeros (rows (x), 6); | 69 1/5 0 0 0 0 0; |
70 3/40 9/40 0 0 0 0; | |
71 44/45 -56/15 32/9 0 0 0; | |
72 19372/6561 -25360/2187 64448/6561 -212/729 0 0; | |
73 9017/3168 -355/33 46732/5247 49/176 -5103/18656 0; | |
74 35/384 0 500/1113 125/192 -2187/6784 11/84]; | |
75 persistent b = [0 1/5 3/10 4/5 8/9 1 1]; | |
76 persistent c = [(35/384) 0 (500/1113) (125/192) (-2187/6784) (11/84)]; | |
77 ## x_est according to Shampine 1986: | |
78 ## persistent c_prime = [(1951/21600) 0 (22642/50085) (451/720), ... | |
79 ## (-12231/42400) (649/6300) (1/60)]; | |
80 persistent c_prime = [(5179/57600) 0 (7571/16695) (393/640), ... | |
81 (-92097/339200) (187/2100) (1/40)]; | |
82 | |
83 s = t + dt * b; | |
84 cc = dt * c; | |
85 aa = dt * a; | |
86 | |
87 args = varargin{1}.vfunarguments; | |
88 k = zeros (rows (x), 7); | |
69 | 89 |
70 if (nargin == 5) # only the options are passed | 90 if (nargin == 5) # only the options are passed |
71 k(:,1) = feval (f, t , x, options.vfunarguments{:}); | 91 k(:,1) = feval (f, t, x, args{:}); |
72 elseif (nargin == 6) # both the options and the k values are passed | 92 elseif (nargin == 6) # both the options and the k values are passed |
73 k(:,1) = varargin{2}(:,end); # FSAL property | 93 k(:,1) = varargin{2}(:,end); # FSAL property |
74 endif | 94 endif |
75 | 95 |
76 k(:,1) = feval (f, t, x, options.vfunarguments{:}); | 96 k(:,1) = feval (f, s(1), x, args{:}); |
77 k(:,2) = feval (f, t + (1/5)*dt, ... | 97 k(:,2) = feval (f, s(2), x + k(:,1) * aa(2, 1).', args{:}); |
78 x + dt * (1/5)*k(:,1), ... | 98 k(:,3) = feval (f, s(3), x + k(:,1:2) * aa(3, 1:2).', args{:}); |
79 options.vfunarguments{:}); | 99 k(:,4) = feval (f, s(4), x + k(:,1:3) * aa(4, 1:3).', args{:}); |
80 k(:,3) = feval (f, t + (3/10)*dt, ... | 100 k(:,5) = feval (f, s(5), x + k(:,1:4) * aa(5, 1:4).', args{:}); |
81 x + dt * ((3/40)*k(:,1) + (9/40)*k(:,2)), ... | 101 k(:,6) = feval (f, s(6), x + k(:,1:5) * aa(6, 1:5).', args{:}); |
82 options.vfunarguments{:}); | |
83 k(:,4) = feval (f, t + (4/5)*dt, ... | |
84 x + dt * ((44/45)*k(:,1) - (56/15)*k(:,2) + (32/9)*k(:,3)), ... | |
85 options.vfunarguments{:}); | |
86 k(:,5) = feval (f, t + (8/9)*dt, ... | |
87 x + dt * ((19372/6561)*k(:,1) - (25360/2187)*k(:,2) ... | |
88 + (64448/6561)*k(:,3) - (212/729)*k(:,4)), ... | |
89 options.vfunarguments{:}); | |
90 k(:,6) = feval (f, t + dt, ... | |
91 x + dt * ((9017/3168)*k(:,1) - (355/33)*k(:,2) ... | |
92 + (46732/5247)*k(:,3) + (49/176)*k(:,4) ... | |
93 - (5103/18656)*k(:,5)), ... | |
94 options.vfunarguments{:}); | |
95 | 102 |
96 ## compute new time and new values for the unkwnowns | 103 ## compute new time and new values for the unkwnowns |
97 varargout{1} = t + dt; | 104 varargout{1} = t + dt; |
98 varargout{2} = x + dt * ((35/384)*k(:,1) + (500/1113)*k(:,3) | 105 varargout{2} = x + k(:,1:6) * cc(:); # 5th order approximation |
99 + (125/192)*k(:,4) - (2187/6784)*k(:,5) | |
100 + (11/84)*k(:,6)); # 5th order approximation | |
101 | 106 |
102 ## if the estimation of the error is required | 107 ## if the estimation of the error is required |
103 if (nargout >= 3) | 108 if (nargout >= 3) |
104 ## new solution to be compared with the previous one | 109 ## new solution to be compared with the previous one |
105 k(:,7) = feval (f, t + dt, varargout{2}, options.vfunarguments{:}); | 110 k(:,7) = feval (f, t + dt, varargout{2}, args{:}); |
106 ## x_est according to Shampine 1986: | 111 cc_prime = dt * c_prime; |
107 ## varargout{3} = x + dt * ((1951/21600)*k(:,1) + (22642/50085)*k(:,3) | 112 varargout{3} = x + k * cc_prime(:); # x_est |
108 ## + (451/720)*k(:,4) - (12231/42400)*k(:,5) | |
109 ## + (649/6300)*k(:,6) + (1/60)*k(:,7)); | |
110 varargout{3} = x + dt * ((5179/57600)*k(:,1) + (7571/16695)*k(:,3) | |
111 + (393/640)*k(:,4) - (92097/339200)*k(:,5) | |
112 + (187/2100)*k(:,6) + (1/40)*k(:,7)); # x_est | |
113 varargout{4} = k; | 113 varargout{4} = k; |
114 endif | 114 endif |
115 | 115 |
116 endfunction | 116 endfunction |
117 | 117 |