KerMor  0.9
Model order reduction for nonlinear dynamical systems and nonlinear approximation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
IterationCompLemmaEstimator.m
Go to the documentation of this file.
1 namespace error{
2 
3 
4 /* (Autoinserted by mtoc++)
5  * This source code has been filtered by the mtoc++ executable,
6  * which generates code that can be processed by the doxygen documentation tool.
7  *
8  * On the other hand, it can neither be interpreted by MATLAB, nor can it be compiled with a C++ compiler.
9  * Except for the comments, the function bodies of your M-file functions are untouched.
10  * Consequently, the FILTER_SOURCE_FILES doxygen switch (default in our Doxyfile.template) will produce
11  * attached source files that are highly readable by humans.
12  *
13  * Additionally, links in the doxygen generated documentation to the source code of functions and class members refer to
14  * the correct locations in the source code browser.
15  * However, the line numbers most likely do not correspond to the line numbers in the original MATLAB source files.
16  */
17 
68  public:
69 
125  public: /* ( Transient ) */
126 
139  private:
140 
141  Ma_norms;
142 
143  c;
149 fIterations = 0;
150 
151  fTDC = true;
152 
153  G;
154 
155  smallz_flag = false;
156 
157 
158  private: /* ( Transient ) */
159 
160  errEst;
170  tstep;
171 
172  lstPreSolve;
173 
174  lstPostSolve;
175 
176 
177  public: /* ( Transient ) */
178 
179  function copy = clone() {
180  copy = error.IterationCompLemmaEstimator;
181  /* ExtraODEDims is set in constructor! */
182  copy = clone@error.BaseCompLemmaEstimator(this, copy);
183  /* Clone local lipschitz function */
184  copy.LocalLipschitzFcn= this.LocalLipschitzFcn.clone;
185  copy.Iterations= this.Iterations;
186  copy.UseTimeDiscreteC= this.UseTimeDiscreteC;
187  copy.Ma_norms= this.Ma_norms;
188  copy.c= this.c;
189  copy.d_iValues= this.d_iValues;
190  copy.errEst= this.errEst;
191  copy.tstep= this.tstep;
192  if ~isempty(copy.ReducedModel)
193  copy.lstPreSolve= addlistener(copy.ReducedModel.ODESolver," PreSolve ",@copy.cbPreSolve);
194  copy.lstPreSolve.Enabled= this.lstPreSolve.Enabled;
195  copy.lstPostSolve= addlistener(copy.ReducedModel.ODESolver," PostSolve ",@copy.cbPostSolve);
196  copy.lstPostSolve.Enabled= this.lstPostSolve.Enabled;
197  end
198  copy.G= this.G;
199  copy.smallz_flag= this.smallz_flag;
200  }
211 
212  offlineComputations@error.BaseCompLemmaEstimator(this, fm);
213 
214  /* Obtain the correct snapshots */
215  f = [];
216  if ~isempty(fm.Approx)
217  f = fm.Approx.Expansion;
218  end
219  if isempty(f)
220  /* This is the also possible case that the full core
221  * function of the system is a KernelExpansion.
222  *
223  * Get centers of full core function */
224  f = fm.System.f.Expansion;
225  end
226  this.c= f.Centers;
227  this.Ma_norms= f.Ma_norms;
228 
229  /* Assign Lipschitz function */
230  lfcn = error.lipfun.ImprovedLocalSecantLipschitz(f.Kernel);
231  /* Pre-Compute bell function xfeats if applicable */
232  [x,X] = Utils.getBoundingBox(this.c.xi);
233  d = norm(X-x);
234  lfcn.precompMaxSecants(d*2,200);
235  this.LocalLipschitzFcn= lfcn;
236  }
248  function prepared = prepareForReducedModel(models.ReducedModel rm) {
249  prepared = prepareForReducedModel@error.BaseCompLemmaEstimator(this, rm);
250 
251  prepared.lstPreSolve= addlistener(rm.ODESolver," PreSolve ",@prepared.cbPreSolve);
252  prepared.lstPostSolve= addlistener(rm.ODESolver," PostSolve ",@prepared.cbPostSolve);
253  prepared.G= rm.G;
254 
255  f = rm.FullModel.Approx;
256  if isempty(f)
257  f = rm.FullModel.System.f;
258  end
259  if f.Expansion.Kernel.IsRBF && ~isempty(rm.V)
260  /* Use the projected centers z_i from the reduces system with x_i = Vz_i in this
261  * case. */
262  hlp = f.project(rm.V, rm.W);
263  prepared.c= hlp.Expansion.Centers;
264  clear hlp;
265  /* The norm is then ||Vz - x_i||_G = ||z-z_i||_V'GV */
266  prepared.G= rm.V^t*(prepared.G*rm.V);
267  /* Set flag for small z state vectors to true */
268  prepared.smallz_flag= true;
269  end
270  }
287  function b = getBeta(colvec xfull,t) {
288 
289  /* Project x variable back to full space if centers are not within the space spanned by V
290  * (indicated by smallz_flag) */
291  x = xfull(1:end-1);
292  if ~this.smallz_flag && ~isempty(this.ReducedModel.V)
293  x = this.ReducedModel.V*x;
294  end
295  di = this.c.xi - repmat(x,1,size(this.c.xi,2));
296  di = sqrt(sum(di.*(this.G*di),1));
297 
298  /* % Normal computations
299  * Standard (worst-) Case */
300  Ct = Inf;
301  /* Time-discrete computation */
302  if this.UseTimeDiscreteC
303  Ct = xfull(end);
304  /* Keep track of distances when iterations are used */
305  elseif this.Iterations > 0
306  this.d_iValues(this.StepNr,:) = di;
307  end
308 
309  /* Check if time and param kernels are used */
310  if (~isempty(this.mu))
311  f = this.ReducedModel.System.f;
312  hlp = this.Ma_norms ...
313  .* f.Expansion.TimeKernel.evaluate(t, this.c.ti) ...
314  .* f.Expansion.ParamKernel.evaluate(this.mu, this.c.mui);
315  else
316  hlp = this.Ma_norms;
317  end
318 
319  b = hlp * this.LocalLipschitzFcn.evaluate(di, Ct)^t;
320  }
332  function clear() {
333  clear@error.BaseCompLemmaEstimator(this);
334  this.d_iValues= [];
335  }
336 
337 
338  function ct = prepareConstants(colvec<double> mu,integer inputidx) {
339 
340  if this.Iterations > 0 && this.UseTimeDiscreteC
341  warning(" Ambiguous configuration. Having Iterations and UseTimeDiscreteC set; preferring UseTimeDiscreteC ");
342  end
343 
344  /* Call superclass method */
345  ct = prepareConstants@error.BaseCompLemmaEstimator(this, mu, inputidx);
346  st = tic;
347  /* Returns the initial error at `t=0` of the integral part. */
348  if isempty(this.lstPreSolve)
349  this.lstPreSolve= addlistener(this.ReducedModel.ODESolver," PreSolve ",@this.cbPreSolve);
350  end
351  this.lstPreSolve.Enabled= true;
352  if isempty(this.lstPostSolve)
353  this.lstPostSolve= addlistener(this.ReducedModel.ODESolver," PostSolve ",@this.cbPostSolve);
354  end
355  this.lstPostSolve.Enabled= true;
356  /* Call ISimConstants update function to compute values that are constant during a
357  * simulation. */
358  this.LocalLipschitzFcn.prepareConstants;
359  ct = ct + toc(st);
360  }
372  function ct = postProcess(colvec<double> x,double t,integer inputidx) {
373  st = tic;
374  this.StateError= x(end,:);
375 
376  /* PreSolve not needed during iterations */
377  this.lstPreSolve.Enabled= false;
378 
379  /* Iteration stuff */
380  if ~this.UseTimeDiscreteC && this.Iterations > 0
381  /* Switch on/off listeners */
382 
383  solver = this.ReducedModel.ODESolver;
384  e0 = this.getE0(this.mu);
385  for it = 1:this.Iterations
386  /* Set time-step counter to one */
387  this.tstep= 1;
388  /* Solve */
389  [~, e] = solver.solve(@this.iterationODEPart, t, e0);
390  end
391  this.StateError= e;
392  end
393 
394  /* PostSolve still needed during iterations */
395  this.lstPostSolve.Enabled= false;
396 
397  ct = postProcess@error.BaseCompLemmaEstimator(this, x, t, inputidx);
398 
399  ct = ct + toc(st);
400  }
414  /* % Getter & Setter */
415  public: /* ( Transient ) */
416 
417 
418 #if 0 //mtoc++: 'set.LocalLipschitzFcn'
419 function LocalLipschitzFcn(value) {
420  if ~isa(value," error.lipfun.Base ")
421  error(" LocalLipschitzFcn must be a error.lipfun.Base subclass. ");
422  end
423  this.LocalLipschitzFcn= value;
424  }
425 
426 #endif
427 
428 
429 
430 #if 0 //mtoc++: 'set.Iterations'
431 function Iterations(value) {
432  if isempty(value)
433  value = 0;
434  elseif ~isscalar(value) || value < 0
435  error(" Iterations value must be a non-negative integer. ");
436  end
437  this.Iterations= value;
438  }
439 
440 #endif
441 
442 
443 
444 #if 0 //mtoc++: 'set.UseTimeDiscreteC'
445 function UseTimeDiscreteC(value) {
446  if isempty(value)
447  value = false;
448  elseif ~islogical(value)
449  error(" The value must be a logical ");
450  end
451  this.UseTimeDiscreteC= value;
452  }
453 
454 #endif
455 
456 
457  private: /* ( Transient ) */
458 
459 
460  function e = iterationODEPart(double t,eold) {
461  idx = this.tstep;
462 
463  if abs(this.EstimationData(1,idx)-t) > 100*eps
464  error(" The ODE solver does not work as required by the iterative scheme. ");
465  end
466 
467  if (~isempty(this.mu))
468  f = this.ReducedModel.System.f;
469  hlp = this.Ma_norms ...
470  .* f.Expansion.TimeKernel.evaluate(t, this.c.ti) ...
471  .* f.Expansion.ParamKernel.evaluate(this.mu, this.c.mui);
472  else
473  hlp = this.Ma_norms;
474  end
475  b = hlp * this.LocalLipschitzFcn.evaluate(...
476  this.d_iValues(idx,:), this.errEst(idx))^t;
477 
478  e = b*eold + this.EstimationData(2,idx);
479 
480  this.EstimationData(3,this.tstep) = b;
481 
482  this.tstep= this.tstep+1;
483  }
497  function cbPreSolve(sender,data) {
498  this.d_iValues= zeros(length(data.Times),size(this.c.xi,2));
499  }
509  function cbPostSolve(sender,data) {
510  this.errEst= data.States(end,:);
511  }
524  public: /* ( Static ) */ /* ( Transient ) */
525 
526  static function errmsg = validModelForEstimator(models.BaseFullModel model) {
527  errmsg = validModelForEstimator@error.BaseCompLemmaEstimator(model);
528  if isempty(errmsg) && ~isempty(model.Approx) && ~isa(model.Approx," dscomponents.ParamTimeKernelCoreFun ")
529  errmsg = " The model "" s approximation function must be a subclass of dscomponents.ParamTimeKernelCoreFun for this error estimator. ";
530  end
531  if isempty(errmsg) && isa(model.System.f," dscomponents.ParamTimeKernelCoreFun ") ...
532  && ~isa(model.System.f.Expansion.Kernel," kernels.BellFunction ")
533  errmsg = " The system "" s kernel must be a kernels.BellFunction for this error estimator. ";
534  end
535  }
547  static function res = test_IterationCompLemmaEstimator() {
548  m = models.synth.KernelTest(10);
549  e = error.IterationCompLemmaEstimator;
550  e.UseTimeDiscreteC= false;
551  e.Iterations= 4;
552 
553  m.ErrorEstimator= e;
554  m.offlineGenerations;
555  r = m.buildReducedModel;
556 
557  r.simulate(r.getRandomParam,[]);
558  e.UseTimeDiscreteC= true;
559  r.simulate(r.getRandomParam,[]);
560 
561  res = true;
562  }
563 
564 
565  /* methods(Static,Access=protected)
566  * function s = loadobj(s)
567  * s = loadobj@error.BaseCompLemmaEstimator(s);
568  * this.lstPreSolve = addlistener(s.ReducedModel.ODESolver,'PreSolve',@s.cbPreSolve);
569  * this.lstPreSolve.Enabled = false;
570  * this.lstPostSolve = addlistener(s.ReducedModel.ODESolver,'PostSolve',@s.cbPostSolve);
571  * this.lstPostSolve.Enabled = false;
572  * end
573  * end */
587 };
588 }
589 
590 
Collection of generally useful functions.
Definition: Utils.m:17
IterationCompLemmaEstimator: A-posteriori error estimator for kernel-based systems using local lipsch...
function offlineComputations(models.BaseFullModel fm)
Overrides the method from BaseEstimator and performs additional computations.
static function errmsg = validModelForEstimator(models.BaseFullModel model)
Validations.
function prepared = prepareForReducedModel(models.ReducedModel rm)
Prepares this estimator for use with a given reduced model. Basically uses the projection matrices an...
BaseCompLemmaEstimator: Base class for error estimators using the comparison lemma formulation...
The base class for any KerMor detailed model.
Definition: BaseFullModel.m:18
models.BaseFullModel FullModel
The full model this reduced model was created from.
Definition: ReducedModel.m:53
models.BaseFirstOrderSystem System
The actual dynamical system used in the model.
Definition: BaseModel.m:102
Iterations
Determines how many postprocessing iterations for the estimator are performed.
logical UseTimeDiscreteC
For the local Lipschitz constant estimation the parameter C can be chosen to equal the error from the...
StateError
The reduction state-space error from the last simulation.
Definition: BaseEstimator.m:82
d_iValues
The values for each integration time-step .
matrix< double > G
The custom scalar product matrix .
Definition: BaseModel.m:132
An integer value.
The KerMor reduced model class.
Definition: ReducedModel.m:18
virtual function ci = evaluate(di, Ct)
Evaluates the local lipschitz estimation function.
function copy = clone()
Creates a deep copy of this estimator instance.
error.lipfun.Base LocalLipschitzFcn
The internal kernel Lipschitz function to use.
static function res = test_IterationCompLemmaEstimator()
matrix< double > V
The matrix that has been used for projection.
Definition: ReducedModel.m:72
function e0 = getE0(colvec< double > mu)
Calls the inner initial error computation strategy.
matrix< double > W
The biorthogonal matrix for V, i.e. .
Definition: ReducedModel.m:85
A boolean value.
solvers.BaseSolver ODESolver
The solver to use for the ODE. Must be an instance of any solvers.BaseSolver subclass.
Definition: BaseModel.m:315
A matlab column vector.
function ct = prepareConstants(colvec< double > mu,integer inputidx)
Return values: ct: The time needed for preprocessing.
function ct = postProcess(colvec< double > x,double t,integer inputidx)
Return values: ct: The time needed for postprocessing.
Base:
Definition: Base.m:19
function b = getBeta(colvec xfull, t)
Compute the local lipschitz constant estimations.
approx.BaseApprox Approx
The approximation method for the CoreFunction.
virtual function copy = clone(target)
The interface method with returns a copy of the current class instance.
#define X(i, j)
EstimationData
matrix containing the values at each time step.
dscomponents.ACoreFun f
The core f function from the dynamical system.
models.ReducedModel ReducedModel
The reduced model associated with the error estimator.
addlistener
Creates a listener for the specified event and assigns a callback function to execute when the event ...
function target = project(V, W, target)
Sets the protected matrices that can be utilized on core function evaluations after projection...
Definition: ACoreFun.m:247
static function [ double bmin , double bmax ] = getBoundingBox(double vectors)
Gets the bounding box for a matrix containing column vectors.
Definition: Utils.m:96