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
Componentwise.m
Go to the documentation of this file.
1 namespace approx{
2 namespace algorithms{
3 
4 
5 /* (Autoinserted by mtoc++)
6  * This source code has been filtered by the mtoc++ executable,
7  * which generates code that can be processed by the doxygen documentation tool.
8  *
9  * On the other hand, it can neither be interpreted by MATLAB, nor can it be compiled with a C++ compiler.
10  * Except for the comments, the function bodies of your M-file functions are untouched.
11  * Consequently, the FILTER_SOURCE_FILES doxygen switch (default in our Doxyfile.template) will produce
12  * attached source files that are highly readable by humans.
13  *
14  * Additionally, links in the doxygen generated documentation to the source code of functions and class members refer to
15  * the correct locations in the source code browser.
16  * However, the line numbers most likely do not correspond to the line numbers in the original MATLAB source files.
17  */
18 
21  public IParallelizable {
57  public: /* ( setObservable ) */
58 
95  public:
96 
110  private:
111 
112  ccomp;
120  public:
121 
123  this = this@approx.algorithms.ABase;
124 
125  this.CoeffConfig= general.interpolation.InterpolConfig;
126 
127  /* Register default property changed listeners */
128  this.registerProps(" CoeffConfig ");
129  }
130 
131 
132  function copy = clone() {
133 
134  /* Create instance as this is the final class so far. If
135  * subclassed, this clone method has to be given an additional
136  * target argument. */
137  copy = approx.algorithms.Componentwise;
138  copy = clone@approx.algorithms.ABase(this, copy);
139 
140  /* copy local props */
141  copy.BestCoeffConfig= this.BestCoeffConfig;
142  if ~isempty(this.CoeffConfig)
143  copy.CoeffConfig= this.CoeffConfig.clone;
144  end
145  copy.SingleRuntimes= this.SingleRuntimes;
146  }
156  function pm = plotSummary(pm) {
157  if nargin < 2
158  pm = PlotManager(false,1,2);
159  pm.LeaveOpen= true;
160  end
161 
164  [X,Y] = meshgrid(1:nc,1:nco);
165 
166  h = pm.nextPlot(" abs "," Absolute errors (train) "," expansion config "," coeff comp config ");
167  LogPlot.logsurf(h,X,Y,this.MaxErrors^t);
168  h = pm.nextPlot(" rel "," Relative errors (train) "," expansion config "," coeff comp config ");
169  LogPlot.logsurf(h,X,Y,this.MaxRelErrors^t);
170 
171  h = pm.nextPlot(" abs "," Absolute errors (val) "," expansion config "," coeff comp config ");
172  LogPlot.logsurf(h,X,Y,this.ValidationErrors^t);
173  h = pm.nextPlot(" rel "," Relative errors (val) "," expansion config "," coeff comp config ");
175  if nargin < 2
176  pm.done;
177  end
178  }
191  function [str , rangetab ] = getApproximationSummary() {
192  [str, rangetab] = getApproximationSummary@approx.algorithms.ABase(this);
193  cc = this.CoeffConfig;
194  str = [str sprintf(" Best coefficient comp configuration at index %d:\n%s\n ",this.BestCoeffConfig,...
195  cc.getConfigurationString(this.BestCoeffConfig))];
196  rangetab = rangetab.append(cc.getValueRanges);
197  if nargout < 2
198  str = [str sprintf(" Configuration ranges:\n%s\n ",...
199  rangetab.toString)];
200  if nargout < 1
201  disp(str);
202  end
203  end
204  }
205 
206 
207  function nc = getTotalNumConfigurations() {
208  nc = getTotalNumConfigurations@approx.algorithms.ABase(this);
209  if ~isempty(this.CoeffConfig)
210  nc = nc * this.CoeffConfig.getNumConfigurations;
211  end
212  }
213 
214 
215  function mink = collectFromExpConfigSplit(algs) {
216  np = length(algs);
217  rs = RangeSplitter(this.ExpConfig.getNumConfigurations, " Num ", np);
218  minerr = Inf;
219  this.LastCompTime= 0;
220  for k=1:np
221  algk = algs[k];
222  idx = rs.getPart(k);
223  this.MaxErrors(idx,:) = algk.MaxErrors;
224  this.MaxRelErrors(idx,:) = algk.MaxRelErrors;
225  this.ValidationErrors(idx,:) = algk.ValidationErrors;
226  this.ValidationRelErrors(idx,:) = algk.ValidationRelErrors;
227  this.SingleRuntimes(idx,:) = algk.SingleRuntimes;
228  this.StopFlags(idx,:) = algk.StopFlags;
229  this.LastCompTime= this.LastCompTime + algk.LastCompTime;
230  hlp = algk.ValidationErrors(algk.BestExpConfig,algk.BestCoeffConfig);
231  if hlp < minerr
232  minerr = hlp;
233  mink = k;
234  this.BestExpConfig= idx(algk.BestExpConfig);
235  this.BestCoeffConfig= algk.BestCoeffConfig;
236  end
237  end
238  }
239 
240 
241  protected: /* ( Sealed ) */
242 
243  function kernels.KernelExpansionkexp = templateComputeApproximation(data.ApproxTrainData atd,avd) {
244  ec = this.ExpConfig;
245 
246  kexp = ec.Prototype;
247  kexp.Centers.xi= atd.xi.toMemoryMatrix;
248  kexp.Centers.ti= atd.ti;
249  kexp.Centers.mui= atd.mui;
250 
251  nc = ec.getNumConfigurations;
252  cc = this.CoeffConfig;
253  nco = cc.getNumConfigurations;
254 
255  if nco == 0
256  error(" No coefficient computation configurations set. See CoeffConfig ");
257  end
258 
259  /* Keep track of maximum errors (matrix-wise for expansion config / coeff config) */
260  hlp = zeros(nc, nco);
261  this.MaxErrors= hlp;
262  this.MaxRelErrors= hlp;
263  this.StopFlags= hlp;
264  this.SingleRuntimes= hlp;
265 
266  minerr = Inf;
267  bestcidx = [];
268  bestcoidx = [];
269  bestMa = [];
270  pi = ProcessIndicator(" Trying %d configurations (%d kernel, %d coeffcomp) ",...
271  nc*nco,false,nc*nco,nc,nco);
272  for kcidx = 1:nc
273  if KerMor.App.Verbose > 2
274  fprintf(" Applying expansion config %s\n ",ec.getConfigurationString(kcidx, false));
275  end
276  kexp = ec.configureInstance(kcidx);
277 
278  /* Initialize the prototype for coeffconfigs with the
279  * current kernel expansion */
280  cc.Prototype.init(kexp);
281 
282  for coidx = 1:nco
283 
284  this.ccomp= cc.configureInstance(coidx);
285 
286  if KerMor.App.Verbose > 2
287  fprintf(" Applying %s config %s\n ",class(this.ccomp),cc.getConfigurationString(coidx, false));
288  end
289 
290  /* Call protected method */
291  time = tic;
292  sf = this.computeCoeffs(kexp, atd.fxi, []);
293  this.StopFlags(kcidx,coidx) = sf;
294 
295  /* Determine maximum error on training data */
296  [val, maxidx] = this.getError(kexp, atd);
297  rel = val / (norm(atd.fxi(:,maxidx))+eps);
298  this.MaxErrors(kcidx,coidx) = val;
299  this.MaxRelErrors(kcidx,coidx) = rel;
300  /* Determine maximum error on validation data (and use
301  * for optimal approx selection) */
302  [val, maxidx] = this.getError(kexp, avd);
303  rel = val / (norm(avd.fxi(:,maxidx))+eps);
304  this.ValidationErrors(kcidx,coidx) = val;
305  this.ValidationRelErrors(kcidx,coidx) = rel;
306 
307  this.SingleRuntimes(kcidx,coidx) = toc(time);
308 
309  if val < minerr
310  minerr = val;
311  bestMa = kexp.Ma;
312  bestcidx = kcidx;
313  bestcoidx = coidx;
314  if KerMor.App.Verbose > 3
315  fprintf(" better: %.5e (rel %.5e) ",val,rel);
316  end
317  else
318  if KerMor.App.Verbose > 3
319  fprintf(" worse : %.5e (rel %.5e) ",val,rel);
320  end
321  end
322  pi.step;
323  end
324  end
325 
326  /* % Assign best values */
327  this.BestCoeffConfig= bestcoidx;
328  this.BestExpConfig= bestcidx;
329  kexp = ec.configureInstance(bestcidx);
330  kexp.Ma= bestMa;
331 
332  if KerMor.App.Verbose > 1
333  figure;
334  plot(this.MaxErrors," r ");
335  end
336 
337  pi.stop;
338  }
339 
340 
341  private:
342 
343 
344  function integersf = computeCoeffs(kexp,fxi,initialalpha) {
345  if nargin < 4 || isempty(initialalpha)
346  initialalpha = double.empty(size(fxi,1),0);
347  end
348  if this.ComputeParallel
349  sf = this.computeCoeffsParallel(kexp, fxi, initialalpha);
350  else
351  sf = this.computeCoeffsSerial(kexp, fxi, initialalpha);
352  end
353  }
376  function integersf = computeCoeffsSerial(kernels.KernelExpansion kexp,fxi,initialalpha) {
377 
378  fdims = size(fxi,1);
379  n = size(kexp.Centers.xi,2);
380  kexp.Ma= zeros(fdims, n);
381  if this.ccomp.MultiTargetComputation
382  if KerMor.App.Verbose > 3
383  fprintf(" Computing approximation for all %d dimensions...\n ",fdims);
384  end
385  /* Call template method */
386  [ai, svidx, sf] = this.ccomp.computeKernelCoefficients(fxi,initialalpha);
387  kexp.Ma(:,svidx) = ai;
388  else
389  for fdim = 1:fdims
390  if KerMor.App.Verbose > 3 && fdims > 1
391  fprintf(" Computing approximation for dimension %d/%d ... %2.0f %%\n ",fdim,fdims,(fdim/fdims)*100);
392  end
393  /* Call template method */
394  [ai, svidx, sf] = this.ccomp.computeKernelCoefficients(fxi(fdim,:),initialalpha(fdim,:));
395  kexp.Ma(fdim,svidx) = ai;
396  end
397  end
398  }
417  function integersf = computeCoeffsParallel(kernels.KernelExpansion kexp,fxi,initialalpha) {
418  n = size(kexp.Centers.xi,2);
419  fdims = size(fxi,1);
420  fprintf(" Starting parallel component-wise approximation computation of %d dimensions on %d workers...\n ",fdims,matlabpool(" size "));
421  Ma = zeros(fdims, n);
422  sf = zeros(fdims, 1);
423  parfor fdim = 1:fdims
424  /* Call template method */
425  [ai, sv, sf(fdim)] = this.ccomp.computeKernelCoefficients(...
426  fxi(fdim,:),initialalpha(fdim,:));/* #ok */
427 
428  Ai = zeros(1,n);
429  Ai(sv) = ai;
430  Ma(fdim,:) = Ai;
431  end
432  kexp.Ma= Ma;
433  /* FIXME: Only allowing for one stopflag thus far, taking last
434  * one to stay according with serial computation */
435  sf = sf(end);
436  }
451  /* % Getter & Setter */
452  public:
453 
454 
455 #if 0 //mtoc++: 'set.CoeffConfig'
456 function CoeffConfig(value) {
457  if ~isempty(value) && ~isa(value," IClassConfig ")
458  error(" Property value must implement the IClassConfig interface ");
459  end
460  this.CoeffConfig= value;
461  }
462 
463 #endif
464 
465 
466  protected: /* ( Static ) */
467 
468  static function this = loadobj() {
469  if ~isa(this," approx.algorithms.Componentwise ")
470  newinst = approx.algorithms.Componentwise;
471  if isfield(this, " SingleRuntimes ")
472  newinst.SingleRuntimes= this.SingleRuntimes;
473  end
474  this = loadobj@approx.algorithms.ABase(newinst, this);
475  else
476  this = loadobj@approx.algorithms.ABase(this);
477  end
478  }
479 
480 
481  public: /* ( Static ) */
482 
483  static function res = test_Componentwise() {
484  m = models.pcd.PCDModel(1);
485  m.dt= .1;
486  m.T= 1;
487  m.EnableTrajectoryCaching= false;
488 
489  /* Define prototype expansion */
490  ec = kernels.config.ExpansionConfig;
491  ec.StateConfig= kernels.config.GaussConfig(" G ",.1:.3);
492 
493  a = approx.algorithms.Componentwise;
494  a.ExpConfig= ec;
495  a.CoeffConfig= general.interpolation.InterpolConfig;
496 
497  ap = approx.KernelApprox(m.System);
498  ap.Algorithm= a;
499 
500  m.Approx= ap;
501  m.System.Params(1).Desired = 2;
502  m.SpaceReducer= spacereduction.PODGreedy;
503  m.SpaceReducer.Eps= 1e-2;
504  m.offlineGenerations;
505 
506  mu = m.getRandomParam;
507  r = m.buildReducedModel;
508  r.simulate(mu);
509 
510  a.CoeffConfig= general.regression.EpsSVRConfig([.1 .15; 1 2]);
511  svr = general.regression.ScalarEpsSVR_SMO;
512  svr.MaxCount= 20;
513  a.CoeffConfig.Prototype= svr;
514  a.UsefScaling= true;
515  m.off5_computeApproximation;
516 
517  r = m.buildReducedModel;
518  r.simulate(mu);
519 
520  res = true;
521  }
522 
528 };
529 }
530 }
531 
532 
533 
534 
matrix< double > ValidationErrors
For each configuration, contains a row with the maximum errors on the validation data. The number of columns depends on the type of algorithm implemented by the subclasses.
Definition: ABase.m:154
matrix< double > Ma
The coefficient data for each dimension.
IClassConfig: Abstract interface for a set of configurations that can be applied to a given algorithm...
Definition: IClassConfig.m:17
matrix< double > MaxRelErrors
For each configuration, contains a row with the maximum relative errors on the training data...
Definition: ABase.m:139
matrix< integer > StopFlags
For each effective configuration, the stop flags are stored here.
Definition: ABase.m:184
data.FileMatrix xi
The state space samples , stored row-wise in a data.FileMatrix instance.
LogPlot: Class with static functions for logarithmic plotting.
Definition: LogPlot.m:17
virtual function integer n = getNumConfigurations()
Returns the number of configurations that can be applied.
data.FileMatrix fxi
The evaluations of , stored row-wise in a data.FileMatrix.
function [ str , rangetab ] = getApproximationSummary()
matrix< double > SingleRuntimes
The times needed for the coefficients to compute for each exp/coeffcomp configuration.
Definition: Componentwise.m:97
integer BestExpConfig
Index of the best expansion config determined by the algorithm.
Definition: ABase.m:201
function kernels.KernelExpansion kexp = templateComputeApproximation(data.ApproxTrainData atd, avd)
function registerProps(varargin)
Call this method at any class that defines DPCM observed properties.
Definition: DPCMObject.m:125
static function res = test_Componentwise()
function copy = clone(copy)
The interface method with returns a copy of the current class instance.
Definition: IClassConfig.m:109
integer BestCoeffConfig
The index of the best coefficient computation configuration.
Definition: Componentwise.m:77
An integer value.
matrix< double > ValidationRelErrors
For each configuration, contains a row with the maximum relative errors on the validation data...
Definition: ABase.m:169
kernels.config.ExpansionConfig ExpConfig
The different kernel expansion configurations to try.
Definition: ABase.m:55
function mink = collectFromExpConfigSplit(algs)
PlotManager: Small class that allows the same plots generated by some script to be either organized a...
Definition: PlotManager.m:17
static function handle p = logsurf(handle h,matrix< double > X,matrix< double > Y,matrix< double > Z, varargin)
Creates a nice surface plot in a logarithmic scale with the given data.
Definition: LogPlot.m:79
function pm = plotSummary(pm)
Overrides the approx.algorithms.ABase function.
rowvec ti
The time samples .
function copy = clone()
Clones the instance.
ComputeParallel
Flag whether the code should be run in parallel or not.
double LastCompTime
The computation time for the last run in seconds.
Definition: ABase.m:111
static function this = loadobj()
function [ double val , integer idx , rowvec errs ] = getError(kernels.KernelExpansion kexp,data.ApproxTrainData atd)
Computes the error according to the chosen error function (see ErrorFun property) with respect to the...
Definition: ABase.m:408
ICloneable Prototype
The prototype class that is to be used as base class before configuring a new instance.
Definition: IClassConfig.m:42
disp
Handle object disp method which is called by the display method. See the MATLAB disp function...
#define X(i, j)
RangeSplitter:
Definition: RangeSplitter.m:17
function n = getNumConfigurations()
Returns the number of configurations that can be applied.
matrix mui
The parameter samples used computing the parent trajectories of .
matrix< double > MaxErrors
For each configuration, contains a row with the maximum errors on the training data. The number of columns depends on the type of algorithm implemented by the subclasses.
Definition: ABase.m:124
IParallelizable Interface to indicate parallel computation capability of the implementing classes...
function nc = getTotalNumConfigurations()
ABase: Base class for any approximation generation algorithms for kernel expansions,.
Definition: ABase.m:19
#define Y(i, j)
Global configuration class for all KerMor run-time settings.
Definition: KerMor.m:17
IClassConfig CoeffConfig
The different coefficient computation algorithm configurations to try. The IClassConfig.Prototype is used as actual algorithm, and needs to implement the IKernelCoeffComp interface.
Definition: Componentwise.m:59
Componentwise: Component-wise kernel approximation with fixed center set.
Definition: Componentwise.m:19
ApproxTrainData: Data class for approximation training data, containing several useful bounding box p...
struct Centers
The kernel centers used in the approximation.
static function KerMor theinstance = App()
The singleton KerMor instance.
Definition: KerMor.m:910
function A = toMemoryMatrix()
Converts this FileMatrix to a full double matrix.
Definition: ABlockedData.m:210
ProcessIndicator: A simple class that indicates process either via waitbar or text output...
KernelExpansion: Base class for state-space kernel expansions.