-
Notifications
You must be signed in to change notification settings - Fork 34
/
sdeprint.m
303 lines (266 loc) · 10.4 KB
/
sdeprint.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
function status=sdeprint(t,y,flag,w)
%SDEPRINT Command window printing SDE output function.
% When the function SDEPRINT is passed to an SDE solver as the 'OutputFUN'
% property, i.e., OPTIONS = SDESET('OutputFUN',@SDEPRINT), the solver calls
% SDEPRINT(T,Y,'') after every timestep. The SDEPRINT function prints the
% components of the solution, Y, as they are computed. If more than 16
% components are specified, an abreviated output is given. To print only
% particular components of the solution, specify their indices via the
% 'OutputYSelect' SDE options property.
%
% At the start of integration, the solver calls SDEPRINT(TSPAN,Y0,'init') to
% initialize the output function. After each integration step to new time, T,
% and solution vector, Y, the solver calls STATUS = SDEPRINT(T,Y,''). If the
% solver's 'Refine' property is greater than one (see SDESET), T is the most
% recent output time and Y is the corresponding column vector. The STATUS
% return value is 1. When the integration is complete, the solver calls
% SDEPRINT([],[],'done').
%
% Set the 'OutputWSelect' SDE options property to 'yes' or to a vector of
% indices to output the integrated Wiener increments, W. The integrated Wiener
% increments are passed to SDEPRINT as a fourth argument, SDEPRINT(T,Y,'',W).
% If the 'OutputWSelect' property is set to 'yes' or a non-empty vector of
% indices the solver calls SDEPRINT(TSPAN,Y0,'init',W0) to initialize the
% output function at the start of integration and SDEPRINT([],[],'done',[])
% when the integration is complete.
%
% The display format of the printed output can be changed via FORMAT.
%
% See also:
% SDEPLOT, SDEPHASEPLOT2, SDEPHASEPLOT3, SDEIMGPLOT, SDESET, SDEGET,
% SDE_EULER, SDE_MILSTEIN, SDE_BM, SDE_GBM, SDE_OU, ODEPRINT, FORMAT
% SDEPRINT is based on an updating of Matlab's ODEPRINT, version 1.17.4.4
% Andrew D. Horchler, horchler @ gmail . com, 5-11-13
% Revision: 1.2, 5-13-13
persistent LEN_TSPAN ITERATION STR BSSTR FSTR C; %#ok<PUSE>
status = 1; % Figure widow still open and and plot axis still present
isW = (nargin > 3); % Have integrated Wiener increments been passed
if nargin < 3
flag = '';
end
bs = char(8); % '\b', backspace character to overwrite previous line
id = '|'; % Progress bar indicator
switch flag
case 'init'
% Number of time samples to expect
LEN_TSPAN = length(t);
% Number of solution variables, Y (cannot change)
N = length(y);
% Allocate blank array for output text, char(10) is '\n'
sp = ' ';
ln = [sp(ones(60,1));10];
if isW
% Number of integrated Wiener increment variables, W (cannot change)
D = length(w);
STR = ln(:,ones(1,min(max(N,D),17)+5));
else
STR = ln(:,ones(1,min(N,17)+5));
end
% Get output format
isDouble = isa(y,'double');
switch get(0,'format')
case 'short'
FSTR = '% -.5g';
case 'long'
if isDouble
FSTR = '% -.15g';
else
FSTR = '% -.7g';
end
case 'shorte'
FSTR = '% -.5d';
case 'longe'
if isDouble
FSTR = '% -.15d';
else
FSTR = '% -.7d';
end
case 'shortg'
FSTR = '% -.5g';
case 'longg'
if isDouble
FSTR = '% -.15g';
else
FSTR = '% -.7g';
end
case 'shorteng'
FSTR = '% -.5e';
case 'longeng'
if isDouble
FSTR = '% -.15e';
else
FSTR = '% -.7e';
end
otherwise
FSTR = '% -.15g';
end
strout = STR;
% Progress bar
strout(1,2) = '[';
strout(end-9:end-2,2) = '] 0.0%';
% Time
tout = sprintf([' T = ' FSTR],t(1));
strout(1:length(tout),4) = tout;
% Step number
ITERATION = 0;
tout = sprintf(' Step = %d',ITERATION);
strout(31:30+length(tout),4) = tout;
% Divider
strout(1:end-2,5) = '-';
% Y
if N >= 1
yout = sprintf([' Y = ' FSTR],y(1));
strout(1:length(yout),6) = yout;
if N > 1
ystr = [' ' FSTR];
if N > 16
for i = 2:15
yout = sprintf(ystr,y(i));
strout(1:length(yout),5+i) = yout;
end
strout(1:9,21) = ' ...';
yout = sprintf(ystr,y(end));
strout(1:length(yout),22) = yout;
else
for i = 2:N
yout = sprintf(ystr,y(i));
strout(1:length(yout),5+i) = yout;
end
end
end
offset = 30;
else
offset = 0;
end
% W
if isW && D >= 1
wout = sprintf([' W = ' FSTR],w(1));
strout(offset+1:offset+length(wout),6) = wout;
if D > 1
wstr = [' ' FSTR];
if D > 16
for i = 2:15
wout = sprintf(wstr,w(i));
strout(offset+1:offset+length(wout),5+i) = wout;
end
strout(offset+1:offset+9,21) = ' ...';
wout = sprintf(wstr,w(end));
strout(offset+1:offset+length(wout),22) = wout;
else
for i = 2:D
wout = sprintf(wstr,w(i));
strout(offset+1:offset+length(wout),5+i) = wout;
end
end
end
end
% Print text, pass as string to handle '%' and '\n' characters
nchars = fprintf(1,'%s',strout(:));
% Allocate array of backspace characters to be used to overwrite text
BSSTR = bs(ones(nchars,1));
% Get and set state of lastwarn so warning can be caught
[lastmsg,lastid] = lastwarn('','SDETools:sdeprint:CatchWarning');
% Persistent cleanup function to ensure lastwarn reset to original state
C = onCleanup(@()lastwarn(lastmsg,lastid));
case ''
if isempty(LEN_TSPAN) || isempty(STR)
if isW
error('SDETools:sdeprint:NotCalledWithInitW',...
['Output function has not been initialized. Use syntax '...
'OutputFUN(TSPAN,Y0,''init'',W0).']);
else
error('SDETools:sdeprint:NotCalledWithInit',...
['Output function has not been initialized. Use syntax '...
'OutputFUN(TSPAN,Y0,''init'').']);
end
end
% Blank out previous data with spaces
strout = STR;
% Progress bar
ITERATION = ITERATION+1;
pct = ITERATION/LEN_TSPAN;
idout = ['[';id(ones(min(round(51*pct),51),1))];
strout(1:length(idout),2) = idout;
strout(end-9:end-2,2) = '] %';
pctout = sprintf('%.1f',100*pct);
strout(end-2-length(pctout):end-3,2) = pctout;
% Time
tout = sprintf([' T = ' FSTR],t(end));
strout(1:length(tout),4) = tout;
% Step number
tout = sprintf(' Step = %d',ITERATION);
strout(31:30+length(tout),4) = tout;
% Divider
strout(1:end-2,5) = '-';
% Y
N = length(y);
if N >= 1
yout = sprintf([' Y = ' FSTR],y(1,end));
strout(1:length(yout),6) = yout;
if N > 1
ystr = [' ' FSTR];
if N > 16
for i = 2:15
yout = sprintf(ystr,y(i,end));
strout(1:length(yout),5+i) = yout;
end
strout(1:9,21) = ' ...';
yout = sprintf(ystr,y(end,end));
strout(1:length(yout),22) = yout;
else
for i = 2:N
yout = sprintf(ystr,y(i,end));
strout(1:length(yout),5+i) = yout;
end
end
end
offset = 30;
else
offset = 0;
end
% W
if isW
D = length(w);
if D >= 1
wout = sprintf([' W = ' FSTR],w(1,end));
strout(offset+1:offset+length(wout),6) = wout;
if D > 1
wstr = [' ' FSTR];
if D > 16
for i = 2:15
wout = sprintf(wstr,w(i,end));
strout(offset+1:offset+length(wout),5+i) = wout;
end
strout(offset+1:offset+9,21) = ' ...';
wout = sprintf(wstr,w(end,end));
strout(offset+1:offset+length(wout),22) = wout;
else
for i = 2:D
wout = sprintf(wstr,w(i,end));
strout(offset+1:offset+length(wout),5+i) = wout;
end
end
end
end
end
% Catch warnings so they are not overwritten
[msg,msgid] = lastwarn; %#ok<*ASGLU>
if ~strcmp(msgid,'SDETools:sdeprint:CatchWarning')
% Reset state of lastwarn
lastwarn('','SDETools:sdeprint:CatchWarning');
% Empty backspace array so warning(s) not overwritten
bsout = [];
else
% Backspace array to overwrite previous text
bsout = BSSTR;
end
% Simultaneously overwrite (backspace) previous text and print new text
fprintf(1,'%s',[bsout;strout(:)]);
case 'done'
if ~isempty(LEN_TSPAN) && ~isempty(STR)
fprintf(1,'\n');
end
otherwise
error('SDETools:sdeprint:InvalidFlag',...
'Invalid status flag passed to output function.');
end