Mercurial > octave-nkf
view scripts/ode/private/odepkg_event_handle.m @ 20580:25623ef2ff4f
doc: Rewrite docstrings for ode* family of functions.
* scripts/ode/module.mk: Remove extra newline.
* ode45.m, odeget.m, odeset.m: Rewrite docstrings.
* AbsRel_Norm.m, fuzzy_compare.m, hermite_quartic_interpolation.m,
integrate_adaptive.m, integrate_const.m, integrate_n_steps.m, kahan.m,
ode_struct_value_check.m, odepkg_event_handle.m, odepkg_structure_check.m,
runge_kutta_45_dorpri.m, starting_stepsize.m:
Don't break @deftypefn lines. Wrap lines at 80 columns rather than 72.
author | Rik <rik@octave.org> |
---|---|
date | Sat, 03 Oct 2015 21:03:16 -0700 |
parents | 6256f6e366ac |
children | eb9e2d187ed2 |
line wrap: on
line source
## Copyright (C) 2006-2012, Thomas Treichl <treichl@users.sourceforge.net> ## ## This file is part of Octave. ## ## Octave is free software; you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or (at ## your option) any later version. ## ## Octave is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{sol}] =} odepkg_event_handle (@var{@@fun}, @var{time}, @var{y}, @var{flag}, @var{par1}, @var{par2}, @dots{}) ## ## Return the solution of the event function that is specified as the first ## input argument @var{@@fun} in form of a function handle. ## ## The second input argument @var{time} is of type double scalar and ## specifies the time of the event evaluation, the third input argument ## @var{y} either is of type double column vector (for ODEs and DAEs) and ## specifies the solutions or is of type cell array (for IDEs and DDEs) and ## specifies the derivatives or the history values, the third input argument ## @var{flag} is of type string and can be of the form ## ## @table @option ## @item @qcode{"init"} ## then initialize internal persistent variables of the function ## @command{odepkg_event_handle} and return an empty cell array of size 4, ## ## @item @qcode{"calc"} ## then do the evaluation of the event function and return the solution ## @var{sol} as type cell array of size 4, ## ## @item @qcode{"done"} ## then cleanup internal variables of the function ## @command{odepkg_event_handle} and return an empty cell array of size 4. ## @end table ## ## Optionally if further input arguments @var{par1}, @var{par2}, @dots{} of ## any type are given then pass these parameters through ## @command{odepkg_event_handle} to the event function. ## ## This function is an OdePkg internal helper function therefore it should ## never be necessary that this function is called directly by a user. There ## is only little error detection implemented in this function file to ## achieve the highest performance. ## @end deftypefn ## ## @seealso{odepkg} function [vretval] = odepkg_event_handle (vevefun, vt, vy, vflag, varargin) ## No error handling has been implemented in this function to achieve ## the highest performance available. ## vretval{1} is true or false; either to terminate or to continue ## vretval{2} is the index information for which event occured ## vretval{3} is the time information column vector ## vretval{4} is the line by line result information matrix ## These persistent variables are needed to store the results and the ## time value from the processing in the time stamp before, veveold ## are the results from the event function, vtold the time stamp, ## vretcell the return values cell array, vyold the result of the ode ## and vevecnt the counter for how often this event handling ## has been called persistent veveold; persistent vtold; persistent vretcell; persistent vyold; persistent vevecnt; ## Call the event function if an event function has been defined to ## initialize the internal variables of the event function an to get ## a value for veveold if (strcmp (vflag, 'init')) if (~iscell (vy)) vinpargs = {vevefun, vt, vy}; else vinpargs = {vevefun, vt, vy{1}, vy{2}}; vy = vy{1}; ## Delete cell element 2 end if (nargin > 4) vinpargs = {vinpargs{:}, varargin{:}}; end [veveold, vterm, vdir] = feval (vinpargs{:}); ## We assume that all return values must be column vectors veveold = veveold(:)'; vterm = vterm(:)'; vdir = vdir(:)'; vtold = vt; vyold = vy; vevecnt = 1; vretcell = cell (1,4); ## Process the event, find the zero crossings either for a rising ## or for a falling edge elseif (isempty (vflag)) if (~iscell (vy)) vinpargs = {vevefun, vt, vy}; else vinpargs = {vevefun, vt, vy{1}, vy{2}}; vy = vy{1}; ## Delete cell element 2 end if (nargin > 4) vinpargs = {vinpargs{:}, varargin{:}}; end [veve, vterm, vdir] = feval (vinpargs{:}); ## We assume that all return values must be column vectors veve = veve(:)'; vterm = vterm(:)'; vdir = vdir(:)'; ## Check if one or more signs of the event has changed vsignum = (sign (veveold) ~= sign (veve)); if (any (vsignum)) ## One or more values have changed vindex = find (vsignum); ## Get the index of the changed values if (any (vdir(vindex) == 0)) ## Rising or falling (both are possible) ## Don't change anything, keep the index elseif (any (vdir(vindex) == sign (veve(vindex)))) ## Detected rising or falling, need a new index vindex = find (vdir == sign (veve)); else ## Found a zero crossing but must not be notified vindex = []; end ## Create new output values if a valid index has been found if (~isempty (vindex)) ## Change the persistent result cell array vretcell{1} = any (vterm(vindex)); ## Stop integration or not vretcell{2}(vevecnt,1) = vindex(1,1); ## Take first event found ## Calculate the time stamp when the event function returned 0 and ## calculate new values for the integration results, we do both by ## a linear interpolation vtnew = vt - veve(1,vindex) * (vt - vtold) / (veve(1,vindex) - veveold(1,vindex)); vynew = (vy - (vt - vtnew) * (vy - vyold) / (vt - vtold))'; vretcell{3}(vevecnt,1) = vtnew; vretcell{4}(vevecnt,:) = vynew; vevecnt = vevecnt + 1; end ## if (~isempty (vindex)) end ## Check for one or more signs ... veveold = veve; vtold = vt; vretval = vretcell; vyold = vy; elseif (strcmp (vflag, 'done')) ## Clear this event handling function clear ('veveold', 'vtold', 'vretcell', 'vyold', 'vevecnt'); vretcell = cell (1,4); end