rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
ei_detailed.m
Go to the documentation of this file.
1 function ei_detailed_data = ei_detailed(model, model_data, LU_fnames, params)
2 %function ei_detailed_data = ei_detailed(model, model_data, LU_fnames, params)
3 % constructs a collateral reduced basis and interpolation points for given
4 % operator evaluations.
5 %
6 % This function prepares the empirical interpolation for an arbitrary
7 % sequence of DOF-vectors. The DOF-vectors are expected to be
8 % stored in the file(s) given in 'LU_fnames', which is a cell array of strings
9 % or a string array. The files are expected to contain a single matrix 'LU',
10 % which is a set of columnwise DOF-vectors. Usually the DOF-vectors correspond
11 % to operator evaluations, which are e.g. computed by
13 %
14 % \attention Every field in the returned structure 'ei_detailed_data' is a
15 % cell array, and this function only manipulates entries indexed by
16 % '(params.index, params.time_index)', e.g.
17 % 'ei_detailed_data.QM{params.index, params.time_index}' holds the basis
18 % functions for the empirical interpolation of the operator with the index
19 % 'params.index' for arguments lying in the time slice indexed by
20 % 'params.time_index'. As this function extends data given in 'model_data',
21 % the empirical interpolation can such be computed for different operators
22 % and time slices.
23 %
24 % optional fields of params:
25 % ei_Mmax : integer indicating, when stop is wanted after
26 % reaching the maximum number of collateral RB
27 % vectors (default = inf)
28 % ei_target_error : string which is one of
29 % - 'approx' for L2-projection error,
30 % - 'interpol' for L2-interpolation error or
31 % - 'linfty-interpol' for `L^{\infty}` interpolation error
32 % .
33 % (default = 'approx')
34 % ei_stop_epsilon : interpolation error limit stopping the basis
35 % extension when reached. (Default: 0)
36 % time_index : index of time slice for which the empirical
37 % interpolation information is generated. See
38 % time splitting for details. (default = 1)
39 % index : an operator index that can be associated with
40 % the generated empirical interpolation data.
41 % compute_lebesgue : compute the Lebesgue constant for the
42 % interpolation (default = false)
43 % skip_search : boolean flag indicating whether the search for
44 % new basis vectors shall be skipped after a
45 % time domain split. If set to false, the basis
46 % vectors from the previous CRB step chosen for
47 % this time domain are used. (default = false)
48 %
49 % optional fields of model_data:
50 % time_split_map : a map between a time step index `t \in \{1,
51 % \ldots, model.nt+1\}` and a time slice index
52 % `s \in \{1, \ldots, S_{\max}\}`, where
53 % `S_{\max}` is the number of time slices.
54 % For more details look at documentation of
55 % 'params.LU_fnames'. (default = `t\mapsto 1
56 % ` for all `t`).
57 %
58 % parameters:
59 % LU_fnames : a cell array of strings or an array of strings
60 % of file names relative to rbmatlabtemp(),
61 % where time series of DOF vectors are stored
62 % for which the collateral reduced basis space
63 % shall be trained. Usually, 'LU_fnames' is
64 % generated by ei_operator_collect_files(). The
65 % files should contain an array named 'LU' of
66 % dimension 'dofs x model.nt+1' or
67 % 'dofs x model.nt+1+\#intermediate newton steps'
68 % In the first case, only the vectors 'LU(:,s)'
69 % with 'model_data.time_split_map(s)==params.time_index'
70 % are used for empirical interpolation.
71 % params : a struct containing control parameters for the
72 % empirical interpolation.
73 %
74 % return values:
75 % ei_detailed_data : a struct containing the vectors and matrices
76 % storing all high dimensional data needed for
77 % empirical interpolation, plus some information
78 % on the basis generation. Note, that this might
79 % be an extension the parameter 'model_data'.
80 %
81 % generated fields of ei_detailed_data:
82 % QM: a matrix of columnwise DOF-vectors `q_j` for interpolation
83 % to be used as the colateral basis
84 % TM: a vector for the set of 'magic points' by containing the index
85 % numbers of the corresponding DOF-nodes (In case of piecewise constant
86 % or linear basis-functions, the maxima `x_i` always can be found in a
87 % cell centroid (deg=0) or a node (deg=1).
88 % BM: the corresponding interpolation-matrix of dimension 'Mmax x Mmax',
89 % i.e. interpolation can be done by solving the equation system `B
90 % \sigma = \left(\zeta(x_1), \ldots, \zeta(x_M)\right)` then `Q
91 % \sigma` is the empirical interpolation. Note, that this
92 % reconstruction may not be done in the online phase!
93 % ei_info: structure giving special details on creation:
94 % - 'max_err_sequence': a vector of errors, AFTER the
95 % corresponding new basis vector extension,
96 % - 'extension_filenum': a vector with the filenumbers, from which
97 % the snapshots are selected
98 % - 'extension_filepos': a vector with the relative position of the
99 % snapshot within its file extension_filenum. By the latter two
100 % fields, a unique identification of the selected snapshots is
101 % possible, i.e. a later translation into parameter vectors,
102 % time, etc.
103 % - 'stopped_on_Mmax': flag indicating, whether stop on maximum
104 % 'params.ei_Mmax' is a reason for termination
105 % - 'stopped_on_monotonicity': flag indicating, that there is no
106 % error decrease anymore, which incicates an accuracy problem,
107 % so termination is performed
108 % - 'stopped_on_duplicate_point': flag indicating, that the
109 % empirical interpolation selected the same interpolation point
110 % twice for interpolation, which indicates an accuracy limit
111 % - 'stopped_on_epsilon': flag indicating, that the empirical
112 % interpolation stopped because the interpolation error dropped
113 % below the given limit 'params.ei_stop_epsilon'
114 %
115 %
116 
117 % Bernard Haasdonk 15.8.2007
118 
119 %ei_target_error = 'interpol';
120 
121 
122 grid = model_data.grid;
123 
124 if ~isfield(model_data, 'time_split_map')
125  model_data.time_split_map = [1:model.nt+1; ones(size(1:model.nt+1)) ]';
126 end
127 
128 if ~isfield(params,'time_index')
129  params.time_index = 1;
130 end
131 
132 if ~isfield(params,'ei_target_error')
133  params.ei_target_error = 'approx';
134 end;
135 
136 if ~isfield(params,'ei_stop_epsilon')
137  params.ei_stop_epsilon = 0;
138 end;
139 
140 if ~isfield(params,'skip_search')
141  params.skip_search = false;
142 end
143 
144 %if ~isfield(params,'ei_rel_abs')
145 % params.ei_rel_abs = 'absolute';
146 %end;
147 
148 if ~isfield(params,'ei_Mmax')
149  params.ei_Mmax = inf;
150 end;
151 
152 if ischar(LU_fnames)
153  LU_fnames = {LU_fnames};
154 end;
155 
156 if ~isfield(params,'index')
157  params.index = 1;
158 end
159 
160 if ~isfield(params,'compute_lebesgue')
161  params.compute_lebesgue = false;
162 end
163 
164 pari = params.index;
165 ti = params.time_index;
166 
167 % get weight matrix for inner-product computation
168 W = model.get_inner_product_matrix(model_data);
169 
170 % determine initial size of vectors:
171 Q = zeros(size(W,1),0);
172 T = zeros(0,1);
173 B = zeros(0,0);
174 
175 % initialize RB_info data
176 max_errs = [];
177 extension_filenum = [];
178 extension_filepos = [];
179 
180 m = 0;
181 % difference to ei from literature:
182 % instead of simply first vector and normalization => search worst l2-error
183 % vector
184 if isfield(model_data, 'QM') ...
185  && all( [pari,ti] <= size(model_data.QM) ) ...
186  && size(model_data.QM{pari,ti},2) > 0
187  m = size(model_data.QM{pari,ti},2);
188  if(model.verbose > 0)
189  disp(['Extending collateral reduced basis space of size ', num2str(m), '.']);
190  end
191  if params.skip_search
192  Q = model_data.QM{pari,ti};
193  T = model_data.TM{pari,ti};
194  B = model_data.BM{pari,ti};
195  end
196  tei_info = model_data.ei_info{pari,ti};
197  max_errs = [ Inf; tei_info.max_err_sequence ];
198  extension_filenum = tei_info.extension_filenum;
199  extension_filepos = tei_info.extension_filepos;
200 end
201 
202 continue_loop = 1;
203 stopped_on_Mmax = 0;
204 stopped_on_monotonicity = 0;
205 stopped_on_epsilon = 0;
206 stopped_on_duplicate_point = 0;
207 if params.ei_Mmax < 1
208  continue_loop = 0;
209 end;
210 
211 use_l2_error = 0;
212 if ismember(params.ei_target_error,{'approx','interpol'})
213  disp('using l2-error for ei offline')
214  use_l2_error = 1;
215 else
216  disp('using linfty-error for ei offline')
217 end;
218 
219 
220 while continue_loop
221  m = m+1;
222 
223  disp(['determining ei-basis & magic point ',num2str(m),':']);
224  % for each discrete function in LU
225  % compute best-l2-approximation in current space spanned by Q
226  %
227  % if <u_H,v_H> = u' * W * v (u,v coefficient vectors)
228  % then min_p (u_H - sum p(i) q_i) is minimized by
229  %
230  % p = (Q' W Q)^(-1) Q^T W u
231  %
232  % So compute whole array of p-vectors and resulting approximation Q*p
233 
234  if params.skip_search && m <= length(extension_filenum)
235  tmp = load(fullfile(rbmatlabtemp,LU_fnames{extension_filenum(m)}));
236  if size(tmp.LU, 2) == tmodel.nt+1
237  tslice = tmodel_data.time_split_map(:,2) == tparams.time_index;
238  tslice = tmodel_data.time_split_map(tslice,1);
239  LU = tmp.LU(:,tslice);
240  else
241  LU = tmp.LU;
242  end
243  zeta_M = tmp.LU(:,extension_filepos(m));
244  else
245  if strcmp(params.ei_target_error, 'approx') == 1
246  A = (Q' * W * Q)^(-1) * Q' * W;
247  else
248  A = [];
249  end
250 
251  tmp_max_is = zeros(length(LU_fnames),1);
252  tmp_max_errs = zeros(length(LU_fnames),1);
253  tmp_zeta_M = zeros(grid.nelements,length(LU_fnames));
254  parfor i=1:length(LU_fnames)
255  tmp = load(fullfile(rbmatlabtemp,LU_fnames{i}));
256  tmodel_data = model_data;
257  tmodel = model;
258  tparams = params;
259 
260  if size(tmp.LU, 2) == tmodel.nt+1
261  tslice = tmodel_data.time_split_map(:,2) == tparams.time_index;
262  tslice = tmodel_data.time_split_map(tslice,1);
263  LU = tmp.LU(:,tslice);
264  else
265  LU = tmp.LU;
266  end
267  LUapprox=[];
268  switch tparams.ei_target_error
269  case 'approx' % approximation, i.e. L2-projection error
270  P = A * LU;
271  LUapprox = Q*P;
272  % interpolation, i.e. empirical interpolation error
273  case {'interpol','linfty-interpol'}
274  coeff = B \ LU(T,:);
275  LUapprox = Q * coeff;
276  otherwise
277  error('ei_target_error unknown!')
278  end;
279  % search maximum l2-error
280  if use_l2_error
281  errors = tmodel.l2_error_sequence_algorithm(LU,LUapprox,model_data.W);
282  else % use infty
283  errors = tmodel.linfty_error_sequence_algorithm(LU,LUapprox,[]);
284  end;
285  % choose maximum error-snapshot for CRB extension
286  [tmp_max_err, tmp_max_i] = max(errors);
287  tmp_max_is(i) = tmp_max_i(1);
288  tmp_max_errs(i) = tmp_max_err(1);
289  tmp_zeta_M(:,i) = LU(:,tmp_max_i(1));
290  end;
291 
292 
293  % get largest from filewise extremes
294  [max_err, max_in] = max(tmp_max_errs);
295  disp(['detected maximum error for extension: ',num2str(max_err(1))]);
296  max_errs = [max_errs; max_err(1)];
297  zeta_M = tmp_zeta_M(:,max_in(1));
298  extension_filenum = [extension_filenum; max_in(1)];
299  extension_filepos = [extension_filepos; tmp_max_is(max_in(1))];
300 
301  end
302 
303  r_M = zeta_M;
304 
305  if (m > 1) % compute interpolant
306  zeta_M_part = zeta_M(T); % get target values in interpolation points
307  %sigma = bicgstab(B,zeta_M_part,[],1000); % get interpolation
308  %coefficients
309  sigma = B \ zeta_M_part;
310  r_M = zeta_M - Q * sigma; % compute residual
311  if model.verbose > 1
312  disp(['positive minus negative contributions of residual (should be zero:)', num2str(sum(r_M))]);
313  disp(['positive minus negative contributions of zeta_M (should be zero:)', num2str(sum(zeta_M))]);
314  end
315  if(sum(r_M)>1e-4)
316  keyboard;
317  end
318  end;
319  [max_r, t_M] = max(abs(r_M));
320  t_M = find(abs(r_M) >= max_r - 1e-12,1);
321  if ~isempty(find(t_M(1)==T, 1))
322  disp('empirical interpolation selected magic point twice!!');
323  stopped_on_duplicate_point = 1;
324  continue_loop = 0;
325 
326  elseif (length(max_errs)>1) && (max_errs(end)>max_errs(end-1)) ...
327  && isequal(params.ei_target_error,'approx')
328  % check that l2-error sequence is decreasing in case of
329  % approximation error (interpol-error can be
330  % non-monotonic...). If not: accuracy
331  % problem and interpolation should be stopped
332  % stop empirical interpolation due to accuracy limit
333  disp('ei detected accuracy limit, loop is stopped.')
334  continue_loop = 0;
335  stopped_on_monotonicity = 1;
336  elseif (length(max_errs) > 1) && (max_errs(end) < params.ei_stop_epsilon)
337  disp('ei detected accuracy limit, loop is stopped.')
338  continue_loop = 0;
339  stopped_on_epsilon = 1;
340  else
341  q_M = r_M/r_M(t_M(1)); % then sign is respected short version
342  % (after verifying zero-1 structure...)
343  % B = [B, zeros(m-1,1) ; ...
344  % Q(t_M,:), 1 ]; % interpolation matrix mit B(i,j) = q_j(t_i)
345  % T = [T; t_M]; % new vector of interpolation DOFs
346  % Q = [Q, q_M]; % new matrix of basis functions
347  B = [B, q_M(T) ; ...
348  Q(t_M,:), q_M(t_M) ]; % interpolation matrix mit B(i,j) = q_j(t_i)
349  T = [T; t_M]; % new vector of interpolation DOFs
350  Q = [Q, q_M]; % new matrix of basis functions
351  if model.verbose > 1
352  disp(['positive minus negative contributions of new basis function (should be zero:)', num2str(sum(q_M))]);
353  end
354  end;
355 
356  if params.ei_Mmax <= length(T)
357  disp('ei reached prescribed number of CRB-vectors, loop is stopped')
358  continue_loop = 0;
359  stopped_on_Mmax = 1;
360  end;
361 end; % loop
362 
363 A = (Q' * W * Q)^(-1) * Q' * W;
364 
365 % determine final error
366 tmp_max_errs = zeros(1, length(LU_fnames));
367 parfor i=1:length(LU_fnames)
368  tmodel = model;
369  tmp = load(fullfile(rbmatlabtemp,LU_fnames{i}));
370  tmodel_data = model_data;
371  tparams = params;
372 
373  tslice = tmodel_data.time_split_map(:,2) == tparams.time_index;
374  tslice = tmodel_data.time_split_map(tslice,1);
375  LU = tmp.LU(:,tslice);
376  LUapprox = [];
377  switch params.ei_target_error
378  case 'approx' % approximation, i.e. L2-projection error
379  P = A * LU;
380  LUapprox = Q * P;
381  case {'interpol','linfty-interpol'} % L2-/Linfty-interpolation error
382  coeff = B \ LU(T,:);
383  LUapprox = Q * coeff;
384  otherwise
385  error('ei_target_error unknown!')
386  end;
387 
388  % search maximum l2- or linfty error
389  if use_l2_error
390  tmp_errors = tmodel.l2_error_sequence_algorithm(LU,LUapprox,model_data.W);
391  % choose maximum l2error-snapshot for CRB extension
392  else % use linfty_error
393  tmp_errors = tmodel.linfty_error_sequence_algorithm(LU,LUapprox,[]);
394  end;
395  [tmp_max_err, tmp_max_i] = max(tmp_errors);
396  tmp_max_errs(i) = tmp_max_err;
397 end;
398 
399 max_err = max(tmp_max_errs);
400 
401 %params.title = 'Interpolation basis functions q_m';
402 %plot_element_data_sequence(grid,Q,params);
403 %disp(['Interpolation matrix B should have lower-triangular structure,' ...
404 % 'one-diagonal:']);
405 %disp(B);
406 %u = zeros(grid.nelements,1);
407 %u(T) = 1;
408 %plot_element_data(grid,u,params);
409 %title('Interpolation points/DOFS');
410 %keyboard;
411 
412 % return results
413 ei_detailed_data = model_data;
414 if ~isfield(ei_detailed_data,'QM')
415  ei_detailed_data.QM = cell(1,1);
416  ei_detailed_data.TM = cell(1,1);
417  ei_detailed_data.BM = cell(1,1);
418  ei_detailed_data.ei_info = cell(1,1);
419 end
420 
421 ei_detailed_data.QM{pari,ti} = Q;
422 ei_detailed_data.TM{pari,ti} = T;
423 ei_detailed_data.BM{pari,ti} = B;
424 ei_detailed_data.ei_info{pari,ti} = [];
425 ei_detailed_data.ei_info{pari,ti}.max_err_sequence = [max_errs(2:end); max_err];
426 ei_detailed_data.ei_info{pari,ti}.extension_filenum = extension_filenum;
427 ei_detailed_data.ei_info{pari,ti}.extension_filepos = extension_filepos;
428 ei_detailed_data.ei_info{pari,ti}.stopped_on_monotonicity = stopped_on_monotonicity;
429 ei_detailed_data.ei_info{pari,ti}.stopped_on_epsilon = stopped_on_epsilon;
430 ei_detailed_data.ei_info{pari,ti}.stopped_on_Mmax = stopped_on_Mmax;
431 ei_detailed_data.ei_info{pari,ti}.ei_stopped_on_duplicate_point = ...
432  stopped_on_duplicate_point;
433 if params.compute_lebesgue
434  XI = Q / B;
435  ei_detailed_data.ei_info{pari,ti}.lebesgue = max(sum(abs(XI),2));
436  ei_detailed_data.ei_info{pari,ti}.max_lebesgue = 2^length(T) - 1;
437 end
438 
function r = verbose(level, message, messageId)
This function displays messages depending on a message-id and/or a level. Aditionally you can set/res...
Definition: verbose.m:17
function ei_detailed_data = ei_detailed(model, model_data, LU_fnames, params)
constructs a collateral reduced basis and interpolation points for given operator evaluations...
Definition: ei_detailed.m:17
function LU_fnames = ei_operator_collect_files(model, model_data, Mtrain, params)
collects operator evaluations on a sample of snapshots
function [ descr , rdescr , dmodel , rmodel ] = newton(steps, combined, M_by_N_ratio, noof_ei_extensions, use_laplacian, model_size, random, num_cpus, Mstrich)
small script demonstrating a buckley leverett problem discretization and RB model reduction ...
Definition: newton.m:17