rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
Algorithm.m
1 classdef Algorithm < Greedy.Interface
2  % default greedy basis generation class
3  %
4  % This implements an abstract version of the default greedy algorithm for
5  % reduced basis and empirical interpolation basis generation. The actual
6  % implementation of the extension and checking and error evaluation routines
7  % is delegated to an underlying object implementing a Greedy.Plugin.Interface. See
8  % \ref basisgen for example usage information.
9  %
10  % The entry point for the greedy algorithm is the method basis_extension().
11  % See there for more details on the algorithm
12 
13  properties(Constant)
14  % cell array of fields to be copied to the detailed data leaf node instance
15  % during init_basis().
16  info_fields = { 'M_train', 'M_validation', ...
17  'stop_epsilon', 'stop_max_val_train_ratio', ...
18  'val_train_ratio_seq_for_break', ...
19  'stop_timeout' };
20  end
21 
22  properties(Dependent)
23  % an object of type SnapshotsGenerator.Cached
24  %
25  % This object is inherited from the #detailed_extension.
26  detailed_gen;
27  end
28 
29  properties(SetAccess=private, Dependent)
31  %
33  generated_basis_type;
34 
36  %
37  % @copydoc Greedy.Interface.id
38  id;
39  end
40 
41  properties(SetAccess = private)
42  % object of type Greedy.Plugin.Interface
43  detailed_extension;
44  end
45 
46  properties
47 
48  % double specifying the maximum error indicator for which the basis
49  % generation shall be stopped.
50  stop_epsilon = 1e-2;
51 
52  % integer specifying the number of seconds after which the basis generation
53  % shall be stopped.
54  stop_timeout = inf;
55 
56  % positive double value specifying the maximum ratio between the maximum
57  % error indicator over the validation paramter set and the maximum error
58  % over the trainining parameter set, for which the basis generation is
59  % stopped.
60  %
61  % Note, that #M_validation needs to be non-empty, if this value is set to
62  % something different than 'inf'.
63  stop_max_val_train_ratio = inf;
64 
65  % number of subsequent cases where the max_err_val_train_ratio is too high
66  % that is needed in order to break with a
67  % Greedy.Info.Base.stop_max_val_train_ratio condition.
68  %
69  % The default is '1', but especially for basis generation with
70  % Greedy.Plugin.PODEI extension algorithm, it is a good idea to set it to
71  % at least '2', because this algorithms can produce very strange basis
72  % spaces in between.
73  %
74  val_train_ratio_seq_for_break = 1;
75 
76  % object of type ParameterSampling.Interface defining the training parameter set
77  % `M_{\text{train}} \subset \cal M`
78  M_train = ParameterSampling.Uniform(1);
79 
80  % object of type ParameterSampling.Interface defining the validation parameter set
81  % `M_{\text{val}} \subset \cal M`
82  M_validation = [];
83  end
84 
85  methods
86  function bgd = Algorithm(detailed_extension, M_train, initial_val_param_set)
87  % constructor for a greedy basis generation algorithm
88  %
89  % This constructs a greedy basis generation algorithm using the following
90  %
91  % Parameters:
92  % detailed_extension: the underlying object of type Greedy.Plugin.Interface.
93  % M_train: an object of type ParameterSampling.Interface specifying an initial
94  % training parameter set.
95  % initial_val_param_set: an object of type ParameterSampling.Interface specifying an initial
96  % validation parameter set.
97  if nargin >=2
98  bgd.M_train = M_train;
99  end
100  if nargin >= 3
101  bgd.M_validation = initial_val_param_set;
102  end
103  bgd.detailed_extension = detailed_extension;
104  end
105 
106  function enabled = enable_validation(this, detailed_data)
107  % function enabled = enable_validation(this, detailed_data)
108  % indicates whether the validation routines shall be executed
109  %
110  % This method returns true when a validation parameter set is given and the
111  % property #stop_max_val_train_ratio is not set to 'inf'
112  %
113  % Parameters:
114  % detailed_data: of type .Greedy.DataTree.Detailed.ILeafNode
115  %
116  % Return values:
117  % enabled: boolean value
118  enabled = ~isempty(detailed_data) && ~isempty(get_field(detailed_data, 'M_validation')) ...
119  && ~isinf(get_field(detailed_data, 'stop_max_val_train_ratio'));
120  end
121 
122  function btype = get.generated_basis_type(this)
123  btype = this.detailed_extension.generated_basis_type;
124  end
126  function detailed_gen = get.detailed_gen(this)
127  detailed_gen = this.detailed_extension.generator;
128  end
129 
130  function id = get.id(this)
131  id = this.detailed_extension.id;
132  end
133 
134  function detailed_data_tree = basis_extension(this, rmodel, detailed_data_tree, checkpoint)
135  % function detailed_data_tree = basis_extension(this, rmodel, detailed_data_tree, checkpoint)
136  % greedy basis generation extension
137  %
138  % @pre If required by the @ref Greedy.Plugin.Interface.error_indicators()
139  % "error_indicators()" routine, the method prepare() should have been
140  % called beforehand
141  % @pre The argument 'detailed_data_tree' should be initialized via by the
142  % init_basis() method.
143  %
144  % During each extension step, the methods from the underlying #detailed_extension
145  % are called in this order:
146  % -# The maximum error indicators are gather by calling
147  % @ref Greedy.Plugin.Interface.error_indicators() "error_indicators()"
148  % for the training set parameters, and if existent also vor the
149  % validation set parameters.
150  % -# Before the actual basis extension, we check whether any termination
151  % condition has been reached by computing some default checks
152  % documented below and extension specific checks in
153  % @ref Greedy.Plugin.Interface.pre_check_for_end() "pre_check_for_end()".
154  % -# For the worst approximated parameter a basis extension call is
155  % initiated by calling the method
156  % @ref Greedy.Plugin.Interface.basis_extension() "basis_extension()".
157  %
158  % Default checks:
159  % By default this methods checks
160  % - whether maximum value for the error indicator dropped below the
161  % value of 'get_field(detailed_data, ''''stop_epsilon'''')',
162  % - whether the timeout barrier #stop_timeout has been reached, or
163  % - whether the ratio between the maximum error indicators over the
164  % training set and the validation set exceeds the barrier of
165  % 'get_field(detailed_data, ''''stop_max_val_train_ratio'''')'
166  %
167  % Parameters:
168  % detailed_data_tree: either a struct containing high dimensional model data
169  % needed to execute detailed simulations or an object
170  % of type Greedy.DataTree.Detailed.INode in case of resume from a
171  % checkpoint.
172  % checkpoint: object of type Greedy.Checkpoint specifying a given point in the
173  % algorithm where it basis generation can be resumed.
174  %
175  % Return values:
176  % detailed_data_tree: object of type Greedy.DataTree.Detailed.INode storing the
177  % reduced basis information in the leaf nodes and
178  % information on the reduced basis generation in every
179  % node.
180 
181  if nargin == 3 || isempty(checkpoint)
182  checkpoint = Greedy.Checkpoint;
183  end
184 
185  basetoc = get(checkpoint, 'toc', 0);
186  % prepare(this, rmodel, detailed_data_tree);
187 
188  alltimer = tic;
190  dd_leaf = get_active_leaf(detailed_data_tree, rmodel);
191  cur_M_train = get_field(dd_leaf, 'M_train');
192  cur_M_validation = get_field(dd_leaf, 'M_validation');
193 
194  % ATTENTION: We assume, that prepare has been called beforehand,
195  % if necessary.
196  % prepare(this, rmodel, detailed_data_tree);
197 
198  while true
199 
200  steptic = tic;
201 
202  rmodel.M = get_ei_size(detailed_data_tree);
203  rmodel.N = get_rb_size(detailed_data_tree);
204 
205  fprintf('\n========================================================\n');
206  disp(['Extended reduced bases to size N = ',...
207  num2str(rmodel.N),...
208  ', M = ', num2str(rmodel.M), '.']);
209 
210  disp(['Computing ', num2str(size(cur_M_train.sample,1)),...
211  ' error indicators for basis extension:']);
212  [errs, max_err_seq, muind] = error_indicators(this,...
213  rmodel,...
214  detailed_data_tree,...
215  cur_M_train.sample);
216  fprintf('\n');
217  this.pretty_print_errs('Error sequence: ', errs);
218 
219  if enable_validation(this, dd_leaf)
220 
221  disp(['Computing ', num2str(size(cur_M_validation.sample,1)),...
222  ' error indicators for validating basis extension:']);
223  val_errs = error_indicators(this,...
224  rmodel,...
225  detailed_data_tree,...
226  cur_M_validation.sample,...
227  true);
228 
229  r_value = max(val_errs) / max(errs);
230  disp(['Max validation/training ratio: ', num2str(r_value)]);
231  append_field(dd_leaf, 'r_value_sequence', r_value);
232  end
233 
234  Greedy.Algorithm.push_back_extension_info(dd_leaf, errs, muind, max_err_seq);
235  if pre_check_for_end_meta(this, rmodel, detailed_data_tree, toc(alltimer)+basetoc);
236  set_field(dd_leaf, 'M_last_errors', errs);
237  break;
238  end
239 
240  mu = cur_M_train.sample(muind,:);
241  disp(['Choosing mu = ', num2str(mu(:)'), ...
242  ' for basis extension (error = ', num2str(max(errs)), ')']);
243 
244  detailed_data_tree = basis_extension( this.detailed_extension,...
245  rmodel,...
246  detailed_data_tree,...
247  max_err_seq, mu );
248 
249  % re-read dd_leaf, because basis extension algorithm is allowed to change the pointer
250  dd_leaf = get_active_leaf(detailed_data_tree, rmodel);
251 
252  rmodel.N = get_rb_size(detailed_data_tree);
253  rmodel.M = get_ei_size(detailed_data_tree);
254 
255  %! \todo check whether we should add another line
256  % errs = error_indicators(this, rmodel, this.detailed_gen, detailed_data);
257  % and do the validation afterwards!
258 
259  append_field(dd_leaf, 'toc_value_sequence', toc(steptic));
260 
261  checkpoint = checkpoint.store(rmodel, detailed_data_tree,...
262  'greedy_extension', ...
263  struct('toc', toc(alltimer)+basetoc));
264 
265  end
266 
267  detailed_data_tree = finalize(this.detailed_extension, rmodel, detailed_data_tree);
268  end
269 
270  function [max_errs, max_err_sequence, max_mu_index] = error_indicators(this, rmodel, detailed_data_tree, parameter_set, reuse_reduced_data)
271  % function [max_errs, max_err_sequence, max_mu_index] = error_indicators(this, rmodel, detailed_data_tree, parameter_set, reuse_reduced_data)
272  % routine computing the error indicators
273  %
274  % Parameters:
275  % detailed_data_tree: an object of type GreedyDataTreeDetailed.INode storing the
276  % reduced basis functions in the leaf nodes.
277  % parameter_set: A matrix of dimension
278  % `\text{npar} \times \dim(\cal M)` containing in
279  % each row a parameter vector for which the error
280  % indicator should be computed.
281  % reuse_reduced_data: boolean flat indicating whether it is necessary to
282  % recompute the reduced data or whether it should
283  % still be valid since the last call to
284  % error_indicators().
285  %
286  % Return values:
287  % max_errs: For transient problems this returns the error sequence over
288  % time for the parameter 'max_mu_index' with the worst error.
289  % max_err_sequence: a vector of the same length as the number of training
290  % set parameters, contining the maximum error in the
291  % error sequence over time for each of those
292  % parameters.
293  % max_mu_index: the parameter index of the parameter `\mu_{\max}` in
294  % the training set.
295  if nargin < 5
296  reuse_reduced_data = false;
297  end
298  if nargin < 4
299  parameter_set = [];
300  end
301  [max_errs, max_err_sequence, max_mu_index] = error_indicators(this.detailed_extension, rmodel, detailed_data_tree, parameter_set, reuse_reduced_data);
302  end
303 
304  % initialization routine for basis extension
305  %
306  % This method is run by the gen_detailed_data() method before the execution
307  % of the init_basis() methods and should is used for preparation purposes of
308  % - the training and validation parameter sample and
309  % - caching detailed simulations if necessary for error_indicators()
310  % computations.
311  function prepare(this, rmodel, model_data)
312  dmodel = rmodel.detailed_model;
313  if init_required(this.M_train)
314  init_sample(this.M_train, rmodel);
315  end
316 
317  if isa(model_data, 'Greedy.DataTree.Detailed.INode')
318  dd_leaf = get_active_leaf(model_data, rmodel);
319  else
320  dd_leaf = [];
321  end
322 
323  validation_enabled = false;
324  if enable_validation(this, dd_leaf)
325  Msamples = get_field(dd_leaf, 'M_validation');
326  validation_enabled = true;
327  elseif isempty(dd_leaf) && ~isempty(this.M_validation) && ~isinf(this.stop_max_val_train_ratio)
328  Msamples = this.M_validation;
329  validation_enabled = true;
330  end
331  if validation_enabled && init_required(Msamples)
332  init_sample(Msamples, rmodel);
333  end
334 
335  if this.detailed_extension.needs_preparation
336  if isa(model_data, 'Greedy.DataTree.Detailed.INode')
337  detailed_data = model_data;
338  model_data = detailed_data.model_data;
339  end
340 
341  prepare(this.detailed_gen, dmodel, model_data, this.M_train.sample);
342 
343  % prepare validation set if existent
344  if validation_enabled
345  prepare(this.detailed_gen, dmodel, model_data, Msamples.sample);
346  end
347  end
348  end
349 
350  function detailed_data_tree = init_basis(this, rmodel, model_data)
351  % function detailed_data_tree = init_basis(this, model_data)
352  % @copybrief GreedyInterface.init_basis()
353  %
354  % @copydoc GreedyInterface.init_basis()
355  %
356  % Parameters:
357  % rmodel: of type Greedy.User.IReducedModel
358  if isa(model_data, 'Greedy.DataTree.Detailed.INode')
359  this.M_train = get_field_on_active_child(model_data, 'M_train', rmodel);
360  end
361  M = this.M_train.sample;
362  detailed_data_tree = init_basis(this.detailed_extension, rmodel, model_data, M);
363  leaf_descrs = get_active_leaf_description(detailed_data_tree, rmodel);
364  for leaf_descr = leaf_descrs
365  detailed_data_leaf = get(detailed_data_tree, leaf_descr.basepath);
366 
367  if isempty(get_field(detailed_data_leaf, Greedy.Algorithm.info_fields{1}, []))
368  set_fields(detailed_data_leaf, this, Greedy.Algorithm.info_fields);
369  end
370  end
371  end
372 
373  end
374 
375  methods (Access=private)
376  function breakcondition = pre_check_for_end_meta(this, rmodel, detailed_data_tree, time)
377 
378  dd_leaf = get_active_leaf(detailed_data_tree, rmodel);
379 
380  breakcondition = false;
381  max_err_sequence = get_field(dd_leaf, 'max_err_sequence');
382  if max_err_sequence(end) < get_field(dd_leaf, 'stop_epsilon')
383  set_stop_flag(dd_leaf, 'stopped_on_epsilon');
384  breakcondition = true;
385  elseif time > this.stop_timeout
386  set_stop_flag(dd_leaf, 'stopped_on_timeout');
387  breakcondition = true;
388  end
389  if enable_validation(this, dd_leaf)
390  val_seq_for_break = get_field(dd_leaf, 'val_train_ratio_seq_for_break');
391  r_values = get_field(dd_leaf, 'r_value_sequence');
392  minindex = min(val_seq_for_break, length(r_values))-1;
393  if all(r_values(end-minindex:end) > get_field(dd_leaf, 'stop_max_val_train_ratio'))
394  set_stop_flag(dd_leaf, 'stopped_on_max_val_train_ratio');
395  breakcondition = true;
396  end
397  end
398  if ~breakcondition
399  breakcondition = pre_check_for_end(this.detailed_extension, rmodel, detailed_data_tree);
400  end
401  set_field(detailed_data_tree, 'elapsed_time', time);
402 
403  end
404  end
405 
406  methods (Access = private, Static)
407  function pretty_print_errs(title, errs)
408  nerrs = length(errs);
409  rows = floor(nerrs/6);
410  resherrs = reshape(errs(1:rows*6), rows, 6);
411  resterrs = errs(rows*6+1:end);
412  format = '%1.4e ';
413  disp(char(title, num2str(resherrs, format), num2str(resterrs(:)', format)));
414  end
415 
416  function push_back_extension_info(detailed_data, errs, muind, max_err_seq)
417 
418  append_field(detailed_data, 'max_err_sequence', max(errs));
419  append_field(detailed_data, 'errs_sequence', {errs});
420  append_field(detailed_data, 'mu_ind_sequence', muind);
421  cur_M_train = get_field(detailed_data, 'M_train');
422  append_field(detailed_data, 'mu_sequence', cur_M_train.sample(muind,:)');
423  set_field(detailed_data, 'M_last_errors', errs);
424 
425  [dummy, maxt] = max(max_err_seq);
426  append_field(detailed_data, 'max_time_index_sequence', maxt);
427  end
428  end
429 
430 
431 end
Interface class for all kind of reduced basis generation algorithms
Definition: Interface.m:18
id
This is an id string inherited by the underlying extension algorithm object implementing a Greedy...
Definition: Interface.m:51
virtual function [ breakloop , reason ] = pre_check_for_end(Greedy.User.IReducedModel rmodel,Greedy.User.IDetailedData detailed_data)
checks whether the basis generation process has come to an end.
Interface class for extension algorithms which define the basis extension routines used by the abstra...
Definition: Interface.m:19
Greedy.Plugin.Interface implementation that extends in each basis extension step, the reduced basis space and/or the collateral reduced basis space(s).
Definition: PODEI.m:19
Helper class used to store and restore data tree objects at specified checkpoints.
Definition: Checkpoint.m:18
Interface for the storage and generation of detailed data that can be used to build reduced basis fun...
Definition: Cached.m:18
virtual function [ max_errs , max_err_sequence , max_mu_index ] = error_indicators(Greedy.User.IReducedModel rmodel,Greedy.User.IDetailedData detailed_data, parameter_set, reuse_reduced_data)
computes error indicators for the reduced simulations for every parameter vector from a given paramet...
default greedy basis generation class
Definition: Algorithm.m:18
Parameter sampling sets.
Definition: Interface.m:1
Definition: leaf.m:17
Parameter sampling class with uniformly distributed parameters in the parameter space.
Definition: Uniform.m:18
id
string identifier for this generator
Definition: Cached.m:56
Interface for parameter sampling classes producing discrete parameter sample in the parameter space ...
Definition: Interface.m:18
Specialization plugins for the greedy algorithm.
Definition: Default.m:2
generated_basis_type
string specifying the detailed data produced by this basis generation algorithm object.
Definition: Interface.m:32
Cacheable generators of detailed data snapshots.
Definition: Cached.m:1
virtual function Greedy.User.IDetailedData detailed_data = basis_extension(Greedy.User.IReducedModel rmodel,Greedy.User.IDetailedData detailed_data, max_err_seq, mu)
extends the reduced basis space from a given function .
This is the interface for a reduced model providing methods to compute low dimensional reduced simula...
Definition: IReducedModel.m:17
Interface class for general data tree nodes storing detailed data returned by Greedy.Interface.gen_detailed_data()
Definition: INode.m:20
Customizable implementation of an abstract greedy algorithm.
Definition: DuneRBLeafNode.m:1