diff --git a/setupgrind.m b/setupgrind.m index 0bcebe12f6e006cbcf675347d4b461b50702ccf9..44b24190ec48b111d432223a568b72616ec49a73 100644 --- a/setupgrind.m +++ b/setupgrind.m @@ -23,9 +23,9 @@ % Reference page in Help browser: % <a href="matlab:commands('setupgrind')">commands setupgrind</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ -function setupgrind(option) +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ +function res=setupgrind(option) %urls for downloading if ~isoctave && verLessThan('matlab', '7.6') error('grind:setup', 'MATLAB version R2008a or newer is required for GRIND'); @@ -34,16 +34,23 @@ function setupgrind(option) checkversions(true); return; end - urls = {'http://content.alterra.wur.nl/webdocs/internet/aew/downloads/', 'http://www.sparcs-center.org/uploads/files/'}; - url = urls{1}; - for i = 1:length(urls) - %find first valid url - [dummy, status] = urlread(sprintf('%s%s', urls{i}, 'grindversion.txt')); %#ok<ASGLU> - if status == 1 - url = urls{i}; - break; - end + %this url should redirect to grindversion.txt and return the exact urls + %for grind.zip etc + urls = read_grindversion('https://sparcs-center.org/grindfiles/grindversion.txt'); + if nargin > 0 && strcmp(option, '-version') + res=urls; + return; end +% for i = 1:length(urls) +% %find first valid url +% try +% dummy = webread(sprintf('%s%s', urls{i}, 'grindversion.txt')); %#ok<ASGLU> +% catch err +% if strcmp(err.identifier,'MATLAB:webservices:HTTP404StatusCodeError') +% url = urls{i}; +% end +% end +% end doanyway = 0; uninstall = 0; addstartup = 0; @@ -53,19 +60,19 @@ function setupgrind(option) doanyway = 1; end if strncmpi(option, '-up', 3) - updategrindfromweb(url); + updategrindfromweb(urls); if isempty(which('grind_coco')) addpath(fullfile(grindpath, 'sys2')); end %update coco from the grind website (only if coco is available) - if ~isempty(grind_coco.findupdate(false, url)) - grind_coco.findupdate(true, url); + if ~isempty(grind_coco.findupdate(false, urls)) + grind_coco.findupdate(true, urls); end - if ~isempty(grind_matcont.findupdate(false, url, true)) - grind_matcont.findupdate(true, url, true); + if ~isempty(grind_matcont.findupdate(false, urls, true)) + grind_matcont.findupdate(true, urls, true); end - if ~isempty(grind_matcont.findupdate(false, url, false)) - grind_matcont.findupdate(true, url, false); + if ~isempty(grind_matcont.findupdate(false, urls, false)) + grind_matcont.findupdate(true, urls, false); end elseif strncmpi(option, '-u', 2) uninstall = 1; @@ -83,7 +90,7 @@ function setupgrind(option) fprintf('Grind uninstalled from %s (no files removed)\n', thegrindpath); else checkversions(false); %if version < 7.12 [~, ] is not supported (replaced with [DUMM] - if exist_newversion(url) < 1 + if exist_newversion(urls) < 1 warning('GRIND:setupgrind:newerversion', 'There is a newer version available, use <a href="matlab: updategrind">updategrind</a> to update.'); end fprintf('Grind was already installed in %s\n', thegrindpath); @@ -100,7 +107,7 @@ function setupgrind(option) warning on MATLAB:MKDIR:DirectoryExists cd(folder); fprintf('Downloading GRIND...\n') - unzip([url 'grind.zip']); + unzip(urls.grind_url); disp('Successfully downloaded'); cd grind setupgrind @@ -225,12 +232,12 @@ end -function updategrindfromweb(url) +function updategrindfromweb(urls) % if ~exist('urlread','file') %exists in R2008 % error('GRIND:updategrind:MATLABversion','This function works only for newer versions of MATLAB'); % end - [nonewer, web, current] = exist_newversion(url); + [nonewer, web, current] = exist_newversion(urls); if isempty(web) error('GRIND:updategrind:noconnection', 'Cannot download GRIND, is internet connected?') end @@ -266,7 +273,7 @@ function updategrindfromweb(url) cd .. cd .. fprintf('Downloading new version (%s)...\n', web.date) - unzip([url 'grind.zip']); + unzip(urls.grind_url); cd(gp) cd('csolver') if exist('compile1.bat', 'file') == 2 @@ -281,22 +288,22 @@ function updategrindfromweb(url) fprintf('GRIND version %s\nRelease date: %s\n', web.version, web.date); end -function [existnew, web, current] = exist_newversion(url) +function [existnew, web, current] = exist_newversion(urls) existnew = 1; current = []; web = []; - try - [s, status] = urlread([url 'grindversion.txt']); - if status == 1 - h = str2cell(s); - else - return; - end - catch - return; - end - web.version = h{1}; - web.date = h{2}; +% try +% [s, status] = urlread([url 'grindversion.txt']); +% if status == 1 +% h = str2cell(s); +% else +% return; +% end +% catch +% return; +% end + web.version = urls.grind_version; + web.date = urls.grind_build; fid = fopen('use.m', 'r'); while ~feof(fid) line = fgetl(fid); @@ -310,7 +317,8 @@ function [existnew, web, current] = exist_newversion(url) end fclose(fid); try - existnew = datenum(web.date) - datenum(current.date) < 1E-4; + f='dd-mm-yyyy HH:MM:SS'; + existnew = datenum(web.date,f) - datenum(current.date,f) < 1E-4; catch return end @@ -505,4 +513,47 @@ function currdir = getgrinddir_dlg(currdir1) end +function str = read_grindversion(url_or_file) + %reads the grind version and file locations from an url or filename + if nargin == 0 + url_or_file = 'http://sparcs-center.org/grindfiles/grindversion.txt'; + end + if strncmp(url_or_file, 'https:', 6) || strncmp(url_or_file, 'http:', 5) + s = webread(url_or_file, weboptions('contenttype', 'text')); + + else + s = evalc(['type ' url_or_file]); + end + s = regexp(s, '[^=\n]*', 'match'); + str = struct(s{:}); + f = fieldnames(str); + for i = 1:length(f) + if isempty(strfind(f{i}, '_url')) + % [~, name, ext] = fileparts(str.(f{i})); + % str.([f{i}(1:end - 4) '_file']) = [name ext]; + %for some reason matlab removes \\ while reading url + str.(f{i}) = regexprep(str.(f{i}), 'http:[\/]([^\/].*)', 'http://$1'); + str.(f{i}) = regexprep(str.(f{i}), 'https:[\/]([^\/].*)', 'https://$1'); + end + end + str.current_grind_version = ''; + str.current_grind_build = ''; + + if exist('use', 'file') + fid = fopen('use.m', 'r'); + while ~feof(fid) + line = fgetl(fid); + f = strfind(line, 'Revision:'); + if ~isempty(f) + f1 = strfind(line, '$'); + str.current_grind_version = strtrim(line(f + 9:f1(1) - 1)); + f = strfind(line, 'Date:'); + str.current_grind_build = strtrim(line(f + 5:f1(end) - 1)); + end + end + fclose(fid); + end +end + + diff --git a/sys/addmode.m b/sys/addmode.m index 2311b8b5fcf6c8fb0607651a503478e021cf0b0f..dda0319efdb3b9028255a2a1d1ccd7329637446b 100644 --- a/sys/addmode.m +++ b/sys/addmode.m @@ -22,8 +22,8 @@ % Reference page in Help browser: % <a href="matlab:commands('addmode')">commands addmode</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function addmode(varargin) %(state, opt) global g_grind g_Y; %#ok<GVMIS> diff --git a/sys/adjr2.m b/sys/adjr2.m index 9a3806fe79fe6b78a7501f4ac4a5247aedee2edb..f85297d5c3ff690ecc4c3c5bb39a0466a78e9bf3 100644 --- a/sys/adjr2.m +++ b/sys/adjr2.m @@ -12,8 +12,8 @@ % Reference page in Help browser: % <a href="matlab:commands('adjr2')">commands adjr2</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function meanAdjR2 = adjr2(npars) global g_data t g_Y g_t; %#ok<GVMIS> if strncmp(npars, '??', 2) diff --git a/sys/analunits.m b/sys/analunits.m index c6eb5100d30bce04ce386154c9fc2d8649a1917e..ffe0ae5762073689f078be8b826f1e29e82954cc 100644 --- a/sys/analunits.m +++ b/sys/analunits.m @@ -49,8 +49,8 @@ % Reference page in Help browser: % <a href="matlab:commands('analunits')">commands analunits</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function [un, vars] = analunits(varargin) %(mod, varlist, unitlist) global g_grind; %#ok<GVMIS> diff --git a/sys/arrows.m b/sys/arrows.m index 6debba05e6a34c398499e664a3be80da53bf3351..706eed856265ed8484930b0a7908084fba198f86 100644 --- a/sys/arrows.m +++ b/sys/arrows.m @@ -19,8 +19,8 @@ % Reference page in Help browser: % <a href="matlab:commands('arrows')">commands arrows</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function arrows(hax, narrow, arg2) nearest = []; if nargin == 1 && ischar(hax) && strncmp(hax, '??', 2) diff --git a/sys/attrbasin.m b/sys/attrbasin.m index 25311f3c6bbd8ed9a250000fa37a8b4b0bfc213b..123b6c4e3e08e621c4c9c98073b934def24b8ff6 100644 --- a/sys/attrbasin.m +++ b/sys/attrbasin.m @@ -20,8 +20,8 @@ % Reference page in Help browser: % <a href="matlab:commands('attrbasin')">commands attrbasin</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function EndsVar = attrbasin(varargin) %(n, var2, EndsX) global g_Y t g_grind g_t; %#ok<GVMIS> diff --git a/sys/back_euler.m b/sys/back_euler.m index 3c823283f5a76e472a810bd6286e44f44cfecd99..f24422717a16204c9a055df6de9f6ed900207902 100644 --- a/sys/back_euler.m +++ b/sys/back_euler.m @@ -38,7 +38,7 @@ function [tout, yout] = back_euler(odefunct, tspan, y0, options) Jfun = options.Jacobian; end if nargin >= 4 - nonNegative = ~isempty(odeget(options, 'NonNegative', [], 'fast')); + nonNegative = ~isempty(odeget(options, 'NonNegative', [])); %if nonNegative % warning('GRIND:back_euler:NonNegativeIgnored', 'BACK_EULER does not constrain solution to be non-negative. Option ''NonNegative'' will be ignored.'); %end diff --git a/sys/backw.m b/sys/backw.m index 25ce063c4500648cf3738511c32ea2b43d4d8e6b..e636ed620906de45d8d90b3577e6ad202d1e0085 100644 --- a/sys/backw.m +++ b/sys/backw.m @@ -26,8 +26,8 @@ % Reference page in Help browser: % <a href="matlab:commands('backw')">commands backw</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function backw(varargin) %(ndays,dotrunc) global g_grind; %#ok<GVMIS> diff --git a/sys/boxcarinflow.m b/sys/boxcarinflow.m index ab1114e66cb04ef65aee844a38bb2dea4201c3bd..665657b66b35ab1f8c127f2f0aae138291489742 100644 --- a/sys/boxcarinflow.m +++ b/sys/boxcarinflow.m @@ -11,8 +11,8 @@ % Reference page in Help browser: % <a href="matlab:commands('boxcarinflow')">commands boxcarinflow</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function res = boxcarinflow(A, inflow) res = zeros(size(A)); if numel(inflow) > 1 diff --git a/sys/boxcartrain.m b/sys/boxcartrain.m index 3bc45ad8a967236954cdb53adb8827489affe3a1..8067b77c90a77d7bc89cd69000e3ed3924be8f0e 100644 --- a/sys/boxcartrain.m +++ b/sys/boxcartrain.m @@ -21,8 +21,8 @@ % Reference page in Help browser: % <a href="matlab:commands('boxcartrain')">commands boxcartrain</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function [res, Anew] = boxcartrain(boxnr, A, devrate, cv_devrate) global g_grind; %#ok<GVMIS> if nargin < 4 diff --git a/sys/combfig.m b/sys/combfig.m index 406337b3091646bb1bf13644a980cfdbd741930b..50cf2644f7b16ffdc12ff3b6b60051b1641b22c4 100644 --- a/sys/combfig.m +++ b/sys/combfig.m @@ -36,8 +36,8 @@ % Reference page in Help browser: % <a href="matlab:commands('combfig')">commands combfig</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function ndx = combfig(varargin) %(fignrs, Cells, starti) if ~exist('i_figno', 'file') diff --git a/sys/commands.m b/sys/commands.m index 4563b4190eb076cfbcb1c5b3b36036f708146769..956ce37c2730bcdd0043ce7688bda178d80e428d 100644 --- a/sys/commands.m +++ b/sys/commands.m @@ -154,7 +154,7 @@ function commands(varargin) k1 = k1 + 1; line = fgets(fid); end - + fid3 = fopen(fname, 'w'); fprintf(fid3, '%s', lines{:}); fwrite(fid3, sprintf('%%\n%% Reference page in Help browser:\n%% <a href="matlab:commands(''%s'')">commands %s</a>\n', aname, aname)); @@ -219,20 +219,24 @@ function commands(varargin) cd(ddir); cd .. cd setup - try - cocoversion = dir('\\SCOMP5341\Webdocs$\Internet\aew\Downloads\coco*.zip'); - if length(cocoversion) ~= 1 - error('grind:commands', 'There must be one coco version on the website'); - end - fid = fopen('cocoversion.txt', 'w'); - fprintf(fid, '%s\n', cocoversion.name); - fclose(fid); - catch - warning('grind:commands', 'cannot open webdocs'); + % try + % cocoversion = dir('\\SCOMP5341\Webdocs$\Internet\aew\Downloads\coco*.zip'); + % if length(cocoversion) ~= 1 + % error('grind:commands', 'There must be one coco version on the website'); + % end + % fid = fopen('cocoversion.txt', 'w'); + % fprintf(fid, '%s\n', cocoversion.name); + % fclose(fid); + % catch + % warning('grind:commands', 'cannot open webdocs'); + % end + if ~exist('i_use', 'file') + addpath([grindpath filesep 'sys2']); end - fid = fopen('grindversion.txt', 'w'); - fprintf(fid, '%s\n%s\n', grindver, updatedat); - fclose(fid); + versions = read_grindversion; + versions.grind_version = versions.current_grind_version; + versions.grind_build = versions.current_grind_build; + write_grindversion(versions, 'grindversion.txt') s = grindpath; f = strfind(s, filesep); s = s(1:f(end) - 1); @@ -431,3 +435,14 @@ function commands(varargin) end end +function write_grindversion(str, filename) + f = fieldnames(str); + fid = fopen(filename, 'w'); + for i = 1:length(f) + if ~strcontains(f{i}, 'current_') + fprintf(fid, '%s=%s\n', f{i}, str.(f{i})); + end + end + fclose(fid); +end + diff --git a/sys/connectmat.m b/sys/connectmat.m index 23c4e3ce1b8028fb56f13c55fad29e4015651f8a..e6bf9432ba16e36a0f4fc5ccc9717d0ebedd1117 100644 --- a/sys/connectmat.m +++ b/sys/connectmat.m @@ -18,8 +18,8 @@ % Reference page in Help browser: % <a href="matlab:commands('connectmat')">commands connectmat</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function [M] = connectmat(varargin) %(s1,s2,isround) fieldnams = {'size', 'i>1', 'size of the matrix.', []; ... diff --git a/sys/contbif.m b/sys/contbif.m index f1e12821a06f9031d2ead1a562abaafb7213c3aa..e545c7e2619264201b4495f8b0d2d995a9ff7de4 100644 --- a/sys/contbif.m +++ b/sys/contbif.m @@ -11,8 +11,8 @@ % Reference page in Help browser: % <a href="matlab:commands('contbif')">commands contbif</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function contbif(varargin) if nargin > 0 conteq('-contbif', varargin{:}); diff --git a/sys/contents.m b/sys/contents.m index c30b77803b926d82ef63319d7a16e4941d1c8401..f51b3ae5f79f3bd3b07a60b80ae87488060af554 100644 --- a/sys/contents.m +++ b/sys/contents.m @@ -134,8 +134,8 @@ % Reference page in Help browser: % <a href="matlab:commands('contents')">commands contents</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ %start disp('') diff --git a/sys/conteq.m b/sys/conteq.m index 2e279591d0677a7edf085d62c16a82d5460d12fb..34671361a0bc4d5c3bdc038bacff84ab2570e319 100644 --- a/sys/conteq.m +++ b/sys/conteq.m @@ -1,6 +1,6 @@ %CONTEQ Continue an equilibrium or bifurcation with COCO or MatCont % This command can do an 1D or 2D bifurcation analysis using the package -% <a href="matlab:help coco">COCO (Continuation Core and Toolboxes)</a> or <a href="matlab:commands matcont">MatCont</a>. +% <a href="matlab:commands coco">COCO (Continuation Core and Toolboxes)</a> or <a href="matlab:commands matcont">MatCont</a>. % Select an equilibrium with <a href="matlab:help findeq">findeq</a>, then you can continue the stable or % unstable equilibrium. It can (currently) detect a fold (=saddle-node), transcritical and a Hopf bifurcation. % A plot of the equilibrium and the eigenvalues is made. @@ -33,7 +33,7 @@ % 'stateranges' [number] - min/max value for each of the state variables, or one row if all are the same (default: [Nan NaN]) % 'symbolic' [logical] - if available use the symbolic toolbox for Jacobians (default 1) % -% <a href="matlab:help Coco">Specific options for COCO</a> +% <a href="matlab:commands Coco">Specific options for COCO</a> % <a href="matlab:commands matcont">Specific options for MatCont</a> for differential equations % <a href="matlab:commands matcontm">Specific options for MatContM</a> (for difference equations) % @@ -69,32 +69,45 @@ % Reference page in Help browser: % <a href="matlab:commands('conteq')">commands conteq</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function conteq(varargin) + % Set up global variables for continuation analysis evalin('base', 'global g_cont;'); global g_grind g_cont; %#ok<GVMIS> + + % Check for a correct model if ~(nargin == 1 && strncmp(varargin{1}, '??', 2)) i_parcheck; end + + % Initialize g_grind.cont fields based on the type of continuation engine if isa(g_cont, 'grind_matcont') && ~isfield(g_grind.cont, 'matcont') g_grind.cont.matcont = g_cont; g_grind.cont.engine = g_cont.settings.derived.engine; end + if isa(g_cont, 'grind_coco') && ~isfield(g_grind.cont, 'coco') g_grind.cont.coco = g_cont; g_grind.cont.engine = 'coco'; end + + % Initialize a flag for continuation bifurcation analysis docontbif = false; + + % Select output plots if nargin > 0 && strncmp(varargin{1}, '-o', 2) if nargin == 1 i_paranaloutdlg('Edit Plots for conteq'); conteq; else + % Call paranal function with additional input arguments paranal(varargin{:}); end return; end + + % Clear continuation session if specified if nargin > 0 && strncmp(varargin{1}, '-c', 2) && ~strncmp(varargin{1}, '-co', 3) if ~isempty(g_cont) disp('cleared conteq session') @@ -103,17 +116,22 @@ function conteq(varargin) return; end + % Display about selected plots if nargin > 0 && strncmp(varargin{1}, '-l', 2) if ~isfield(g_grind, 'paranal') paranal('-default'); end for i = 1:length(g_grind.paranal.plots) - fprintf('conteq -out %d [''%s'' ''%s'' ''%s''] [%g %g] [%g %g] [%g %g]\n', i, strtrim(sprintf('%s ', g_grind.paranal.plots{i}.xaxis{:})), ... - strtrim(sprintf('%s ', g_grind.paranal.plots{i}.yaxis{:})), strtrim(sprintf('%s ', g_grind.paranal.plots{i}.zaxis{:})), ... + fprintf('conteq -out %d [''%s'' ''%s'' ''%s''] [%g %g] [%g %g] [%g %g]\n', i, ... + strtrim(sprintf('%s ', g_grind.paranal.plots{i}.xaxis{:})), ... + strtrim(sprintf('%s ', g_grind.paranal.plots{i}.yaxis{:})), ... + strtrim(sprintf('%s ', g_grind.paranal.plots{i}.zaxis{:})), ... g_grind.paranal.plots{i}.xlim, g_grind.paranal.plots{i}.ylim, g_grind.paranal.plots{i}.zlim); end return; end + + % Handle specific input arguments related to continuation analysis if nargin > 0 ndx = cellfun(@ischar, varargin); f1 = strcmp(varargin(ndx), '-contbif'); @@ -135,6 +153,7 @@ function conteq(varargin) varargin = varargin(~(f1 | f2 | f3)); end + % Update continuation engine based on user input if strncmp(g_grind.cont.engine, 'matcont', 7) && ~isa(g_cont, 'grind_matcont') if isfield(g_grind.cont, 'matcont') && ~isempty(g_cont) g_cont = g_grind.cont.matcont; @@ -143,6 +162,7 @@ function conteq(varargin) g_grind.cont.matcont = g_cont; end end + if strcmp(g_grind.cont.engine, 'coco') && ~isa(g_cont, 'grind_coco') if isfield(g_grind.cont, 'coco') && ~isempty(g_cont) g_cont = g_grind.cont.coco; @@ -151,10 +171,14 @@ function conteq(varargin) g_grind.cont.coco = g_cont; end end + + % Set up additional arguments for the continuation engine args = struct('opt', ''); if ~isempty(varargin) args = g_cont.set(varargin{:}); end + + % Load a saved session if specified in the arguments if isfield(args, 'file') g_cont = g_cont.load_session(args.file); g_grind.cont.engine = g_cont.settings.derived.engine; @@ -164,6 +188,8 @@ function conteq(varargin) g_grind.cont.matcont = g_cont; end end + + % Perform continuation analysis or display GUI based on user input if ~(isfield(args, 'par1') || isfield(args, 'par2')) || isempty(g_cont.settings.derived.freepars) if docontbif g_cont.gui('contbif'); @@ -174,9 +200,12 @@ function conteq(varargin) if numel(g_cont.points) <= 1 g_cont.add_points(findeqs('maxtime', 10)); end - if isempty(g_cont.settings.derived.frompoint) %by default the current initial conditions + if isempty(g_cont.settings.derived.frompoint) % by default the current initial conditions g_cont.settings.derived.frompoint = g_cont.add_points; end g_cont.cont; end end + + + diff --git a/sys/conteq2d.m b/sys/conteq2d.m index d07e16571e90886e93469c640882d94db9d332c9..507415f133b994c7e983d036d82102b2fed433c9 100644 --- a/sys/conteq2d.m +++ b/sys/conteq2d.m @@ -16,8 +16,8 @@ % Reference page in Help browser: % <a href="matlab:commands('conteq2d')">commands conteq2d</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function conteq2d(varargin) hasengine = false; for i = 1:length(varargin) diff --git a/sys/copyfig.m b/sys/copyfig.m index f3b6ffcdd14ffc03e457b6324ff50345d96cfd29..edb3f66c2cb422ad21534245ada0041059449b97 100644 --- a/sys/copyfig.m +++ b/sys/copyfig.m @@ -15,43 +15,64 @@ % Reference page in Help browser: % <a href="matlab:commands('copyfig')">commands copyfig</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function copyfig(varargin) - %(from,to) + + % Define default values and field names for argument parsing fieldnams = {'from', 'h', 'original figure handle.', get(0, 'CurrentFigure'); ... 'to', 'n', 'number of the new figure', 1000}'; + + % Parse input arguments args = i_parseargs(fieldnams, 'if nargs==1,deffields=''to'';else,deffields=''from,to'';end;', '', varargin); + + % Add sys2 directory to the path if i_checkstr function doesn't exist if ~exist('i_checkstr', 'file') addpath([grindpath filesep 'sys2']); end + + % Set default 'from' value if not specified if ~isfield(args, 'from') args.from = get(0, 'CurrentFigure'); end + + % Set default 'to' value if not specified if ~isfield(args, 'to') + % Prompt user for figure numbers if not provided prompt = {'Figure number to copy (gcf=current):', 'Copy to:'}; answer = inputdlg(prompt, 'Copy figure', 1, {'', ''}); + + % Set 'from' and 'to' values based on user input if isempty(answer{1}) answer{1} = 'gcf'; end args = i_parseargs(fieldnams, 'if nargs==1,deffields=''to'';else,deffields=''from,to'';end;', '', answer); end + + % Delete the new figure if it already exists if ishandle(args.to) delete(args.to); end + + % Create a new figure with the specified number h = i_figure(args.to); + + % Copy axes objects from the original figure to the new figure if ishandle(args.from) - % ax=findobj(args.from,'type','axes'); if strcmp(get(args.from, 'type'), 'axes') hax = args.from; else hax = get(args.from, 'children'); end + + % Copy axes objects to the new figure copyobj(hax, h); + + % Adjust the position of the axes in the new figure axnew = findobj(h, 'type', 'axes'); set(axnew, 'position', [0.1300 0.1100 0.7750 0.8150], 'Units', 'normalized'); - else + % Display an error if the source figure doesn't exist error('GRIND:copyfig:UnknownFig', 'Copyfig: source figure doesn''t exist'); end end diff --git a/sys/csolver/csolver.layout b/sys/csolver/csolver.layout index 4ff230b8505e0124868176e25284d0284c75902c..44b745783de56fd051e579949a447b4596eeee81 100644 --- a/sys/csolver/csolver.layout +++ b/sys/csolver/csolver.layout @@ -2,6 +2,21 @@ <CodeBlocks_layout_file> <FileVersion major="1" minor="0" /> <ActiveTarget name="Debug" /> + <File name="onedimtools.cpp" open="1" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="1912" topLine="52" /> + </Cursor> + </File> + <File name="matmatrix.h" open="1" top="1" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="3422" topLine="88" /> + </Cursor> + </File> + <File name="main.cpp" open="1" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> + <Cursor> + <Cursor1 position="18" topLine="0" /> + </Cursor> + </File> <File name="csolver1.cpp" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> <Cursor> <Cursor1 position="11507" topLine="334" /> @@ -27,19 +42,4 @@ <Cursor1 position="2422" topLine="0" /> </Cursor> </File> - <File name="onedimtools.cpp" open="1" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> - <Cursor> - <Cursor1 position="1912" topLine="52" /> - </Cursor> - </File> - <File name="matmatrix.h" open="1" top="1" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> - <Cursor> - <Cursor1 position="3422" topLine="88" /> - </Cursor> - </File> - <File name="main.cpp" open="1" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0"> - <Cursor> - <Cursor1 position="18" topLine="0" /> - </Cursor> - </File> </CodeBlocks_layout_file> diff --git a/sys/csolver/param1.tmp b/sys/csolver/param1.tmp deleted file mode 100644 index b94ef899f47b365fda92b1eae4e4a44316439468..0000000000000000000000000000000000000000 Binary files a/sys/csolver/param1.tmp and /dev/null differ diff --git a/sys/csolvers.m b/sys/csolvers.m index c4024531ef5131812fea183fd768e92f70c8d633..2edc128a0a8d76d832f32a73e566ab1ba05b1c12 100644 --- a/sys/csolvers.m +++ b/sys/csolvers.m @@ -39,8 +39,8 @@ % Reference page in Help browser: % <a href="matlab:commands('csolvers')">commands csolvers</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function [ts, ys, comm] = csolvers(ode, tspan, y0, ~, varargin) global g_grind g_permanent; %#ok<GVMIS> if nargin == 0 diff --git a/sys/dde_euler.m b/sys/dde_euler.m index 8b12062d1bfc8f33f728105eb384aa69f27a8e8f..97aec13650105545e90a0a8b70e8ed72982e71a4 100644 --- a/sys/dde_euler.m +++ b/sys/dde_euler.m @@ -2,7 +2,7 @@ function [tout, yout, varargout] = dde_euler(odefile, tspan, y0, options, vararg global g_grind; %#ok<GVMIS> %DDE23('F',LAGS,HISTORY,TSPAN) if nargin >= 4 - nonNegative = ~isempty(odeget(options, 'NonNegative', [], 'fast')); + nonNegative = ~isempty(odeget(options, 'NonNegative', [])); if nonNegative warning('GRIND:DDE23:NonNegativeIgnored', 'DDE23 does not constrain solution to be non-negative. Option ''NonNegative'' will be ignored.'); end @@ -109,14 +109,14 @@ function sol = dde_euler1(odefile, lags, history, tspan, options,varargin) sol.history = history; end y0 = temp(:); - initialy = ddeget(options, 'InitialY', [], 'fast'); + initialy = ddeget(options, 'InitialY', []); if ~isempty(initialy) y0 = initialy(:); end if nargin < 4 nonNegative = []; else - nonNegative = odeget(options, 'NonNegative', [], 'fast'); + nonNegative = odeget(options, 'NonNegative', []); end anyNonNegative = ~isempty(nonNegative); haveOutputFcn = ~isempty(options.OutputFcn); diff --git a/sys/ddesol.m b/sys/ddesol.m index e2779778731045c57da0ed30d5069f70e10b22a7..7bf6eb08bc5f86366773070a7a5900b1d9804368 100644 --- a/sys/ddesol.m +++ b/sys/ddesol.m @@ -2,7 +2,7 @@ function [tout, yout, varargout] = ddesol(odefile, tspan, y0, options, varargin) global g_grind; %#ok<GVMIS> %DDE23('F',LAGS,HISTORY,TSPAN) if nargin >= 4 - nonNegative = ~isempty(odeget(options, 'NonNegative', [], 'fast')); + nonNegative = ~isempty(odeget(options, 'NonNegative', [])); if nonNegative warning('GRIND:DDE23:NonNegativeIgnored', 'DDE23 does not constrain solution to be non-negative. Option ''NonNegative'' will be ignored.'); end diff --git a/sys/defextern.m b/sys/defextern.m index 241e5d8039f7d96dd82a0425322699221dfff74c..fabdd8fa91bcc41c3fcf184cf29bc25ce34ec315 100644 --- a/sys/defextern.m +++ b/sys/defextern.m @@ -28,8 +28,8 @@ % Reference page in Help browser: % <a href="matlab:commands('defextern')">commands defextern</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function g_result = defextern(varargin) %(name, default, data, opt1, opt2) global g_grind g_Y; %#ok<GVMIS> diff --git a/sys/definepars.m b/sys/definepars.m index 52a89036add65402b646d7b0c571b7c05e7f8023..2fa2bd04b89ee594d1f905858a7e2c6c45582b6d 100644 --- a/sys/definepars.m +++ b/sys/definepars.m @@ -14,8 +14,8 @@ % Reference page in Help browser: % <a href="matlab:commands('definepars')">commands definepars</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function definepars(varargin) fieldnams = {'par', 'U1', 'define parameter par.', ''}'; i_parseargs(fieldnams, 'par(+)', '', varargin, false, {@i_isid}); diff --git a/sys/definespace.m b/sys/definespace.m index 2cfebcbbedc2f794d6b6be434dfca46c48fbf7fb..6f33566f920c27c06bb7830d181d4ea15ef0ec22 100644 --- a/sys/definespace.m +++ b/sys/definespace.m @@ -34,8 +34,8 @@ % Reference page in Help browser: % <a href="matlab:commands('definespace')">commands definespace</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function definespace(varargin) global g_grind; %#ok<GVMIS> fieldnams = {'gridsize', 'i>0&length(i)<=2', 'size of the grid, adapts sizes of state variables and parameters', [1 1]; ... diff --git a/sys/defpermanent.m b/sys/defpermanent.m index 284bc6d40af7af4d532340ecb6c0129682a75b7e..fb1a7128b7152d3895e25081f5cce99af501b4d2 100644 --- a/sys/defpermanent.m +++ b/sys/defpermanent.m @@ -32,8 +32,8 @@ % Reference page in Help browser: % <a href="matlab:commands('defpermanent')">commands defpermanent</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function res = defpermanent(varargin) %(avar, avalue, apar) global g_permanent g_grind g_t; %#ok<GVMIS> diff --git a/sys/dirfield.m b/sys/dirfield.m index 66154071d0a0c8588dd39fb894ff7f9fd60633c5..ef516b2cd3b6ce5c8dfb1b73ab35dff227f2711c 100644 --- a/sys/dirfield.m +++ b/sys/dirfield.m @@ -21,8 +21,8 @@ % Reference page in Help browser: % <a href="matlab:commands('dirfield')">commands dirfield</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function dirfield(varargin) global g_grind t; %#ok<GVMIS> % avar=varargin{1}; diff --git a/sys/downcells.m b/sys/downcells.m index 6b300dd454c94c115f15edc9594b459a509f60d6..3cef1896e2141f7b53037bd2f7cc017ee6e2eab3 100644 --- a/sys/downcells.m +++ b/sys/downcells.m @@ -15,8 +15,8 @@ % Reference page in Help browser: % <a href="matlab:commands('downcells')">commands downcells</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function result = downcells(N, bordered, aValue) if nargin < 2 bordered = 'neumann'; diff --git a/sys/drawuniform.m b/sys/drawuniform.m index 581d9f1705846faa9cc07012148a71a7984e4c8a..7c34d9439de140e8bdb17b41a7da0e2fca7e1e15 100644 --- a/sys/drawuniform.m +++ b/sys/drawuniform.m @@ -10,8 +10,8 @@ % Reference page in Help browser: % <a href="matlab:commands('drawuniform')">commands drawuniform</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function A = drawuniform(dim1, dim2, minA, maxA) if nargin == 3 maxA = minA; diff --git a/sys/dwiener.m b/sys/dwiener.m index c784d08430859462c9909293e5dd80078714c396..3c91ec1c79428c7a2f750c48205952dc24921709 100644 --- a/sys/dwiener.m +++ b/sys/dwiener.m @@ -45,8 +45,8 @@ % Reference page in Help browser: % <a href="matlab:commands('dwiener')">commands dwiener</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function res = dwiener(at, gY, dgY_dY, No, varargin) global g_dwiener %#ok<GVMIS> if ~isempty(g_dwiener)&&isequal(at,'-i') diff --git a/sys/e2n.m b/sys/e2n.m index 048a37e4b1526d66c070d9a4a9a1d27921434eb0..8e327fba743626734766612ebf93027f8e9acf88 100644 --- a/sys/e2n.m +++ b/sys/e2n.m @@ -6,8 +6,8 @@ % Reference page in Help browser: % <a href="matlab:commands('e2n')">commands e2n</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ %start function e2n(varargin) i_parseargs('', '', '', varargin); diff --git a/sys/e2p.m b/sys/e2p.m index 3fd6d39a0d3e7994cc3e2494baae94f865c4afab..7a33c008cfdbdac8bdb40d8363905c42c8c4ef98 100644 --- a/sys/e2p.m +++ b/sys/e2p.m @@ -6,8 +6,8 @@ % Reference page in Help browser: % <a href="matlab:commands('e2p')">commands e2p</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ %start function e2p(varargin) i_parseargs('', '', '', varargin); diff --git a/sys/e2r.m b/sys/e2r.m index 9b5370ec471c727bf63f931c2a4d64fa723e9682..b21ebb5c71e18516963f5f866e6bc2698574a472 100644 --- a/sys/e2r.m +++ b/sys/e2r.m @@ -6,8 +6,8 @@ % Reference page in Help browser: % <a href="matlab:commands('e2r')">commands e2r</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ %start function e2r(varargin) i_parseargs('', '', '', varargin); diff --git a/sys/e3r.m b/sys/e3r.m index 59ee0202a1d43e8cb3d669ada96f269ff7a93e20..fd0686a4405cf1b18808095b2e825e9cbc02e4e7 100644 --- a/sys/e3r.m +++ b/sys/e3r.m @@ -6,8 +6,8 @@ % Reference page in Help browser: % <a href="matlab:commands('e3r')">commands e3r</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ %start function e3r(varargin) i_parseargs('', '', '', varargin); diff --git a/sys/eigen.m b/sys/eigen.m index 5a20704c2d82e0bbcefb1e503ae1b2bd60259590..73e56f247afe493c9504979b84ab832190473146 100644 --- a/sys/eigen.m +++ b/sys/eigen.m @@ -31,8 +31,8 @@ % Reference page in Help browser: % <a href="matlab:commands('eigen')">commands eigen</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function Eigs = eigen(varargin) global g_grind g_Y t g_t; %#ok<GVMIS> fieldnams = {'sizedist', 'n>0', 'Size of the perturbation of perturbation', 0.00001; ... diff --git a/sys/enterjac.m b/sys/enterjac.m index bff2af8742fc5c8d07b6d2d92160bff5c2b49eed..5ddfe11e78a733bc1fda5206328e34d9fa045a91 100644 --- a/sys/enterjac.m +++ b/sys/enterjac.m @@ -46,8 +46,8 @@ % Reference page in Help browser: % <a href="matlab:commands('enterjac')">commands enterjac</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function [res, maxdif] = enterjac(varargin) global g_grind; %#ok<GVMIS> % if ~isempty(g_grind) diff --git a/sys/era.m b/sys/era.m index 909ceaed8fe0180eca63f79746e3937b3b24cfda..7dafb2c85a728dae7ee45228c01d862b0439ffae 100644 --- a/sys/era.m +++ b/sys/era.m @@ -9,8 +9,8 @@ % Reference page in Help browser: % <a href="matlab:commands('era')">commands era</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function era(varargin) args = i_parseargs('', '', '-a', varargin); allfigures = any(strcmp(args.opts, '-a')); diff --git a/sys/externvar.m b/sys/externvar.m index 2fe4f6d46cdfd37b66645c06491f9dcde3c1c2f3..3d743133ad7803023e8b1f44a9db525044eb971b 100644 --- a/sys/externvar.m +++ b/sys/externvar.m @@ -18,8 +18,8 @@ % Reference page in Help browser: % <a href="matlab:commands('externvar')">commands externvar</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function V = externvar(varnr, default, at) global g_grind g_t; if nargin == 2 diff --git a/sys/fglobalmin.m b/sys/fglobalmin.m index ed59ae2e8147a283fcf609624787ac3029fdaef8..28525331293eeb09d40e8cc1c594f4e772f7dfab 100644 --- a/sys/fglobalmin.m +++ b/sys/fglobalmin.m @@ -42,8 +42,8 @@ % Reference page in Help browser: % <a href="matlab:commands('fglobalmin')">commands fglobalmin</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function [bestx, bestf, exitflag, output] = fglobalmin(funfcn, ax, bx, options, varargin) %FGLOBALMIN Scalar bounded global function minimization. % Using the very robust Shuffled Complex Evolution (SCE-UA) global optimization algorithm. diff --git a/sys/figdata.m b/sys/figdata.m index efd4589d0ebe11e33530eb33f87c9d281a34ea2a..d9cfa8664fa1b498cf988f462769c09fa53f96b6 100644 --- a/sys/figdata.m +++ b/sys/figdata.m @@ -22,8 +22,8 @@ % Reference page in Help browser: % <a href="matlab:commands('figdata')">commands figdata</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function A = figdata(varargin) %(serno,ax) fieldnams = {'serno', 'i>0', 'number of the series to copy', 1; ... diff --git a/sys/fokkerplanck.m b/sys/fokkerplanck.m index c5b9876174826d685ff918478cb1cd78e85f9bbd..95bfa0942f90deee53c39d82f112216450b8136b 100644 --- a/sys/fokkerplanck.m +++ b/sys/fokkerplanck.m @@ -34,8 +34,8 @@ % Reference page in Help browser: % <a href="matlab:commands('fokkerplanck')">commands fokkerplanck</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function fokkerplanck(varargin) evalin('base', 'global g_langevin_eq'); global g_langevin_eq g_grind; %#ok<GVMIS> diff --git a/sys/funcs.m b/sys/funcs.m index dcb92aa45f5eaff3de779094f191811e8cd8cbfb..1f0e09ad0fec6585341842c878355cb1e71e5567 100644 --- a/sys/funcs.m +++ b/sys/funcs.m @@ -27,8 +27,8 @@ % Reference page in Help browser: % <a href="matlab:commands('funcs')">commands funcs</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function funcs(varargin) global g_grind; %#ok<GVMIS> eoln = sprintf('\n'); %#ok<SPRINTFN> diff --git a/sys/funplot.m b/sys/funplot.m index 06bbb4958f9b8b31cf81bf19b36b0bf5ae3608f2..59a4ad63c54ee2eba617e14048ac91119819d25d 100644 --- a/sys/funplot.m +++ b/sys/funplot.m @@ -42,8 +42,8 @@ % Reference page in Help browser: % <a href="matlab:commands('funplot')">commands funplot</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function l_HH = funplot(varargin) %function funplot(afun,g_l_avar,[exchange],[axrange, ayrange],logxy, npoints); % diff --git a/sys/funplot3.m b/sys/funplot3.m index 2da65e8bfc18d510d3362fe05dc145fd54479157..64b81207fa72c73f25db80c9f681c41f31955967 100644 --- a/sys/funplot3.m +++ b/sys/funplot3.m @@ -30,8 +30,8 @@ % Reference page in Help browser: % <a href="matlab:commands('funplot3')">commands funplot3</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function funplot3(varargin) %(afun, varx, vary, axrange, ayrange, npoints) global g_grind; %#ok<GVMIS> diff --git a/sys/grind.cfg b/sys/grind.cfg index a30eed04ac1d1a0e98552e1e1e95795eb3f58c6e..1b006dd9bd21f6004a75532b6ee12e18dcbced83 100644 --- a/sys/grind.cfg +++ b/sys/grind.cfg @@ -1,2 +1,3 @@ -matcontdir=C:\d\alg\MAT LAB\MatCont7p4 -matcontmdir=C:\d\alg\MAT LAB\matcontm5p4 +current_coco=C:\d\alg\MAT LAB\coco_2023October26 +current_matcontm=C:\d\alg\MAT LAB\matcontm5p4 +current_matcont=C:\d\alg\MAT LAB\MatCont7p4 diff --git a/sys/grind.m b/sys/grind.m index 2823fbb663a29651788d22250ed3a07c648ebf5e..48af68016fab8a70f593352f6103c9476ac02002 100644 Binary files a/sys/grind.m and b/sys/grind.m differ diff --git a/sys/grindhelp.chm b/sys/grindhelp.chm index 240b1c99d5bd84a205fe56bb1776c8ba1e72f92c..5df824b1f19e21f8657c62cac1040cd7da1c672a 100644 Binary files a/sys/grindhelp.chm and b/sys/grindhelp.chm differ diff --git a/sys/grindpath.m b/sys/grindpath.m index eb7879ecec3b51fd970a99154fccd6b2e0d9f37f..1451a14ec4b6aa8ac33c3de8fbbfdaa0268a1fcd 100644 --- a/sys/grindpath.m +++ b/sys/grindpath.m @@ -4,8 +4,8 @@ % Reference page in Help browser: % <a href="matlab:commands('grindpath')">commands grindpath</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function p = grindpath(sys) if nargin == 0 sys = 1; diff --git a/sys/growths.m b/sys/growths.m index 422fdb6962f9b891493f6142214b2476d1b62152..56ec87b198d319ee40c960fe9ece965108f27de3 100644 --- a/sys/growths.m +++ b/sys/growths.m @@ -13,8 +13,8 @@ % Reference page in Help browser: % <a href="matlab:commands('growths')">commands growths</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function growths(varargin) %(igrid) global g_grind; %#ok<GVMIS> diff --git a/sys/gstat.m b/sys/gstat.m index 56ebb074bed8773e43673c8f2e10df4a50c70248..9cdb865f5f8a3f238dc015c2b1f65471d780c783 100644 --- a/sys/gstat.m +++ b/sys/gstat.m @@ -13,8 +13,8 @@ % Reference page in Help browser: % <a href="matlab:commands('gstat')">commands gstat</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function gstat(varargin) global g_grind t g_Y g_t; %#ok<GVMIS> fieldnams = {'output', 's', 'full or partial output (full,modelonly,paronly)'}'; diff --git a/sys/iif.m b/sys/iif.m index b491423b1332fc582fc921d4894aae372fce767d..db599017c0a45e9ef4e10e4222f6c3db1a7f1e6e 100644 --- a/sys/iif.m +++ b/sys/iif.m @@ -21,8 +21,8 @@ % Reference page in Help browser: % <a href="matlab:commands('iif')">commands iif</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function res = iif(cond, A1, A2) if nargin < 3 error('GRIND:iif:ArgError', '"iff" needs three arguments: iif(condition,iftrue,iffalse)'); diff --git a/sys/implicitdisperse.m b/sys/implicitdisperse.m index 24c28e76c38aaed74ac99b3f70f18e5617357da1..f2c86e5653e8bf85fe9f8b8c5f4e3c0270cc4ffe 100644 --- a/sys/implicitdisperse.m +++ b/sys/implicitdisperse.m @@ -14,8 +14,8 @@ % Reference page in Help browser: % <a href="matlab:commands('implicitdisperse')">commands implicitdisperse</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function dA = implicitdisperse(ivar, avar, D) % %i_makemodel calls: diff --git a/sys/implicitplot.m b/sys/implicitplot.m index 7a3746ed24c63c84f60e3574a836dd4e76910a1c..b2175219ab512361f58070653aa4f3a498118b8a 100644 --- a/sys/implicitplot.m +++ b/sys/implicitplot.m @@ -28,8 +28,8 @@ % Reference page in Help browser: % <a href="matlab:commands('implicitplot')">commands implicitplot</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function implicitplot(varargin) %(afun, varx, vary, axrange, ayrange, npoints, issurf) global g_grind; %#ok<GVMIS> diff --git a/sys/initgrind.m b/sys/initgrind.m index 79b641f7afbc9400b8c04ec4aef28f58dc20f303..576b008c83281aa567eec22aa9aac26828cce6e5 100644 --- a/sys/initgrind.m +++ b/sys/initgrind.m @@ -8,8 +8,8 @@ % Reference page in Help browser: % <a href="matlab:commands('initgrind')">commands initgrind</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ %start global t g_Y g_t g_data g_grind g_paranal g_cont; %#ok<GVMIS> addpath([grindpath filesep 'sys2']); diff --git a/sys/insim.m b/sys/insim.m index d993b7f8d357ae34abb37a0cef24bdc09ee5a2d0..addfc445c2981ca133acc4b2a1a251e78896d8f3 100644 --- a/sys/insim.m +++ b/sys/insim.m @@ -21,8 +21,8 @@ % Reference page in Help browser: % <a href="matlab:commands('insim')">commands insim</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function [outp] = insim(varargin) %(filename) global g_grind; %#ok<GVMIS> diff --git a/sys/itermap.m b/sys/itermap.m index a57803ea2a4596a70968b13e1e7785ce49a2e53d..809e58328822a20ae5e3f0462df499821e18e31a 100644 --- a/sys/itermap.m +++ b/sys/itermap.m @@ -28,8 +28,8 @@ % Reference page in Help browser: % <a href="matlab:commands('itermap')">commands itermap</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function hline = itermap(varargin) %(n, avar, alim, hax) global g_grind; %#ok<GVMIS> diff --git a/sys/ke.m b/sys/ke.m index 2e33e96572e49cc6118eb3990a48fd72ff64db64..bee97d0e883be0a931129c7f765ed3e51ab6f524 100644 --- a/sys/ke.m +++ b/sys/ke.m @@ -17,8 +17,8 @@ % Reference page in Help browser: % <a href="matlab:commands('ke')">commands ke</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function ke(varargin) global g_Y g_t g_grind; %#ok<GVMIS> if (nargin > 0) diff --git a/sys/lag.m b/sys/lag.m index f7bc69a204599bec17338d9e506f28e7bbe73c00..fdae986c0d2af8657ec0bdce273cba87454dc0e0 100644 --- a/sys/lag.m +++ b/sys/lag.m @@ -17,8 +17,8 @@ % Reference page in Help browser: % <a href="matlab:commands('lag')">commands lag</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function res = lag(var, timelag) global g_t; if ischar(var) diff --git a/sys/leftcells.m b/sys/leftcells.m index 355deb2d653d5b3fd987d00291ac05891598ddb5..165f8df4e81a5484f5083e7570110e599a98d16a 100644 --- a/sys/leftcells.m +++ b/sys/leftcells.m @@ -15,8 +15,8 @@ % Reference page in Help browser: % <a href="matlab:commands('leftcells')">commands leftcells</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function result = leftcells(N, bordered, aValue) if nargin < 2 bordered = 'neumann'; diff --git a/sys/loaddata.m b/sys/loaddata.m index 0427cc854697093d7bacf23cb684b2bfe8934b9c..f331a600175eb3f6be26f3cd2df37c9018ac75bb 100644 --- a/sys/loaddata.m +++ b/sys/loaddata.m @@ -24,8 +24,8 @@ % Reference page in Help browser: % <a href="matlab:commands('loaddata')">commands loaddata</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function loaddata(varargin) global g_grind; %#ok<GVMIS> if nargin == 0 diff --git a/sys/lorenzmap.m b/sys/lorenzmap.m index 4bd2915e8b644e96425431cf0546906c237e4d3d..503131e1b4d18e4370ccf6f7f0a44adba27d187b 100644 --- a/sys/lorenzmap.m +++ b/sys/lorenzmap.m @@ -16,8 +16,8 @@ % Reference page in Help browser: % <a href="matlab:commands('lorenzmap')">commands lorenzmap</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function lorenzmap(varargin) %avar global g_Y g_t g_grind t; %#ok<GVMIS> diff --git a/sys/lyapunov.m b/sys/lyapunov.m index b9a6dccb1e6fad671149c8f3bd1df2ca9fdb9f56..8fb0e3a14272ef8fbb11440b8eca22bcf6e11214 100644 --- a/sys/lyapunov.m +++ b/sys/lyapunov.m @@ -22,8 +22,8 @@ % Reference page in Help browser: % <a href="matlab:commands('lyapunov')">commands lyapunov</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function [res, nhoriz] = lyapunov(varargin) global t g_Y g_t g_grind; %#ok<GVMIS> defaultdisturb = 1E-8; diff --git a/sys/makemap.m b/sys/makemap.m index 7eff2d56bf663fabe5c4bc4cf38ab5c3dc1a62df..ea52f1d4e45fa96ded309dd0d7ea087b374d0977 100644 --- a/sys/makemap.m +++ b/sys/makemap.m @@ -34,8 +34,8 @@ % Reference page in Help browser: % <a href="matlab:commands('makemap')">commands makemap</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function makemap(varargin) %(maptype, p1, p2) global g_grind; %#ok<GVMIS> diff --git a/sys/manifolds.m b/sys/manifolds.m index 81863bbe3b5bc09c29fb07cae31a8832641609fb..99bb423cd4f3687d48d5f9e675afc5533302fc6e 100644 --- a/sys/manifolds.m +++ b/sys/manifolds.m @@ -22,8 +22,8 @@ % Reference page in Help browser: % <a href="matlab:commands('manifolds')">commands manifolds</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function res1 = manifolds(varargin) %(stable) global g_grind g_Y; %#ok<GVMIS> diff --git a/sys/marbleplot.m b/sys/marbleplot.m index cccfa7d2fea502abe6bb9606b3a6cd63b4ddcfad..8596cfc542f46b683e84ffbdae4dd6b1edee1f67 100644 --- a/sys/marbleplot.m +++ b/sys/marbleplot.m @@ -40,8 +40,8 @@ % Reference page in Help browser: % <a href="matlab:commands('marbleplot')">commands marbleplot</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function res = marbleplot(varargin) % (npot, par, rangepar, statevar, rangestatevar,varzero, ... % stemlength, patchheight, mincolor, maxcolor, opaqueness) diff --git a/sys/matlabLessThan.m b/sys/matlabLessThan.m new file mode 100644 index 0000000000000000000000000000000000000000..2a949ad016d61e8b49eb20c7c508b95a6310da89 --- /dev/null +++ b/sys/matlabLessThan.m @@ -0,0 +1,24 @@ +function res = matlabLessThan(verparts) + %matlabLessThan + %This function is similar as verLessThan('matlab',..), but significantly + %faster. It only checks the version in two levels. + %usage: + %if matlabLessThan(verparts) + % ... + %endif + %verparts should be a 2 x 1 vector with version numbers + % for instance + % if matlabLessThan([8 8]) + % + persistent curparts + if isempty(curparts) + %slowest part + curparts = sscanf(version, '%d.%d')'; + end + if verparts(1) ~= curparts(1) + res = curparts(1) < verparts(1); + else + res = curparts(2) < verparts(2); + end +end + diff --git a/sys/mcarlo.m b/sys/mcarlo.m index 3ff1ceb3b65dd80f224310353e95f4cdc0d81312..0a4ff808b71c9f871aa3e17665198d27aefeaee2 100644 --- a/sys/mcarlo.m +++ b/sys/mcarlo.m @@ -53,8 +53,8 @@ % Reference page in Help browser: % <a href="matlab:commands('mcarlo')">commands mcarlo</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function res = mcarlo(varargin) %(atype, opt) evalin('base', 'global g_mcarlo;'); diff --git a/sys/model.m b/sys/model.m index a4831210a09b66ae717cb6af4429e1b8ee7bace5..cf7ee1278652ecc8134c21283f0dab48790f4cca 100644 --- a/sys/model.m +++ b/sys/model.m @@ -65,8 +65,8 @@ % Reference page in Help browser: % <a href="matlab:commands('model')">commands model</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function model(varargin) global g_grind; %#ok<GVMIS> %if the model name has spaces it can be read as separate arguments diff --git a/sys/neighborcells.m b/sys/neighborcells.m index 864ff1f4f5be765576cfb7b69262f4498db1654f..77ba615255cda79d921d19048a101dfde54f56c7 100644 --- a/sys/neighborcells.m +++ b/sys/neighborcells.m @@ -19,8 +19,8 @@ % Reference page in Help browser: % <a href="matlab:commands('neighborcells')">commands neighborcells</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function Result = neighborcells(N, nneighbors, bordered, value) siz = size(N); if nargin < 2 diff --git a/sys/nextpen.m b/sys/nextpen.m index 6c8734e186b2993feb3e027a73c468f0b4893dc2..3acec200585be0f5540a36a902ad2cf048ba7dac 100644 --- a/sys/nextpen.m +++ b/sys/nextpen.m @@ -20,8 +20,8 @@ % Reference page in Help browser: % <a href="matlab:commands('nextpen')">commands nextpen</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function pen = nextpen(varargin) global g_grind; %#ok<GVMIS> if nargin == 0 diff --git a/sys/nmaxima.m b/sys/nmaxima.m index fb4dd361573f276fab8f7430427b0f371fb8ed89..1e8bb781c61fea9663b6379b71cd614e548e6d91 100644 --- a/sys/nmaxima.m +++ b/sys/nmaxima.m @@ -43,8 +43,8 @@ % Reference page in Help browser: % <a href="matlab:commands('nmaxima')">commands nmaxima</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function result = nmaxima(varargin) %(nsteps, options, par2, par3) % diff --git a/sys/null3.m b/sys/null3.m index eaa72edacd7e84f779a12128f5b1583ec1fec21f..1c46cca2eb193648b5d80fe1e090034d9130e2ec 100644 --- a/sys/null3.m +++ b/sys/null3.m @@ -18,8 +18,8 @@ % Reference page in Help browser: % <a href="matlab:commands('null3')">commands null3</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function null3(varargin) %(npoints, opt) global g_grind; %#ok<GVMIS> diff --git a/sys/ode78.m b/sys/ode78.m index 07a4f827c95beb03b8920266f1b11519983057c2..63fffc0fbf5788d69c377ab3ec891c4d1a00fead 100644 --- a/sys/ode78.m +++ b/sys/ode78.m @@ -65,7 +65,7 @@ function [tout, xout] = ode78(odefun, tspan, x0, options, varargin) if nargin >= 4 - nonNegative = ~isempty(odeget(options, 'NonNegative', [], 'fast')); + nonNegative = ~isempty(odeget(options, 'NonNegative', [])); if nonNegative warning('GRIND:ode78:NonNegativeIgnored', 'ODE78 does not constrain solution to be non-negative. Option ''NonNegative'' will be ignored.'); end @@ -105,7 +105,7 @@ function [tout, xout] = ode78(odefun, tspan, x0, options, varargin) % Output function checking and output parameters haveoutfun = 1; - outfun = odeget(options, 'OutputFcn', [], 'fast'); + outfun = odeget(options, 'OutputFcn', []); if isempty(outfun) haveoutfun = 0; end diff --git a/sys/ode87.m b/sys/ode87.m index eba840285aef5ab5b109fe26ad37a0ffb519a7ce..c597b96be39fa89fc97a5e6b43795ff92e5bcf8c 100644 --- a/sys/ode87.m +++ b/sys/ode87.m @@ -69,7 +69,7 @@ function [tout, xout] = ode87(odefun, tspan, x0, options, varargin) pow = 1 / 8; % power for step control if nargin >= 4 - nonNegative = ~isempty(odeget(options, 'NonNegative', [], 'fast')); + nonNegative = ~isempty(odeget(options, 'NonNegative', [])); if nonNegative warning('GRIND:ode87:NonNegativeIgnored', 'ODE87 does not constrain solution to be non-negative. Option ''NonNegative'' will be ignored.'); end @@ -105,7 +105,7 @@ function [tout, xout] = ode87(odefun, tspan, x0, options, varargin) % Output ODEction checking and output parameters haveoutfun = 1; - outfun = odeget(options, 'OutputFcn', [], 'fast'); + outfun = odeget(options, 'OutputFcn', []); if isempty(outfun) haveoutfun = 0; end diff --git a/sys/onstart.m b/sys/onstart.m index 20602e6cb067fe927d3baef6e59a6925c64a8d78..b2284482aba0bce1996d7b0a5cb4072c09bc14c1 100644 --- a/sys/onstart.m +++ b/sys/onstart.m @@ -21,8 +21,8 @@ % Reference page in Help browser: % <a href="matlab:commands('onstart')">commands onstart</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function onstart(varargin) global g_grind; fieldnams = {'fun', 'f#s', 'function/single line of code to be run before starting each run', ''}'; diff --git a/sys/optimpars.m b/sys/optimpars.m index e8c29b3ee6b0e081ec0dddf863e39d310b00bf33..7ca93070b40a7cd7e98ef319446d3aeb136873c6 100644 --- a/sys/optimpars.m +++ b/sys/optimpars.m @@ -37,8 +37,8 @@ % Reference page in Help browser: % <a href="matlab:commands('optimpars')">commands optimpars</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function optimpars(varargin) global g_data g_grind g_Y; %#ok<GVMIS> if ~isfield(g_data, 'options') || isempty(g_data.options) diff --git a/sys/out.m b/sys/out.m index 2615c04fbf399f536a4d20d28a4c8659bd3e93da..592c89baf902879daa79d1f99885a66a14dd0e8b 100644 --- a/sys/out.m +++ b/sys/out.m @@ -43,8 +43,8 @@ % Reference page in Help browser: % <a href="matlab:commands('out')">commands out</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function out(varargin) global g_grind; %#ok<GVMIS> if isempty(g_grind) diff --git a/sys/outf.m b/sys/outf.m index 79b06cba6a9412ba5f5429937f4d6d3fe267e068..50617f23746b2f44af31bd8d30944da866d9b98d 100644 --- a/sys/outf.m +++ b/sys/outf.m @@ -51,8 +51,8 @@ % Reference page in Help browser: % <a href="matlab:commands('outf')">commands outf</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function res = outf(varargin) global g_Y g_t g_permanent g_func g_grind; %#ok<GVMIS> diff --git a/sys/outfun.m b/sys/outfun.m index a79e82b1d7ca18534ee35548ca03caa575d513e5..0cdad120d595b45b5879b5728b5a9cc4b8800041 100644 --- a/sys/outfun.m +++ b/sys/outfun.m @@ -33,8 +33,8 @@ % Reference page in Help browser: % <a href="matlab:commands('outfun')">commands outfun</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function [F, ndxs] = outfun(varargin) %(s, opt, acatfun) global g_grind g_paranal g_permanent g_cont g_mcarlo g_Y g_t; %#ok<GVMIS> diff --git a/sys/par.m b/sys/par.m index 81b051bdd14468b40b4d97149ea5ae861d51ef1d..62b379260e5c961005e93996e813924f27f89a1b 100644 --- a/sys/par.m +++ b/sys/par.m @@ -34,8 +34,8 @@ % Reference page in Help browser: % <a href="matlab:commands('par')">commands par</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function [p, p2] = par(varargin) global g_grind t; %#ok<GVMIS> if nargin >= 1 && strcmp(varargin{1}, 'group') diff --git a/sys/paranal.m b/sys/paranal.m index 636275577bfed839758cfce996c00f38fab6bb1c..f08721d8b6dca769960c7e57fa7606f9fad013fc 100644 --- a/sys/paranal.m +++ b/sys/paranal.m @@ -36,8 +36,8 @@ % Reference page in Help browser: % <a href="matlab:commands('paranal')">commands paranal</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function paranal(varargin) global g_paranal g_grind; %#ok<GVMIS> diff --git a/sys/paranal2d.m b/sys/paranal2d.m index 7a24e03d60dab74547fe12a4464f8286588ba4bc..b8db1c9aa47ec186d6a6e360f13e719fdc9e8ae5 100644 --- a/sys/paranal2d.m +++ b/sys/paranal2d.m @@ -41,8 +41,8 @@ % Reference page in Help browser: % <a href="matlab:commands('paranal2d')">commands paranal2d</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function paranal2d(varargin) %evalin('base','global g_paranal2d;'); %implicit i_parseargs diff --git a/sys/parlookup.m b/sys/parlookup.m index c68763076c040620e9fb37ef5606645f65fac7ee..05001c6948e90840f500769895694285faffeef0 100644 --- a/sys/parlookup.m +++ b/sys/parlookup.m @@ -17,8 +17,8 @@ % Reference page in Help browser: % <a href="matlab:commands('parlookup')">commands parlookup</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function apar = parlookup(tabl, key1, extrapolate, NaNisZero) if nargin < 4 NaNisZero = 1; diff --git a/sys/phas.m b/sys/phas.m index bd6150568769032186751afde350aaac0513b8b3..076ababd0567f35397dc6fca46e600fc1637398a 100644 --- a/sys/phas.m +++ b/sys/phas.m @@ -31,8 +31,8 @@ % Reference page in Help browser: % <a href="matlab:commands('phas')">commands phas</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function phas(varargin) global g_grind t g_Y g_t; %#ok<GVMIS> fieldnams = {'ndays', 'n>0', 'number of days to run', g_grind.ndays; ... diff --git a/sys/plotdata.m b/sys/plotdata.m index 3f545c81374468d53b7df61decfe42f222743a59..179ddf93004251d63448bf3bc192657998783e82 100644 --- a/sys/plotdata.m +++ b/sys/plotdata.m @@ -4,8 +4,8 @@ % Reference page in Help browser: % <a href="matlab:commands('plotdata')">commands plotdata</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function plotdata i_plotdatadlg; end diff --git a/sys/plotdiff.m b/sys/plotdiff.m index fd30f23677e2609f93f4d4cc26f891ba00577a73..9badbf1eead25c462e710b8789d879d58df4acc6 100644 --- a/sys/plotdiff.m +++ b/sys/plotdiff.m @@ -24,8 +24,8 @@ % Reference page in Help browser: % <a href="matlab:commands('plotdiff')">commands plotdiff</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function [aX, aY, hplot] = plotdiff(varargin) %(avar, alim, npoints, hax) global g_grind; %#ok<GVMIS> diff --git a/sys/plotreldiff.m b/sys/plotreldiff.m index 9f26e3bd75c735334a31a327dee61e4a5242bc9c..0b301795b2caa788290a9c2b0d480ca58222fbcf 100644 --- a/sys/plotreldiff.m +++ b/sys/plotreldiff.m @@ -18,8 +18,8 @@ % Reference page in Help browser: % <a href="matlab:commands('plotreldiff')">commands plotreldiff</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function [aX, aY, hplot] = plotreldiff(varargin) %(avar, alim, npoints, hax) global g_grind; %#ok<GVMIS> diff --git a/sys/poincaremap.m b/sys/poincaremap.m index a5ffd4afe2e261012b2001b9a52cfcf594878171..22bc7545123f5628fea63fcf251c7da6a4c73be7 100644 --- a/sys/poincaremap.m +++ b/sys/poincaremap.m @@ -25,8 +25,8 @@ % Reference page in Help browser: % <a href="matlab:commands('poincaremap')">commands poincaremap</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function poincaremap(varargin) %(avar1, aplane, increasing) global g_grind g_t; diff --git a/sys/poincaresect.m b/sys/poincaresect.m index 43a63ae75c0bcddfacdef2d95cf571fc513e9fdc..0671e0f9869887e16ad31520b101354c052acd0b 100644 --- a/sys/poincaresect.m +++ b/sys/poincaresect.m @@ -25,8 +25,8 @@ % Reference page in Help browser: % <a href="matlab:commands('poincaresect')">commands poincaresect</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function poincar2 = poincaresect(varargin) %(aplane, increasing) global g_grind g_t; diff --git a/sys/randinit.m b/sys/randinit.m index 3e55fb7742a233d1ba7f3fcd4dd6f85f0bcb5966..309a2261cd261127ed13613a1520dc30d5d063ee 100644 --- a/sys/randinit.m +++ b/sys/randinit.m @@ -12,7 +12,7 @@ % RANDINIT('method',@(dim1,dim2)(randi(2,dim1,dim2)-1)*2-1) - use a different distribution % for the initial conditions. The user function should have 2 arguments like the function rand(dim1, dim2) % RANDINIT('argname',argvalue,...) - Valid argument <a href="matlab:commands func_args">name-value pairs</a> [with type]: -% 'method' [uniform | uneven | findeqs or function_handle] - method to draw the initial points (uniform, uneven or user function) +% 'method' [uniform | uneven | findeqs | simple_uneven or function_handle] - method to draw the initial points (uniform, uneven or user function) % 'range' [double and length(double)<=2] - range for the initial points % 'var' [state variable or empty] - state variable (empty=all) % @@ -22,19 +22,19 @@ % Reference page in Help browser: % <a href="matlab:commands('randinit')">commands randinit</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function res = randinit(varargin) %(VarName,range) global g_grind g_Y; %#ok<GVMIS> fieldnams = {'var', 'v#E', 'state variable (empty=all)', []; ... - 'method', 'e[uniform|uneven|findeqs]#f', 'method to draw the initial points (uniform, uneven or user function)', 'uniform'; ... + 'method', 'e[uniform|uneven|findeqs|simple_uneven]#f', 'method to draw the initial points (uniform, uneven or user function)', 'uniform'; ... 'range', 'd&length(d)<=2', 'range for the initial points', [0 100]}'; if nargin == 1 && isstruct(varargin{1}) %this is used by findeqs for speed args = varargin{1}; else - args = i_parseargs(fieldnams, 'if(argtype(1,''e[uniform|uneven]'')),deffields=''method,range'';elseif(argtype(1,''d'')),deffields=''range'';else,deffields=''var,range'';end;', '', varargin); + args = i_parseargs(fieldnams, 'if(argtype(1,''e[uniform|uneven|findeqs|simple_uneven]'')),deffields=''method,range'';elseif(argtype(1,''d'')),deffields=''range'';else,deffields=''var,range'';end;', '', varargin); i_parcheck; end if ~isfield(args, 'var') @@ -56,12 +56,15 @@ function res = randinit(varargin) case 'uniform' args.method = @(dim1,dim2)drawuniform(dim1,dim2,args.range(1), args.range(2)); case 'uneven' - args.method = @(dim1,dim2)drawuneven(dim1,dim2,args.range(1), args.range(2)); + args.method = @(dim1,dim2)drawbetarnd(dim1,dim2,args.range(1), args.range(2)); + case 'simple_uneven' + %for testing without stats toolbox + args.method = @(dim1,dim2)drawsimple_uneven(dim1,dim2,args.range(1), args.range(2)); case 'findeqs' args.method = @(dim1,dim2)drawfindeqs(dim1, dim2, args.range(2)); end end - + %args.method is used to draw the full vector allways N1 = args.method(g_grind.statevars.dim, 1); if isempty(args.var) @@ -92,18 +95,23 @@ function N0 = drawfindeqs(dim1, dim2, scale) N0(f3) = -N0(f3); end -function N0 = drawuneven(dim1, dim2, minrange, maxrange) + +function N0 = drawsimple_uneven(dim1, dim2, minrange, maxrange) + N0 = drawuniform(dim1, dim2, minrange, maxrange); + ndx = rand(size(N0)) < 0.2; + N0(ndx) = N0(ndx) .* 0.1; + ndx = rand(size(N0)) < 0.1; + N0(ndx) = N0(ndx) .* 0.01; +end + +function N0 = drawbetarnd(dim1, dim2, minrange, maxrange) try N0 = betarnd(0.4, 0.4, dim1, dim2) * (maxrange - minrange) + minrange; catch err %if the statistics toolbox is not present we offer an %alternative if strcmp(err.identifier, 'MATLAB:UndefinedFunction') - N0 = drawuniform(dim, 1, minrange, maxrange); - ndx = rand(size(N0)) < 0.1; - N0(ndx) = N0(ndx) .* 0.1; - ndx = rand(size(N0)) < 0.1; - N0(ndx) = N0(ndx) .* 0.01; + N0 = drawsimple_uneven(dim1, dim2, minrange, maxrange); else rethrow(err) end diff --git a/sys/rednoise.m b/sys/rednoise.m index c2e29454780074964d1283ba12d951413954a656..70e6a52b4a50bb001b5c80ff178ef25fc0b07130 100644 --- a/sys/rednoise.m +++ b/sys/rednoise.m @@ -35,8 +35,8 @@ % Reference page in Help browser: % <a href="matlab:commands('rednoise')">commands rednoise</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function T = rednoise(tnow, T0, lambda, beta, eqnr, deltat) %function T = rednoise(tnow, T0, labda, beta, isets, deltat) global g_rednoise g_grind; %#ok<GVMIS> diff --git a/sys/replayall.m b/sys/replayall.m index 1ca3599f42eac91e88f2ad5e127334bc12cb2641..726f6a941a1fc542ef11d991b8a9adfc9cb0f8f9 100644 --- a/sys/replayall.m +++ b/sys/replayall.m @@ -43,8 +43,8 @@ % Reference page in Help browser: % <a href="matlab:commands('replayall')">commands replayall</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function res = replayall(varargin) global g_grind; %#ok<GVMIS> % if isempty(which('i_replayall')) diff --git a/sys/returntime.m b/sys/returntime.m index 3134d1f497e0e94c1e5ccf1e820c4f68da7b687d..a55d934666c3a604a60312d464b8ba4d55594f1c 100644 --- a/sys/returntime.m +++ b/sys/returntime.m @@ -20,8 +20,8 @@ % Reference page in Help browser: % <a href="matlab:commands('returntime')">commands returntime</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function [rettime, YY] = returntime(varargin) %(err1, maxt, methodopt), methods: both,change,equil global g_Y t g_t g_grind; %#ok<GVMIS> diff --git a/sys/returntime2d.m b/sys/returntime2d.m index bab15c13f222f87d817e695b9ecbc6a3e4f43c54..6704f6711c4a79cc92141590b714848bbedfe1f7 100644 --- a/sys/returntime2d.m +++ b/sys/returntime2d.m @@ -20,8 +20,8 @@ % Reference page in Help browser: % <a href="matlab:commands('returntime2d')">commands returntime2d</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function [Vect, X, Y, Vect3d] = returntime2d(varargin) %(err, npoints) global g_grind; %#ok<GVMIS> diff --git a/sys/rightcells.m b/sys/rightcells.m index 1709cec8e174065f6381fbd55f069a4ec65bbd01..314ef103a6774f6635c4d51546ed8b1ea00bcef5 100644 --- a/sys/rightcells.m +++ b/sys/rightcells.m @@ -14,8 +14,8 @@ % Reference page in Help browser: % <a href="matlab:commands('rightcells')">commands rightcells</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function result = rightcells(N, bordered, aValue) if nargin < 2 diff --git a/sys/rk4.m b/sys/rk4.m index a9293aa1bf3d71ec6222ee743fcfee69908dbb71..5bd82a73b57a7fb261579a9a5453f923a037f941 100644 --- a/sys/rk4.m +++ b/sys/rk4.m @@ -15,8 +15,8 @@ % Reference page in Help browser: % <a href="matlab:commands('rk4')">commands rk4</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function [tout, yout] = rk4(odefunct, tspan, y0, options) global g_grind; if (nargin < 4) @@ -41,7 +41,7 @@ function [tout, yout] = rk4(odefunct, tspan, y0, options) if nargin < 4 nonNegative = []; else - nonNegative = odeget(options, 'NonNegative', [], 'fast'); + nonNegative = odeget(options, 'NonNegative', []); end anyNonNegative = ~isempty(nonNegative); haveOutputFcn = ~isempty(options.OutputFcn); diff --git a/sys/rk4_old.m b/sys/rk4_old.m index 75e6dd031a806cd126b47b11e18a381fe80185a4..931cdd23fea47b660126ea9293f689256f53da39 100644 --- a/sys/rk4_old.m +++ b/sys/rk4_old.m @@ -50,7 +50,7 @@ function [tout, yout] = rk4(FunFcn, tspan, y0, options) if nargin < 4 nonNegative = []; else - nonNegative = odeget(options, 'NonNegative', [], 'fast'); + nonNegative = odeget(options, 'NonNegative', []); end anyNonNegative = ~isempty(nonNegative); haveOutputFcn = ~isempty(options.OutputFcn); diff --git a/sys/ru.m b/sys/ru.m index 3d4f3bdba2b78251b4d94c2dd26613e2e79e186e..9a6b46c53dd7fab9450bcd5d04e3cdfabfcd8351 100644 --- a/sys/ru.m +++ b/sys/ru.m @@ -25,8 +25,8 @@ % Reference page in Help browser: % <a href="matlab:commands('ru')">commands ru</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function ru(varargin) global t g_grind g_Y g_t; fieldnams = {'ndays', 'n>0', 'number of days to run', 1000}'; diff --git a/sys/rungrid.m b/sys/rungrid.m index f1e674e1a5890b3f1ec66bdfaca0460a29ff6d71..218a21a407876dc1a91c5973818d227f869a2f23 100644 --- a/sys/rungrid.m +++ b/sys/rungrid.m @@ -19,8 +19,8 @@ % Reference page in Help browser: % <a href="matlab:commands('rungrid')">commands rungrid</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function rungrid(varargin) %(nx, ny, ndays, twodir) global g_grind; diff --git a/sys/savemodel.m b/sys/savemodel.m index 3027041c8021f77ff285a51ca749f27ad594e650..a5b1cf6feba85c3a43bb16ad8782e491c230f5b6 100644 --- a/sys/savemodel.m +++ b/sys/savemodel.m @@ -19,8 +19,8 @@ % Reference page in Help browser: % <a href="matlab:commands('savemodel')">commands savemodel</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function savemodel(varargin) %afilename, overwrite, filetype global g_grind; diff --git a/sys/savepar.m b/sys/savepar.m index 4e7e9e1778c280ec0f234229291c152df58421c3..bbd213b703154fc4709c8ffc8190c92f635d2c31 100644 --- a/sys/savepar.m +++ b/sys/savepar.m @@ -21,8 +21,8 @@ % Reference page in Help browser: % <a href="matlab:commands('savepar')">commands savepar</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function savepar(varargin) %(afile, overwrite, keeprand) global g_grind g_data; %#ok<GVMIS> diff --git a/sys/setcolormap.m b/sys/setcolormap.m index 6276e1ed6ffdd95fd383fc08bbafedb2a520543b..aa7d0fdf733c67ccac2f41cf58d0e9c60cc46992 100644 --- a/sys/setcolormap.m +++ b/sys/setcolormap.m @@ -21,8 +21,8 @@ % Reference page in Help browser: % <a href="matlab:commands('setcolormap')">commands setcolormap</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function result = setcolormap(varargin) %(m, bottomcolor, topcolor) %hsv = 1; diff --git a/sys/setdata.m b/sys/setdata.m index ebd9b9a2ed9bcf1e5814c813815a02f668bb3890..4e8615cf4cbf96cbedaa9d266c32ff7bc3497438 100644 --- a/sys/setdata.m +++ b/sys/setdata.m @@ -28,8 +28,8 @@ % Reference page in Help browser: % <a href="matlab:commands('setdata')">commands setdata</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function outlist = setdata(varargin) %(amatrix, varlist) global g_data g_grind; diff --git a/sys/setdefaults.m b/sys/setdefaults.m index 3959aaad87961e4dcb1fafc7228df56b86ccc042..0d944402cc2c4079591e2d9c57d46ed77af79658 100644 --- a/sys/setdefaults.m +++ b/sys/setdefaults.m @@ -12,8 +12,8 @@ % Reference page in Help browser: % <a href="matlab:commands('setdefaults')">commands setdefaults</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function def = setdefaults(varargin) %(doload) global g_grind; diff --git a/sys/setdimension.m b/sys/setdimension.m index 874b61e274cef9bb8f0f0680c6928a83d80b4897..b9a9a1780c24c07d068629729d090ebbe0402fd7 100644 --- a/sys/setdimension.m +++ b/sys/setdimension.m @@ -36,8 +36,8 @@ % Reference page in Help browser: % <a href="matlab:commands('setdimension')">commands setdimension</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function res = setdimension(varargin) %(avar, dims, createfun ,diagon) global g_Y g_grind; diff --git a/sys/setevent.m b/sys/setevent.m index 267a43df96697cc4e3bda6588a59857a3b4bca07..44cf134c5f58f064fed364fcf138191f73bf5800 100644 --- a/sys/setevent.m +++ b/sys/setevent.m @@ -37,8 +37,8 @@ % Reference page in Help browser: % <a href="matlab:commands('setevent')">commands setevent</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function setevent(varargin) %(event, dt,varargin) if nargin == 0 diff --git a/sys/setmat.m b/sys/setmat.m index ca3598db9f5bb15495f2d245e4594eea6c888118..49905774f1cf68c76c4b50aa7b348f965b0b800e 100644 --- a/sys/setmat.m +++ b/sys/setmat.m @@ -32,8 +32,8 @@ % Reference page in Help browser: % <a href="matlab:commands('setmat')">commands setmat</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function [A, locs] = setmat(varargin) %(var, loc, siz, value, num) global g_grind; diff --git a/sys/setodefile.m b/sys/setodefile.m index 5b2ef3d8deedcfce65263a2985226c02e40e9453..eacf9dfcbde36d9a2b8b3191a539c654d9e5a633 100644 --- a/sys/setodefile.m +++ b/sys/setodefile.m @@ -19,8 +19,8 @@ % Reference page in Help browser: % <a href="matlab:commands('setodefile')">commands setodefile</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function ggrind = setodefile(varargin) %(afile, varlist,opt) global g_grind diff --git a/sys/setpen.m b/sys/setpen.m index cacae051f51d66a5e0cd410d75899ebb0a8db889..f7139872ee4fb9417b8cf710623da9d58b761a6a 100644 --- a/sys/setpen.m +++ b/sys/setpen.m @@ -44,8 +44,8 @@ % Reference page in Help browser: % <a href="matlab:commands('setpen')">commands setpen</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function thepen = setpen(varargin) %(acolor, linestyle, markerstyle,cycle ) global g_grind; diff --git a/sys/simtime.m b/sys/simtime.m index 367cb0e926ff4771bc0c9f6f9675cd5002c21d8b..75aef0e30c6bcf5dc4f0a042aea7a2a9f30e8be1 100644 --- a/sys/simtime.m +++ b/sys/simtime.m @@ -22,8 +22,8 @@ % Reference page in Help browser: % <a href="matlab:commands('simtime')">commands simtime</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function simtime(varargin) global t g_grind; %#ok<GVMIS> fieldnams = {'t', 'n', 'start time', 0; ... diff --git a/sys/solver.m b/sys/solver.m index 3ecf9784a0d5fecec87da785f35263d218c26f1c..381f9c21eeb6ba708da94d4af3b021466f1b777e 100644 --- a/sys/solver.m +++ b/sys/solver.m @@ -49,8 +49,8 @@ % Reference page in Help browser: % <a href="matlab:commands('solver')">commands solver</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function [res] = solver(varargin) %(solv, p1, p2, p3, p4) global g_grind; %#ok<GVMIS> diff --git a/sys/stabil.m b/sys/stabil.m index 5136b93422e8288c4bc66006fa5ce73e3653d907..39da6cab61216f9368fb274ebc68b6f0ff62d126 100644 --- a/sys/stabil.m +++ b/sys/stabil.m @@ -19,8 +19,8 @@ % Reference page in Help browser: % <a href="matlab:commands('stabil')">commands stabil</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function stabil(varargin) global t g_grind g_Y; fieldnams = {'ndays', 'n>0', 'number of days to stabilize', 1000; ... diff --git a/sys/sys2/Dx.m b/sys/sys2/Dx.m index d31ccd082db650cd183d06c00473dad8bf4fad2b..5f1d9337c412885be5b7c3a4240f53b6efb90d23 100644 --- a/sys/sys2/Dx.m +++ b/sys/sys2/Dx.m @@ -15,8 +15,8 @@ % Reference page in Help browser: % <a href="matlab:commands('Dx')">commands Dx</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function differ = Dx(N) global g_grind; if ~isfield(g_grind, 'space') || isempty(g_grind.space) diff --git a/sys/sys2/Dxx.m b/sys/sys2/Dxx.m index 85f55123f189eb6d03866928021e3cb5fc620062..d88b411950820706c375ac723bac6fe037f0774f 100644 --- a/sys/sys2/Dxx.m +++ b/sys/sys2/Dxx.m @@ -14,8 +14,8 @@ % Reference page in Help browser: % <a href="matlab:commands('Dxx')">commands Dxx</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function differ = Dxx(N) global g_grind; if ~isfield(g_grind, 'space') || isempty(g_grind.space) diff --git a/sys/sys2/Dy.m b/sys/sys2/Dy.m index 6c28eb94aa4895fce534ce18c6659fb911bed57d..28b538158a1fe3cf5626c8aa359f8e57efcda8f5 100644 --- a/sys/sys2/Dy.m +++ b/sys/sys2/Dy.m @@ -15,8 +15,8 @@ % Reference page in Help browser: % <a href="matlab:commands('Dy')">commands Dy</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function differ = Dy(N) global g_grind; if ~isfield(g_grind, 'space') || isempty(g_grind.space) diff --git a/sys/sys2/Dyy.m b/sys/sys2/Dyy.m index c5bc75403919e93da9828544d96ed69b3d7ef7b1..d31f44d75b7a2236636fb8e7e32b6c3fe97bf7f0 100644 --- a/sys/sys2/Dyy.m +++ b/sys/sys2/Dyy.m @@ -15,8 +15,8 @@ % Reference page in Help browser: % <a href="matlab:commands('Dyy')">commands Dyy</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function differ = Dyy(N) global g_grind; if ~isfield(g_grind, 'space') || isempty(g_grind.space) diff --git a/sys/sys2/autocorrs.m b/sys/sys2/autocorrs.m index b3d0bae87c4da0b3b66377651f80e4dce8231126..60ea89e035e9af7c2806ebc31d3db78c2d71bbe7 100644 --- a/sys/sys2/autocorrs.m +++ b/sys/sys2/autocorrs.m @@ -16,8 +16,8 @@ % Reference page in Help browser: % <a href="matlab:commands('autocorrs')">commands autocorrs</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function [result, A] = autocorrs(varargin) %(maxlag) global g_Y g_t t g_grind; diff --git a/sys/sys2/ax.m b/sys/sys2/ax.m index fe99a4050d8cd6121b7840a4bbd6500db30606f7..90bbfd7e9af743062a463a9c505b3a86af8cdc16 100644 --- a/sys/sys2/ax.m +++ b/sys/sys2/ax.m @@ -37,8 +37,8 @@ % Reference page in Help browser: % <a href="matlab:commands('ax')">commands ax</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function ax(varargin) %axname, axvar, axlim, axmax) global g_grind g_paranal; diff --git a/sys/sys2/back_differ.m b/sys/sys2/back_differ.m index ce8309b60ac3635c75398f7ffb724d6f915786cd..1be5fb47cd728a04b44ab0ebb73f2c04279f10e7 100644 --- a/sys/sys2/back_differ.m +++ b/sys/sys2/back_differ.m @@ -17,7 +17,7 @@ function [tout, yout] = back_differ(odefunct, tspan, y0, options) end if nargin >= 4 - nonNegative = ~isempty(odeget(options, 'NonNegative', [], 'fast')); + nonNegative = ~isempty(odeget(options, 'NonNegative', [])); if nonNegative warning('GRIND:back_euler:NonNegativeIgnored', 'BACK_EULER does not constrain solution to be non-negative. Option ''NonNegative'' will be ignored.'); end diff --git a/sys/sys2/ddesolsd.m b/sys/sys2/ddesolsd.m index 2a219e3d8ec1829079be136ae1719653b9077fbb..5b73554ccf4f98cb72a823d9ac141a2d0eb5ef40 100644 --- a/sys/sys2/ddesolsd.m +++ b/sys/sys2/ddesolsd.m @@ -2,7 +2,7 @@ function [tout, yout, varargout] = ddesolsd(odefile, tspan, y0, options, varargi global g_grind; %DDEsd('F',LAGS,HISTORY,TSPAN) if nargin >= 4 - nonNegative = ~isempty(odeget(options, 'NonNegative', [], 'fast')); + nonNegative = ~isempty(odeget(options, 'NonNegative', [])); if nonNegative warning('GRIND:DDESD:NonNegativeIgnored', 'DDESD does not constrain solution to be non-negative. Option ''NonNegative'' will be ignored.'); end diff --git a/sys/sys2/djump.m b/sys/sys2/djump.m index cdd9dfccca75801f907d0be89186a6d96e25c85e..84efd40a68972b274bee874526bbdd092ff0e9d9 100644 --- a/sys/sys2/djump.m +++ b/sys/sys2/djump.m @@ -39,8 +39,8 @@ % Reference page in Help browser: % <a href="matlab:commands('djump')">commands djump</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:40 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:36 $ function args1 = djump(varargin) global g_grind fieldnams = {'timing', 's', 'equation that generates the duration of the intervals', 100; ... diff --git a/sys/sys2/euler.m b/sys/sys2/euler.m index 008d415f620c4547f24fd28cee479ce17a16d7d5..29ecf0da930b94426fc6785427fccb679efa9072 100644 --- a/sys/sys2/euler.m +++ b/sys/sys2/euler.m @@ -9,8 +9,8 @@ % Reference page in Help browser: % <a href="matlab:commands('euler')">commands euler</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function [tout, yout] = euler(odefunct, tspan, y0, options) % global g_grind; if (nargin < 4) @@ -35,7 +35,7 @@ function [tout, yout] = euler(odefunct, tspan, y0, options) if nargin < 4 nonNegative = []; else - nonNegative = odeget(options, 'NonNegative', [], 'fast'); + nonNegative = odeget(options, 'NonNegative', []); end anyNonNegative = ~isempty(nonNegative); haveOutputFcn = ~isempty(options.OutputFcn); diff --git a/sys/sys2/externlag.m b/sys/sys2/externlag.m index 7382ec943fe53244496286152f3ac1d3ddbb6e43..79b938e9c9b652e319d8498392c4ff85b23a9a76 100644 --- a/sys/sys2/externlag.m +++ b/sys/sys2/externlag.m @@ -18,8 +18,8 @@ % Reference page in Help browser: % <a href="matlab:commands('externlag')">commands externlag</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function res = externlag(var, timelag) global g_t; if ischar(var) diff --git a/sys/sys2/fftconv.m b/sys/sys2/fftconv.m index 0669117b0a3ab3f7ee8c3bfaaff447b8afcdbfce..689b7007dbdd56f768e836fe940f5c814724c4d5 100644 --- a/sys/sys2/fftconv.m +++ b/sys/sys2/fftconv.m @@ -25,8 +25,8 @@ % Reference page in Help browser: % <a href="matlab:commands('fftconv')">commands fftconv</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function [P1] = fftconv(P, L, pars, kernell) global g_grind; if ((nargin == 4)) || ~isfield(g_grind, 'fK') diff --git a/sys/sys2/findeq.m b/sys/sys2/findeq.m index b7fdcacff06d6a2ec757eb08ecc2753291b43be6..2dc4921dcf5fa3f29d863c150e3ab6927227d760 100644 --- a/sys/sys2/findeq.m +++ b/sys/sys2/findeq.m @@ -37,8 +37,8 @@ % Reference page in Help browser: % <a href="matlab:commands('findeq')">commands findeq</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function [N1, found] = findeq(varargin) global g_Y g_grind; if isfield(g_grind, 'solver') diff --git a/sys/sys2/findeqs.m b/sys/sys2/findeqs.m index 4ca2e2c8bfe331d8afc06e6c224d73f4c583b96f..9b0b3fc81446753ae2a7184182b1d7a6d5e415dd 100644 --- a/sys/sys2/findeqs.m +++ b/sys/sys2/findeqs.m @@ -50,8 +50,8 @@ % Reference page in Help browser: % <a href="matlab:commands('findeqs')">commands findeqs</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function [eqlist, eqs] = findeqs(varargin) %(ntrial, scal) global g_grind; diff --git a/sys/sys2/fixedstep_solver.m b/sys/sys2/fixedstep_solver.m index 15c2386e041588bb5034326962ada317ace411e6..88a8f5da6e5e6de8dfdbd649ffc216a41f458655 100644 --- a/sys/sys2/fixedstep_solver.m +++ b/sys/sys2/fixedstep_solver.m @@ -87,7 +87,7 @@ function [tout, yout] = fixedstep_solver(solvername, odefunct, tspan, y0, option if nargin < 5 nonNegative = []; else - nonNegative = odeget(options, 'NonNegative', [], 'fast'); + nonNegative = odeget(options, 'NonNegative', []); end nout = 0; anyNonNegative = ~isempty(nonNegative); diff --git a/sys/sys2/forward_stabil.m b/sys/sys2/forward_stabil.m index 8e94c6468f2c0bf2de5b550741f97dfa03b7a577..bcfecc835790c4c0f966aa1d2c582e1f089a03c7 100644 --- a/sys/sys2/forward_stabil.m +++ b/sys/sys2/forward_stabil.m @@ -38,8 +38,8 @@ % Reference page in Help browser: % <a href="matlab:commands('forward_stabil')">commands forward_stabil</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function res = forward_stabil(varargin) global g_paranal g_grind g_Y fieldnams = {'parvalue', 'n', 'the values of the parameters of the point', 0; ... diff --git a/sys/sys2/graphplot.m b/sys/sys2/graphplot.m index 15cb98a2bc91de8187cc96a92de546633cdc80a5..c292a90fa36d4b4090f65aab0871d958b382273e 100644 --- a/sys/sys2/graphplot.m +++ b/sys/sys2/graphplot.m @@ -18,8 +18,8 @@ % Reference page in Help browser: % <a href="matlab:commands('graphplot')">commands graphplot</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:41 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function graphplot(varargin) global g_Y g_t t g_grind; % g_t = (g_t(1):g_t(2):g_t(3))'; diff --git a/sys/sys2/grind_coco.m b/sys/sys2/grind_coco.m index db31c7a0ede2ae51868ebcfedee7b8aaca1c2f8a..c010e28463ce3d7dc0a3d0254c0d5657a7f77559 100644 --- a/sys/sys2/grind_coco.m +++ b/sys/sys2/grind_coco.m @@ -16,41 +16,42 @@ classdef grind_coco < grind_cont obj.settings.derived.engine = 'coco'; init_engine(obj); init_engine(obj, true); - verfile = fullfile(obj.settings.derived.engine_path, 'cocoversion.txt'); - if exist(verfile, 'file') - fid = fopen(verfile, 'r'); - obj.settings.derived.version = fgetl(fid); - obj.settings.derived.version = obj.settings.derived.version(6:end - 4); - fclose(fid); - else - obj.settings.derived.version = 'unknown'; - end + [~,obj.settings.derived.version]=fileparts(obj.settings.derived.engine_path); +% verfile = fullfile(obj.settings.derived.engine_path, 'cocoversion.txt'); +% if exist(verfile, 'file') +% fid = fopen(verfile, 'r'); +% obj.settings.derived.version = fgetl(fid); +% obj.settings.derived.version = obj.settings.derived.version(6:end - 4); +% fclose(fid); +% else +% obj.settings.derived.version = 'unknown'; +% end - crveprops = {'EP', 1, 'EP - Equilibrium points', false, 'b'; ... - 'H', 2, 'H - Hopf bifurcation', false, 'r'; ... - 'LC', 1, 'LC - Limit cycle', true, 'b'; ... - 'T', 2, 'T - Transcritical bifurcation', false, 'b'; ... + crveprops = {'EP', 1, 'EP - Equilibrium points', false, 'b'; ... + 'H', 2, 'H - Hopf bifurcation', false, 'r'; ... + 'LC', 1, 'LC - Limit cycle', true, 'b'; ... + 'T', 2, 'T - Transcritical bifurcation', false, 'b'; ... 'F', 2, 'F - Fold bifurcation', false, 'g'}; - obj.curveprops = struct('ctype', crveprops(:, 1), 'clabel', crveprops(:, 1), 'npars', crveprops(:, 2), 'iscycle', crveprops(:, 4), ... + obj.curveprops = struct('ctype', crveprops(:, 1), 'clabel', crveprops(:, 1), 'npars', crveprops(:, 2), 'iscycle', crveprops(:, 4), ... 'descr', crveprops(:, 3), 'color', crveprops(:, 5), 'resfun', @extract_coco_curve_eq); ndx = obj.getndx('curveprops', 'ctype', 'F'); obj.curveprops(ndx).clabel = 'SN'; ndx = obj.getndx('curveprops', 'ctype', 'T'); obj.curveprops(ndx).clabel = 'SN'; - pntprops = {'BT', 'Bogdanov-Takens', 2, ''; ... - 'CP', 'Cusp', 2, ''; ... - 'EP', 'Equilibrium', 0, 'EP'; ... - 'F', 'Fold', 1, 'F'; ... - 'GH', 'Generalized Hopf', 2, ''; ... - 'H', 'Hopf', 1, 'H,LC'; ... - 'HH', 'Double Hopf', 2, ''; ... - 'LC', 'Limit cycle', 0, ''; ... - 'P', 'Any initial conditions', 0, 'EP,LC'; ... - 'T', 'Transcritical bif.', 1, 'EP,T'; ... + pntprops = {'BT', 'Bogdanov-Takens', 2, ''; ... + 'CP', 'Cusp', 2, ''; ... + 'EP', 'Equilibrium', 0, 'EP'; ... + 'F', 'Fold', 1, 'F'; ... + 'GH', 'Generalized Hopf', 2, ''; ... + 'H', 'Hopf', 1, 'H,LC'; ... + 'HH', 'Double Hopf', 2, ''; ... + 'LC', 'Limit cycle', 0, ''; ... + 'P', 'Any initial conditions', 0, 'EP,LC'; ... + 'T', 'Transcritical bif.', 1, 'EP,T'; ... 'ZH', 'Zero-Hopf', 2, ''}; - obj.pointprops = struct('ptype', pntprops(:, 1), 'label', pntprops(:, 1), 'descr', pntprops(:, 2), ... + obj.pointprops = struct('ptype', pntprops(:, 1), 'label', pntprops(:, 1), 'descr', pntprops(:, 2), ... 'codim', pntprops(:, 3), 'ctypes', pntprops(:, 4)); for i = 1:length(obj.pointprops) obj.pointprops(i).ctypes = regexp(obj.pointprops(i).ctypes, '[\,]', 'split'); @@ -88,7 +89,7 @@ classdef grind_coco < grind_cont %%% NOTE Here I assume that the options structure and grind_opt have the same order!! if nargin == 2 && strcmp('-nondefault', varargin{1}) args = [descr(:, 1), allopts(:, end)]; - for i = size(args, 1): - 1:1 + for i = size(args, 1): -1:1 if struccmp(descr{i, 4}, args{i, end}) args(i, :) = []; elseif strcmp(args{i, 1}, 'activepars') && (islogical(args{i, end}) && all(args{i, end})) @@ -196,8 +197,8 @@ classdef grind_coco < grind_cont % end % end % pairs4={'frompoint(c#s)';'ctype(c#s)';'file(s)'}; - ext_opts = {'frompoint', 'c#s', 'code of the point from which the continuation starts (for instance ''EP1'') (default: empty)', ''; ... - 'ctype', 'c#s', 'type of curve for continuations (for instance EP)', ''; ... + ext_opts = {'frompoint', 'c#s', 'code of the point from which the continuation starts (for instance ''EP1'') (default: empty)', ''; ... + 'ctype', 'c#s', 'type of curve for continuations (for instance EP)', ''; ... 'file', 's', 'open a previously saved conteq session', ''}; args = i_parseargs([obj.corr_opt; obj.cont_opt; obj.grind_opt; ext_opts].', 'if nargs==1,deffields=''file'';else,deffields=''par1,frompoint,ctype'';end;', '-defaults,-coco,-matcont,-c,-out,-l', varargin); if any(strcmp(args.opts, '-defaults')) @@ -399,69 +400,69 @@ classdef grind_coco < grind_cont function argnames = get_func_args(label, clabel) - init_functs = {'BP_BP', {'odefile', 'x', 'p', 'ap', 'bp'}; ... - 'BPC_BPC', {'odefile', 'x', 's', 'ap', 'ntst', 'NCOL', 'bp'}; ... - 'BP_EP', {'odefile', 'x', 'p', 's', 'amp'}; ... - 'EP_EP', {'odefile', 'x', 'p', 'ap'}; ... - 'H_EP', {'odefile', 'x', 'p', 'ap'}; ... - 'LP_EP', {'odefile', 'x', 'p', 'ap', 'varargin'}; ... - 'HTHet_Het', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... - 'Het_Het', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... - 'BT_Hom', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'TTolerance ', 'amplitude', 'extravec'}; ... - 'HSN_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... - 'HTHom_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... - 'Hom_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... - 'LC_Hom', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... - 'NCH_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... - 'HSN_HSN', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... - 'HTHSN_HSN', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... - 'Hom_HSN', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... - 'LC_HSN', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... - 'NCH_HSN', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... - 'HTHet_HTHet', {'odefile', 'x', 'v', 's', 'p', 'ap', 'up', 'aup', 'sp', 'asp', 'NTST', 'NCOL', 'T', 'eps1', 'eps1tol'}; ... - 'HTHom_HTHom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'up', 'aup', 'sp', 'asp', 'NTST', 'NCOL', 'T', 'eps1', 'eps1tol'}; ... - 'HTHSN_HTHSN', {'odefile', 'x', 'v', 's', 'p', 'up', 'aup', 'sp', 'asp', 'NTST', 'NCOL', 'T', 'eps1', 'eps1tol'}; ... - 'BT_H', {'odefile', 'x', 'p', 'ap'}; ... - 'GH_H', {'odefile', 'x', 'p', 'ap'}; ... - 'HH_H', {'odefile', 'x', 'p', 'ap'}; ... - 'H_H', {'odefile', 'x', 'p', 'ap'}; ... - 'ZH_H', {'odefile', 'x', 'p', 'ap'}; ... - 'BPC_LC', {'odefile', 'x', 'v', 's', 'NTST', 'NCOL', 'h'}; ... - 'H_LC', {'odefile', 'x', 'p', 'ap', 'amp', 'NTST', 'NCOL'}; ... - 'LC_LC', {'odefile', 'x', 'v', 's', 'par', 'ap', 'NTST', 'NCOL'}; ... - 'LPC_LC', {'odefile', 'x', 'v', 's', 'par', 'ap', 'NTST', 'NCOL'}; ... - 'NS_LC', {'odefile', 'x', 'v', 's', 'par', 'ap', 'NTST', 'NCOL'}; ... - 'P_EP', {'odefile', 'x', 'p', 'ap', 'ndays'}; ... - 'P_LC', {'odefile', 'x', 'p', 'ap', 'NTST', 'NCOL', 'ndays', 'cycletol'}; ... - 'PD_LC', {'odefile', 'x', 's', 'NTST', 'NCOL', 'h'}; ... - 'PD_LC2', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL', 'h'}; ... - 'BP_LP', {'odefile', 'x', 'p', 'ap'}; ... - 'BT_LP', {'odefile', 'x', 'p', 'ap'}; ... - 'CP_LP', {'odefile', 'x', 'p', 'ap'}; ... - 'LP_LP', {'odefile', 'x', 'p', 'ap', 'varargin'}; ... - 'ZH_LP', {'odefile', 'x', 'p', 'ap'}; ... - 'BPC_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'CPC_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'GH_LPC', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps', 'varargin'}; ... - 'LPC_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL', 'varargin'}; ... - 'LPNS_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'LPPD_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'R1_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'CHNS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'HH_NS1', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps'}; ... - 'HH_NS2', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps'}; ... - 'LPNS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'NS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'PDNS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'R1_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'R2_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'R3_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'R4_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'ZH_NS', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps'}; ... - 'GPD_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'LPPD_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'PDNS_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... - 'PD_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + init_functs = {'BP_BP', {'odefile', 'x', 'p', 'ap', 'bp'}; ... + 'BPC_BPC', {'odefile', 'x', 's', 'ap', 'ntst', 'NCOL', 'bp'}; ... + 'BP_EP', {'odefile', 'x', 'p', 's', 'amp'}; ... + 'EP_EP', {'odefile', 'x', 'p', 'ap'}; ... + 'H_EP', {'odefile', 'x', 'p', 'ap'}; ... + 'LP_EP', {'odefile', 'x', 'p', 'ap', 'varargin'}; ... + 'HTHet_Het', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... + 'Het_Het', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... + 'BT_Hom', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'TTolerance ', 'amplitude', 'extravec'}; ... + 'HSN_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... + 'HTHom_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... + 'Hom_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... + 'LC_Hom', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... + 'NCH_Hom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... + 'HSN_HSN', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... + 'HTHSN_HSN', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... + 'Hom_HSN', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... + 'LC_HSN', {'odefile', 'x', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... + 'NCH_HSN', {'odefile', 'x', 'v', 's', 'p', 'ap', 'NTST', 'NCOL', 'extravec', 'T', 'eps0', 'eps1'}; ... + 'HTHet_HTHet', {'odefile', 'x', 'v', 's', 'p', 'ap', 'up', 'aup', 'sp', 'asp', 'NTST', 'NCOL', 'T', 'eps1', 'eps1tol'}; ... + 'HTHom_HTHom', {'odefile', 'x', 'v', 's', 'p', 'ap', 'up', 'aup', 'sp', 'asp', 'NTST', 'NCOL', 'T', 'eps1', 'eps1tol'}; ... + 'HTHSN_HTHSN', {'odefile', 'x', 'v', 's', 'p', 'up', 'aup', 'sp', 'asp', 'NTST', 'NCOL', 'T', 'eps1', 'eps1tol'}; ... + 'BT_H', {'odefile', 'x', 'p', 'ap'}; ... + 'GH_H', {'odefile', 'x', 'p', 'ap'}; ... + 'HH_H', {'odefile', 'x', 'p', 'ap'}; ... + 'H_H', {'odefile', 'x', 'p', 'ap'}; ... + 'ZH_H', {'odefile', 'x', 'p', 'ap'}; ... + 'BPC_LC', {'odefile', 'x', 'v', 's', 'NTST', 'NCOL', 'h'}; ... + 'H_LC', {'odefile', 'x', 'p', 'ap', 'amp', 'NTST', 'NCOL'}; ... + 'LC_LC', {'odefile', 'x', 'v', 's', 'par', 'ap', 'NTST', 'NCOL'}; ... + 'LPC_LC', {'odefile', 'x', 'v', 's', 'par', 'ap', 'NTST', 'NCOL'}; ... + 'NS_LC', {'odefile', 'x', 'v', 's', 'par', 'ap', 'NTST', 'NCOL'}; ... + 'P_EP', {'odefile', 'x', 'p', 'ap', 'ndays'}; ... + 'P_LC', {'odefile', 'x', 'p', 'ap', 'NTST', 'NCOL', 'ndays', 'cycletol'}; ... + 'PD_LC', {'odefile', 'x', 's', 'NTST', 'NCOL', 'h'}; ... + 'PD_LC2', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL', 'h'}; ... + 'BP_LP', {'odefile', 'x', 'p', 'ap'}; ... + 'BT_LP', {'odefile', 'x', 'p', 'ap'}; ... + 'CP_LP', {'odefile', 'x', 'p', 'ap'}; ... + 'LP_LP', {'odefile', 'x', 'p', 'ap', 'varargin'}; ... + 'ZH_LP', {'odefile', 'x', 'p', 'ap'}; ... + 'BPC_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'CPC_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'GH_LPC', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps', 'varargin'}; ... + 'LPC_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL', 'varargin'}; ... + 'LPNS_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'LPPD_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'R1_LPC', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'CHNS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'HH_NS1', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps'}; ... + 'HH_NS2', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps'}; ... + 'LPNS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'NS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'PDNS_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'R1_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'R2_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'R3_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'R4_NS', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'ZH_NS', {'odefile', 'x', 'p', 's', 'ap', 'NTST', 'NCOL', 'eps'}; ... + 'GPD_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'LPPD_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'PDNS_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... + 'PD_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}; ... 'R2_PD', {'odefile', 'x', 's', 'ap', 'NTST', 'NCOL'}}; ndx = strcmp([label '_' clabel], init_functs(:, 1)); argnames = init_functs(ndx, 2); @@ -469,20 +470,20 @@ classdef grind_coco < grind_cont argnames = argnames{1}; end end - function engine_path = findupdate(checkupdates, url) + function engine_path = findupdate(checkupdates, urls) function writecfg(engine_path) if exist('grind.cfg', 'file') fid = fopen('grind.cfg', 'r'); lines = textscan(fid, '%s', 'delimiter', '\n', 'whitespace', ''); lines = lines{1}; fclose(fid); - ndx = ~cellfun('isempty', (strfind(lines, 'cocodir='))); + ndx = ~cellfun('isempty', (strfind(lines, 'current_coco='))); if ~any(ndx) ndx = length(lines) + 1; end - lines{ndx} = sprintf('cocodir=%s', engine_path); + lines{ndx} = sprintf('current_coco=%s', engine_path); else - lines = {sprintf('cocodir=%s', engine_path)}; + lines = {sprintf('current_coco=%s', engine_path)}; end fid = fopen(fullfile(grindpath, 'grind.cfg'), 'w'); fprintf(fid, '%s\n', lines{:}); @@ -498,14 +499,14 @@ classdef grind_coco < grind_cont end engine_path = ''; if nargin < 2 - url = 'http://content.alterra.wur.nl/webdocs/internet/aew/downloads/'; + urls = read_grindversion; end if exist('grind.cfg', 'file') fid = fopen('grind.cfg', 'r'); lines = textscan(fid, '%s', 'delimiter', '\n', 'whitespace', ''); lines = lines{1}; fclose(fid); - ndx = ~cellfun('isempty', (strfind(lines, 'cocodir='))); + ndx = ~cellfun('isempty', (strfind(lines, 'current_coco='))); if any(ndx) line = lines{ndx}; engine_path = regexp(line, '(?<=[=]).*', 'match', 'once'); @@ -546,42 +547,44 @@ classdef grind_coco < grind_cont end if ~isempty(checkupdates) && checkupdates - [newversion, status] = urlread([url 'cocoversion.txt']); + %[newversion, status] = urlread([url 'cocoversion.txt']); + [~, newversion] = fileparts(urls.coco_url); if newversion(end) + 0 == 10 newversion = newversion(1:end - 1); end - if status == 1 - if ~isempty(engine_path) - verfile = fullfile(engine_path, 'cocoversion.txt'); - if exist(verfile, 'file') - fid = fopen(verfile, 'r'); - oldversion = fgetl(fid); - fclose(fid); - else - oldversion = ''; - end - - if strcmp(oldversion, newversion) - disp('No newer version of COCO (Continuation Core and Toolboxes) available'); - return; - else - if ~isempty(oldversion) || strcmp(questdlg('OK to remove old version of COCO? (recommended)', ... - 'Remove coco', 'Yes', 'No', 'Yes'), 'Yes') - disp('Removing old version of COCO'); - warning('off', 'MATLAB:RMDIR:RemovedFromPath'); - rmdir(engine_path, 's'); - warning('on', 'MATLAB:RMDIR:RemovedFromPath'); - oldversion = 'removed'; - end - - end - + %if status == 1 + if ~isempty(engine_path) + [~,oldversion]=fileparts(engine_path); +% verfile = fullfile(engine_path, 'cocoversion.txt'); +% if exist(verfile, 'file') +% fid = fopen(verfile, 'r'); +% oldversion = fgetl(fid); +% fclose(fid); +% else +% oldversion = ''; +% end + + if strcmp(oldversion, newversion) + fprintf('COCO version "%s", no newer version available\n',oldversion); + return; else - oldversion = ''; + if ~isempty(oldversion) || strcmp(questdlg('OK to remove old version of COCO? (recommended)', ... + 'Remove coco', 'Yes', 'No', 'Yes'), 'Yes') + disp('Removing old version of COCO'); + warning('off', 'MATLAB:RMDIR:RemovedFromPath'); + rmdir(engine_path, 's'); + warning('on', 'MATLAB:RMDIR:RemovedFromPath'); + oldversion = 'removed'; + end + end - - + + %else + % oldversion = ''; + %end + end + if isempty(engine_path) engine_path = grindpath; f = strfind(engine_path, 'grind'); @@ -593,35 +596,37 @@ classdef grind_coco < grind_cont engine_path = engine_path(1:f(1) + 4); end end - + else f = strfind(engine_path, 'coco'); if ~isempty(f) engine_path = engine_path(1:f(1) - 2); end - - end - fprintf('Downloading %s\n', newversion) - unzip([url newversion], engine_path); - engine_path = fullfile(engine_path, 'coco'); - if ~isempty(oldversion) || ~cocofound - verfile = fullfile(engine_path, 'cocoversion.txt'); - fid = fopen(verfile, 'w'); - fprintf(fid, '%s\n', newversion); - fclose(fid); end + + fprintf('Downloading %s\n', newversion) + unzip(urls.coco_url, engine_path); + % engine_path = fullfile(engine_path, n); + %if ~isempty(oldversion) || ~cocofound + movefile(fullfile(engine_path, 'coco'), fullfile(engine_path, newversion)); + engine_path = fullfile(engine_path, newversion); + % verfile = fullfile(engine_path, 'cocoversion.txt'); + % fid = fopen(verfile, 'w'); + % fprintf(fid, '%s\n', newversion); + % fclose(fid); + % end writecfg(engine_path) disp('Updated Continuation Core and Toolboxes (COCO)'); - end - - end + % end + end + end %method end methods (Access = protected) %for testing public must become private - - + + function parrange = makerange(obj, parrange, freepar) if nargin < 3 freepar = obj.settings.derived.freepars(1); @@ -698,7 +703,7 @@ classdef grind_coco < grind_cont elems = allelems(g_grind.pars{i}, siz); pars = [pars , transpose(elems(:))]; %#ok<AGROW> end - + else pars = g_grind.pars; end @@ -710,14 +715,14 @@ classdef grind_coco < grind_cont obj.settings.derived.prob = []; obj.settings.derived.parranges = struct('par', {}, 'range', [NaN NaN]); end - + function run_point(obj, frompoint, ctype, varargin) global g_grind; % ndx=obj.getndx('curveprops','ctype',ctype); % if any(strcmp(ctype,{'F','T'})) % ctype='SN'; % end - fprintf(['\nRunning <a href="https://sourceforge.net/projects/cocotools/">COCO[%s] (Continuation Core and Toolboxes)</a> ' ... + fprintf(['\nRunning <a href="https://sourceforge.net/projects/cocotools/">COCO[%s] (Continuation Core and Toolboxes)</a> ' ... '\n(Dankowicz, H. & Schilder, F. 2013 Recipes for Continuation. \nSIAM, Philadelphia. 584 pp.)\n'], obj.settings.derived.version); extract_curve_files(obj) if obj.settings.grind.symbolic && (isempty(g_grind.syms.Jacobian) || isempty(g_grind.syms.Jacobianp)) @@ -739,7 +744,7 @@ classdef grind_coco < grind_cont obj.updateprob(true); No = length(obj.curves) + 1; therunid = fullfile(grindpath, 'tmp', g_grind.odefile, int2str(No)); - + contpar1 = obj.translatepars(obj.settings.derived.allpars(obj.settings.derived.freepars(1:npars)), obj.settings.derived.allpars); cocopars = obj.translatepars(obj.settings.derived.allpars(obj.settings.grind.activepars), obj.settings.derived.allpars); %[ode_handle, jac_handle, jacp_handle] @@ -753,7 +758,7 @@ classdef grind_coco < grind_cont elseif numjacp disp('Jacobianp evaluated numerically'); end - + parrange = obj.makerange(obj.settings.grind.parranges1); findingGH = false; % label=obj.pointprops(frompoint.propndx).label; @@ -772,7 +777,7 @@ classdef grind_coco < grind_cont hands{4} = i_getodehandle(12, obj.settings.derived.allpars, 'numonly'); Jacp = hands{4}(frompoint.x0, frompoint.p0(obj.settings.grind.activepars)); end - + if ~any(isnan(Jacp(:))) x0 = zeros(size(frompoint.x0)); if any(isnan((hands{2}(x0, frompoint.p0(obj.settings.grind.activepars))))) @@ -781,7 +786,7 @@ classdef grind_coco < grind_cont end Jacp = hands{4}(x0, frompoint.p0(obj.settings.grind.activepars)); end - + if any(isnan(Jacp(:))) warning('grind:conteq', 'Jacp has NaN values, removed some active parameters, alternatively you can set "symbolic" false') activepars = obj.settings.grind.activepars & ~any(isnan(Jacp), 1); @@ -817,33 +822,33 @@ classdef grind_coco < grind_cont if ~isvalidrange(frompoint.x0, obj.settings.grind.stateranges) error('grind:conteq', 'Cannot start continuation outside the defined range for state variables'); end - + [data, uidx] = coco_get_func_data(obj.settings.derived.prob, 'ep', 'data', 'uidx'); % minstates=obj.settings.N0ranges(:,1);%this can become adjustable mask with minimal values (0) or NAN for state variables % maxstates=obj.settings.N0ranges(:,2); - obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'coco_state_boundary', @(prob, data, u)coco_state_boundary(prob, data, u, obj.settings.grind.stateranges), data.ep_eqn, ... + obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'coco_state_boundary', @(prob, data, u)coco_state_boundary(prob, data, u, obj.settings.grind.stateranges), data.ep_eqn, ... 'regular', 'x.min', 'uidx', uidx); obj.settings.derived.prob = coco_add_event(obj.settings.derived.prob, 'EPS', 'boundary', 'x.min', 0); end - + %run continuation problem % bd3 = coco(obj.prob,runid_bif, [], contpars, makerange(obj.settings.parranges{1})); % cont toolbox arguments - + bd1 = coco(obj.settings.derived.prob, therunid, [], 1, contpar1, parrange); % cont toolbox arguments i_waitbar(1); %save the results in the same way as in MATCONT - curve = struct('freepars', obj.settings.derived.freepars(1:npars), 'ctype', ctype, 'frompoint', frompoint.id, ... + curve = struct('freepars', obj.settings.derived.freepars(1:npars), 'ctype', ctype, 'frompoint', frompoint.id, ... 'data', [], 'color', [], 'propndx', find(obj.getndx('curveprops', 'ctype', ctype)), 'results', struct('stabil', [])); curve.color = obj.curveprops(curve.propndx).color; curve.data.haslyapunov = findingGH; curve.data.runids = {therunid}; curve.data.settings = obj.get('-nondefault'); curve = obj.extract_curve_data(bd1, curve, cocopars); - + add_curve(obj, curve); - + end - + function curve = extract_curve_data(obj, bd1, curve, cocopars) %replace x as it may lead to confusion; bd1{1, strcmp(bd1(1, :), 'x')} = 'results.x'; @@ -933,7 +938,7 @@ classdef grind_coco < grind_cont end function obj = updateprob(obj, refresh) global g_grind; - + if isempty(obj.settings.derived.prob) || refresh obj.settings.derived.prob = coco_prob(); obj.settings.derived.prob = coco_set(obj.settings.derived.prob, 'ode', 'vectorized', strcmp(g_grind.solver.opt.Vectorized, 'on')); @@ -942,7 +947,7 @@ classdef grind_coco < grind_cont obj.settings.derived.prob = coco_set(obj.settings.derived.prob, 'corr', 'LogLevel', 1); %show results in command window obj.settings.derived.prob = coco_set(obj.settings.derived.prob, 'ep', 'NSA', true, 'BTP', true); %detect neutral saddle points and Bogdanov-Takens points end - + %ueer settings: settings1 = eval_settings(obj); tbs = fieldnames(settings1); @@ -951,36 +956,36 @@ classdef grind_coco < grind_cont sett = transpose([fieldnames(settings1.(tb)), struct2cell(settings1.(tb))]); obj.settings.derived.prob = coco_set(obj.settings.derived.prob, tb, sett{:}); end - - + + % s = sprintf('%s(:);', obj.settings.grind.activepars{:}); % obj.settings.p0 = full(par('-v','type','doub;e')); end function findingGH = addfuncsHB(obj) if obj.settings.grind.HH && (obj.settings.derived.ndim >= 4) [data, uidx] = coco_get_func_data(obj.settings.derived.prob, 'ep', 'data', 'uidx'); - obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'coco_test_HH', @coco_test_HH, data, ... + obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'coco_test_HH', @coco_test_HH, data, ... 'regular', 'test.HH', 'uidx', uidx); obj.settings.derived.prob = coco_add_event(obj.settings.derived.prob, 'HH', 'test.HH', 0); end - + if obj.settings.grind.FH && (obj.settings.derived.ndim >= 3) [data, uidx] = coco_get_func_data(obj.settings.derived.prob, 'ep', 'data', 'uidx'); - obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'coco_test_FH', @coco_test_FH, data, ... + obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'coco_test_FH', @coco_test_FH, data, ... 'regular', 'test.FH', 'uidx', uidx); obj.settings.derived.prob = coco_add_event(obj.settings.derived.prob, 'FH', 'test.FH', 0); end - + if obj.settings.grind.GH findingGH = true; [data, uidx] = coco_get_func_data(obj.settings.derived.prob, 'ep', 'data', 'uidx'); - obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'lyap', i_getodehandle('coco_lyap', obj.settings.derived.allpars(obj.settings.grind.activepars)), data.ep_eqn, ... + obj.settings.derived.prob = coco_add_func(obj.settings.derived.prob, 'lyap', i_getodehandle('coco_lyap', obj.settings.derived.allpars(obj.settings.grind.activepars)), data.ep_eqn, ... 'regular', 'test.L1', 'uidx', uidx); obj.settings.derived.prob = coco_add_event(obj.settings.derived.prob, 'GH', 'test.L1', 0); end - + end - + function expand_curve(obj, frompoint, ctype, backward) function fullcurve = append_curve(oldcurve, addedcurve) fullcurve = oldcurve; @@ -1015,14 +1020,14 @@ classdef grind_coco < grind_cont %do not expand if the curve is already filling the parrange return; end - + obj.updateprob(true); No = length(obj.curves) + 1; therunid = fullfile(grindpath, 'tmp', g_grind.odefile, int2str(No)); - + contpar1 = obj.translatepars(obj.settings.derived.allpars(curve.freepars), obj.settings.derived.allpars); cocopars = obj.translatepars(obj.settings.derived.allpars(obj.settings.grind.activepars), obj.settings.derived.allpars); - + findingGH = false; if backward obj.settings.derived.prob = coco_set(obj.settings.derived.prob, 'cont', 'PtMX', [0, obj.settings.cont.PtMX]); @@ -1041,7 +1046,7 @@ classdef grind_coco < grind_cont case 'EP' %remove EP obj.settings.derived.prob = ode_ep2ep(obj.settings.derived.prob, '', point0.data.runid, point0.data.labnr); - + case 'H' obj.settings.derived.prob = ode_HB2HB(obj.settings.derived.prob, '', point0.data.runid, point0.data.labnr); findingGH = obj.addfuncsHB; @@ -1051,7 +1056,7 @@ classdef grind_coco < grind_cont return; end bd1 = coco(obj.settings.derived.prob, therunid, [], 1, contpar1, parrange); % cont toolbox arguments - newcurve = struct('freepars', obj.settings.derived.freepars, 'ctype', ctype, 'frompoint', frompoint.id, ... + newcurve = struct('freepars', obj.settings.derived.freepars, 'ctype', ctype, 'frompoint', frompoint.id, ... 'data', [], 'color', curve.color, 'propndx', find(obj.getndx('curveprops', 'ctype', ctype)), 'results', struct('stabil', [])); i_waitbar([]); newcurve.data = curve.data; @@ -1064,9 +1069,9 @@ classdef grind_coco < grind_cont obj.add_curve(append_curve(curve, newcurve)); end end - - - + + + function [tspan, y0, options] = my_init(obj) global g_grind; han = obj.handles; @@ -1074,7 +1079,7 @@ classdef grind_coco < grind_cont options = odeset('Jacobian', han(3), 'JacobianP', han(4), 'Hessians', han(5), 'HessiansP', han(6), 'Vectorized', g_grind.solver.opt.Vectorized); tspan = [0 10]; end - + function settings1 = eval_settings(obj) relh = obj.settings.grind.relh; %#ok<NASGU> if isempty(obj.settings.grind.parranges1) @@ -1083,11 +1088,11 @@ classdef grind_coco < grind_cont range = obj.settings.grind.parranges1; range = abs(range(2) - range(1)); end - + if isnan(range) && ~isempty(obj.settings.derived.freepars) range = abs(evalin('base', obj.settings.derived.allpars{obj.settings.derived.freepars(1)})); end - + if isnan(range) || range == 0 range = 1; %#ok<NASGU> end @@ -1133,11 +1138,11 @@ classdef grind_coco < grind_cont end end end - + end - - - + + + function add_curve(obj, curve) if strcmp(curve.ctype, 'EP') p0 = obj.points(obj.getndx('points', 'id', curve.frompoint)).p0; @@ -1157,8 +1162,8 @@ classdef grind_coco < grind_cont obj.curves(end + 1) = curve; end end - - + + function [point, pntndx] = create_point(obj, spoint, x0, p0) point = struct('id', '', 'p0', p0, 'x0', x0, 'data', spoint.data, 'propndx', []); if isfield(spoint, 'id') @@ -1188,11 +1193,11 @@ classdef grind_coco < grind_cont %find translation for label For instance LP->F if isempty(point.propndx) point = []; - pntndx = - 1; + pntndx = -1; return; end lab = obj.pointprops(point.propndx).ptype; - + point.id = [lab int2str(length(oldndx) + 1)]; end if isfield(point, 'propndx') @@ -1208,11 +1213,11 @@ classdef grind_coco < grind_cont point.id = sprintf('H%d', length(oldndx) + 1); end end - + end - - - + + + function init_engine(obj, remove) if nargin == 1 remove = false; @@ -1225,11 +1230,11 @@ classdef grind_coco < grind_cont obj.settings.derived.engine_path = obj.findupdate; end cocodir = obj.settings.derived.engine_path; - fullpath = {fullfile(cocodir, 'core', 'toolbox'), fullfile(cocodir, 'covering', 'toolbox'), ... - fullfile(cocodir, 'ep', 'toolbox'), fullfile(cocodir, 'coll', 'toolbox'), ... - fullfile(cocodir, 'po', 'toolbox'), fullfile(cocodir, 'recipes'), ... + fullpath = {fullfile(cocodir, 'core', 'toolbox'), fullfile(cocodir, 'covering', 'toolbox'), ... + fullfile(cocodir, 'ep', 'toolbox'), fullfile(cocodir, 'coll', 'toolbox'), ... + fullfile(cocodir, 'po', 'toolbox'), fullfile(cocodir, 'recipes'), ... fullfile(cocodir, 'continex', 'toolbox')}; - + if ~remove for i = 1:length(fullpath) addpath(fullpath{i}); @@ -1241,7 +1246,7 @@ classdef grind_coco < grind_cont end end end - + properties (Hidden = true, Access = public) %Options: % %name,validation,description,matcont default @@ -1251,47 +1256,47 @@ classdef grind_coco < grind_cont % 'engine(e[coco|cocogrind|grind])','par(s)','par1(p)','par2(p)','parranges(n)','parranges1(n)','parranges2(n)','id0(s)','p0(n)','N0(n)',... % 'relh(n>0)','allpars(c)','activepars(l)','symbolic(l)','silent(l)',... % 'posonly(l)','N0ranges(n)','GH(l)','HH(l)','FH(l)','ngrid(i>0)'}; - - cont_opt = {'h_min', '', 'Minimum step size', '0.001*relh*range'; ... - 'h0', '', 'Initial step size', '0.01*relh*range'; ... - 'h_max', '', 'Maximum step size', 'relh*range'; ... - 'h_fac_min', 'n>0', 'Minimum step size adaptation factor', 0.5; ... - 'h_fac_max', 'n>0', 'Maximum step size adaptation factor', 2; ... - 'PtMX', 'i>0', 'Maximum number of continuation steps', 300; ... - 'NPR', 'n', 'diagnostic output every NPR steps (default 10).', 10; ... - 'NSV', 'n', 'save solution every NSV steps, empty is the same as NPR (default []).', ''; ... - 'NAdapt', '', 'remesh frequency, (default 0(ep) or 1(po)).', 'defaultNAdapt'; ... + + cont_opt = {'h_min', '', 'Minimum step size', '0.001*relh*range'; ... + 'h0', '', 'Initial step size', '0.01*relh*range'; ... + 'h_max', '', 'Maximum step size', 'relh*range'; ... + 'h_fac_min', 'n>0', 'Minimum step size adaptation factor', 0.5; ... + 'h_fac_max', 'n>0', 'Maximum step size adaptation factor', 2; ... + 'PtMX', 'i>0', 'Maximum number of continuation steps', 300; ... + 'NPR', 'n', 'diagnostic output every NPR steps (default 10).', 10; ... + 'NSV', 'n', 'save solution every NSV steps, empty is the same as NPR (default []).', ''; ... + 'NAdapt', '', 'remesh frequency, (default 0(ep) or 1(po)).', 'defaultNAdapt'; ... 'RMMX', 'n', 'maximum number of remesh loops (default 10)).', 10}; - - corr_opt = {'ItMX', 'i>0', 'Maximum number of iterations before step is reduced', 10; ... - 'SubItMX', 'i>0', 'number of damping steps (default 7)', 7; ... - 'TOL', 'n>0', 'Tolerance of Newton correction', 1e-006; ... - 'ResTOL', 'n>0', 'converge criterion of norm of the residium (default 1.00E-06).', 1e-006; ... - 'NTST', 'n', 'number of mesh intervals', 50; ... - 'NCOL', 'n>0', 'number of collocation nodes', 5; ... - 'NTSTMN', 'n', 'minimum number of mesh intervals', 'min(NTST,5)'; ... + + corr_opt = {'ItMX', 'i>0', 'Maximum number of iterations before step is reduced', 10; ... + 'SubItMX', 'i>0', 'number of damping steps (default 7)', 7; ... + 'TOL', 'n>0', 'Tolerance of Newton correction', 1e-006; ... + 'ResTOL', 'n>0', 'converge criterion of norm of the residium (default 1.00E-06).', 1e-006; ... + 'NTST', 'n', 'number of mesh intervals', 50; ... + 'NCOL', 'n>0', 'number of collocation nodes', 5; ... + 'NTSTMN', 'n', 'minimum number of mesh intervals', 'min(NTST,5)'; ... 'NTSTMX', 'n', 'maximum number of mesh intervals', 'max(NTST,NCOL*dim)'}; - grind_opt = {'relh', 'n>0', 'Step size relative to the range of the active parameter (default 0.1).', 1; ... - 'par1', 'p', 'first free parameter (default: '''')', ''; ... - 'parranges1', 'n&length(n)==2', 'range for the first parameter (default: [NaN NaN])', [NaN NaN]; ... - 'par2', 'p#E', 'second free parameter (default: '''')', ''; ... - 'parranges2', 'n&length(n)==2', 'range for the second parameter (default: [NaN NaN])', [NaN NaN]; ... - 'par3', 'p#E', 'third free parameter (default: '''')', ''; ... - 'mindist', 'n>0', 'minimum distance between different special points (default: 1E-5)', 1E-5; ... - 'stateranges', 'n', 'min/max value for each of the state variables, or one row if all are the same (default: [Nan NaN])', [NaN NaN]; ... - 'symbolic', 'l', 'if available use the symbolic toolbox for Jacobians', true; ... - 'activepars', 'l#c', 'indices of the active parameters (default: all 1)', true; ... - 'GH', 'l', 'detect generalized Hopf or Bautin bifurcations (default true).', true; ... - 'HH', 'l', 'detect Hopf-Hopf bifurcations (default true)', true; ... + grind_opt = {'relh', 'n>0', 'Step size relative to the range of the active parameter (default 0.1).', 1; ... + 'par1', 'p', 'first free parameter (default: '''')', ''; ... + 'parranges1', 'n&length(n)==2', 'range for the first parameter (default: [NaN NaN])', [NaN NaN]; ... + 'par2', 'p#E', 'second free parameter (default: '''')', ''; ... + 'parranges2', 'n&length(n)==2', 'range for the second parameter (default: [NaN NaN])', [NaN NaN]; ... + 'par3', 'p#E', 'third free parameter (default: '''')', ''; ... + 'mindist', 'n>0', 'minimum distance between different special points (default: 1E-5)', 1E-5; ... + 'stateranges', 'n', 'min/max value for each of the state variables, or one row if all are the same (default: [Nan NaN])', [NaN NaN]; ... + 'symbolic', 'l', 'if available use the symbolic toolbox for Jacobians', true; ... + 'activepars', 'l#c', 'indices of the active parameters (default: all 1)', true; ... + 'GH', 'l', 'detect generalized Hopf or Bautin bifurcations (default true).', true; ... + 'HH', 'l', 'detect Hopf-Hopf bifurcations (default true)', true; ... 'FH', 'l', 'detect fold-Hopf bifurcations (default true).', true}; - + %ctype npars args handle descr curveprops = struct('ctype', {}, 'npars', [], 'color', [], 'handle', [], 'descr', []) % id descr codim ctypes pointprops = struct('ptype', {}, 'label', [], 'descr', [], 'codim', [], 'ctypes', []); - - + + end end @@ -1362,7 +1367,7 @@ function ok = isvalidrange(N0, N0ranges) xhigh = inf; end - ok = min(xlow, xhigh) > - 1e-5; + ok = min(xlow, xhigh) > -1e-5; end end diff --git a/sys/sys2/grind_matcont.m b/sys/sys2/grind_matcont.m index b568928eb3f6cea418056ca173a901007f7b1b23..cf2ad9cd363b1758524226941712ae2eda0bb823 100644 --- a/sys/sys2/grind_matcont.m +++ b/sys/sys2/grind_matcont.m @@ -959,7 +959,7 @@ classdef grind_matcont < grind_cont cd(oldcd); end - function [engine_path, matcontfile] = findupdate(checkupdates, url, ismap) + function [engine_path, matcontfile] = findupdate(checkupdates, urls, ismap) %try to find the path of matcont and writes to grind.cfg for %future use. If matcont is not found it is downloaded from %url. @@ -987,8 +987,9 @@ classdef grind_matcont < grind_cont checkupdates = []; %only update if engine is not found end engine_path = ''; - if nargin <= 1 || isempty(url) - url = 'http://content.alterra.wur.nl/webdocs/internet/aew/downloads/'; + if nargin <= 1 || isempty(urls) + urls=read_grindversion; + % url = webread('https://sparcs-center.org/grindfiles/grindfolder.txt'); end if nargin <= 2 || isempty(ismap) if isempty(g_grind) @@ -1000,12 +1001,16 @@ classdef grind_matcont < grind_cont if ismap matcontfile = 'matcontm.m'; - fileitem = 'matcontmdir='; - statfile = 'matcontmversion.txt'; + [~,newversion]=fileparts(urls.matcontm_url); + matconturl=urls.matcontm_url; + fileitem = 'current_matcontm='; + % statfile = 'matcontmversion.txt'; else matcontfile = 'matcont.m'; - fileitem = 'matcontdir='; - statfile = 'matcontversion.txt'; + [~,newversion]=fileparts(urls.matcont_url); + matconturl=urls.matcont_url; + fileitem = 'current_matcont='; + % statfile = 'matcontversion.txt'; end % if isempty(engine_path)||~exist(engine_path,'dir') if exist('grind.cfg', 'file') @@ -1037,22 +1042,22 @@ classdef grind_matcont < grind_cont end if ~isempty(checkupdates) && checkupdates - [newversion, status] = urlread([url statfile]); - if newversion(end) + 0 == 10 - newversion = newversion(1:end - 1); - end - - if status == 1 - if ~isempty(engine_path) +% [newversion, status] = urlread([url statfile]); +% if newversion(end) + 0 == 10 +% newversion = newversion(1:end - 1); +% end +% +% if status == 1 + if ~isempty(engine_path) if strcontains(engine_path, newversion) if ismap - disp('No newer version of MATCONTM available'); + fprintf('MATCONTM version "%s", no newer version available\n',newversion); else - disp('No newer version of MATCONT available'); + fprintf('MATCONT version "%s", no newer version available\n',newversion); end return; end - end + end engine_path = grindpath; f = strfind(engine_path, 'grind'); @@ -1063,9 +1068,9 @@ classdef grind_matcont < grind_cont engine_path = engine_path(1:f(1) + 4); end end - zipfile = [newversion '.zip']; - fprintf('Downloading %s\n', zipfile) - unzip([url zipfile], engine_path); + %zipfile = [newversion '.zip']; + fprintf('Downloading %s\n', matconturl) + unzip(matconturl, engine_path); engine_path = fullfile(engine_path, newversion); writecfg(engine_path) grind_matcont.repairBugs(ismap, engine_path); %I found a bug in MATCONTM that is crucial @@ -1074,7 +1079,7 @@ classdef grind_matcont < grind_cont else disp('Updated MATCONT'); end - end + % end end end @@ -1488,7 +1493,7 @@ classdef grind_matcont < grind_cont if DEBUG fprintf(' opt=contset;\n'); for i = 1:length(f) - if ~isempty(sett1.(f{i})) + if ~isempty(sett1.(f{i}))&&isnumeric(sett1.(f{i})) fprintf(' opt=contset(opt,''%s'',%s);\n', f{i}, mat2str(sett1.(f{i}))); end end @@ -2122,7 +2127,7 @@ function plotjac(fid, jac, separ, func) end function res = DEBUG - res = true; + res = false; end function curve1 = docont(obj, curve1, args, sett1) global cds; diff --git a/sys/sys2/heun.m b/sys/sys2/heun.m index de4ce8f611a0d8d469df9fd5039ce575f422ebe3..7af6db2abac64c172875bac9809eb3de78408ab7 100644 --- a/sys/sys2/heun.m +++ b/sys/sys2/heun.m @@ -9,8 +9,8 @@ % Reference page in Help browser: % <a href="matlab:commands('heun')">commands heun</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function [tout, yout] = heun(odefunct, tspan, y0, options) global g_grind; if (nargin < 4) @@ -35,7 +35,7 @@ function [tout, yout] = heun(odefunct, tspan, y0, options) if nargin < 4 nonNegative = []; else - nonNegative = odeget(options, 'NonNegative', [], 'fast'); + nonNegative = odeget(options, 'NonNegative', []); end anyNonNegative = ~isempty(nonNegative); haveOutputFcn = ~isempty(options.OutputFcn); diff --git a/sys/sys2/heun1.m b/sys/sys2/heun1.m index c73b3032a2b6bc653550e437a7151d79df60a572..92f674f19d6dbdc13cdf203b25807feeed062a99 100644 --- a/sys/sys2/heun1.m +++ b/sys/sys2/heun1.m @@ -31,7 +31,7 @@ function [tout, yout] = heun(odefunct, tspan, y0, options) if nargin < 4 nonNegative = []; else - nonNegative = odeget(options, 'NonNegative', [], 'fast'); + nonNegative = odeget(options, 'NonNegative', []); end anyNonNegative = ~isempty(nonNegative); haveOutputFcn = ~isempty(options.OutputFcn); diff --git a/sys/sys2/i_differ.m b/sys/sys2/i_differ.m index 306e1aff46ef52c155c9968da3c08856e9e9f0a6..18bb1bbf2364b4692cbaf0dc7771285655588af4 100644 --- a/sys/sys2/i_differ.m +++ b/sys/sys2/i_differ.m @@ -5,7 +5,7 @@ function [T, Y] = i_differ(odefunct, TSPAN, Y0, OPTIONS) if (nargin < 4) nonNegative = []; else - nonNegative = odeget(OPTIONS, 'NonNegative', [], 'fast'); + nonNegative = odeget(OPTIONS, 'NonNegative', []); end anyNonNegative = ~isempty(nonNegative); haveOutputFcn = ~isempty(OPTIONS.OutputFcn); diff --git a/sys/sys2/i_discrete_events.m b/sys/sys2/i_discrete_events.m index b845fd42c6289b3b737c0011b42e0c60a95b5866..5813d7642d5dba945a59732a76c00d826f16ae39 100644 --- a/sys/sys2/i_discrete_events.m +++ b/sys/sys2/i_discrete_events.m @@ -7,7 +7,7 @@ function [T, Y] = i_discrete_events(odefunct, tspan, Y0, options) if (nargin < 4) nonNegative = []; else - nonNegative = odeget(options, 'NonNegative', [], 'fast'); + nonNegative = odeget(options, 'NonNegative', []); end anyNonNegative = ~isempty(nonNegative); haveOutputFcn = ~isempty(options.OutputFcn); diff --git a/sys/sys2/i_grindlegend.m b/sys/sys2/i_grindlegend.m index e79354394d22e9a833ddc169522d2df1a5ed03b0..1cd1f47e0dbb639eabd121bbe90e8d1f8d250eae 100644 --- a/sys/sys2/i_grindlegend.m +++ b/sys/sys2/i_grindlegend.m @@ -182,7 +182,7 @@ function pout = i_grindlegend(flag, h, par2, xtrapar) s = get(ser(1), 'DisplayName'); s1 = get(get(h, 'ylabel'), 'string'); if isempty(s1) - ylabel(s); + ylabel(h,s); end end diff --git a/sys/sys2/i_klepperen.m b/sys/sys2/i_klepperen.m index 2873635388a30ee67e590e3be6854f120fb4ca02..e980d10e51ead628443c2789f0942ec8b7e23809 100644 --- a/sys/sys2/i_klepperen.m +++ b/sys/sys2/i_klepperen.m @@ -162,6 +162,8 @@ function i_klepperen(s_matrix, vlabels, plabels, dummy_matrix, atitle, dendrpars nlab = length(plabels2); if nlab < 2 warning('GRIND:mcarlo:dendrogram1var', 'Cannot make a dendrogram if there is only one parameter/variable'); + elseif ~exist('pdist','file') + warning('GRIND:mcarlo:dendrogram1var', 'Statistics toolbox is needed for a dendrogram'); else Y = pdist(s_matrix, str2func('sinedist')); % calculate distances if ~all(isnan(Y)) diff --git a/sys/sys2/implicitvars.m b/sys/sys2/implicitvars.m index 3215cf0fd80bc412c8e657aec6cf5e76798fc4ff..2a44e7222979e7fc4826ecb3cc49aad6b2d32254 100644 --- a/sys/sys2/implicitvars.m +++ b/sys/sys2/implicitvars.m @@ -24,8 +24,8 @@ % Reference page in Help browser: % <a href="matlab:commands('implicitvars')">commands implicitvars</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:37 $ function implicitvars(varargin) disp('Use this function only in a definition of a model'); end diff --git a/sys/sys2/langevin_eq.m b/sys/sys2/langevin_eq.m index b14ef386cb1a8877b169ca2925711ab68117d034..2c888fa0f526bed4349f524c42c9ad9ca5f9f402 100644 --- a/sys/sys2/langevin_eq.m +++ b/sys/sys2/langevin_eq.m @@ -58,12 +58,17 @@ classdef langevin_eq < handle domain_ = obj.domain; sumpdf = integral(fun, domain_(1), domain_(2)); res = @(x)fun(x)/sumpdf; + case 'uniform' + uniform_pdf = makedist('Uniform', obj.domain(1), obj.domain(2)); + res = @(x)uniform_pdf.pdf(x); case 'normal_dom' res = obj.getinitfun('normalize', @(x)exp(-(x - obj.domain(2) ./ 2).^2)); case 'normal' mean = varargin{1}; std = varargin{2}; - res = @(x)pdf('normal',x,mean,std); + normal_pdf = makedist('Normal', mean, std); + normal_pdf = normal_pdf.truncate(obj.domain(1), obj.domain(2)); + res = @(x)normal_pdf.pdf(x); case 'dirichlet' x0 = varargin{1}; if length(varargin) > 1 @@ -189,7 +194,7 @@ classdef langevin_eq < handle result.pdfs = u; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - function [c, f, s] = pdex1pde(x, ~, u, DuDx , D1, D2, DD2) + function [c, f, s] = pdex1pde(x, ~, u, DuDx, D1, D2, DD2) %Forward Fokker Planck: %diff(P,t) = - diff (D1(x)*P(x,t),x) + diff(diff(D2(x)*P(x,t),x),x) % @@ -311,24 +316,24 @@ classdef langevin_eq < handle if ~exist('fittype', 'file') error('langevin_eq:toolboxmissing', 'The curvefitting toolbox is required for the ''weightedspline'' option') end - ft = fittype( 'smoothingspline' ); + ft = fittype('smoothingspline'); if all(results.ErrorD1 == 0) w1 = ones(size(results.ErrorD1)); else w1 = 1 ./ results.ErrorD1; end - [xData, yData, weights1] = prepareCurveData(results.C, results.D1, w1 ); - opts = fitoptions( 'Method', 'SmoothingSpline', 'SmoothingParam', 0.9982070110205727, 'Weights', weights1); - [d1, results.gofD1] = fit( xData, yData, ft, opts ); + [xData, yData, weights1] = prepareCurveData(results.C, results.D1, w1); + opts = fitoptions('Method', 'SmoothingSpline', 'SmoothingParam', 0.9982070110205727, 'Weights', weights1); + [d1, results.gofD1] = fit(xData, yData, ft, opts); if all(results.ErrorD2 == 0) w2 = ones(size(results.ErrorD1)); else w2 = 1 ./ results.ErrorD2; end w2(results.D2 - results.ErrorD2 <= 0) = 0; %I assign 0 weight to the very few bins for D2 when D2<0 - [xData, yData, weights1] = prepareCurveData(results.C, results.D2, w2 ); - opts = fitoptions( 'Method', 'SmoothingSpline', 'SmoothingParam', 0.9982070110205727, 'Weights', weights1); - [d2, results.gofD2] = fit( xData, yData, ft, opts ); + [xData, yData, weights1] = prepareCurveData(results.C, results.D2, w2); + opts = fitoptions('Method', 'SmoothingSpline', 'SmoothingParam', 0.9982070110205727, 'Weights', weights1); + [d2, results.gofD2] = fit(xData, yData, ft, opts); if exist('chebfun', 'file') && ~any(strcmp(options, 'nocheb')) l = linspace(L1, R1, 2^13); D1 = chebfun(d1(l), [L1 R1], 'equi', 5000); @@ -349,6 +354,22 @@ classdef langevin_eq < handle end end obj.xtra.reconstr = results; + elseif nargin == 1 && isfield(varargin{1}, 'mufun') && isfield(varargin{1}, 'sigmafun') + %results of euler_reconstruction or + %hermite_reconstruction + results=varargin{1}; + pars=results.estimated_par; + d1=@(x)results.mufun(x,pars); + d2=@(x)0.5*results.sigmafun(x,pars).^2; + L=results.options.l; + R=results.options.r; + if isempty(L) + L=results.datarange(1); + end + if isempty(R) + R=results.datarange(2); + end + obj.set('D1', d1, 'D2', d2, 'domain', [L R]); elseif nargin == 2 && ~ischar(varargin{1}) %2 default arguments D1 and D2 obj.set('D1', varargin{1}, 'D2', varargin{2}); @@ -490,7 +511,7 @@ classdef langevin_eq < handle if ~isfield(args, 'simuldata') disp('Simulating'); sizedata = numel(data); - [simuldata, fcn] = obj.simulate( linspace(0, (sizedata - 1) * args.dt, sizedata)', obj.draw_pdf(args.nreplicates, 1), struct('MaxStep', args.MaxStep, 'NonNegative', args.NonNegative)); + [simuldata, fcn] = obj.simulate(linspace(0, (sizedata - 1) * args.dt, sizedata)', obj.draw_pdf(args.nreplicates, 1), struct('MaxStep', args.MaxStep, 'NonNegative', args.NonNegative)); res.simuldata = fcn; simuldatat = simuldata.t; simuldata = simuldata.y; @@ -599,7 +620,7 @@ classdef langevin_eq < handle res.mesh = linspace(args.domain(1), args.domain(2), args.nmesh); [res.datadistr, res.sizes] = getdistrib(data1, stepdata); disp('Simulating'); - [simuldata, fcn] = obj.simulate( linspace(0, (sizedata - 1) * args.dt, sizedata)', ... + [simuldata, fcn] = obj.simulate(linspace(0, (sizedata - 1) * args.dt, sizedata)', ... obj.draw_pdf(args.nreplicates, 1), struct('MaxStep', args.MaxStep, 'NonNegative', args.NonNegative)); res.simuldata = fcn; simuldata1 = simuldata.y(args.nstep + 1:end, :); @@ -846,6 +867,7 @@ classdef langevin_eq < handle % 'D1' plot the drift function % 'D2' plot the diffusion function % 'DD2' plot the derivative of the diffusion function + % 'D4' D4 plot % 'equilibria' plot the equilibria in the D1 plot % 'exit_distrib' plot the probability density function of % exit times for a certain initial state @@ -946,7 +968,12 @@ classdef langevin_eq < handle x = obj.DD2; end elseif strcmp(varargin{1}, 'D4') - x = griddedInterpolant(obj.xtra.reconstr.C, obj.xtra.reconstr.D4, 'spline'); + if ~isfield(obj.xtra,'reconstr') + disp('Cannot plot "D4" as the model is not from reconstructed data from LangevinReconst'); + return; + else + x = griddedInterpolant(obj.xtra.reconstr.C, obj.xtra.reconstr.D4, 'spline'); + end end % ploterror=true; % ts=1; @@ -1030,7 +1057,7 @@ classdef langevin_eq < handle hax1 = xline(obj.equilibria(unstableeqs(i)).x, 'k--'); catch %older versions of matlab do not have xline - ylim1=get(gca,'ylim'); + ylim1 = get(gca, 'ylim'); plot(obj.equilibria(unstableeqs(i)).x + zeros(1, 2), ylim1, 'k--') end end @@ -1042,7 +1069,7 @@ classdef langevin_eq < handle if ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'pdf') obj.pdf; end - hax1 = obj.plot(obj.xtra.results.pdf); + hax1 = obj.plot(obj.xtra.results.pdf, args{:}); case 'survival' hold on if nargin > 2 || ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'survival') @@ -1054,9 +1081,9 @@ classdef langevin_eq < handle result = args{1}; else if nargin == 2 && ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'pdfs') - obj.pdfs; + obj.pdf; end - result = obj.xtra.results.pdfs; + result = obj.xtra.results.pdf; end nt = size(result.pdfs, 1); result.t = result.t(1:nt); @@ -1114,7 +1141,11 @@ classdef langevin_eq < handle end case {'survival_func', 'exit_distrib'} %args1 is x0 args2 = survival results hold on - x0 = args{1}; + if isempty(args) + x0=0.01; + else + x0 = args{1}; + end if (length(args) < 2) || ~(isstruct(args{2}) || iscell(args{2})) if isfield(obj.xtra, 'results') && isfield(obj.xtra.results, 'survival') results = obj.xtra.results.survival; @@ -1196,6 +1227,8 @@ classdef langevin_eq < handle plot(stab, zeros(size(stab)), 'ko', 'MarkerSize', 8, 'MarkerFaceColor', 'k'); hold on hax1 = plot(unstab, zeros(size(unstab)), 'ko', 'MarkerSize', 8, 'MarkerFaceColor', [1 1 1]); + otherwise + error('plotting command "%s" not recognized, valid commands are: ''basinprob'', ''D1'', ''D2'', ''DD2'', ''D4'', ''equilibria'', ''exit_distrib'', ''exitprob'', ''mean_exit'', ''pdf'', ''potential'', ''potential_eff'', ''survival'', ''survival_func'', ''vertical_basin_boundaries''',varargin{1}); end else result = varargin{1}; @@ -1242,24 +1275,55 @@ classdef langevin_eq < handle if ~isfield(args, 'verticalbar') || args.verticalbar obj.plot('vertical_basin_boundaries'); end - elseif isfield(result, 'PDF') || isfield(result, 'pdfs') %pdf + elseif isfield(result, 'PDF') || isfield(result, 'pdfs') %pdf if isfield(args, 't') t = args.t; else t = result.t(end); end - hax1 = findobj(get(0, 'currentfigure'), 'tag', 'pdfs'); + hfig = get(0, 'currentfigure'); + hax1 = findobj(hfig, 'tag', 'pdfs'); if ~isempty(hax1) updatefig = true; else updatefig = false; end - it = find(result.t >= t, 1); - if isempty(it) - it = length(result.t); + if isfield(args, 'movie') && args.movie + maxt = size(result.pdfs, 1); + F = getframe(gca); + htext = []; + for i = 1:maxt + hax = obj.plot(result, 'ndxt', i); + if isempty(htext) + htext = text(0.9, 0.9, '', 'Units', 'Normalized', 'tag', 'ttext'); + end + set(htext, 'string', sprintf('t=%d', round(result.t(i)))); + F(i) = getframe(gcf); + end + ud = get(hfig, 'userdata'); + ud.frames = F; + set(hfig, 'userdata', ud); + h = findobj(hfig, 'tag', 'moviemenu'); + if isempty(h) + h = uimenu(hfig, 'Text', '&Movie', 'tag', 'moviemenu'); + uimenu(h, 'Text', '&Replay', 'MenuSelectedFcn', @movie_callback); + uimenu(h, 'Text', '&Save as mp4', 'MenuSelectedFcn', @save_movie_callback); + end + if isfield(args, 'mp4file') + save_themovie(args.mp4file, ud.frames); + end + return; + end + if isfield(args, 'ndxt') + ndxt = args.ndxt; + else + ndxt = find(result.t >= t, 1); + end + if isempty(ndxt) + ndxt = length(result.t); end - if (it == length(result.t)) && isfield(result, 'PDF') + if (ndxt == length(result.t)) && isfield(result, 'PDF') if updatefig set(hax1, 'YData', [result.PDF, 0 0]); else @@ -1267,9 +1331,9 @@ classdef langevin_eq < handle end else if updatefig - set(hax1, 'YData', [result.pdfs(it, :), 0 0]); + set(hax1, 'YData', [result.pdfs(ndxt, :), 0 0]); else - hax1 = fill([result.x result.x(end) result.x(1)], [result.pdfs(it, :), 0 0], [0.75 0.75 1]); + hax1 = fill([result.x result.x(end) result.x(1)], [result.pdfs(ndxt, :), 0 0], [0.75 0.75 1]); end end xlim(obj.domain); @@ -1289,7 +1353,7 @@ classdef langevin_eq < handle ylabel(obj.namex); elseif isfield(result, 'survival') %survival [x, y] = meshgrid(result.x, result.t); - colormap( [linspace(1, 0.5, 50)', linspace(1, 0.5, 50)', ones(50, 1)]); + colormap([linspace(1, 0.5, 50)', linspace(1, 0.5, 50)', ones(50, 1)]); [~, hax1] = contourf(x, y, result.survival, 100); set(hax1, 'LineColor', 'none') hold on @@ -1602,7 +1666,7 @@ classdef langevin_eq < handle LL.rbc = @(T)T; end %solving T - res.T = solvebvp(LL , -1); + res.T = solvebvp(LL, -1); T2 = chebfun(res.T, domain2); if ~isempty(PDF) res.WT = sum(PDF * T2) / sum(PDF); @@ -1618,7 +1682,7 @@ classdef langevin_eq < handle LL.lbc = @(T)T; LL.rbc = @(T)T; % T = LL \ (-res1.P_left); - [T, sol] = solvebvp(LL , -res1.P_left); + [T, sol] = solvebvp(LL, -res1.P_left); if sol.error > 0.001 xpoints = linspace(domain_(1), domain_(2), 200); P_l = griddedInterpolant(xpoints, res1.P_left(xpoints)); @@ -1645,7 +1709,7 @@ classdef langevin_eq < handle LL.lbc = @(T)T; LL.rbc = @(T)T; %T = LL \ (- res1.P_right); - [T, sol] = solvebvp(LL , -res1.P_right); + [T, sol] = solvebvp(LL, -res1.P_right); if sol.error > 0.001 xpoints = linspace(domain_(1), domain_(2), 200); P_l = griddedInterpolant(xpoints, res1.P_right(xpoints)); @@ -1662,9 +1726,9 @@ classdef langevin_eq < handle T2 = chebfun(res.T_right, domain2, 'splitting', 'on'); if ~isempty(PDF) - res.WT_right = []; - else res.WT_right = sum(PDF * T2) / sum(PDF); + else + res.WT_right = []; end res.P_right = res1.P_right; end @@ -1789,8 +1853,16 @@ classdef langevin_eq < handle % or a scalar number (Dirichlet delta function is then assumed). % % - % options (optional) the pdepe options (see pdepe, for instance RelTol and AbsTol) + % options (optional) the pdepe options: + %(see pdepe, for instance RelTol and AbsTol) + % RelTol + % AbsTol + % NormControl + % InitialStep + % MaxStep + % Events % + additional fields: + % BC boundary conditions RR AR RA AA % maxtime = duration of the simulation % ntime = number of time outputs (minimal=3) (default 3) % nx = number of points in x direction (default obj.nx) @@ -1806,6 +1878,7 @@ classdef langevin_eq < handle if nargin < 2 pdf0 = []; end + % if nargin > 3 options = struct(varargin{:}); elseif nargin == 3 @@ -1813,6 +1886,14 @@ classdef langevin_eq < handle else options = []; end + if ~isempty(options) + f = fieldnames(options); + validoptions = {'RelTol', 'AbsTol', 'NormControl', 'InitialStep', 'MaxStep', 'Events', 'maxtime', 'ntime', 'nx', 'BC'}; + if any(~ismember(f, validoptions)) + s = sprintf('''%s'' ', validoptions{:}); + error('langevin_eq:pdf', 'Cannot run pdf as some options are unknown\nValid options are: %s', s(1:end - 1)); + end + end if ~isfield(options, 'maxtime') options.maxtime = 4000; end @@ -1949,7 +2030,7 @@ classdef langevin_eq < handle case 'RR' BCfun = @(~, ~ , ~, ~, ~)deal(0, 1, 0, 1); otherwise - error('langevin_eq:bc', 'boundary conditions "%s" undefined',eqn.BC); + error('langevin_eq:bc', 'boundary conditions "%s" undefined', eqn.BC); end if ~isfield(options, 'Stats') options.Stats = 'on'; @@ -2112,7 +2193,7 @@ function [tout, yout] = euler(odefunct, tspan, y0, options) if nargin < 4 nonNegative = []; else - nonNegative = odeget(options, 'NonNegative', [], 'fast'); + nonNegative = odeget(options, 'NonNegative', []); end anyNonNegative = ~isempty(nonNegative); haveOutputFcn = ~isempty(options.OutputFcn); @@ -2302,5 +2383,28 @@ function res = simulate_rng(randseed, odefun, tspan, y0, options) [res.t, res.y] = euler(odefun, tspan, y0, options); end +function movie_callback(h, ~, ~) + hfig = get(get(h, 'parent'), 'parent'); + ud = get(hfig, 'userdata'); + % h = findobj(hfig, 'tag', 'pdfs'); + %drawnow; + movie(hfig, ud.frames); +end +function save_movie_callback(h, ~, ~) + hfig = get(get(h, 'parent'), 'parent'); + ud = get(hfig, 'userdata'); + [afile, apath] = uiputfile('video.mp4'); + cd(apath); + save_themovie(afile, ud.frames); + +end + +function save_themovie(afile, frames) + v = VideoWriter(afile, 'MPEG-4'); + open(v) + writeVideo(v, frames); + close(v) + fprintf('written to %s\n', afile) +end % ------------------------------------------------------------------------- diff --git a/sys/sys2/langevin_eq_old.m b/sys/sys2/langevin_eq_old.m new file mode 100644 index 0000000000000000000000000000000000000000..ff1082f7e63191feeb176768ae73c917995f09bf --- /dev/null +++ b/sys/sys2/langevin_eq_old.m @@ -0,0 +1,2306 @@ +classdef langevin_eq < handle + %This class is used to analyze a reconstructed Langevin equation. It is + %especially suitable for discretized D1 and D2 functions. + %When you use smooth functions they are also descretized + %Use this class to calculate/plot the propeties of the Langevin + %equation: + %Main methods: + % plot: used to plot the results + % pdf: calculated the stationary pdf + % mean_exit: calculates the mean exit time for all initial conditions + % of a domain + % survival: calculates the survival function for all initial + % conditions + % potential: the potential function based on D1 + % potential_eff: the effective potential function, includes effects of + % D2 + % + %Optionally, it uses chebfun: + % Driscoll, T. A., N. Hale, and L. N. Trefethen. 2014. Chebfun Guide. Pafnuty Publication, Oxford. + % + properties + D1 = []; %drift + D2 = []; %diffusion + DD2 = []; %derivative of diffusion + equilibria = struct('x', {}, 'stable', false, 'BC', '', 'domain', []); %list of equilibria + % x= state variable, stable = logical variable true if stable, BC boundary conditons RA AA AR or RR, + % domain - the basin of attraction of stable equilibrium, outer borders are -Inf Inf + xtra %struct with extra information, for instance last results and reconstr information + nx = 100; %default number of x for Fokker-Planck equations + domain = [0 10]; %domain of the Langevin equation + namex = 'x' %name of the x coordinate for plotting + timeunit = ''; %time unit for plotting + end + methods + function res = getinitfun(obj, atype, varargin) + % get an initial function for pdepe/bvp5v: + % usage: + % obj.getinitfun('normal_dom') - for runpde + % obj.getinitfun('normal',mean,std) - for runpde + % obj.getinitfun('dirichlet',x0) - for runpde + % obj.getinitfun('cosine',BC) - for mean_exit + + function u0 = dirichlet_delta_ic(x0, meshx) %vectorized + dx = meshx(2) - meshx(1); + [~, ix0] = min(abs(meshx - x0)); + u0 = zeros(size(meshx)); + ndx = abs(meshx - x0) < dx / 2 | (abs(meshx - x0) == dx / 2 & meshx > x0); + u0(ndx) = 1 / dx; + if ix0 == 1 || ix0 == length(meshx) + u0 = u0 * 2; + end + end + %initial sine, make sure that the BC are correct + %initfun = @(x)[cos(4 * x), -4 * sin(4 * x) ] ; + switch atype + case 'normalize' + fun = varargin{1}; + domain_ = obj.domain; + sumpdf = integral(fun, domain_(1), domain_(2)); + res = @(x)fun(x)/sumpdf; + case 'normal_dom' + res = obj.getinitfun('normalize', @(x)exp(-(x - obj.domain(2) ./ 2).^2)); + case 'normal' + mean = varargin{1}; + std = varargin{2}; + res = @(x)pdf('normal',x,mean,std); + case 'dirichlet' + x0 = varargin{1}; + if length(varargin) > 1 + meshx = varargin{2}; + else + meshx = linspace(obj.domain(1), obj.domain(2), obj.nx); + end + u0 = dirichlet_delta_ic(x0, meshx); + interpolant = griddedInterpolant(meshx, u0); + res = @(x)interpolant(x); + % res = @(x)dirichlet_delta_ic(x, x0, meshx); + case 'cosine;sine' %for mean_exit + % BC the boundary value code: + % 'AA' = left and right absorbing + % 'RA' = left reflecting and right absorbing + % 'AR' = left absorbing and right reflecting + domain_ = obj.domain; + BC = varargin{1}; + starth = 0; + endh = 2 * pi; + if BC(1) == 'R' + %start at pi/2 to have correct BC + starth = starth + pi / 2; + end + if BC(2) == 'R' + %start at pi/2 to have correct BC + endh = endh + pi / 2; + end + per = (endh - starth) / (domain_(2) - domain_(1)); + res = @(x)[cos(per * (x-domain_(1))+starth); -per * sin(per * (x-domain_(1))+starth) ]; + end + end + + end + methods (Access = protected) + function result = solvepdf(obj, pdf0, varargin) + %solve pdfs + %used both by pdf and by runpdf + if isempty(obj.D1) || isempty(obj.D2) + error('langevin_eq:nomodel', 'No Langevin equation defined'); + end + if nargin > 2 && ischar(pdf0) + varargin = [{pdf0} varargin]; + pdf0 = []; + end + if nargin < 2 || isempty(pdf0) + if isa(obj.D1, 'chebfun') + pdf0 = chebfun(@(x)exp(-(x - obj.domain(2) / 2)^2), obj.domain, 'vectorize'); + pdf0 = pdf0 / sum(pdf0); + else + pdf0 = obj.getinitfun('normal_dom'); + end + end + if length(varargin) > 1 + options = struct(varargin{:}); + elseif length(varargin) == 1 + options = varargin{1}; + else + options = []; + end + if ~isfield(options, 'maxtime') + options.maxtime = 1000; + end + if ~isfield(options, 'ntime') + options.ntime = 1000; + end + if ~isfield(options, 'nx') + options.nx = obj.nx; + end + + L = min(obj.domain); + R = max(obj.domain); + m = 0; + result.t = linspace(0, options.maxtime, options.ntime); + x = linspace(L, R, options.nx); + % Mesh = x; + if isnumeric(pdf0) && length(pdf0) == 1 + pdf0 = obj.getinitfun('dirichlet', pdf0, x); + if isa(obj.D1, 'chebfun') + pdf0 = chebfun(pdf0, obj.domain, 'vectorize'); + end + end + if isempty(obj.DD2) + DD2_ = diff_fun(obj.D2); + else + DD2_ = obj.DD2; + end + %we bind the D1 D2 and DD2 functions to this anonymous function + if isa(obj.D1, 'chebfun') + %using chebfuns is 100x slower, griddedInterpolant are really + %efficient + x1 = linspace(L, R, options.nx * 1000); %more points for precision + d1 = griddedInterpolant(x1, obj.D1(x1)); + d2 = griddedInterpolant(x1, obj.D2(x1)); + dd2 = griddedInterpolant(x1, DD2_(x1)); + fp_equat = @(x,t,u,DuDx)pdex1pde(x, 0, u, DuDx ,d1,d2,dd2); + else + fp_equat = @(x,t,u,DuDx)pdex1pde(x, 0, u, DuDx ,obj.D1, obj.D2, DD2_); + end + if ~isfield(options, 'RelTol') || isempty(options.RelTol) + options.RelTol = 1E-3; + end + if ~isfield(options, 'AbsTol') || isempty(options.AbsTol) + options.AbsTol = 1E-4; + end + if ~isfield(options, 'BC') || isempty(options.BC) + options.BC = 'RR'; + end + switch options.BC + case 'AA' + pdebc = @(~, ul, ~, ur, ~)deal(ul,0,ur,0); + case 'AR' + pdebc = @(~, ul, ~, ~, ~)deal(ul,0,0,1); + case 'RA' + pdebc = @(~, ~, ~, ur, ~)deal(0,1,ur,0); + otherwise %default RR + pdebc = @(varargin)deal(0,1,0,1); %border conditions; pl, ql pr qr + end + sol = pdepe(m, fp_equat, pdf0, pdebc, x, result.t, options); + % sol = pdepe(m,@pdex1pde,@pdex1ic,@pdex1bc,x,t); + u = sol(:, :, 1); + result.x = x; + result.pdfs = u; + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + function [c, f, s] = pdex1pde(x, ~, u, DuDx , D1, D2, DD2) + %Forward Fokker Planck: + %diff(P,t) = - diff (D1(x)*P(x,t),x) + diff(diff(D2(x)*P(x,t),x),x) + % + %general form for pdepe (see Matlab help) + %c(x,t,u,dudx)*diff(u,t) = x^m * diff(x^m * f(x,t,u,dudx),x) + s(x,t,u,dudx) + % + %we need work out our double integral as that is not in pdepe (we define DD2= d(D2)/dx) + %product rule: diff(D2(x)*P(x,t),x)= DD2 * P + D2 * dPdx + %so our reworked equation is + %diff(P,t) = diff (-D1 * P + DD2 * P + D2 * dPdx,x) + % + %this means we loose some terms: + %m=0: c=1: s=0 + % keeping only: + %diff(u,t) = diff(f,x) + %where + %f =-D1*P + DD2 * P + D2 * dPdx + % + c = 1; + f = -D1(x) .* u + DD2(x) .* u + D2(x) .* DuDx; + s = 0; + end + end + function [res, isconstant] = set_Dfun(obj, Dfun, avar) + if nargin < 3 + avar = ''; + end + isconstant = false; + res = Dfun; + if isa(Dfun, 'chebfun') + obj.domain = Dfun.domain; + if strcmp(avar, 'g') + res = 0.5 * res^2; + end + elseif ischar(Dfun) + val = str2double(Dfun); + if ~isnan(val) + [res, isconstant] = obj.set_Dfun(val, avar); + return; + else + [res, isconstant] = obj.set_Dfun(evalin('base', sprintf('@(%s)%s', obj.namex, Dfun)), avar); + end + elseif isnumeric(Dfun) && numel(Dfun) == 1 + isconstant = true; + if strcmp(avar, 'g') + res = @(x)0.5*Dfun^2+zeros(size(x)); + else + res = @(x)Dfun+zeros(size(x)); + end + elseif isa(Dfun, 'function_handle') + try + if strcmp(avar, 'g') + Dfun = @(x)0.5*Dfun(x).^2; + end + %test whether the function is in vector notation or + %returning a constant. + s1 = Dfun(1:10); + if numel(s1) == 1 + %constant + isconstant = true; + res = @(x)Dfun(x)+zeros(size(x)); + elseif numel(s1) ~= 10 + %wrong size of resultr + res = @(x)simulate_vector(Dfun,x); + else + res = Dfun; + end + catch err + %no vector notation supported, but simulate a + %vector + if strcmp(err.identifier, 'MATLAB:innerdim') + res = @(x)simulate_vector(Dfun,x); + end + end + end + end + end + + methods + function obj = langevin_eq(varargin) + %if chebfun is on the search path it will be used for the + %functions (except if option 'nocheb' is used) + % + %obj = langevin_eq(res,'weightedspline') - where res is + %the result of the function LangevinReconst, 'weightedspline' + %fits a spline while weighing down points that are uncertain. + %is the default if the curvefitting toolbox is present (else + %spline) + %obj = langevin_eq(res,'spline') - uses standard spline + %interpolation (not recommended) + %obj = langevin_eq(res,'weightedspline','nocheb') - do not use + %chebfun functions + % + %obj = langevin_eq('D1',@func1,'D2',@funct2,'domain',[min + %max]) - function handle mode of this class, give + %function handles for D1 and D2 + %D2 can also be a constant (just enter a numeric value) + % + if nargin > 0 + ndx = cellfun(@ischar, varargin); + options = varargin(ndx); + if nargin > 0 && isfield(varargin{1}, 'ErrorD2') %result of LangevinReconst + %splining the D1 and D2 functions determined with the Langevin Approach + %(aka Langevin Reconstruction) + results = varargin{1}; + if ~isfield(results, 'options') + results.options = options; + end + if isfield(results, 'bootstrap') + obj.xtra.bootstrap = results.bootstrap; + results = rmfield(results, 'bootstrap'); + end + L1 = results.C(1); + R1 = results.C(end); + %reconstructed Langevin equation + if ((nargin == 1 && exist('fittype', 'file')) || any(strcmp(options, 'weightedspline'))) + %weighted spline fitting Weighing down of + %uncertain points + if ~exist('fittype', 'file') + error('langevin_eq:toolboxmissing', 'The curvefitting toolbox is required for the ''weightedspline'' option') + end + ft = fittype( 'smoothingspline' ); + if all(results.ErrorD1 == 0) + w1 = ones(size(results.ErrorD1)); + else + w1 = 1 ./ results.ErrorD1; + end + [xData, yData, weights1] = prepareCurveData(results.C, results.D1, w1 ); + opts = fitoptions( 'Method', 'SmoothingSpline', 'SmoothingParam', 0.9982070110205727, 'Weights', weights1); + [d1, results.gofD1] = fit( xData, yData, ft, opts ); + if all(results.ErrorD2 == 0) + w2 = ones(size(results.ErrorD1)); + else + w2 = 1 ./ results.ErrorD2; + end + w2(results.D2 - results.ErrorD2 <= 0) = 0; %I assign 0 weight to the very few bins for D2 when D2<0 + [xData, yData, weights1] = prepareCurveData(results.C, results.D2, w2 ); + opts = fitoptions( 'Method', 'SmoothingSpline', 'SmoothingParam', 0.9982070110205727, 'Weights', weights1); + [d2, results.gofD2] = fit( xData, yData, ft, opts ); + if exist('chebfun', 'file') && ~any(strcmp(options, 'nocheb')) + l = linspace(L1, R1, 2^13); + D1 = chebfun(d1(l), [L1 R1], 'equi', 5000); + D2 = chebfun(d2(l), [L1 R1], 'equi', 5000); + obj.set('D1', D1, 'D2', D2); + else + obj.set('D1', @(x)reshape(d1(x),size(x)), 'D2', @(x)reshape(d2(x),size(x)), 'domain', [L1 R1]); + end + elseif nargin == 1 || any(strcmp(options, 'spline')) %default if curvefitting toolbox is missing + d1 = griddedInterpolant(results.C, results.D1, 'spline'); + d2 = griddedInterpolant(results.C, results.D2, 'spline'); + if exist('chebfun', 'file') && ~any(strcmp(options, 'nocheb')) + D1 = chebfun(@(x)d1(x), [L1 R1]); + D2 = chebfun(@(x)d2(x), [L1 R1]); + obj.set('D1', D1, 'D2', D2); + else + obj.set('D1', @(x)d1(x), 'D2', @(x)d2(x), 'domain', [L1 R1]); + end + end + obj.xtra.reconstr = results; + elseif nargin == 2 && ~ischar(varargin{1}) + %2 default arguments D1 and D2 + obj.set('D1', varargin{1}, 'D2', varargin{2}); + else + obj.set(varargin{:}); + end + if isempty(obj.equilibria) + obj.equilibria = obj.find_equilibria('deterministic'); %can be changed to 'effective' if you use ueff + end + end + end + + function res = simple_stoch_exit(obj, data, varargin) + %one-step (or n-step) conditional distribution + %default nstep=1 + % + + function res = SojournTimes(data, dt, stable_equilibrium, width) + repelor = stable_equilibrium.domain(~isinf(stable_equilibrium.domain)); + if numel(repelor) > 1 + error('not yet implemented'); + end + res.periods_in = cell(size(data, 2), 1); + for m = 1:size(data, 2) + s = []; + data1 = data(:, m); + if stable_equilibrium.x < repelor + T = 0; + %discard the first part of the time series if we start below the + %stable equilibrium + Idx = find(data1 > stable_equilibrium.x - width, 1); + if Idx > 1 + Idx = Idx - 1; + end + data1 = data1(Idx:end); + while ~isempty(T) + Idx = find(data1 < stable_equilibrium.x + width, 1); + %Idx=find(data>e-width & data<e+width,1); + data1 = data1(Idx:end); + T = find(data1 > repelor, 1); + if ~isempty(T) + s = [s T]; + data1 = data1(T:end); + end + end + else + T = 0; + %discard the first part of the time series if we start above the + %stable equilibrium + Idx = find(data1 < stable_equilibrium.x + width, 1); + if Idx > 1 + Idx = Idx - 1; + end + data1 = data1(Idx:end); + while ~isempty(T) + Idx = find(data1 > stable_equilibrium.x - width, 1); + %Idx=find(data>e-width & data<e+width,1); + data1 = data1(Idx:end); + T = find(data1 < repelor, 1); + if ~isempty(T) + s = [s T]; + data1 = data1(T:end); + end + end + end + res.periods_in{m} = s .* dt; + end + if size(data, 2) == 1 + res.periods_in = res.periods_in{m}; + end + res.equilibrium = stable_equilibrium; + end + + % function res = direct_exit(datat, datax, domain) + % %simple way of determining exit time from data or simulations: + % % we first (optionally) apply a moving average to smooth the data set. + % % we then determine the mean exit times based on transitions past a certain + % % threshold + % res.periods_in = []; + % res.domain = domain; + % for m = 1:size(datax, 2) + % higheq = datax(:, m) > domain(1) & datax(:, m) < domain(2); + % shiftsup = datat(diff(higheq) == 1); + % shiftsdown = datat(diff(higheq) == -1); + % period_up = nan(size(shiftsdown)); + % for i = 1:length(shiftsup) + % k = find(shiftsdown > shiftsup(i), 1); + % %we get nan if none is found + % if ~isempty(k) + % period_up(i) = shiftsdown(k) - shiftsup(i); + % end + % end + % res.periods_in = [res.periods_in; period_up]; + % end + % ndx = ~isnan(res.periods_in); + % res.periods_in = res.periods_in(ndx); + % % res.period_down = period_down; + % + % end + + args = struct(varargin{:}); + if ~isfield(args, 'windowsize') + args.windowsize = 1; + end + if ~isfield(args, 'dt') + args.dt = obj.xtra.reconstr.options.dt; + end + if ~isfield(args, 'nreplicates') + args.nreplicates = 100; + end + if ~isfield(args, 'width') + args.width = 0; + end + if ~isfield(args, 'MaxStep') + args.MaxStep = 0.001; + end + if ~isfield(args, 'NonNegative') + args.NonNegative = []; + end + if args.windowsize <= 1 + trend = data(:); + else + trend = movmean(data(:), args.windowsize); + end + % datat = linspace(0, numel(data) * args.dt, numel(data))'; + direct_exits = cell(1, obj.nbasin); + % simul_exits = cell(1, obj.nbasin); + stableeq = find([obj.equilibria.stable]); + res.equilibria = [obj.equilibria(stableeq).x]; + for i1 = 1:length(stableeq) + direct_exits{i1} = SojournTimes(data, args.dt, obj.equilibria(stableeq(i1)), args.width); + %direct_exits{i1} = direct_exit(datat(:), trend, obj.equilibria(stableeq(i1)).domain); + % simul_exits{i1} = direct_exit(simuldatat, simultrend, obj.equilibria(stableeq(i1)).domain); + end + res.dataexits = direct_exits; + %res.simulexits = simul_exits; + + + if ~isfield(args, 'simuldata') + disp('Simulating'); + sizedata = numel(data); + [simuldata, fcn] = obj.simulate( linspace(0, (sizedata - 1) * args.dt, sizedata)', obj.draw_pdf(args.nreplicates, 1), struct('MaxStep', args.MaxStep, 'NonNegative', args.NonNegative)); + res.simuldata = fcn; + simuldatat = simuldata.t; + simuldata = simuldata.y; + if args.windowsize <= 1 + simultrend = simuldata; + else + simultrend = movmean(simuldata, args.windowsize); + end + end + + res.options = args; + datat = linspace(0, numel(data) * args.dt, numel(data))'; + direct_exits = cell(1, obj.nbasin); + simul_exits = cell(1, obj.nbasin); + stableeq = find([obj.equilibria.stable]); + res.equilibria = [obj.equilibria(stableeq).x]; + for i1 = 1:length(stableeq) + direct_exits{i1} = SojournTimes(trend, args.dt, obj.equilibria(stableeq(i1)), args.width); + %direct_exits{i1} = direct_exit(datat(:), trend, obj.equilibria(stableeq(i1)).domain); + simul_exits{i1} = SojournTimes(simultrend, args.dt, obj.equilibria(stableeq(i1)), args.width); + %simul_exits{i1} = direct_exit(simuldatat, simultrend, obj.equilibria(stableeq(i1)).domain); + end + res.dataexits = direct_exits; + res.simulexits = simul_exits; + % figure + % subplot(2, 1, 1) + % stairs(sort(res.simulexits{1}.periods_in), cumsum(sort(res.simulexits{1}.periods_in)) / sum(res.simulexits{1}.periods_in)) + % hold on + % stairs(sort(res.dataexits{1}.periods_in), cumsum(sort(res.dataexits{1}.periods_in)) / sum(res.dataexits{1}.periods_in)) + % subplot(2, 1, 2) + % stairs(sort(res.simulexits{2}.periods_in), cumsum(sort(res.simulexits{2}.periods_in)) / sum(res.simulexits{2}.periods_in)) + % hold on + % stairs(sort(res.dataexits{2}.periods_in), cumsum(sort(res.dataexits{2}.periods_in)) / sum(res.dataexits{2}.periods_in)) + end + + + function res = condition_step_distr(obj, data, varargin) + %one-step (or n-step) conditional distribution + %default nstep=1 + % + function [distr, sizes] = getdistrib(thedata, stepdata, perc) + if nargin < 3 + perc = []; + end + distr = cell(args.bins, 1); + sizes = zeros(args.bins, 1); + bincenters = linspace(args.domain(1), args.domain(2), args.bins); + mesh = linspace(args.domain(1), args.domain(2), args.nmesh); + binsiz = (bincenters(2) - bincenters(1)) / 2; + for l = 1:args.bins + F = nan(size(thedata, 2), args.nmesh); + siz = nan(size(thedata, 2), 1); + for j = 1:size(thedata, 2) + ndx1 = thedata(:, j) > bincenters(l) - binsiz & thedata(:, j) < bincenters(l) + binsiz; + data1 = stepdata(ndx1, j); + siz(j) = length(data1); + if ~isempty(data1) + [F1, ~] = ksdensity(data1(:), mesh); + F(j, :) = F1 ./ (trapz(mesh, F1)); + else + F(j, :) = 0; + end + end + if ~isempty(perc) + distr{l} = quantile(F, perc); + sizes(l) = median(siz); + else + sizes(l) = siz; + distr{l} = F; + end + end + end + args = struct(varargin{:}); + if ~isfield(args, 'bins') + args.bins = obj.xtra.reconstr.options.bins; + end + if ~isfield(args, 'nmesh') + args.nmesh = obj.nx; + end + if ~isfield(args, 'dt') + args.dt = obj.xtra.reconstr.options.dt; + end + if ~isfield(args, 'nreplicates') + args.nreplicates = 100; + end + if ~isfield(args, 'MaxStep') + args.MaxStep = 0.001; + end + if ~isfield(args, 'NonNegative') + args.NonNegative = []; + end + if ~isfield(args, 'nstep') + args.nstep = 1; + end + if ~isfield(args, 'domain') + args.domain = obj.domain; + end + if ~isfield(args, 'percentiles') + args.percentiles = [0.275 0.5 0.975]; + end + data = data(:); + sizedata = size(data, 1); + data1 = data(args.nstep + 1:end); + stepdata = data(1:end - args.nstep); %second row is the time lag + res.bincenters = linspace(args.domain(1), args.domain(2), args.bins); + res.mesh = linspace(args.domain(1), args.domain(2), args.nmesh); + [res.datadistr, res.sizes] = getdistrib(data1, stepdata); + disp('Simulating'); + [simuldata, fcn] = obj.simulate( linspace(0, (sizedata - 1) * args.dt, sizedata)', ... + obj.draw_pdf(args.nreplicates, 1), struct('MaxStep', args.MaxStep, 'NonNegative', args.NonNegative)); + res.simuldata = fcn; + simuldata1 = simuldata.y(args.nstep + 1:end, :); + stepsimuldata = simuldata.y(1:end - args.nstep, :); + res.simuldatadistr = getdistrib(simuldata1, stepsimuldata, args.percentiles); + n1 = 10; + if n1 > args.nreplicates + n1 = args.nreplicates; + end + res.exampledata = simuldata.y(:, 1:n1); %at most ten example data sets + res.options = args; + sumdiff = 0; + sumsiz = sum(res.sizes); + for l = 1:length(res.sizes) + simuldist = res.simuldatadistr{l}; + simuldist = simuldist(2, :); + datadist = res.datadistr{l}; + sumdiff = sumdiff + res.sizes(l) / sumsiz * sum(abs(simuldist - datadist)); + end + res.sumdiff = sumdiff; + end + + function equilibria1 = find_equilibria(obj, mode) + %find the equilibria and basin of attractions + % can be improved as it finds sometimes bubbles + %if mode is 'deterministic' + % the equilibria are just roots of D1 + %if mode is 'effective' (default) + % the effect of D2 is accounted + if nargin == 1 + mode = 'effective'; + end + if strncmpi(mode, 'd', 1) + %naively D1 + d1 = obj.D1; + mode = 'deterministic'; + else + %-derivative of the effective potential (chain rule on log) + if isa(obj.D1, 'chebfun') + d1 = obj.D1 ./ obj.D2 - diff(obj.D2) ./ obj.D2; + else + dd2 = diff_fun(obj.D2); + d1 = @(x)obj.D1(x) ./ obj.D2(x) - dd2(x) ./ obj.D2(x); + end + mode = 'effective'; + end + Eqs = roots_fun(d1, obj.domain); + DD1 = diff_fun(d1); + isstable = DD1(Eqs) < 0; + Eqms = struct('x', {}, 'stable', [], 'BC', [], 'domain', []); + + for i = 1:length(Eqs) + Eqms(i) = struct('x', Eqs(i), 'stable', isstable(i), 'BC', '', 'domain', []); + end + + for i = 1:length(Eqms) + if isstable(i) + BC = 'RR'; + dom = [-Inf Inf]; + if i > 1 + BC(1) = 'A'; + dom(1) = Eqms(i - 1).x; + end + if i < length(Eqms) + BC(2) = 'A'; + dom(2) = Eqms(i + 1).x; + end + Eqms(i).domain = dom; + Eqms(i).BC = BC; + end + end + if nargout == 0 + fprintf('Equilibria (%s):\n', mode) + for i = 1:length(Eqms) + if Eqms(i).stable + stab = ' stable'; + else + stab = 'unstable'; + end + fprintf('%s equilibrium: %g %s %s\n', stab, Eqms(i).x, Eqms(i).BC, mat2str(Eqms(i).domain)); + end + else + equilibria1 = Eqms; + end + end + + function res = odefun(obj, dt) + %creates an ode function to be used in Euler integration + %it can also + L = obj.domain(1); + R = obj.domain(2); + Mesh = linspace(L, R, 1000); + %griddedInterpolant is really fast + d1 = griddedInterpolant(Mesh, obj.D1(Mesh), 'linear'); + d2 = griddedInterpolant(Mesh, obj.D2(Mesh), 'linear'); + %the noise part is multiplied with sqrt(t) and divided by dt, + %in Euler it is multiplied again with dt, so it is a correct Euler Maruyama + % + %if x<L, x=L + %if x>R, x=R + %D1(x) + sqrt(2*dt*D2(x))*randn(1)/dt + res = @(t,y)d1(min(R,max(L,y)))+sqrt(2 .* dt .* d2(min(R,max(L,y)))) .* randn(size(y)) /dt; + end + + function [res, fcn] = simulate(obj, tspan, y0, options) + %simulate - time integration of the Langevin equation using + % Euler-Maruyama + % + % Arguments: + % tspan = time span of the integration or all t values + % y0 = the initial condition (default 0.01). y0 can be a vector, the + % model will then be integrated for each y0 (efficient + % due to vector notation) + % options = a structure with options for the integration, used + % fields: MaxStep (or StepSize) - the step size + % NonNegative - force non-negative see Matlab + % Outputs: + % res struct with the data sets (res.t= time; res.y = data) + % fcn function handle that can reproduce the data (use for + % efficient storage) + % + % + if nargin < 2 + tspan = 1:1000; + end + if nargin < 3 + y0 = 0.01; + end + if nargin < 4 + options = odeset([], 'AbsTol', []); + end + if isfield(options, 'MaxStep') && ~isempty(options.MaxStep) + dt = options.MaxStep; + else + if isfield(options, 'StepSize') && ~isempty(options.StepSize) + dt = options.StepSize; + else + dt = 0.01; + end + end + %the noise part is divided by dt, in Euler it is multiplied + %again, to it is a correct Euler Mayaruma + %save random seed + r1 = rng; + %some prework + odefun = obj.odefun(dt); + options = odeset(options); + options.MaxStep = dt; + fcn = @()simulate_rng(r1,odefun,tspan,y0,options); + %[res.t, res.y] = euler(odefun, tspan, y0, options); + res = fcn(); + end + + + function res = draw_pdf(obj, siz1, siz2) + %draw_pdf - draw random number from the stationary pdf + %use this to get a stabilized initial condition + % + % res=obj.draw_pdf(siz1,siz2) + if ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'pdf') + thepdf = obj.pdf; + else + thepdf = obj.xtra.results.pdf; + end + %make cumulative density function + cdf = cumtrapz(thepdf.x, thepdf.PDF); + if nargin < 2 + siz1 = 1; + end + if nargin < 3 + siz2 = siz1; + end + %interpolate from the inverted cumulative density function + res = interp1(cdf, thepdf.x, rand(siz1, siz2)); + end + + + function n = nbasin(obj) + %number of basins of attraction + n = sum([obj.equilibria.stable]); + end + + function adjusttimescale(obj, ts) + %optionnally you can adjust the time scale of the Langevin + %equation by multiplying D1 and D2 with a factor + if ~isfield(obj.xtra.reconstr, 'ts') + obj.D1 = obj.D1 * ts; + obj.D2 = obj.D2 * ts; + obj.xtra.reconstr.ts = ts; + if isfield(obj.xtra.reconstr, 'D1') + obj.xtra.reconstr.D1 = obj.xtra.reconstr.D1 * ts; + obj.xtra.reconstr.D2 = obj.xtra.reconstr.D2 * ts; + obj.xtra.reconstr.ErrorD1 = obj.xtra.reconstr.ErrorD1 * ts; + obj.xtra.reconstr.ErrorD2 = obj.xtra.reconstr.ErrorD2 * ts; + end + else + error('Timescale was already changed'); + end + end + + function result = potential(obj) + %calculate the potential function + if isempty(obj.D1) || isempty(obj.D2) + error('langevin_eq:nomodel', 'No Langevin equation defined'); + end + if isa(obj.D1, 'chebfun') + result.u = -cumsum(obj.D1); % Clearly, here we do not need to care about time scale change. + else + h = integralx_fun(obj.D1, obj.domain(1), obj.domain(2)); + result.u = @(x)-h(x); + end + result.dom = linspace(obj.domain(1), obj.domain(2), obj.nx); + end + + function result = potential_eff(obj) + %calculate the effective potential. This includes the effects + %of diffusion on the stationary pdf + if isempty(obj.D1) || isempty(obj.D2) + error('langevin_eq:nomodel', 'No Langevin equation defined'); + end + if isa(obj.D1, 'chebfun') + result.ueff = cumsum(-obj.D1 / obj.D2) + log(obj.D2); % Clearly, here we do not need to care about time scale change. + else + h1 = @(x)-obj.D1(x)/obj.D2(x); + h = integralx_fun(h1, obj.domain(1), obj.domain(2)); + result.ueff = @(x)h(x)+log(obj.D2(x)); + end + result.dom = linspace(obj.domain(1), obj.domain(2), obj.nx); + end + + function [hax, res] = plot(obj, varargin) + %plot the results of the analyses, two ways of running: + % 1) use the output of one of the methods as input of plot: + % >> obj.plot(obj.pdf) - to plot the stationary pdf + % 2) use text: (if necessary the analyses is done with default + % parameters) + % for instance: + % >> figure; + % >> obj.plot('D1'); + % + % parameters: + % 'basinprob' plot the probabilities of being in each + % attraction basin vs. time + % 'D1' plot the drift function + % 'D2' plot the diffusion function + % 'DD2' plot the derivative of the diffusion function + % 'equilibria' plot the equilibria in the D1 plot + % 'exit_distrib' plot the probability density function of + % exit times for a certain initial state + % 'exitprob' probability of exit from each boundary in a + % AA boundary condition + % 'mean_exit' mean exit time of the basin + % 'pdf' plot the stationary pdf + % 'potential' potential + % 'potential_eff' effective potential + % 'survival' plot the survival and median exit time + % 'survival_func' plot the survival function for an inital + % state + % 'vertical_basin_boundaries' indicate the basin boundaries + % in the current figure + + + function res = getbootresults(bootstrap) + C = bootstrap.results(1).reconstr.C; + Ts = zeros(numel(bootstrap.results), numel(C)); + WTs = zeros(numel(bootstrap.results), numel(bootstrap.results(1).results.mean_exit)); + for i1 = 1:numel(bootstrap.results) + T = zeros(size(C)); + for j1 = 1:numel(bootstrap.results(i1).results.mean_exit) + me = bootstrap(1).results(i1).results.mean_exit{j1}; + ndx = C >= me.domain(1) & C <= me.domain(2); + WTs(i1, j1) = me.WT; + if isa(me.T, 'chebfun') + T(ndx) = me.T(C(ndx)); + else + T(ndx) = me.T(ndx); + end + end + Ts(i1, :) = T; + end + if ~isfield(bootstrap.options, 'bias') + bias = NaN; + else + bias = bootstrap.options.bias; + end + res = struct('C', C, 'Ts', Ts, 'WTs', WTs, 'CL_WT', quantile(WTs, [0.025, 0.975]), 'CL_Ts', quantile(Ts, [0.025, 0.975]), 'bias', bias); + end + function hax1 = plot_mean_exit(T, domain, WT, acolor, nx) + if isa(T, 'chebfun') + l1 = linspace(min(domain), max(domain), nx); + hax1 = plot(l1, T(l1), [acolor '-'], 'LineWidth', 1.5); + else + l1 = linspace(min(domain), max(domain), numel(T)); + hax1 = plot(l1, T, [acolor '-'], 'LineWidth', 1.5); + end + hold on + if ~isempty(WT) + plot([l1(1), l1(end)], [WT, WT], [acolor '--'], 'LineWidth', 1); + end + end + if isempty(obj.D1) || isempty(obj.D2) + error('langevin_eq:nomodel', 'No Langevin equation defined'); + end + hax1 = []; + res = []; + if nargin == 1 + if isfield(obj.xtra, 'results') + f = fieldnames(obj.xtra.results); + for i = 1:length(f) + res = obj.xtra.results.(f{i}); + if isfield(res, 'figno') + figure(res.figno) + else + figure; + end + obj.plot(res); + end + else + hax1 = obj.plot('D1'); + end + elseif iscell(varargin{1}) + for i = 1:length(varargin{1}) + hax1(i) = obj.plot(varargin{1}{i}, varargin{2:end}); + end + elseif ischar(varargin{1}) + args = varargin(2:end); + switch varargin{1} + case {'D1', 'D2' , 'DD2', 'D4'} + %extra options: + %timescale: simply scales yaxis + %npoints: number of interpolation points + %ylabel: specify the y label + %noboot: true/false suppress plotting of bootstrap + %error: true/false suppress plotting of errors + args = struct(args{:}); + if strcmp(varargin{1}, 'D1') + x = obj.D1; + elseif strcmp(varargin{1}, 'D2') + x = obj.D2; + elseif strcmp(varargin{1}, 'DD2') + if isempty(obj.DD2) + x = diff_fun(obj.D2); + else + x = obj.DD2; + end + elseif strcmp(varargin{1}, 'D4') + x = griddedInterpolant(obj.xtra.reconstr.C, obj.xtra.reconstr.D4, 'spline'); + end + % ploterror=true; + % ts=1; + % args.verticalbar=true; + if ~isfield(args, 'timescale') + args.timescale = 1; + end + if ~isfield(args, 'noboot') + args.noboot = false; + end + if ~isfield(args, 'npoints') + args.npoints = 50; + end + if ~isfield(args, 'ylabel') + if strcmp(varargin{1}, 'D1') + args.ylabel = 'Drift D1'; + elseif strcmp(varargin{1}, 'DD2') + args.ylabel = 'd(D2)/dx'; + else + args.ylabel = 'Diffusion D2'; + end + end + + dom = linspace(obj.domain(1), obj.domain(2), args.npoints); + + if isfield(obj.xtra, 'bootstrap') && ~args.noboot + results = obj.xtra.reconstr; + hold on + %vectorbased fast: + recs = [obj.xtra.bootstrap(1).results(:).reconstr]; + boots = vertcat(recs.(varargin{1})); + range = quantile(boots, [0.025, 0.975]); + fill([results.C , fliplr(results.C)], args.timescale * [range(1, :), fliplr(range(2, :))], [1 0.8 0.8], 'EdgeColor', 'none'); + elseif ~(~isfield(obj.xtra, 'reconstr') || isempty(obj.xtra.reconstr)) && (~isfield(args, 'error') || args.error) + hold on + results = obj.xtra.reconstr; + if strcmp(varargin{1}, 'D1') + %hax1 = errorbar(results.C, results.D1, results.ErrorD1, '.b'); + fill([results.C , fliplr(results.C)], [args.timescale * results.D1 - results.ErrorD1, fliplr(args.timescale * results.D1 + results.ErrorD1)], [1 0.8 0.8], 'EdgeColor', 'none') + elseif strcmp(varargin{1}, 'D2') + fill([results.C , fliplr(results.C)], [args.timescale * results.D2 - results.ErrorD2, fliplr(args.timescale * results.D2 + results.ErrorD2)], [1 0.8 0.8], 'EdgeColor', 'none') + end + end + hax1 = plot(dom, args.timescale .* x(dom), '-r', 'linewidth', 1.5, 'tag', varargin{1}); + xlim(obj.domain); + xlabel(obj.namex); + ylabel(args.ylabel) + if strcmp(varargin{1}, 'D1') + yline(0, 'k-'); + end + if ~isfield(args, 'verticalbar') || args.verticalbar + obj.plot('vertical_basin_boundaries'); + end + % case 'D4' + % %plot the Relative error of the Langevin + % %reconstruction + % if ~isfield(args, 'timescale') + % args.timescale = 1; + % end + % if isfield(obj.xtra, 'bootstrap') + % results = obj.xtra.reconstr; + % hold on + % %boots = zeros(numel(obj.xtra.bootstrap(1).results), numel(results.C)); + % recs = [obj.xtra.bootstrap(1).results(:).reconstr]; + % boots = vertcat(recs.D4); + % % for i = 1:numel(obj.xtra.bootstrap(1).results) + % % boots(i, :) = obj.xtra.bootstrap(1).results(i).reconstr.D4; + % % end + % range = quantile(boots, [0.025, 0.975]); + % fill([results.C , fliplr(results.C)], [range(1, :), fliplr(range(2, :))], [1 0.8 0.8], 'EdgeColor', 'none'); + % end + % hax1 = plot(obj.xtra.reconstr.C, args.timescale .* obj.xtra.reconstr.D4, '-r'); + % hold on + % ylabel('D_{4}') + % xlabel(obj.namex); + case 'vertical_basin_boundaries' + hold on + unstableeqs = find(~[obj.equilibria.stable]); + for i = 1:length(unstableeqs) + try + hax1 = xline(obj.equilibria(unstableeqs(i)).x, 'k--'); + catch + %older versions of matlab do not have xline + ylim1=get(gca,'ylim'); + plot(obj.equilibria(unstableeqs(i)).x + zeros(1, 2), ylim1, 'k--') + end + end + case 'potential_eff' + hax1 = obj.plot(obj.potential_eff, args{:}); + case 'potential' + hax1 = obj.plot(obj.potential, args{:}); + case 'pdf' + if ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'pdf') + obj.pdf; + end + hax1 = obj.plot(obj.xtra.results.pdf); + case 'survival' + hold on + if nargin > 2 || ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'survival') + obj.survival('all', args{:}); + end + hax1 = obj.plot(obj.xtra.results.survival); + case 'basinprob' + if nargin > 2 + result = args{1}; + else + if nargin == 2 && ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'pdfs') + obj.pdfs; + end + result = obj.xtra.results.pdfs; + end + nt = size(result.pdfs, 1); + result.t = result.t(1:nt); + eqs = obj.equilibria([obj.equilibria(:).stable]); + for i = 1:length(eqs) + eqs(i).domain = min(result.x(end), max(result.x(1), eqs(i).domain)); + end + Ps = zeros(nt, length(eqs)); + + for j = 1:length(eqs) + ran = result.x < max(eqs(j).domain) & result.x > min(eqs(j).domain); + for i = 1:nt + Ps(i, j) = trapz(result.x(ran), result.pdfs(i, ran)); + end + end + if ~isempty(Ps) + hax1 = plot(result.t, Ps); + end + xlabel('Time (t)') + ylabel('Probability') + leg = cell(length(eqs), 1); + for j = 1:length(eqs) + leg{j} = sprintf('%s in [%g,%g]', obj.namex, min(eqs(j).domain), max(eqs(j).domain)); + end + legend(leg); + ylim([0, 1]); + xlim([result.t(1), result.t(end)]); + case 'exitprob' %args1 is mean_exit results of AA problem + if nargin > 2 + result = args{1}; + else + if nargin == 2 && ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'mean_exit') + obj.mean_exit; + end + result = obj.xtra.results.mean_exit; + end + if isfield(result, 'T') || isfield(result, 'T_left') %mean exit time + xpoints = linspace(result.domain(1), result.domain(2), length(result.P_left)); + if isfield(result, 'T_left') + if isa(result.P_left, 'chebfun') + plot(xpoints, result.P_left(xpoints), 'b'); + hold on + plot(xpoints, result.P_right(xpoints), 'm'); + else + plot(xpoints, result.P_left, 'b') + hold on + plot(xpoints, result.P_right, 'm'); + end + else + plot(xpoints, ones(size(xpoints)), 'b'); + end + ylim([0 1]) + xlabel(obj.namex) + ylabel('Probability of exit P') + end + case {'survival_func', 'exit_distrib'} %args1 is x0 args2 = survival results + hold on + x0 = args{1}; + if (length(args) < 2) || ~(isstruct(args{2}) || iscell(args{2})) + if isfield(obj.xtra, 'results') && isfield(obj.xtra.results, 'survival') + results = obj.xtra.results.survival; + else + results = obj.survival('all', args{2:end}); + end + else + results = args{2}; + end + if iscell(results) + for i = 1:length(results) + [hax, res1] = obj.plot(varargin{1}, x0, results{i}); + if ~isempty(res1) + res = res1; + end + end + else + if x0 > min(results.x) && x0 < max(results.x) + n = find(results.x >= x0, 1); + surv = results.survival(:, n(1)); + res.surv = surv; + res.t = results.t; + if strcmp(varargin{1}, 'survival_func') + fill([results.t(:); results.t(end); results.t(1)], [surv; 0; 0], [0.75 1 0.75]); + ylim([0 1]); + ylabel('Survival') + end + if strcmp(varargin{1}, 'exit_distrib') + if isa(obj.D1, 'chebfun') + f = chebfun(surv, [results.t(1) results.t(end)], 'equi', 10000); + f = -diff(f); + else + f = @(x)interp1(results.t,surv,x,'spline'); + f1 = diff_fun(f); + f = @(x)-f1(x); + end + res.density = f(results.t); + fill([results.t(:); results.t(end); results.t(1)], [res.density(:); 0; 0], [0.75 1 1]); + ylabel('Density') + ylim([0 Inf]) + end + xlim([min(results.t), max(results.t)]) + xlabel(sprintf('Time %s', obj.timeunit)) + end + end + case 'mean_exit' + hold on + if isempty(args) + args = {'all', obj.pdf}; + end + if isfield(args{1}, 'PDF') + args = [{'all'}, args]; + end + if nargin > 2 || ~isfield(obj.xtra, 'results') || ~isfield(obj.xtra.results, 'mean_exit') + obj.mean_exit(args{:}); + end + if isfield(obj.xtra, 'bootstrap') + %add the bootstrapped percentiles + hold on + res = getbootresults(obj.xtra.bootstrap(1)); + fill([res.C , fliplr(res.C)], [res.CL_Ts(1, :), fliplr(res.CL_Ts(2, :))], [0.75 1 1], 'EdgeColor', 'none'); + % range = quantile(res.WTs(:, [1 2]), [0.025 0.25 0.5 0.75 0.975]); + titl = []; + s = []; + disp(obj.xtra.bootstrap(1).bootmethod); + for i = 1:size(res.WTs, 2) + titl = sprintf('%sCL Basin %d\trelrange %d\t', titl, i, i); + CL = quantile(res.WTs(:, i), [0.025 0.975]); + med = median(res.WTs(:, i)); + s = sprintf('%s[%g %g]\t%g\t', s, CL(1), CL(2), (CL(2) - CL(1)) / med); + end + fprintf('%s\n', titl); + fprintf('%s\n', s); + end + hax1 = obj.plot(obj.xtra.results.mean_exit); + case 'equilibria' + stab = [obj.equilibria([obj.equilibria.stable]).x]; + unstab = [obj.equilibria(~[obj.equilibria.stable]).x]; + plot(stab, zeros(size(stab)), 'ko', 'MarkerSize', 8, 'MarkerFaceColor', 'k'); + hold on + hax1 = plot(unstab, zeros(size(unstab)), 'ko', 'MarkerSize', 8, 'MarkerFaceColor', [1 1 1]); + end + else + result = varargin{1}; + args = struct(varargin{2:end}); + if isfield(result, 'T') || isfield(result, 'T_left') %mean exit time + + if isfield(result, 'T_left') + plot_mean_exit(result.T_left, result.domain, [], 'b', obj.nx); + hold on; + plot_mean_exit(result.T_right, result.domain, [], 'm', obj.nx); + end + hax1 = plot_mean_exit(result.T, result.domain, result.WT, 'g', obj.nx); + xlim(obj.domain); + yl = get(gca, 'ylim'); + if yl(1) < 0 + set(gca, 'ylim', [0 yl(2)]); + end + xlabel(obj.namex); + if isempty(obj.timeunit) + ylabel('Mean exit time T') + else + ylabel(sprintf('Mean exit time T (%s)', obj.timeunit)) + end + if ~isfield(args, 'verticalbar') || args.verticalbar + obj.plot('vertical_basin_boundaries'); + end + elseif isfield(result, 'ueff') %effective potential + U = result.ueff(result.dom); + U = U - min(U) + 0.1 * (max(U) - min(U)); + hax1 = fill([result.dom, result.dom(end), result.dom(1)], [U, 0, 0], [0.75 0.75 1]); + xlim(obj.domain); + xlabel(obj.namex); + ylabel('Effective potential') + if ~isfield(args, 'verticalbar') || args.verticalbar + obj.plot('vertical_basin_boundaries'); + end + elseif isfield(result, 'u') %potential + U = result.u(result.dom); + U = U - min(U) + 0.1 * (max(U) - min(U)); + hax1 = fill([result.dom, result.dom(end), result.dom(1)], [U, 0, 0], [0.75 0.75 1]); + xlim(obj.domain); + xlabel(obj.namex); + ylabel('Potential') + if ~isfield(args, 'verticalbar') || args.verticalbar + obj.plot('vertical_basin_boundaries'); + end + elseif isfield(result, 'PDF') || isfield(result, 'pdfs') %pdf + if isfield(args, 't') + t = args.t; + else + t = result.t(end); + end + hax1 = findobj(get(0, 'currentfigure'), 'tag', 'pdfs'); + if ~isempty(hax1) + updatefig = true; + else + updatefig = false; + end + it = find(result.t >= t, 1); + if isempty(it) + it = length(result.t); + end + + if (it == length(result.t)) && isfield(result, 'PDF') + if updatefig + set(hax1, 'YData', [result.PDF, 0 0]); + else + hax1 = fill([result.x result.x(end) result.x(1)], [result.PDF, 0 0], [0.75 0.75 1]); + end + else + if updatefig + set(hax1, 'YData', [result.pdfs(it, :), 0 0]); + else + hax1 = fill([result.x result.x(end) result.x(1)], [result.pdfs(it, :), 0 0], [0.75 0.75 1]); + end + end + xlim(obj.domain); + xlabel(obj.namex); + if isfield(result, 'PDF') && isempty(args) + ylabel('Stationary density') + else + ylabel('Probability density') + end + set(hax1, 'tag', 'pdfs'); + if ~isfield(args, 'verticalbar') || args.verticalbar + obj.plot('vertical_basin_boundaries'); + end + elseif isfield(result, 'y') %integration + hax = plot(result.t, result.y, 'b-'); + xlabel('Time'); + ylabel(obj.namex); + elseif isfield(result, 'survival') %survival + [x, y] = meshgrid(result.x, result.t); + colormap( [linspace(1, 0.5, 50)', linspace(1, 0.5, 50)', ones(50, 1)]); + [~, hax1] = contourf(x, y, result.survival, 100); + set(hax1, 'LineColor', 'none') + hold on + [~, hax1] = contour(x, y, result.survival, [0.5 0.5]); + set(hax1, 'LineColor', 'k', 'LineWidth', 2) + [~, hax1] = contour(x, y, result.survival, [0.75 0.25]); + set(hax1, 'LineColor', 'b', 'LineWidth', 1) + % [~, hax1] = contour(x, y, result.survival, 1-[0.9:0.001:0.999]); + % set(hax1, 'LineColor', 'g', 'LineWidth', 1) + xlim(obj.domain); + xlabel(obj.namex); + if isempty(obj.timeunit) + ylabel('Survival time') + else + ylabel(sprintf('Survival time (%s)', obj.timeunit)) + end + if ~isfield(args, 'verticalbar') || args.verticalbar + obj.plot('vertical_basin_boundaries'); + end + elseif isfield(result, 'command') + obj.plot(result.command); + end + end + if nargout > 0 + hax = hax1; + end + end + + function res = prob_exit(obj, domain_, BC, options) + % prob_exit (numerically) determines the probability to exit + % left or right + % + % obj.mean_exit(ibasin, PDF, options) + % + % Inputs are: + % + % domain= range of conditions + % BC the boundary value code: + % 'AA' = left and right absorbing + % 'RA' = left reflecting and right absorbing + % 'AR' = left absorbing and right reflecting + % + % options (optional) the boundary value problem options (see + % bvpopt) + additional fields: + % nx = number of points in x direction + % initfunc = function handle describing the initial guess of + % the boundary value problem + % can also be entered as field, value pairs (case sensitive) + % + % Outputs is a structure with fields: + % domain: the domain + % BC: boundary condition + % P_left: the probability of exit from left boundary. + % P_right: the probability of exit from right boundary. + % + function res = getinitfun(domain_, BC) + %initial sine, make sure that the BC are correct + %initfun = @(x)[cos(4 * x), -4 * sin(4 * x) ] ; + starth = 0; + endh = 2 * pi; + if BC(1) == 'R' + %start at pi/2 to have correct BC + starth = starth + pi / 2; + end + if BC(2) == 'R' + %start at pi/2 to have correct BC + endh = endh + pi / 2; + end + per = (endh - starth) / (domain_(2) - domain_(1)); + res = @(x)[cos(per * (x-domain_(1))+starth); -per * sin(per * (x-domain_(1))+starth) ]; + end + res.domain = domain_; + res.BC = BC; + if ~strcmp(BC, 'AA') + if BC(1) == 'R' + res.P_left = 0; + else + res.P_left = 1; + end + if BC(2) == 'R' + res.P_left = 0; + else + res.P_left = 1; + end + else + + if isa(obj.D1, 'chebfun') + d1 = obj.D1; + d1.domain = domain_; + d2 = obj.D2; + d2.domain = domain_; + LP = chebop(domain_); % LP is operator for the probability of exit + LP.op = @(x, P) d1 .* diff(P) + d2 .* diff(P, 2); + LP.lbc = @(P)P - 1; + LP.rbc = @(P)P; + P = LP \ (0); + res.P_left = P; + + LP = chebop(domain_); % LP is operator for the probability of exit + LP.op = @(x, P) d1 .* diff(P) + d2 .* diff(P, 2); + LP.lbc = @(P)P; + LP.rbc = @(P)P - 1; + P = LP \ (0); + + res.P_right = P; + else + % function handle mode + % + %Backward Fokker Planck equation: + %D1(x0)*T'+D2(x0 )*T''=-1 + % + %define: + %T2=T'; + %D1(x0)*T2+D2(x0)*T2'=-1 + % + %yields the following 2D ODE system + %T2'=-(D1(x0)*T2 + 1)/D2(x0) + %T'=T2; + if nargin < 4 + options = []; + end + if ~isfield(options, 'nx') + options.nx = obj.nx; + end + if ~isfield(options, 'RelTol') || isempty(options.RelTol) + options.RelTol = 1E-7; + end + if ~isfield(options, 'AbsTol') || isempty(options.RelTol) + options.RelTol = 1E-6; + end + if ~isfield(options, 'initfun') || isempty(options.initfun) + options.initfun = {getinitfun(domain_, 'AR'), getinitfun(domain_, 'RA')}; + elseif ~iscell(options.initfun) + options.initfun = {options.initfun, options.initfun}; + end + xpoints = linspace(res.domain(1), res.domain(2), options.nx); + %We determine the probabilities of leaving the + %left border with het BVP equation: + %0 = D1(x0) * P' + D2(x0) * P''; + % + %define: + %P2 =P'; + %D1(x0) *P2 + D2(x0) * P2' = 0 + % + %yields the following 2D ODE system + %P'=P2; + %P2'=-(D1(x0)*P2)/D2(x0) + % + odefunP = @(x,P)[P(2,:);-obj.D1(x) .* P(2,:) ./ obj.D2(x) ]; + + %left BC P = 1, right BC P = 0 + BCfunleft = @(ya,yb)[ya(1)-1; yb(1)]; + solinit = bvpinit(xpoints, options.initfun{1}); + %determine the left probabilities + sol = bvp4c(odefunP, BCfunleft, solinit, options); + res.P_left = deval(sol, xpoints); %only if we want to interpolate between the mesh + res.P_left = res.P_left(1, :); + BCfunright = @(ya,yb)[ya(1); yb(1)-1]; + solinit = bvpinit(xpoints, options.initfun{2}); + sol = bvp4c(odefunP, BCfunright, solinit); + res.P_right = deval(sol, xpoints); %only if we want to interpolate between the mesh + res.P_right = res.P_right(1, :); + end + end + end + + function res = mean_exit(obj, ibasin, PDF, varargin) + % mean_exit (numerically) solves the backward Fokker-Planck equation + % and then calculates many quantities. + % + % obj.mean_exit(ibasin, PDF, options) + % + % Inputs are: + % + % ibasin = the number of the basin or 'all' or a struct with + % the fields "domain" and "BC" + % Where domain is the domain and BC the boundary value code: + % 'AA' = left and right absorbing + % 'RA' = left reflecting and right absorbing + % 'AR' = left absorbing and right reflecting + % + % PDF (optional) is a struct describing the stationary probability density + % function or empty, see output of the method "pdf" + % + % options (optional) the boundary value problem options (see + % bvpopt) + additional fields: + % nx = number of points in x direction + % initfunc = function handle describing the initial guess of + % the boundary value problem + % can also be entered as field, value pairs (case sensitive) + % + % Outputs is a structure with fields: + % + % T: is a (chebfun) function which tells us the average time to escape the + % domain (see exit curves in Figures 2,3,5 in the main text). + % WT: is the average time to escape the domain. It implements the calculations of Formula 4 in the main text. + % P: calculates the probability of exit from left or right boundaries. Note that, it only makes sense if + % the boundary conditions are of AAleft or AAright types (we did not use it in this paper). + % + % use obj.plot(res) to plot the results + % + + if nargin < 2 + ibasin = 'all'; + end + if nargin < 3 + PDF = []; + end + if nargin > 4 + options = struct(varargin{:}); + elseif nargin == 4 + options = varargin{1}; + else + options = bvpset; + end + + if ischar(ibasin) && strcmp(ibasin, 'all') + res = cell(1, obj.nbasin); + for i = 1:length(res) + res{i} = obj.mean_exit(i, PDF); + end + obj.xtra.results.mean_exit = res; + return; + end + if isstruct(ibasin) && length(ibasin) > 1 + %if ibasin is a struct with equilibria + %remove basins without BC + ndx = ~cellfun('isempty', {ibasin(:).BC}); + ibasin = ibasin(ndx); + res = cell(1, length(ibasin)); + for i = 1:length(res) + res{i} = obj.mean_exit(ibasin(i), PDF); + end + obj.xtra.results.mean_exit = res; + return; + end + if isstruct(ibasin) + domain2 = ibasin.domain; + domain2(domain2 < obj.domain(1)) = obj.domain(1); + domain2(domain2 > obj.domain(2)) = obj.domain(2); + BC = ibasin.BC; + else + nbasin1 = obj.nbasin; + if ibasin > nbasin1 + error('langevin_eq:mean_exit', 'basin number too large'); + end + stableeq = find([obj.equilibria.stable]); + eqnr = stableeq(ibasin); + domain2 = obj.equilibria(eqnr).domain; + domain2(domain2 < obj.domain(1)) = obj.domain(1); + domain2(domain2 > obj.domain(2)) = obj.domain(2); + BC = obj.equilibria(eqnr).BC; + end + + if ~any(strcmp(BC, {'RA', 'AR', 'AA', 'RR'})) + error('langevin_eq:mean_exit', 'boundary condition "%s" unknown', BC); + end + domain_ = domain2; + res.domain = domain_; + res.BC = BC; + if ~isfield(options, 'initfun') || isempty(options.initfun) + %initial sine, make sure that the BC are correct + %initfun = @(x)[cos(4 * x), -4 * sin(4 * x) ] ; + starth = 0; + endh = 2 * pi; + if BC(1) == 'R' + %start at pi/2 to have correct BC + starth = starth + pi / 2; + end + if BC(2) == 'R' + %start at pi/2 to have correct BC + endh = endh + pi / 2; + end + per = (endh - starth) / (res.domain(2) - res.domain(1)); + % if isa(obj.D1,'chebfun') + % x=chebfun('x'); + % initfunT=[cos(per * (x-res.domain(1))+starth); -per * sin(per * (x-res.domain(1))+starth) ] ; + % else + initfunT = @(x)[cos(per * (x - res.domain(1)) + starth); -per * sin(per * (x - res.domain(1)) + starth) ] ; + % end + %do not add initfun to options, as we use them also for + %prob_exit + else + initfunT = options.initfun; + end + + + if isa(obj.D1, 'chebfun') + if ~isempty(PDF) + if ~isa(PDF, 'chebfun') + PDF = chebfun(PDF.PDF', obj.domain, 'equi', 5000); + end + PDF.domain = domain2; + end + d1 = obj.D1; + d1.domain = domain_; + d2 = obj.D2; + d2.domain = domain_; + %setting up chebop boundary value problem + LL = chebop(domain_); + LL.op = @(x, T) d1 .* diff(T) +d2 .* diff(T, 2); + if BC(1) == 'R' + LL.lbc = @(T)diff(T); + else + LL.lbc = @(T)T; + end + if BC(2) == 'R' + LL.rbc = @(T)diff(T); + else + LL.rbc = @(T)T; + end + %solving T + res.T = solvebvp(LL , -1); + T2 = chebfun(res.T, domain2); + if ~isempty(PDF) + res.WT = sum(PDF * T2) / sum(PDF); + else + res.WT = []; + end + res.P = []; + + if strcmp(BC, 'AA') + res1 = obj.prob_exit(domain_, BC); + LL = chebop(domain_); + LL.op = @(x, T) d1 .* diff(T) + d2 .* diff(T, 2); + LL.lbc = @(T)T; + LL.rbc = @(T)T; + % T = LL \ (-res1.P_left); + [T, sol] = solvebvp(LL , -res1.P_left); + if sol.error > 0.001 + xpoints = linspace(domain_(1), domain_(2), 200); + P_l = griddedInterpolant(xpoints, res1.P_left(xpoints)); + odefunT = @(x,T)[T(2)+zeros(size(x)); -(obj.D1(x) .* T(2) + P_l(x)) ./ obj.D2(x)]; + BCfun = @(ya,yb)[ya(1) yb(1)]; + one = chebfun(1, domain_); + v0 = [one 0 * one]; + T1 = bvp4c(odefunT, BCfun, v0); + res.T_left = chebfun(T1(:, 1) ./ res1.P_left, 'splitting', 'on'); + else + res.T_left = chebfun(T ./ res1.P_left, 'splitting', 'on'); + end + + T2 = chebfun(res.T_left, domain2, 'splitting', 'on'); + if ~isempty(PDF) + res.WT_left = sum(PDF * T2) / sum(PDF); + else + res.WT_left = []; + end + res.P_left = res1.P_left; + + LL = chebop(domain_); + LL.op = @(x, T) d1 .* diff(T) + d2 .* diff(T, 2); + LL.lbc = @(T)T; + LL.rbc = @(T)T; + %T = LL \ (- res1.P_right); + [T, sol] = solvebvp(LL , -res1.P_right); + if sol.error > 0.001 + xpoints = linspace(domain_(1), domain_(2), 200); + P_l = griddedInterpolant(xpoints, res1.P_right(xpoints)); + odefunT = @(x,T)[T(2)+zeros(size(x)); -(obj.D1(x) .* T(2) + P_l(x)) ./ obj.D2(x)]; + BCfun = @(ya,yb)[ya(1) yb(1)]; + one = chebfun(1, domain_); + v0 = [one 0 * one]; + T1 = bvp4c(odefunT, BCfun, v0); + res.T_right = chebfun(T1(:, 1) ./ res1.P_right, 'splitting', 'on'); + else + res.T_right = chebfun(T ./ res1.P_right, 'splitting', 'on'); + end + %plot(T); + + T2 = chebfun(res.T_right, domain2, 'splitting', 'on'); + if ~isempty(PDF) + res.WT_right = []; + else + res.WT_right = sum(PDF * T2) / sum(PDF); + end + res.P_right = res1.P_right; + end + else + % function handle mode + % + %Backward Fokker Planck equation: + %D1(x0)*T'+D2(x0 )*T''=-1 + % + %define: + %T2=T'; + %D1(x0)*T2+D2(x0)*T2'=-1 + % + %yields the following 2D ODE system + %T2'=-(D1(x0)*T2 + 1)/D2(x0) + %T'=T2; + if ~isfield(options, 'nx') + options.nx = obj.nx; + end + if ~isfield(options, 'RelTol') || isempty(options.RelTol) + options.RelTol = 1E-7; + end + if ~isfield(options, 'AbsTol') || isempty(options.RelTol) + options.RelTol = 1E-6; + end + options.Vectorized = 'on'; + xpoints = linspace(res.domain(1), res.domain(2), options.nx); + % + %Reflecting means that T'==0 + %Absorbing means that T==0 + %this BCfun function should return the RESIDUAL + %ya is left yb is right boundary + switch BC + case 'RA' + BCfun = @(ya,yb)[ya(2) yb(1)]; + case 'AR' + BCfun = @(ya,yb)[ya(1) yb(2)]; + case 'AA' + BCfun = @(ya,yb)[ya(1) yb(1)]; + case 'RR' + BCfun = @(ya,yb)[ya(2) yb(2)]; + end + solinit = bvpinit(xpoints, initfunT); + + %The BVP solver returns the structure 'sol'. + %for exit time T(x) + try + odefunT = @(x,y)[y(2,:); -(obj.D1(x) .* y(2,:) + 1) ./ obj.D2(x)]; + sol = bvp4c(odefunT, BCfun, solinit, options); + Tx = deval(sol, xpoints); + catch err + disp(err.message); + Tx = NaN; + end + res.T = Tx(1, :); + if ~isempty(PDF) + pdf = griddedInterpolant(PDF.x, PDF.PDF); + PDF = pdf(xpoints); + res.WT = sum(PDF .* res.T) ./ sum(PDF); + else + res.WT = []; + end + if strcmp(BC, 'AA') + %first we need to determine the probabilities of leaving the + %left border with BVP equation: + res1 = obj.prob_exit(domain_, BC, options); + %mean exit through left: + res.P_left = res1.P_left; + P_l = griddedInterpolant(xpoints, res1.P_left); + odefunT = @(x,T)[T(2,:)+zeros(size(x)); -(obj.D1(x) .* T(2,:) + P_l(x)) ./ obj.D2(x)]; + + sol = bvp4c(odefunT, BCfun, solinit, options); + res.T_left = deval(sol, xpoints); + res.T_left = res.T_left(1, :) ./ res.P_left; + + res.P_right = res1.P_right; + P_r = griddedInterpolant(xpoints, res.P_right); + odefunT = @(x,T)[T(2,:); -(obj.D1(x) .* T(2,:) + P_r(x)) ./ obj.D2(x)]; + sol = bvp4c(odefunT, BCfun, solinit, options); + res.T_right = deval(sol, xpoints); + res.T_right = res.T_right(1, :) ./ res.P_right; + end + end + obj.xtra.results.mean_exit = res; + end + + function result = runpdf(obj, varargin) + % This code (numerically) solves the Fokker-Planck equation. + % + % obj.solvepdf(PDF0,options) + % Inputs are: + % PDF0: is the initial distribution of states (is a chebfun function or function handle + % or a scalar number (Dirichlet delta function is then assumed). + % + % + % options (optional) the pdepe options (see pdepe, for instance RelTol and AbsTol) + % + additional fields: + % maxtime = duration of the simulation + % ntime = number of time outputs (minimal=3) (default 3) + % nx = number of points in x direction (default obj.nx) + % + % can also be entered as field, value pairs (case sensitive) + % + % Output is a structure with fields: + % x = mesh of x values + % t = time output values + % pdfs = pdfs in time + % + result = solvepdf(obj, varargin{:}); + obj.xtra.results.pdfs = result; + end + + + + function result = pdf(obj, pdf0, varargin) + + % This code (numerically) solves the Fokker-Planck equation. + % + % obj.pdf(PDF0,options) + % Inputs are: + % PDF0: is the initial distribution of states (is a chebfun function or function handle + % or a scalar number (Dirichlet delta function is then assumed). + % + % + % options (optional) the pdepe options (see pdepe, for instance RelTol and AbsTol) + % + additional fields: + % maxtime = duration of the simulation + % ntime = number of time outputs (minimal=3) (default 3) + % nx = number of points in x direction (default obj.nx) + % + % can also be entered as field, value pairs (case sensitive) + % + % Output is a structure with fields: + % x = mesh of x values + % t = time output values + % pdfs = all pdfs in time + % PDF = last (stationary) pdf + % + if nargin < 2 + pdf0 = []; + end + if nargin > 3 + options = struct(varargin{:}); + elseif nargin == 3 + options = varargin{1}; + else + options = []; + end + if ~isfield(options, 'maxtime') + options.maxtime = 4000; + end + if ~isfield(options, 'ntime') + options.ntime = 3; + end + result = obj.solvepdf(pdf0, options); + result.PDF = result.pdfs(end, :); + %another way of determining the PDF using the effective + %potential + %integral D1/D2: + if isa(obj.D1, 'chebfun') + try + h2 = 1 / obj.D2 * exp(cumsum(obj.D1 / obj.D2)); + xpoints = linspace(obj.domain(1), obj.domain(2), 4000); + intg = trapz(xpoints, h2(xpoints)); + result.PDF_eq = 1 / obj.D2 * exp(cumsum(obj.D1 / obj.D2)) / intg; + catch + result.PDF_eq = []; + end + else + h1 = @(x)obj.D1(x)./obj.D2(x); + h = integralx_fun(h1, obj.domain(1), obj.domain(2)); + % + %1/D2 * exp(int(D1/D2,x)) + h2 = @(x)1 ./obj.D2(x).*exp(h(x)); + + %normalize to surface = 1 + xpoints = linspace(obj.domain(1), obj.domain(2), 4000); + intg = trapz(xpoints, h2(xpoints)); + %normalized pdf + result.PDF_eq = @(x)1 ./obj.D2(x).*exp(h(x))./intg; + end + obj.xtra.results.pdf = result; + end + + + + + function res = survival(obj, ibasin, varargin) + + % This code (numerically) calculates the survival function (Formula 1 in the main text) of the 'Langevin system' for all initial states. + % You can find full mathematical details in Appendix S3 which is from the following book + % Schuss, Z. Theory and applications of stochastic processes: an analytical approach. Vol. 170 (Springer Science & Business Media, 2009). + % + % Inputs are: + % + % ibasin = the number of the basin or 'all' or a struct with + % the fields "domain" and "BC" + % Where domain is the domain and BC the boundary value code: + % 'AA' = left and right absorbing + % 'RA' = left reflecting and right absorbing + % 'AR' = left absorbing and right reflecting + % + % options (optional) the pdepe options (RelTol and AbsTol for instance) + % + additional fields: + % time_range = range of time + % ntime = number of points for output of time axis + % nx = number of points in x direction + % initfunc = function handle describing the initial + % conditions (default = all 1) + % options can also be entered as field, value pairs (case + % sensitive) + % for instance: + % obj.survival('all','ntime',100,'AbsTol',1E-6) + % + % + % + % IMPORTANT NOTE: + % For a much better accuracy we recommend NOT to use a regular mesh for mesh_time. Instead, we + % recommend to use a chebychev mesh point which has 2^n points. For instance, + % to generate a chebychev mesh point on the interval [0 300] of length 2^16 + % simply type mesh_time=chebpts([0 300],2^15); + % + % Output is: + % structure with fields: + % t = output points in time + % x = meshpoints of x + % survival = output of pdepe + % you can use obj.plot(res) to plot the output structure + % + if nargin < 2 + ibasin = 'all'; + end + if nargin > 3 + options = struct(varargin{:}); + elseif nargin == 3 + options = varargin{1}; + else + options = []; + end + if isnumeric(options) && ~isempty(options) %alternatively you can only give the time_range + options = struct('time_range', options); + end + if ~isfield(options, 'time_range') + options.time_range = []; %empty is automatic (takes an extra run however) + end + if ~isfield(options, 'ntime') + options.ntime = 50; + end + if ~isfield(options, 'nx') + options.nx = obj.nx; + end + %nspace = obj.nx; + if ischar(ibasin) && strcmp(ibasin, 'all') + res = cell(1, obj.nbasin); + for i = 1:length(res) + res{i} = obj.survival(i, options); + end + obj.xtra.results.survival = res; + return; + end + if isstruct(ibasin) + eqn = ibasin; + else + nbasin1 = obj.nbasin; + if ibasin > nbasin1 + error('langevin_eq:survival', 'basin number too large'); + end + stableeq = find([obj.equilibria.stable]); + eqn = obj.equilibria(stableeq(ibasin)); + end + domain_ = eqn.domain; + domain_(domain_ < obj.domain(1)) = obj.domain(1); + domain_(domain_ > obj.domain(2)) = obj.domain(2); + switch eqn.BC + %absorbing = ul,0 (or ur,0) reflecting = 0,1 + case 'AA' + BCfun = @(~, ul, ~, ur, ~)deal(ul, 0 , ur, 0); %"deal" deals the values to the 4 requested outputs + case 'RA' + BCfun = @(~, ~, ~, ur, ~)deal(0, 1, ur, 0); + case 'AR' + BCfun = @(~, ul, ~, ~, ~)deal(ul, 0, 0, 1); + case 'RR' + BCfun = @(~, ~ , ~, ~, ~)deal(0, 1, 0, 1); + otherwise + error('langevin_eq:bc', 'boundary conditions "%s" undefined',eqn.BC); + end + if ~isfield(options, 'Stats') + options.Stats = 'on'; + end + if ~isfield(options, 'RelTol') || isempty(options.RelTol) + options.RelTol = 1E-6; + end + if ~isfield(options, 'AbsTol') || isempty(options.AbsTol) + options.AbsTol = 1E-7; + end + if ~isfield(options, 'initfun') || isempty(options.initfun) + options.initfun = @(x)1; + end + if isempty(obj.DD2) + DD2_ = diff_fun(obj.D2); + else + DD2_ = obj.DD2; + end + %we bind the functions D1 D2 and DD2_ in the anonymous function + if isa(obj.D1, 'chebfun') + %else this is much slower + x = linspace(min(domain_), max(domain_), 100 * options.nx); + d1 = griddedInterpolant(x, obj.D1(x)); + d2 = griddedInterpolant(x, obj.D2(x)); + dd2 = griddedInterpolant(x, DD2_(x)); + surv_equat = @(x,t,u,DuDx)survpde(x, 0, u, DuDx ,d1,d2,dd2); + else + surv_equat = @(x,t,u,DuDx)survpde(x, 0, u, DuDx ,obj.D1, obj.D2, DD2_); + end + m = 0; + if isempty(options.time_range) + options.time_range = [0 50]; + % %do a test run to find a reasonable range for the time + % %(without having too many zeros - does + % %not work very well + % options1=options; + % options1.time_range=[0 1000]; + % options1.ntime = 1000; + % testrun=obj.survival(ibasin,options1); + % meansurv=max(testrun.survival,[],2); + % options.time_range=[0 find(meansurv<0.0001,1)+1]; + end + if length(options.time_range) == 2 + res.t = linspace(options.time_range(1), options.time_range(2), options.ntime)'; + elseif length(options.time_range) == 1 + res.t = linspace(0, options.time_range(1), options.ntime)'; + else + res.t = linspace(0, 1000, options.ntime)'; + end + %res.t = options.time_range; % t = linspace(0,T,N_t); % IMPORTANT: here t is not the usual time we use for IVPs (initial value problems). + %Our problem here is IBVP (initial boundary value problem). Therefore considering only 3 mesh points for t does not work. + res.x = linspace(min(domain_), max(domain_), options.nx); + + % options = odeset('Stats', 'on', 'RelTol', 1e-6, 'AbsTol', 1e-7); + res.survival = pdepe(m, surv_equat, options.initfun, BCfun, res.x, res.t, options); + obj.xtra.results.survival = res; + %u = sol(:, :, 1); + + %S = u(:, :); + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + function [c, f, s] = survpde(x, ~, ~, DuDx, D1, D2, DD2) + %Survival PDE: + %diff(S,t) = D1(x) diff(S(x,t),x) + D2(x)*diff(diff(S(x,t),x),x) + % + %general form for pdepe (see Matlab help) + %>>> c(x,t,u,dudx)*diff(u,t) = x^m * diff(x^m * f(x,t,u,dudx),x) + s(x,t,u,dudx) + %simplify: + %m=0;c=1 + % + %assume f = D2*dSdx + %remember D2 can be dependent on x (multiplicative noise)! + % + %so product rule: diff(D2 * dSdx,x)=D2 * diff(dSdx,x)+DD2 * dSdx + %we only need D2*diff(dSdx,x) so we just subtract DD2*dSdx from the s term + %m=0:c=1: + %diff(u,t) = diff(f(x,t,u,dudx),x) + s(x,t,u,dudx) + %f = D2 * dSdx + %s = D1 * dSdx - DD2 * dSdx + % + c = 1; + f = D2(x) * DuDx; + s = (D1(x) - DD2(x)) * DuDx; + end + + end + + + function set(obj, varargin) + + if nargin > 1 + if ~isstruct(varargin{1}) + args = struct(varargin{:}); + else + args = varargin{1}; + end + end + if isfield(args, 'domain') + obj.domain = args.domain; + if isa(obj.D1, 'chebfun') + obj.D1.domain = obj.domain; + end + if isa(obj.D2, 'chebfun') + obj.D2.domain = obj.domain; + end + end + if isfield(args, 'timeunit') + obj.timeunit = args.timeunit; + end + if isfield(args, 'namex') + obj.namex = args.namex; + end + if isfield(args, 'nx') + obj.nx = args.nx; + end + if isfield(args, 'f') + obj.D1 = obj.set_Dfun(args.f); + end + if isfield(args, 'g') + obj.D2 = obj.set_Dfun(args.g, 'g'); + end + if isfield(args, 'D1') + obj.D1 = obj.set_Dfun(args.D1); + end + if isfield(args, 'D2') + [obj.D2, isconstant] = obj.set_Dfun(args.D2); + if isconstant + % the derivative is zero + obj.DD2 = obj.set_Dfun(0); + end + end + if isfield(args, 'DD2') + obj.DD2 = obj.set_Dfun(args.DD2); + end + if isfield(args, 'equilibria') + obj.equilibria = args.equilibria; + end + if isfield(args, 'nx') + obj.nx = args.nx; + end + end + end +end + +function [tout, yout] = euler(odefunct, tspan, y0, options) + %Euler integration + if (nargin < 4) + %if there are no valid options use default stepsize + delta = 0.01; + options.StepSize = 0.3; + else + %use the option StepSize as step size + if ~isfield(options, 'StepSize') + options.StepSize = options.MaxStep; + end + if isempty(options.StepSize) + options.StepSize = 0.1; + end + delta = options.StepSize; + end + if nargin < 4 + nonNegative = []; + else + nonNegative = odeget(options, 'NonNegative', []); + end + anyNonNegative = ~isempty(nonNegative); + haveOutputFcn = ~isempty(options.OutputFcn); + outputFcn = options.OutputFcn; + if haveOutputFcn + feval(outputFcn, tspan, y0, 'init'); + end + % Test that tspan is internally consistent. + tspan = tspan(:); + ntspan = length(tspan); + if ntspan == 1 + t0 = 0; + next = 1; + else + t0 = tspan(1); + next = 2; + end + tfinal = tspan(ntspan); + if t0 == tfinal + error('euler:tpan', 'The last entry in tspan must be different from the first entry.'); + end + tdir = sign(tfinal - t0); + if any(tdir * (tspan(2:ntspan) - tspan(1:ntspan - 1)) <= 0) + error('euler:tspan', 'The entries in tspan must strictly increase or decrease.'); + end + t = t0; + y = y0(:); + neq = length(y); + %adapt delta if there should be given more output + step_tspan = median(diff(tspan)); + delta = min(delta, step_tspan); + % Set the output flag. + + outflag = ntspan > 2; % output only at tspan points + + % Allocate memory if we're generating output. + delta = delta * tdir; + + if nargout > 0 + if outflag % output only at tspan points + tout = tspan; + outflag = delta ~= step_tspan; + yout = nan(ntspan, neq); + else + tout = transpose(t0:delta:tfinal); + if tout(end) < tfinal %if tfinal cannot divided in delta's + tout(end + 1) = tfinal; + end + + yout = nan(size(tout, 1), neq); + end + nout = 1; + tout(nout) = t; + yout(nout, :) = transpose(y); + end + % + %MAIN LOOP + %evaluate the odefunction for the next time steps + %fold=[]; + running = 1; + while running + f = feval(odefunct, t, y); + % simple Euler + ynew = y + f .* delta; + if anyNonNegative + ynew(nonNegative) = max(ynew(nonNegative), 0); + end + + + tnew = t + delta; + if tnew >= tfinal + running = 0; + end + + if ~outflag % computed points, no refinement only the last value + nout = nout + 1; + if ~running + if nout > length(tout) + nout = length(tout); + end + t1 = tout(nout); + yout(nout, :) = transpose(y + (ynew - y) ./ (tnew - t) .* (t1 - t)); + else + yout(nout, :) = transpose(ynew); + end + tnew = tout(nout); + if haveOutputFcn + if feval(outputFcn, tnew, transpose(ynew), '') + ndx = ~isnan(yout(:, 1)); + yout = yout(ndx, :); + tout = tout(ndx); + running = false; + end + end + elseif (tdir * (tnew - tspan(next)) >= 0) % at tspan, tspan assumed to be larger than delta + nout = nout + 1; + t1 = tout(nout); + y1 = transpose((y + (ynew - y) ./ (tnew - t) .* (t1 - t))); + yout(nout, :) = y1; + next = next + 1; + if haveOutputFcn + if feval(outputFcn, t1, y, '') + ndx = ~isnan(yout(:, 1)); + yout = yout(ndx, :); + tout = tout(ndx); + running = false; + end + end + end + + y = ynew; + t = tnew; + end +end + +function fun = integralx_fun(afun, ystart, xstart) + if isa(afun, 'chebfun') + fun = cumsum(afun); + else + if nargin < 2 + ystart = 0; + end + if nargin < 3 + xstart = 0; + end + h = @(x,t)afun(x); + fun = @(timespan)myode45(h,timespan,ystart,xstart); + end +end + +function y = myode45(h, timespan, t0, x0) + if length(timespan) == 1 + timespan = [t0 timespan]; + [~, y] = ode45(h, timespan, x0); + y = y(end); + else + [~, y] = ode45(h, timespan(:), x0); + if numel(y) < numel(timespan) + y(end + 1:numel(timespan)) = NaN; + end + y = reshape(y, size(timespan)); + end +end + +function fun = diff_fun(afun, dt) + if nargin < 3 + dt = 1E-7; %not too small for rounding errors + end + if isa(afun, 'chebfun') + fun = diff(afun); + elseif isa(afun, 'function_handle') + fun = @(x)(afun(x+dt/2)-afun(x-dt/2))/dt; + else + error('langevin:diff', 'type of function not supported'); + end +end + +function xout = simulate_vector(afun, x) + xout = zeros(size(x)); + for i = 1:numel(x) + xout(i) = afun(x(i)); + end +end + +function rootsx = roots_fun(afun, dom) + if isa(afun, 'chebfun') + rootsx = roots(afun); + else + % find zeros without precision + x = linspace(dom(1), dom(2), 100); + res = afun(x); + ndx = diff(sign(res)) ~= 0; + rootsx = x(ndx); + %adapt with precision + for i = length(rootsx): -1:1 + if isnan(res(i)) + rootsx(i) = []; + else + rootsx(i) = fzero(afun, rootsx(i)); + end + end + end +end + +function res = simulate_rng(randseed, odefun, tspan, y0, options) + rng(randseed) + [res.t, res.y] = euler(odefun, tspan, y0, options); +end + + +% ------------------------------------------------------------------------- diff --git a/sys/sys2/loadlifecells.m b/sys/sys2/loadlifecells.m index 76b14d677b63bb3d24387b539e1eda77becd3e7a..da4fd4c62771a3388cfef6467846d1f1c5c596b9 100644 --- a/sys/sys2/loadlifecells.m +++ b/sys/sys2/loadlifecells.m @@ -2,6 +2,7 @@ % load one of a large number of patterns for Conways Game of Life, that were % compiled by Alan Hensel and others. Downloaded from: % http://www.argentum.freeserve.co.uk/lex_home.htm. +% http://www.radicaleye.com/lifepage/lexicon.html % % (p1) = still life (period 1) % (p4) = period 4 diff --git a/sys/sys2/lyapspect.m b/sys/sys2/lyapspect.m index 3fde21f8ce3c911569a1ed4884d34394f2376947..ac4264a086c2a043c0c4add021a584542a190795 100644 --- a/sys/sys2/lyapspect.m +++ b/sys/sys2/lyapspect.m @@ -26,8 +26,8 @@ % Reference page in Help browser: % <a href="matlab:commands('lyapspect')">commands lyapspect</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function [res] = lyapspect(varargin) %(ndays,step,stepjac) global g_grind t; diff --git a/sys/sys2/makecartesian.m b/sys/sys2/makecartesian.m index a56197951cb444dc07901f16532e8d574e3985b7..e380ad39aa498376185a4688940757e28b7ba1e4 100644 --- a/sys/sys2/makecartesian.m +++ b/sys/sys2/makecartesian.m @@ -32,8 +32,8 @@ % Reference page in Help browser: % <a href="matlab:commands('makecartesian')">commands makecartesian</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function makecartesian(varargin) global g_grind fieldnams = {'radiusvar', 'U1', 'the name of the radius variable (default ''r'')', 'r'; ... diff --git a/sys/sys2/null.m b/sys/sys2/null.m index 7421cf061ca39c7ccb9505f4cac50abd584493b7..c36ad960de1343ce3fafb9b8dced7841b9ad37c3 100644 --- a/sys/sys2/null.m +++ b/sys/sys2/null.m @@ -34,8 +34,8 @@ % Reference page in Help browser: % <a href="matlab:commands('null')">commands null</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function Z = null(varargin) %(npoints, opt, opt2) global g_grind ; diff --git a/sys/sys2/open_matcont_gui.m b/sys/sys2/open_matcont_gui.m index 36b43d701e90491dd638643d8112c626605fccb9..c0b8ba5d8fc882357eef9b93326d490614ec6c3c 100644 --- a/sys/sys2/open_matcont_gui.m +++ b/sys/sys2/open_matcont_gui.m @@ -20,8 +20,8 @@ % Reference page in Help browser: % <a href="matlab:commands('open_matcont_gui')">commands open_matcont_gui</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:42 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function open_matcont_gui(varargin) global g_grind; i_parseargs('', '', '', varargin); diff --git a/sys/sys2/perturb.m b/sys/sys2/perturb.m index 6a2039d34d394328a70dc44a5b4ac78bc47b3be7..789699ea0203e2f68a8980c0de992a863b129dac 100644 --- a/sys/sys2/perturb.m +++ b/sys/sys2/perturb.m @@ -29,8 +29,8 @@ % Reference page in Help browser: % <a href="matlab:commands('perturb')">commands perturb</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function [pert, x] = perturb(varargin) %(dir, persize,u,del) if (nargin > 2) || (nargout > 0) && length(which('perturb', '-all')) > 1 diff --git a/sys/sys2/potential.m b/sys/sys2/potential.m index 2b3698f5c9bed8d390cbd000f340764e422d151e..6f4d4aad85f0a0fbc238215d768ebcccb9ce2233 100644 --- a/sys/sys2/potential.m +++ b/sys/sys2/potential.m @@ -35,8 +35,8 @@ % Reference page in Help browser: % <a href="matlab:commands('potential')">commands potential</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function [xs, pot] = potential(varargin) %(VRange, npoints, only2D) global g_grind; diff --git a/sys/sys2/quasipot.m b/sys/sys2/quasipot.m index 8e87946be60b153c5999e59822798a1161bfdbed..bcdfda8d70ad92a5945c8a5089831121faca87a1 100644 --- a/sys/sys2/quasipot.m +++ b/sys/sys2/quasipot.m @@ -49,8 +49,8 @@ % Reference page in Help browser: % <a href="matlab:commands('quasipot')">commands quasipot</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:38 $ function res = quasipot(varargin) global g_grind g_quasipot; if isempty(g_quasipot) diff --git a/sys/sys2/read_grindversion.m b/sys/sys2/read_grindversion.m new file mode 100644 index 0000000000000000000000000000000000000000..b298ab308c6e0714cf760353b5db33cf347beab2 --- /dev/null +++ b/sys/sys2/read_grindversion.m @@ -0,0 +1,56 @@ + +function str = read_grindversion(url_or_file) + %reads the grind version and file locations from an url or filename + if nargin == 0 + url_or_file = 'http://sparcs-center.org/grindfiles/grindversion.txt'; + end + if strncmp(url_or_file, 'https:', 6) || strncmp(url_or_file, 'http:', 5) + s = webread(url_or_file, weboptions('contenttype', 'text')); + + else + s = evalc(['type ' url_or_file]); + end + s = regexp(s, '[^=\n]*', 'match'); + str = struct(s{:}); + f = fieldnames(str); + for i = 1:length(f) + if strcontains(f{i}, '_url') + % [~, name, ext] = fileparts(str.(f{i})); + % str.([f{i}(1:end - 4) '_file']) = [name ext]; + %for some reason matlab removes \\ while reading url + str.(f{i}) = regexprep(str.(f{i}), 'http:[\/]([^\/].*)', 'http://$1'); + str.(f{i}) = regexprep(str.(f{i}), 'https:[\/]([^\/].*)', 'https://$1'); + end + end + str.current_grind_version = ''; + str.current_grind_build = ''; + str.current_matcont = []; + str.current_matcontm = []; + str.current_coco = []; + if exist('grind.cfg', 'file') + fid = fopen('grind.cfg', 'r'); + lines = textscan(fid, '%s', 'delimiter', '\n', 'whitespace', ''); + lines = lines{1}; + fclose(fid); + lines = regexp(lines, '[^=\n]*', 'match'); + for i = 1:length(lines) + if exist(lines{i}{2}, 'dir') + str.(lines{i}{1}) = lines{i}{2}; + end + end + end + if exist('use', 'file') + fid = fopen('use.m', 'r'); + while ~feof(fid) + line = fgetl(fid); + f = strfind(line, 'Revision:'); + if ~isempty(f) + f1 = strfind(line, '$'); + str.current_grind_version = strtrim(line(f + 9:f1(1) - 1)); + f = strfind(line, 'Date:'); + str.current_grind_build = strtrim(line(f + 5:f1(end) - 1)); + end + end + fclose(fid); + end +end diff --git a/sys/sys2/run_parallel.m b/sys/sys2/run_parallel.m index 26373573a5d304d30ec2e29bbd259af91d09b839..e099b2a345d936ae79225c384a7994dab15f1a52 100644 --- a/sys/sys2/run_parallel.m +++ b/sys/sys2/run_parallel.m @@ -28,8 +28,8 @@ % Reference page in Help browser: % <a href="matlab:commands('run_parallel')">commands run_parallel</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:43 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function res = run_parallel(varargin) function cpar = getpar(j, cpar) if ~isempty(args.parvalues) diff --git a/sys/sys2/stochast_heun.m b/sys/sys2/stochast_heun.m index c0226fd76f20a6e7081b4c2a5a2d57bad62912f7..3f5afa314e305d8e1a45e5fddd9e512b37776d44 100644 --- a/sys/sys2/stochast_heun.m +++ b/sys/sys2/stochast_heun.m @@ -20,8 +20,8 @@ % Reference page in Help browser: % <a href="matlab:commands('stochast_heun')">commands stochast_heun</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function [tout, yout] = stochast_heun(funcs, tspan, y0, options) global g_grind; if ~isa(funcs, 'cell') @@ -47,10 +47,10 @@ function [tout, yout] = stochast_heun(funcs, tspan, y0, options) haveOutputFcn = false; isIto = true; else - nonNegative = odeget(options, 'NonNegative', [], 'fast'); - haveOutputFcn = ~isempty(odeget(options, 'OutputFcn', [], 'fast')); - outputFcn = odeget(options, 'OutputFcn', [], 'fast'); - SDEmethod = odeget(options, 'SDEmethod', [], 'fast'); + nonNegative = odeget(options, 'NonNegative', []); + haveOutputFcn = ~isempty(odeget(options, 'OutputFcn', [])); + outputFcn = odeget(options, 'OutputFcn', []); + SDEmethod = odeget(options, 'SDEmethod', []); if isempty(SDEmethod) isIto = true; else diff --git a/sys/sys2/time.m b/sys/sys2/time.m index cd05267fc5615f955b360548c2aea467816af98c..16938d29e590faf43142c52165a7e8679087c7ac 100644 --- a/sys/sys2/time.m +++ b/sys/sys2/time.m @@ -31,8 +31,8 @@ % Reference page in Help browser: % <a href="matlab:commands('time')">commands time</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function [outmat, leg] = time(varargin) if nargout > 0 [outmat, leg] = i_time(varargin{:}); diff --git a/sys/sys2/val.m b/sys/sys2/val.m index 00699d75040071ea64673666c2459636bbe15fe0..847f84bfdb6de4520041488bdbc7e6bd4fcb19ee 100644 --- a/sys/sys2/val.m +++ b/sys/sys2/val.m @@ -18,8 +18,8 @@ % Reference page in Help browser: % <a href="matlab:commands('val')">commands val</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function v = val(varargin) %(full, atitle) global g_grind g_Y; diff --git a/sys/sys2/z1test.m b/sys/sys2/z1test.m index 37deab988128eed4d4112d6679ff3e5958e738e8..b0b69f869760335044cd6370ab3c3d4d013952e0 100644 --- a/sys/sys2/z1test.m +++ b/sys/sys2/z1test.m @@ -32,8 +32,8 @@ % Reference page in Help browser: % <a href="matlab:commands('z1test')">commands z1test</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:40 $ function results = z1test(x) % This function is adapted from code from Paul Matthews: diff --git a/sys/takens.m b/sys/takens.m index d359ea68a3b76a368483db977a29ed2055fd597e..1952bf41b928103f18299a9043d74a72a9867ac9 100644 --- a/sys/takens.m +++ b/sys/takens.m @@ -15,8 +15,8 @@ % Reference page in Help browser: % <a href="matlab:commands('takens')">commands takens</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function takens(varargin) global g_Y g_t t g_grind; fieldnams = {'timelag', 'n>0', 'time lag for the Takens plot', 1}'; diff --git a/sys/timesens.m b/sys/timesens.m index 0007ed7b688dcf536d8d2ea282350a4c4f399793..b5fd9b5d921c72dd29cab5837f484dafe04196eb 100644 --- a/sys/timesens.m +++ b/sys/timesens.m @@ -42,8 +42,8 @@ % Reference page in Help browser: % <a href="matlab:commands('timesens')">commands timesens</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function [result, vtitles, ptitles] = timesens(varargin) global g_Y g_t t g_grind g_sens g_paranal; %#ok<GVMIS> evalin('base', 'global g_sens'); diff --git a/sys/torus.m b/sys/torus.m index b2f77cde913dcd567a29f347d6eeca75716fbc76..ce17f9a5496af0dad8bd10bd4af41584625c487d 100644 --- a/sys/torus.m +++ b/sys/torus.m @@ -6,6 +6,7 @@ % TORUS PERIOD XSTART - create torus plot with a period of PERIOD steps. The x axis % starts at -XSTART. % TORUS('argname',argvalue,...) - Valid argument <a href="matlab:commands func_args">name-value pairs</a> [with type]: +% 'hax' [general] - handle of the axis to write % 'period' [number>0] - the period of the torus. % 't' [number] - plot till time t, NaN=to end % 'xstart' [number] - the x axis starts at -XSTART @@ -16,13 +17,14 @@ % Reference page in Help browser: % <a href="matlab:commands('torus')">commands torus</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function torus(varargin) %(period,increment) global g_t g_Y t g_grind; fieldnams = {'period', 'n>0', 'the period of the torus.', 365; ... 'xstart', 'n', 'the x axis starts at -XSTART', 1; ... + 'hax', '', 'handle of the axis to write', []; ... 't', 'n', 'plot till time t, NaN=to end', nan}'; args = i_parseargs(fieldnams, 'period,xstart', '', varargin); i_parcheck; @@ -32,7 +34,9 @@ function torus(varargin) if ~isfield(args, 'xstart') args.xstart = 1; end - + if ~isfield(args, 'hax') + args.hax = []; + end N0 = i_initvar; if i_settingschanged(N0) @@ -43,9 +47,13 @@ function torus(varargin) if ~iX.isvar || ~iY.isvar error('GRIND:torus:NoStatevars', 'Error: there are no state variables on the axes, use ax to set the first 2 axes'); end - hfig = i_makefig('torus'); - - hld = ishold; + if isempty(args.hax) + hfig = i_makefig('torus'); + args.hax=gca; + else + hfig=get(args.hax,'parent'); + end + hld = ishold(args.hax); if isfield(args, 't') ft = find(g_t >= args.t); @@ -55,17 +63,17 @@ function torus(varargin) ts = g_t(1:ft, :); Ys = g_Y(1:ft, :); [X1, Y1, Z1] = toruscoord(ts, Ys(:, iX.no), Ys(:, iY.no), args.period, args.xstart); - hh = findobj(gcf, 'tag', 'dataline'); + hh = findobj(hfig, 'tag', 'dataline'); if isempty(hh) [X2, Y2, Z2] = toruscoord(g_t, g_Y(:, iX.no), g_Y(:, iY.no), args.period, args.xstart); plottorus(hfig, X2, Y2, Z2, args); end set(hh, 'XData', X1, 'YData', Y1, 'ZData', Z1); - hh = findobj(gcf, 'tag', 'where'); + hh = findobj(hfig, 'tag', 'where'); if isempty(hh) - hold on - plot3(X1(end), Y1(end), Z1(end), 'ro', 'MarkerFaceColor', 'r', 'tag', 'where'); + hold(args.hax,'on'); + plot3(args.hax,X1(end), Y1(end), Z1(end), 'ro', 'MarkerFaceColor', 'r', 'tag', 'where'); else set(hh, 'XData', X1(end), 'YData', Y1(end), 'ZData', Z1(end)); end @@ -73,38 +81,42 @@ function torus(varargin) end [X1, Y1, Z1] = toruscoord(g_t, g_Y(:, iX.no), g_Y(:, iY.no), args.period, args.xstart); plottorus(hfig, X1, Y1, Z1, args); - if ~hld - hold off; - end us1.period = args.period; us1.increment = args.xstart; set(hfig, 'userdata', us1); addreplaydata(hfig) + if ~hld + hold off; + end end function plottorus(hfig, X1, Y1, Z1, args) global g_grind; - plot3(X1, Y1, Z1, 'tag', 'dataline'); + hax=findobj(hfig,'type','axes'); + if isempty(hax) + hax=gca; + end + plot3(hax,X1, Y1, Z1, 'tag', 'dataline'); i_plotdefaults(hfig); if ~isoctave && verLessThan('matlab', '8.4.0') - set(gca, 'drawmode', 'fast'); + set(hax, 'drawmode', 'fast'); else - set(gca, 'SortMethod', 'depth'); + set(hax, 'SortMethod', 'depth'); end - - hold on; - box off; - lims = max(abs([get(gca, 'xlim'), get(gca, 'ylim')])); - zlim = get(gca, 'zlim'); - plot3([0; 0], [0; 0], get(gca, 'zlim'), 'k') - plot3([0; 0], [ - lims, lims], [zlim(1), zlim(1)], 'k'); - plot3([ -lims, lims], [0; 0], [zlim(1), zlim(1)], 'k'); - xlabel(['sin(t)*' g_grind.xaxis.var]); - ylabel(['cos(t)*' g_grind.xaxis.var]); - zlabel(g_grind.yaxis.var); + hold(hax,'on'); + % hold on; + box(hax,'off'); + lims = max(abs([get(hax, 'xlim'), get(hax, 'ylim')])); + zlim = get(hax, 'zlim'); + plot3(hax,[0; 0], [0; 0], get(hax, 'zlim'), 'k') + plot3(hax,[0; 0], [ - lims, lims], [zlim(1), zlim(1)], 'k'); + plot3(hax,[ -lims, lims], [0; 0], [zlim(1), zlim(1)], 'k'); + xlabel(hax,['sin(t)*' g_grind.xaxis.var]); + ylabel(hax,['cos(t)*' g_grind.xaxis.var]); + zlabel(hax,g_grind.yaxis.var); t1 = 0:0.05:6.5; - plot3(sin(t1) * lims, cos(t1) * lims, zlim(1) * ones(1, length(t1)), 'k'); - plot3(sin(t1) * args.xstart, cos(t1) * args.xstart, zlim(1) * ones(1, length(t1)), 'k'); + plot3(hax,sin(t1) * lims, cos(t1) * lims, zlim(1) * ones(1, length(t1)), 'k'); + plot3(hax,sin(t1) * args.xstart, cos(t1) * args.xstart, zlim(1) * ones(1, length(t1)), 'k'); end function [X1, Y1, Z1] = toruscoord(ts, X, Y, period, xstart) @@ -132,7 +144,7 @@ end function onend(hax,flag) global g_t; - torus('t',g_t(end)); + torus('t',g_t(end),'hax',hax); hh = findobj(hax, 'tag', 'where'); delete(hh); @@ -154,12 +166,15 @@ function onstart(hax) end end function t = replaycallback(hax, avar, relt) - global g_grind; %#ok<GVMIS> + % global g_grind; %#ok<GVMIS> t = []; - if ishandle(hax) && isfield(g_grind, 'viewcells') && isempty(avar) || strcmp(avar, 't') + if ishandle(hax) && strcmp(avar,'t') %|| strcmp(avar, g_paranal.run.pars{1}) ud = get(hax, 'userdata'); + if ~isfield(ud,'replay') + disp(''); + end t = ud.replay.settings.tlim(1) + relt * (ud.replay.settings.tlim(end) - ud.replay.settings.tlim(1)); - torus('t',t); + torus('t',t,'hax',hax); % ser = get(hax, 'children'); % if isfield(ud, 'replay') % i = ud.replay.no; diff --git a/sys/trdet.m b/sys/trdet.m index 7ce74ed5fd175c38e76124461cc34fddd2c8daa9..1415a0378dbf1fe703c0512733b2580ef008c202 100644 --- a/sys/trdet.m +++ b/sys/trdet.m @@ -32,8 +32,8 @@ % Reference page in Help browser: % <a href="matlab:commands('trdet')">commands trdet</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function [res1,htmlres] = trdet(varargin) %(donumerical) global g_grind; diff --git a/sys/upcells.m b/sys/upcells.m index 60facffdcef47e7bd13a45c05cb7f070b9a2257c..a8d059cd2db5997cbb24e9a52b15fb56b469b853 100644 --- a/sys/upcells.m +++ b/sys/upcells.m @@ -16,8 +16,8 @@ % Reference page in Help browser: % <a href="matlab:commands('upcells')">commands upcells</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function result = upcells(N, bordered, aValue) if nargin < 2 bordered = 'neumann'; diff --git a/sys/updategrind.m b/sys/updategrind.m index 301cac6e8ab250738c0a2500ed1bf612879bcde0..774da1b5a1b1312cb328982f7e95f8578d0329ae 100644 --- a/sys/updategrind.m +++ b/sys/updategrind.m @@ -10,8 +10,8 @@ % Reference page in Help browser: % <a href="matlab:commands('updategrind')">commands updategrind</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function updategrind curdir = pwd; try diff --git a/sys/use.m b/sys/use.m index 070d2f9f8f8d3f96d530063c9bcb008c3103c9e1..f33121949114e2544adb70fd80246eb68110e30e 100644 --- a/sys/use.m +++ b/sys/use.m @@ -16,8 +16,8 @@ % Reference page in Help browser: % <a href="matlab:commands('use')">commands use</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function use(varargin) %amodel = []; %if the model name has spaces it can be read as separate arguments diff --git a/sys/varcopy.m b/sys/varcopy.m index 09ed248c8fba5a1bed0284d052901c53151a4489..b1fc561aa879bc37942422fb793f92b008769852 100644 --- a/sys/varcopy.m +++ b/sys/varcopy.m @@ -14,8 +14,8 @@ % Reference page in Help browser: % <a href="matlab:commands('varcopy')">commands varcopy</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function varcopy(A, precision) if nargin == 0 prompt = {'Enter variable:', 'Number of digits to copy:'}; diff --git a/sys/varpaste.m b/sys/varpaste.m index 42a8e3c6cae05b74900e4fed061edceb418ab67c..1abd449ba43209dc63c5b706185cefb32b296657 100644 --- a/sys/varpaste.m +++ b/sys/varpaste.m @@ -34,8 +34,8 @@ % Reference page in Help browser: % <a href="matlab:commands('varpaste')">commands varpaste</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function A = varpaste(varargin) %forcetype, filename) fieldnams = {'class', 'e[n+umeric|ce+ll|ch+ar|string|da+taset|t+able|l+ogical|int8|uint8|int16|uint16|int32|uint32|int64|uint64|si+ngle|do+uble]#E', 'the class of the resulting variable (default=''numeric'')'; ... diff --git a/sys/vector.m b/sys/vector.m index 9726d8c06f754843d87361b607c7ebbf5f7413d9..b6419a97692e0dfbdf9b345e4e860d7821e1b483 100644 --- a/sys/vector.m +++ b/sys/vector.m @@ -20,8 +20,8 @@ % Reference page in Help browser: % <a href="matlab:commands('vector')">commands vector</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function [X1, Y1, Vect1] = vector(varargin) %(igrid, opt, opt2) fieldnams = {'npoints', 'i>0&length(i)<=2', 'size of the grid for the arrows', 20; ... diff --git a/sys/vectplot.m b/sys/vectplot.m index 4bcc3f35b171c4596ce52333b22470c88756fe20..7777c47c52bc05255cae9edd439a60575a393521 100644 --- a/sys/vectplot.m +++ b/sys/vectplot.m @@ -42,8 +42,8 @@ % Reference page in Help browser: % <a href="matlab:commands('vectplot')">commands vectplot</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function vectplot(varargin) %function vectplot(flag, no,xyzax, atype, varargin) global g_grind t g_t g_Y; %#ok<GVMIS> diff --git a/sys/viewcells.m b/sys/viewcells.m index d23018bc441183ac2a284675e7982461dbd81209..8ea711135fa630643ce6039bc24a1b6b28980785 100644 --- a/sys/viewcells.m +++ b/sys/viewcells.m @@ -35,8 +35,8 @@ % Reference page in Help browser: % <a href="matlab:commands('viewcells')">commands viewcells</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:39 $ function viewcells(varargin) global t g_grind g_Y g_t; %#ok<GVMIS> %opengl software diff --git a/sys/vismod.m b/sys/vismod.m index 729563abdbdc655fb48462d853346e3fb65249f2..feba471a129596dce054208d2cdbfb828494460a 100644 --- a/sys/vismod.m +++ b/sys/vismod.m @@ -32,8 +32,8 @@ % Reference page in Help browser: % <a href="matlab:commands('vismod')">commands vismod</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:40 $ function vismod(varargin) global g_grind; %#ok<GVMIS> if ~exist('i_use', 'file') diff --git a/sys/where.m b/sys/where.m index 78253be1bbddab40b8ff860dd9f710d978d95ab0..9f5050147f36ed840f7812683cd4a22ae31d1ce3 100644 --- a/sys/where.m +++ b/sys/where.m @@ -23,8 +23,8 @@ % Reference page in Help browser: % <a href="matlab:commands('where')">commands where</a> -% Copyright 2023 WUR -% Revision: 1.2.1 $ $Date: 30-Aug-2023 17:22:44 $ +% Copyright 2024 WUR +% Revision: 1.2.1 $ $Date: 17-Apr-2024 10:32:40 $ function h1 = where(varargin) %(apen, apen1) global g_Y g_t g_grind t; %#ok<GVMIS>