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
DEIM.m
Go to the documentation of this file.
1 namespace general{
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 
18 class DEIM
19  :public KerMorObject,
20  public general.AProjectable,
58  public: /* ( setObservable ) */
59 
79  public: /* ( Dependent ) */
80 
100  public:
101 
120  protected:
121 
150  private:
151 
152  rowvec<integer> fOrder = "[]";
163  public:
164 
205 
206 
207  M1;
208 
209  M2;
210 
211 
212  public:
213 
242  public:
243 
245 
246  this.f= f;
247  if ~isa(this.f," dscomponents.ACompEvalCoreFun ");
248  error(" Cannot use DEIM with non ACompEvalCoreFun-implementing functions. ");
249  elseif ~f.test_ComponentEvalMatch
250  error(" Component evaluation does not match direct evaluation. ");
251  elseif ~f.test_ComponentEvalMatch(10)
252  error(" Component evaluation does not match direct evaluation for multi-arguments. ");
253  end
254 
255  if size(fxi,1) < this.MaxOrder
256  fprintf(2," Warning: MaxOrder %d of DEIM approximation is larger than actual f dimension %d. Setting MaxOrder=%d\n ",...
257  this.MaxOrder,size(fxi,1),size(fxi,1));
258  this.MaxOrder= size(fxi,1);
259  end
260 
261  /* % Generate u_1 ... u_m base */
262  p = general.POD;
263  p.Mode= " abs ";
264  p.Value= this.MaxOrder;
265 
266  /* p.UseSVDS = size(fxi,1) > 10000; */
267  [Utmp, this.SingularValues] = p.computePOD(fxi);
268  if isa(Utmp," data.FileMatrix ")
269  Utmp = Utmp.toMemoryMatrix;
270  end
271  this.u= Utmp;
272 
273  if size(this.u,2) < this.MaxOrder
274  fprintf(" POD returned less (=%d) than MaxOrder (=%d) basis vectors. Setting MaxOrder=%d.\n ",...
275  size(this.u,2),this.MaxOrder,size(this.u,2));
276  this.MaxOrder= size(this.u,2);
277  end
278 
279  /* Get interpolation points */
280  this.pts= this.getInterpolationPoints(this.u);
281 
282  /* Trigger computation of U matrix.
283  * If no order has been set yet ("first computation"), use
284  * predefined order. Otherwise, just ensure the order data
285  * corresponds to the current u/pts. */
286  if isempty(this.fOrder)
287  this.Order= ceil(this.MaxOrder/10);
288  else
289  this.updateOrderData;
290  end
291  }
303  function fx = evaluate(colvec<double> x,double t) {
304  fx = this.U * this.f.evaluateComponentSet(1, x, t);
305  }
306 
307 
308  function fx = evaluateMulti(colvec<double> x,double t,colvec<double> mu) {
309  fx = this.U * this.f.evaluateComponentSetMulti(1, x, t, mu);
310  }
311 
312 
313  function J = getStateJacobian(colvec<double> x,double t) {
314  hlp = this.U * this.f.evaluateComponentSetGradientsAt(1, x, t);
315  if isempty(this.V)
316  p = logical(this.f.JSparsityPattern);
317  J = sparse(this.f.fDim,this.f.xDim);
318  J(p) = hlp(p);
319  else
320  J = hlp;
321  end
322  }
323 
324 
326 
327  n = size(u,1);
328  m = size(u,2);
329  pts = zeros(1, m);
330  v = pts;
331  [v(1), pts(1)] = max(abs(u(:,1)));
332  P = zeros(n,1);
333  P(pts(1)) = 1;
334  for i=2:m
335  c = (P" *u(:,1:(i-1))) \ (P "*u(:,i));
336  [v(i), pts(i)] = max(abs(u(:,i) - u(:,1:(i-1))*c));
337  P = sparse(pts(1:i),1:i,ones(i,1),n,i);
338  end
339  this.Residuals= v;
340  if KerMor.App.Verbose > 2
341  fprintf(" DEIM interpolation points [%s] with values [%s]\n ",...
342  Utils.implode(pts," "," %d "),Utils.implode(v," "," %2.2e "));
343  end
344  }
356  function err = getEstimatedError(colvec<double> x,double t,colvec<double> mu) {
357  if this.fOrder(2) == 0
358  error(" No error estimation possible with zero ErrorOrder property ");
359  end
360  err = this.Uerr1 * this.f.evaluateComponentSetMulti(1, x, t, mu) ...
361  - this.Uerr2 * this.f.evaluateComponentSetMulti(2, x, t, mu);
362  }
363 
364 
365  function DEIMtarget = project(matrix<double> V,matrix<double> W,DEIM target) {
366 
367  if nargin < 4
368  target = this.clone;
369  end
370  target = project@general.AProjectable(this, V, W, target);
371  /* Important: Project the component evaluable function, too! */
372  target.f= this.f.project(V, W);
373  target.updateOrderData;
374  }
397  function copy = clone(copy) {
398  if nargin < 2
399  copy = general.DEIM;
400  end
401  copy = clone@general.AProjectable(this, copy);
402  /* Clone associated f as different orders for the cloned object
403  * lead to different PointSets for the component evaluable
404  * function. */
405  copy.f= this.f.clone;
406  copy.fOrder= this.fOrder;
407  copy.u= this.u;
408  copy.pts= this.pts;
409  copy.U= this.U;
410  copy.U_nonproj= this.U_nonproj;
411  copy.MaxOrder= this.MaxOrder;
412  copy.Uerr1= this.Uerr1;
413  copy.Uerr2= this.Uerr2;
414  copy.M1= this.M1;
415  copy.M2= this.M2;
416  copy.SingularValues= this.SingularValues;
417  }
418 
419 
420  function plotSummary(pm,context) {
421  if ~isempty(this.SingularValues)
422  str = sprintf(" %s: DEIM POD singular value decay, MaxOrder: %d ",context,this.MaxOrder);
423  h = pm.nextPlot(" deim_singvals ",...
424  str," POD size "," singular values ");
425  semilogy(h,this.SingularValues," LineWidth ",2);
426  end
427  if ~isempty(this.Residuals)
428  str = sprintf(" %s: maximum basis residual, MaxOrder: %d ",context,this.MaxOrder);
429  h = pm.nextPlot(" max_residuals ",...
430  str," Point number "," residual ");
431  semilogy(h,this.Residuals," LineWidth ",2);
432  end
433  }
434 
435 
436  protected:
437 
438  function updateOrderData() {
439 
440  if KerMor.App.Verbose > 3
441  fprintf(" general.DEIM.updateOrderData: Updating order data of DEIM (%s, #%s) to [%d %d]\n ",class(this),this.ID,this.fOrder);
442  end
443 
444  o = this.fOrder(1);
445  n = size(this.u,1);
446 
447  P = sparse(this.pts(1:o),1:o,ones(o,1),n,o);
448  this.U_nonproj= this.u(:,1:o) / (P^t*this.u(:,1:o));
449 
450  /* Set primary point set in ACompEvalCoreFun */
451  this.f.setPointSet(1, this.pts(1:o));
452 
453  om = this.fOrder(2);
454  if om > 0
455  /* Use second point set in ACompEvalCoreFun */
456  this.f.setPointSet(2, this.pts(o+1:o+om));
457 
458  Perr = sparse(this.pts(o+1:o+om),1:om,ones(om,1),n,om);
459 
460  Um = this.u(:,1:o);
461  Umd = this.u(:,o+1:o+om);
462  A = P^t*Um;
463  B = P^t*Umd;
464  C = Perr^t*Um;
465  D = Perr^t*Umd;
466  E = C / A;
467  F = D - E*B;
468  this.Uerr2= ((Um/A)*B - Umd) / F;
469  this.Uerr1= this.Uerr2 * E;
470  else
471  this.Uerr1= [];
472  this.Uerr2= [];
473  end
474 
475  if ~isempty(this.W)
476  this.U= this.W^t*this.U_nonproj;
477  if om > 0
478  /* Compute values for error estimator */
479  this.M1= this.Uerr1 + (Um - this.V*(this.W^t*Um))/A;
480  this.M2= this.Uerr2;
481 
482  /* Project DEIM error estimation values */
483  this.Uerr1= this.W^t*this.Uerr1;
484  this.Uerr2= this.W^t*this.Uerr2;
485  end
486  else
487  this.U= this.U_nonproj;
488  end
489 
490  /* Fire order updated event */
491  notify(this, " OrderUpdated ", event.EventData);
492  }
500  /* % Getter & Setter */
501  public:
502 
503 
504 #if 0 //mtoc++: 'get.Order'
505 function o = Order() {
506  o = this.fOrder;
507  }
508 
509 #endif
510 
511 
512 
513 #if 0 //mtoc++: 'set.Order'
514 function Order(value) {
515  if isempty(this.u) || isempty(this.pts)
516  error(" Cannot set DEIM order as approximateSystemFunction has not been called yet. ");
517  end
518  if numel(value) ~= 2
519  if numel(value) ~= 1
520  error(" Order must be either a scalar or two element integer vector ");
521  else
522  value(2) = 0;
523  end
524  end
525  if any(value) > size(this.u,2) || any(value) < 1
526  error(" Invalid Order/ErrOrder value. Allowed are integers in [1, %d] ",size(this.u,2));
527  elseif sum(value) > this.MaxOrder
528  warning(" KerMor:DEIM ",sprintf(...
529  " Order (%d) and ErrOrder (%d) values may not exceed MaxOrder (%d). Using [%d 0] ",...
530  value,this.MaxOrder,this.MaxOrder));/* #ok */
531 
532  value = [this.MaxOrder 0];
533  end
534  /* Only re-compute error order matrices if an actual change
535  * happenend */
536  if ~isequal(this.fOrder, value)
537  this.fOrder= value;
538  this.updateOrderData;
539  end
540  }
541 
542 #endif
543 
544 
545 
546 #if 0 //mtoc++: 'set.MaxOrder'
547 function MaxOrder(value) {
548  if ~isposintscalar(value)
549  error(" MaxOrder has to be a positive integer scalar. ");
550  end
551  this.MaxOrder= value;
552  }
553 
554 #endif
555 
556 
557  public:
558 
569  protected: /* ( Static ) */
570 
571  static function obj = loadobj(obj,varargin) {
572  obj = loadobj@general.AProjectable(obj, varargin[:]);
573  obj = loadobj@KerMorObject(obj, varargin[:]);
574  }
575 
585 };
586 }
587 
Collection of generally useful functions.
Definition: Utils.m:17
function J = getStateJacobian(colvec< double > x,double t)
Definition: DEIM.m:313
function res = test_ComponentEvalMatch(xsize)
Tests if the local implementation of evaluateComponents matches the full evaluation.
integer fDim
The current output dimension of the function.
Definition: ACoreFun.m:171
DEIM: Implements the DEIM-Algorithm from .
Definition: DEIM.m:18
notify
Broadcast a notice that a specific event is occurring on a specified handle object or array of handle...
function err = getEstimatedError(colvec< double > x,double t,colvec< double > mu)
Definition: DEIM.m:356
function copy = clone(copy)
The interface method with returns a copy of the current class instance.
Definition: DEIM.m:397
Interface for all components that can be projected.
Definition: AProjectable.m:18
EVENT OrderUpdated
Gets fired whenever this DEIM instance has updated it's order matrices.
Definition: DEIM.m:559
rowvec< double > SingularValues
The singular values returned by the SVD decomposition to compute the DEIM POD basis.
Definition: DEIM.m:102
integer MaxOrder
The maximum order up to which the DEIM approximation should be computed.
Definition: DEIM.m:60
Base class for any KerMor class.
Definition: KerMorObject.m:17
static function obj = loadobj(obj, varargin)
Definition: DEIM.m:571
function fx = evaluate(colvec< double > x,double t)
Definition: DEIM.m:303
matrix< double > U_nonproj
If projection is applied, this contains the non-projected full matrix for use in subclasses...
Definition: DEIM.m:178
An integer value.
rowvec< integer > Order
The actual order for the current DEIM approximation.
Definition: DEIM.m:81
function fx = evaluateComponentSetMulti(integer nr,matrix< double > x,rowvec< double > t,matrix< double > mu)
Computes the full component functions of the given point set.
rowvec< double > pts
Interpolation points.
Definition: DEIM.m:135
dscomponents.ACompEvalCoreFun f
The function which DEIM is applied to.
Definition: DEIM.m:214
A boolean value.
#define F(x, y, z)
Definition: CalcMD5.c:168
KerMorObject()
Constructs a new KerMor object.
Definition: KerMorObject.m:55
A variable number of input arguments.
function DEIM target = project(matrix< double > V,matrix< double > W,DEIM target)
Pojects instance according to the projection biorthogonal matrices .
Definition: DEIM.m:365
IReductionSummaryPlotProvider:
matrix< double > Uerr1
Some matrices for M+M' error estimation.
Definition: DEIM.m:192
function copy = clone(copy)
The interface method with returns a copy of the current class instance.
function pts = getInterpolationPoints(matrix< double > u)
Computes the interpolation indices according to the DEIM algorithm.
Definition: DEIM.m:325
matrix< double > U
The U matrix for the current Order.
Definition: DEIM.m:165
V
The matrix of the biorthogonal pair .
Definition: AProjectable.m:61
ID
An ID that allows to uniquely identify this DPCMObject (at least within the current MatLab session/co...
Definition: DPCMObject.m:70
function setPointSet(nr, pts, jpd)
Parameters: pts: A row vector with the desired points jpd: ("Jacobian Partial Derivatives") A cell ar...
function target = project(V, W, target)
function computeDEIM(dscomponents.ACompEvalCoreFun f,matrix< double > fxi)
Implementation of the DEIM algorithm.
Definition: DEIM.m:244
sparse< logical > JSparsityPattern
Sparsity pattern for the jacobian matrix.
Definition: ACoreFun.m:127
matrix< double > u
The full approximation base.
Definition: DEIM.m:122
ACompEvalCoreFun: A normal CoreFun which supports single-component evaluation.
function updateOrderData()
Update approximation order as specified in fOrder. As a consequence some matrices have to be recalcul...
Definition: DEIM.m:438
static function char str = implode(char|rowvec data,char glue,char format)
Implodes the elements of data using glue.
Definition: Utils.m:208
function res = isposintscalar(value)
isposintscalar: Backwards-compatibility function for matlab versions greater than 2012a ...
Global configuration class for all KerMor run-time settings.
Definition: KerMor.m:17
static function KerMor theinstance = App()
The singleton KerMor instance.
Definition: KerMor.m:910
W
The matrix of the biorthogonal pair .
Definition: AProjectable.m:72
function dfx = evaluateComponentSetGradientsAt(integer nr,colvec< double > x,double t)
Computes the full/reduced gradients of all component functions of the given point set...
function fx = evaluateMulti(colvec< double > x,double t,colvec< double > mu)
Definition: DEIM.m:308
rowvec< double > Residuals
The maximum residuals obtained along the magic points computation.
Definition: DEIM.m:229
function plotSummary(pm, context)
Definition: DEIM.m:420
function fx = evaluateComponentSet(integer nr,colvec< double > x,double t)
Computes the full or reduced component functions of the given point set.