samer@4
|
1 function x0=iterate(varargin)
|
samer@4
|
2 % iterate - Simulate recursive iteration of a function
|
samer@4
|
3 %
|
samer@4
|
4 % iterate ::
|
samer@4
|
5 % (A=>(A | empty)) ~'function to iterate, can return [] to terminate',
|
samer@4
|
6 % A ~'initial state',
|
samer@4
|
7 % options iterate_timed_options
|
samer@4
|
8 % -> A ~'final state'.
|
samer@4
|
9 %
|
samer@4
|
10 % iterate ::
|
samer@4
|
11 % cell {
|
samer@4
|
12 % (A->(A | empty)) ~'function to iterate, can return [] to terminate',
|
samer@4
|
13 % A ~'initial state'
|
samer@4
|
14 % } ~'iterated system as a cell array',
|
samer@13
|
15 % options iterate_options
|
samer@4
|
16 % -> A ~'final state'.
|
samer@4
|
17 %
|
samer@13
|
18 % iterate_options = {
|
samer@4
|
19 % its :: natural /inf ~'Iteration limit';
|
samer@13
|
20 % quiet :: bool /1 ~'controls verbosity';
|
samer@4
|
21 % pre :: A=>void ~'something to do before each iteration';
|
samer@4
|
22 % post :: A=>void ~'something to do after each iteration';
|
samer@4
|
23 % save :: natural /0 ~'iterations between state saving (0=off)';
|
samer@4
|
24 % id :: string /'iterstate@' ~'name of mat file to save to';
|
samer@13
|
25 % recover :: bool /0 ~'recover from saved state';
|
samer@13
|
26 % drawnow :: bool /1 ~'controls graphics updating';
|
samer@13
|
27 % pause :: natural /0 ~'pause between iterations (in ms) or 1 for indefinite'
|
samer@4
|
28 % }.
|
samer@4
|
29 %
|
samer@4
|
30 % The function must return an empty array to force termination.
|
samer@4
|
31
|
samer@4
|
32 if iscell(varargin{1})
|
samer@4
|
33 [f,x]=varargin{1}{:};
|
samer@37
|
34 varargs=varargin(2:end);
|
samer@4
|
35 else
|
samer@4
|
36 f=varargin{1};
|
samer@4
|
37 x=varargin{2};
|
samer@37
|
38 varargs=varargin(3:end);
|
samer@4
|
39 end
|
samer@4
|
40
|
samer@37
|
41 opts=options('its',inf,'quiet',1,'save',0,'recover',0,'id','iterstate@',varargs{:});
|
samer@4
|
42 pauserfn=pauser(opts);
|
samer@4
|
43 post=isfield(opts,'post');
|
samer@4
|
44 pre=isfield(opts,'pre');
|
samer@4
|
45
|
samer@4
|
46 i=0;
|
samer@4
|
47 if opts.recover
|
samer@4
|
48 if exist([opts.id,'.mat'],'file')
|
samer@4
|
49 fprintf('Attempting to recover from saved state %s.mat\n',opts.id);
|
samer@4
|
50 load(opts.id);
|
samer@4
|
51 fprintf('Continuing from iteration %d\n',i);
|
samer@4
|
52 else
|
samer@4
|
53 fprintf('Recovery file %s.mat does not exist.\n',opts.id);
|
samer@4
|
54 end
|
samer@4
|
55 end
|
samer@4
|
56
|
samer@4
|
57 if ~post && ~pre && opts.quiet && opts.save==0
|
samer@4
|
58 while ~isempty(x) && i<opts.its,
|
samer@4
|
59 i=i+1;
|
samer@4
|
60 x0=x; x=f(x0);
|
samer@4
|
61 pauserfn();
|
samer@4
|
62 end
|
samer@4
|
63 else
|
samer@4
|
64 if opts.save>0
|
samer@4
|
65 fprintf('Will save every %d iterations to %s.mat\n',opts.save,opts.id);
|
samer@4
|
66 end
|
samer@4
|
67
|
samer@4
|
68 if isfinite(opts.its), itformat=sprintf('%%%dd. ',ceil(log10(opts.its)));
|
samer@4
|
69 else itformat='%d. '; end
|
samer@4
|
70
|
samer@4
|
71
|
samer@4
|
72 while ~isempty(x) && i<opts.its,
|
samer@4
|
73 i=i+1;
|
samer@4
|
74 if ~opts.quiet, fprintf(itformat,i); end
|
samer@4
|
75 if pre, opts.pre(x); end
|
samer@4
|
76 x0=x; x=feval(f,x0);
|
samer@4
|
77 if post, opts.post(x); end
|
samer@4
|
78
|
samer@4
|
79 % save state every opts.save iterations
|
samer@4
|
80 if mod(i,opts.save)==0,
|
samer@4
|
81 fprintf('\nsaving at %d.\n',i);
|
samer@4
|
82 save(opts.id,'x','i');
|
samer@4
|
83 end
|
samer@4
|
84 pauserfn();
|
samer@4
|
85 end
|
samer@4
|
86 if opts.save>0,
|
samer@4
|
87 fprintf('Deleting recovery file %s.mat\n',opts.id);
|
samer@4
|
88 delete([opts.id '.mat']);
|
samer@4
|
89 end
|
samer@4
|
90 end
|
samer@4
|
91 if ~isempty(x), x0=x; end
|
samer@4
|
92
|
samer@4
|
93
|
samer@4
|
94
|