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
VKOGA.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 
19 class VKOGA
46  public:
47 
85 
86 
88 
89 
90  public:
91 
93 
94 
106  public:
107 
108  VKOGA() {
109  this = this@approx.algorithms.AAdaptiveBase;
110  }
111 
112 
113  function copy = clone() {
114  copy = approx.algorithms.VKOGA;
115  copy = clone@approx.algorithms.AAdaptiveBase(this, copy);
116  copy.UsefPGreedy= this.UsefPGreedy;
117  copy.MaxAbsResidualErr= this.MaxAbsResidualErr;
118  copy.MaxRelErrors= this.MaxRelErrors;
119  copy.ValidationErrorMeasure= this.ValidationErrorMeasure;
120  copy.VKOGABound= this.VKOGABound;
121  copy.basis_norms= this.basis_norms;
122  copy.AllExpansions= this.AllExpansions;
123  }
133  protected: /* ( Sealed ) */
134 
135  function kernels.KernelExpansionkexp = startAdaptiveExtension(data.ApproxTrainData atd,avd) {
136  vb = KerMor.App.Verbose;
137 
138  ec = this.ExpConfig;
139  nc = ec.getNumConfigurations;
140 
141  this.basis_norms= this.MaxErrors;
142  this.StopFlags= zeros(nc,1);
143  this.VKOGABound= this.basis_norms;
144  this.BestExpConfig= 0;
145  this.AllExpansions= eval(sprintf(" %s.empty ",class(ec.Prototype)));
146 
147  xi = atd.xi.toMemoryMatrix;
148  fxi = atd.fxi.toMemoryMatrix;
149  fxinorm = this.ErrorFun(fxi);
150  fxinorm(fxinorm == 0) = 1;
151  if ~isempty(avd)
152  vxi = avd.xi.toMemoryMatrix;
153  vfxi = avd.fxi.toMemoryMatrix;
154  vfxinorm = this.ErrorFun(vfxi);
155  vfxinorm(vfxinorm == 0) = 1;
156  end
157  N = size(xi,2);
158 
159  minerr = Inf;
160  bestNV = [];
161  bestc = [];
162  bestused = [];
163 
164  /* % Run loop for all desired distances */
165  pi = ProcessIndicator(" VKOGA approximation for %d kernel configurations ",nc,false,nc);
166  for cidx = 1:nc
167  m = 1;
168 
169  /* Set current hyperconfiguration */
170  kexp = ec.configureInstance(cidx);
171 
172  /* Compute Kernel matrix diagonal */
173  if isa(kexp.Kernel," kernels.ARBFKernel ")
174  Kdiag = kexp.Kernel.evaluate(xi(:,1),xi(:,1))*ones(1,N);
175  else
176  Kdiag = zeros(1,N);
177  for k=1:N
178  Kdiag(k) = kexp.Kernel.evaluate(xi(k,1),xi(k,1));
179  end
180  end
181 
182  /* Values of Newton basis */
183  NV = zeros(N,this.MaxExpansionSize);
184  NV(:,1) = kexp.getKernelMatrixColumn(this.initialidx, xi, atd.ti, atd.mui);
185 
186  /* Coefficients of Newton basis */
187  c = zeros(size(atd.fxi,1),this.MaxExpansionSize);
188  c(:,1) = atd.fxi(:,this.initialidx)/sqrt(Kdiag(this.initialidx));
189 
190  /* Sum_j N_j^2(x_i) (for denominator) */
191  sumNsq = (NV(:,1).^2)^t;
192 
193  fresidual = fxi;
194 
195  used = zeros(1,N);
196  used(1) = this.initialidx;
197 
198  this.VKOGABound(cidx, m) = 1/max(Kdiag - sumNsq);
199 
200  /* % Main extension loop */
201  while true
202 
203  /* % Residual and error computation
204  * Cumulative computation (more effective) */
205  fresidual = fresidual - c(:,m)*(NV(:,m))^t;
206  /* Complete computation
207  * fresidual1 = fxi - c(:,1:m)*(NV(:,1:m))'; */
208 
209  e = this.ErrorFun(fresidual);
210  this.MaxErrors(cidx,m) = max(e);
211  this.MaxRelErrors(cidx,m) = max(e./fxinorm);
212 
213  /* % Check stopping conditions */
214  if m == this.MaxExpansionSize
215  if vb > 1
216  fprintf(" VKOGA stopping criteria holds: Max expansion size %d reached.\nResidual error %.7e > %.7e, Max relative error %.7e > %.7e\n ",...
217  m,this.MaxErrors(cidx,m-1),this.MaxAbsResidualErr,this.MaxRelErrors(cidx,m-1),this.MaxRelErr);
218  end
219  stopflag = StopFlag.MAX_SIZE;
220  break;
221  elseif this.MaxRelErrors(cidx,m) < this.MaxRelErr
222  if vb > 1
223  fprintf(" VKOGA stopping criteria holds: Relative error %.7e < %.7e\n ",this.MaxRelErrors(cidx,m),this.MaxRelErr);
224  end
225  stopflag = StopFlag.REL_ERROR;
226  break;
227  elseif this.MaxErrors(cidx,m) < this.MaxAbsResidualErr
228  if vb > 1
229  fprintf(" VKOGA stopping criteria holds: Residual error %.7e < %.7e\n ",this.MaxErrors(cidx,m),this.MaxAbsResidualErr);
230  end
231  stopflag = StopFlag.ABS_ERROR;
232  break;
233  end
234 
235  /* % Next basis point selection */
236  if this.UsefPGreedy
237  /* Cap too small norms! */
238  div = Kdiag - sumNsq;
239  div(used(1:m)) = Inf;
240  /* div(div <= 0) = Inf; */
241  else
242  div = 1;
243  end
244  sum_fresidual = sum(fresidual.^2,1) ./ div;
245 
246  [~, maxidx] = max(sum_fresidual);
247  tN = kexp.getKernelMatrixColumn(maxidx, xi, atd.ti, atd.mui) - NV(:,1:m)*NV(maxidx,1:m)^t;
248 
249  /* % Emergency break:
250  * An entry of the power function for which a value greater than one has
251  * been summed up would be chosen, leading to imaginary norms. */
252  if sumNsq(maxidx) > 1
253  if vb > 1
254  fprintf(" VKOGA emergency stop at iteration %d: Power function value > 1 detected.\nResidual error %.7e > %.7e, Max relative error %.7e > %.7e\n ",...
255  m,this.MaxErrors(cidx,m-1),this.MaxAbsResidualErr,this.MaxRelErrors(cidx,m-1),this.MaxRelErr);
256  end
257  stopflag = StopFlag.NEGATIVE_POWFUN;
258  break;
259  end
260 
261  m = m+1;
262  tNnorm = sqrt(Kdiag(maxidx)-sumNsq(maxidx));
263  NV(:,m) = tN/tNnorm;
264  c(:,m) = fresidual(:,maxidx)./tNnorm;
265  sumNsq = sumNsq + (NV(:,m).^2)^t;
266  used(m) = maxidx;
267 
268  this.basis_norms(cidx,m) = tNnorm;
269  this.VKOGABound(cidx, m) = this.VKOGABound(cidx, m-1) + 1/max(Kdiag - sumNsq);
270  end
271 
272  this.ExpansionSizes(cidx) = m;
273  this.MaxErrors(cidx,m+1:end) = Inf;
274  this.MaxRelErrors(cidx,m+1:end) = Inf;
275 
276  kexp.setCentersFromATD(atd, used(1:m));
277  kexp.Ma= c(:,1:m);
278  kexp.Base= NV(used(1:m),1:m);
279  this.AllExpansions(cidx) = kexp;
280 
281  /* If set, compute error on validation set */
282  if ~isempty(avd)
283  e = this.ErrorFun(vfxi - kexp.evaluate(vxi,avd.ti,avd.mui));
284  this.ValidationErrors(cidx,1) = max(e);
285  this.ValidationRelErrors(cidx,1) = max(e./vfxinorm);
286  this.ValidationErrors(cidx,2) = mean(e);
287  this.ValidationRelErrors(cidx,2) = mean(e./vfxinorm);
288  else
289  /* Otherwise just copy the training set error */
290  this.ValidationErrors(cidx,1) = this.MaxErrors(cidx,m);
291  this.ValidationRelErrors(cidx,1) = this.MaxRelErrors(cidx,m);
292  this.ValidationErrors(cidx,2) = mean(e);
293  this.ValidationRelErrors(cidx,2) = mean(e./fxinorm);
294  end
295 
296  if strcmp(this.ValidationErrorMeasure," rel ")
297  val = this.ValidationRelErrors(cidx,2);
298  else
299  val = this.ValidationErrors(cidx,2);
300  end
301  if val < minerr
302  minerr = val;
303  bestused = used(1:m);
304  bestNV = NV(:,1:m);
305  bestc = c(:,1:m);
306  this.BestExpConfig= cidx;
307  end
308  this.StopFlags(cidx) = stopflag;
309  pi.step;
310  end
311 
312  /* % Set (& apply) best configuration */
313  if isempty(bestused)
314  error(" No centers found ");
315  end
316  this.Used= bestused;
317  kexp = ec.configureInstance(this.BestExpConfig);
318  kexp.setCentersFromATD(atd, bestused);
319 
320  /* Compute Ma */
321  this.bestNewtonBasisValuesOnATD= bestNV;
322  kexp.Ma= bestc;
323  /* Extract partial cholesky matrix */
324  kexp.Base= bestNV(bestused,1:length(bestused));
325 
326  /* Some cleanup */
327  maxsize = max(this.ExpansionSizes);
328  this.MaxErrors= this.MaxErrors(:,1:maxsize);
329  this.MaxRelErrors= this.MaxRelErrors(:,1:maxsize);
330 
331  /* Debug stuff */
332  this.VKOGABound= size(fxi,1) ./ (1 + this.VKOGABound/size(fxi,1));
333 
334  if vb > 1
335  og = " off ";
336  if this.UsefPGreedy
337  og = " on ";
338  end
339  fprintf(" VKOMP best kernel config index:%d for VKOGA with f/P-Greedy=%s, exp-size:%d\n ",...
340  this.BestExpConfig,og,length(bestused));
341  end
342 
343  pi.stop;
344  }
363  protected: /* ( Static ) */
364 
365  static function this = loadobj() {
366  if ~isa(this, " approx.algorithms.VKOGA ")
367  a = approx.algorithms.VKOGA;
368  if isfield(this," UsefPGreedy ") && ~isempty(this.UsefPGreedy)
369  a.UsefPGreedy= this.UsefPGreedy;
370  elseif isfield(this," UseOGA ")
371  a.UsefPGreedy= this.UseOGA;
372  end
373  if isfield(this," MaxAbsResidualErr ")
374  a.MaxAbsResidualErr= this.MaxAbsResidualErr;
375  end
376  if isfield(this," bestNewtonBasisValuesOnATD ")
377  a.bestNewtonBasisValuesOnATD= this.bestNewtonBasisValuesOnATD;
378  end
379  if isfield(this," basis_norms ")
380  a.basis_norms= this.basis_norms;
381  end
382  if isfield(this," stopFlags ")
383  a.StopFlags= this.stopFlags;
384  end
385  this = loadobj@approx.algorithms.AAdaptiveBase(a, this);
386  end
387  if isempty(this.StopFlags)
388  this.StopFlags= zeros(size(this.MaxErrors));
389  end
390  }
391 
392 
393  public: /* ( Static ) */
394 
395 
396  static function res = test_VKOGA1DnD() {
397 
398  demos.VKOGA.VKOGA_1D_nD(1,false);
399  demos.VKOGA.VKOGA_1D_nD(1,true);
400  demos.VKOGA.VKOGA_1D_nD(2,false);
401  demos.VKOGA.VKOGA_1D_nD(2,true);
402  demos.VKOGA.VKOGA_1D_nD(3,false,10);
403  demos.VKOGA.VKOGA_1D_nD(3,true);
404  demos.VKOGA.VKOGA_1D_nD(4,false,10);
405  demos.VKOGA.VKOGA_1D_nD(4,true);
406  res = true;
407  }
415  static function [res , d ] = test_VKOGA2D1D() {
416 
417  /* % Data setup */
418  [f, r] = testing.TestFunctions.F8;
419  step = .02;
420  x1 = r(1,1):step:r(1,2);
421  x2 = r(2,1):step:r(2,2);
422  [X,Y] = meshgrid(x1,x2);
423  xi = [X(:)" ; Y(:) "];
424  fxi = f(xi);
425 
426  atd = data.ApproxTrainData(xi,[],[]);
427  atd.fxi= fxi;
428 
429  /* % Algorithm setup */
430  alg = approx.algorithms.VKOGA;
431  alg.MaxExpansionSize= 100;
432  alg.UsefPGreedy= true;
433  ec = kernels.config.ExpansionConfig;
434  ec.Prototype.Kernel= kernels.Wendland;
435  c = Utils.createCombinations(linspace(.5,2,5),[2 3]);
436  ec.StateConfig= kernels.config.WendlandConfig(...
437  " G ",c(1,:)," S ",c(2,:)," Dim ",1);
438  alg.ExpConfig= ec;
439 
440  kexp = alg.computeApproximation(atd);
441 
442  /* % Plot approximated function */
443 
444  pm = PlotManager(false,2,2);
445  pm.LeaveOpen= true;
446 
447  h = pm.nextPlot(" fun "," Function "," x "," f(x) ");
448  Z = reshape(fxi,length(x1),[]);
449  surf(h,X,Y,Z);
450 
451  h = pm.nextPlot(" fun "," Approximation "," x "," kexp(x) ");
452  aZ = reshape(kexp.evaluate(xi),length(x1),[]);
453  surf(h,X,Y,aZ);
454 
455  h = pm.nextPlot(" fun "," Error "," x "," f(x)-kexp(x) ");
456  surf(h,X,Y,abs(Z-aZ));
457 
458  h = pm.nextPlot(" nfun "," Last Newton Basis Function "," x "," N(x) ");
459  Z = reshape(alg.bestNewtonBasisValuesOnATD(:,end),length(x1),[]);
460  surf(h,X,Y,Z);
461 
462  alg.plotSummary(pm, " test_VKOGA ");
463  pm.done;
464 
465  d = struct;
466  d.kexp= kexp;
467  d.atd= atd;
468  d.alg= alg;
469  res = true;
470  }
480 };
481 }
482 }
483 
484 
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
static const REL_ERROR
Relative error tolerance reached.
Definition: StopFlag.m:47
Collection of generally useful functions.
Definition: Utils.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.
static const ABS_ERROR
Absolute error tolerance reached.
Definition: StopFlag.m:38
static function comb = createCombinations(ranges, varargin)
Creates the cartesian product of the vectors passed as a matrix containing elements of each vector pe...
Definition: Utils.m:114
data.FileMatrix fxi
The evaluations of , stored row-wise in a data.FileMatrix.
integer BestExpConfig
Index of the best expansion config determined by the algorithm.
Definition: ABase.m:201
A double value.
function kernels.KernelExpansion kexp = startAdaptiveExtension(data.ApproxTrainData atd, avd)
Starts the adaptive extension of the VKOGA algorithm.
Definition: VKOGA.m:135
reshape
hanges the dimensions of the handle object array to the specified dimensions. See the MATLAB reshape ...
matrix< double > ValidationRelErrors
For each configuration, contains a row with the maximum relative errors on the validation data...
Definition: ABase.m:169
VKOGA: Vectorial kernel orthogonal greedy algorithm.
Definition: VKOGA.m:19
kernels.config.ExpansionConfig ExpConfig
The different kernel expansion configurations to try.
Definition: ABase.m:55
logical UsefPGreedy
Flag on whether to use the f/P-Greedy variant instead of f-Greedy.
Definition: VKOGA.m:48
PlotManager: Small class that allows the same plots generated by some script to be either organized a...
Definition: PlotManager.m:17
function copy = clone()
Clones the instance.
Definition: VKOGA.m:113
rowvec ti
The time samples .
A boolean value.
static function [ res , d ] = test_VKOGA2D1D()
Tests the VKOGA algorithm.
Definition: VKOGA.m:415
Used
The indices of the effectively used centers during the.
static const NEGATIVE_POWFUN
Stop flag from the VKOGA algorithm.
Definition: StopFlag.m:65
function_handle ErrorFun
The error function to apply on each data vector.
Definition: ABase.m:87
static function res = test_VKOGA1DnD()
Tests the VKOGA algorithm by running the demos.
Definition: VKOGA.m:396
double MaxAbsResidualErr
Stopping criteria for the VKOGA algorithm. The execution for on expansion configuration is stopped if...
Definition: VKOGA.m:58
#define X(i, j)
basis_norms
debug props
Definition: VKOGA.m:95
static function this = loadobj()
Definition: VKOGA.m:365
function n = getNumConfigurations()
Returns the number of configurations that can be applied.
char ValidationErrorMeasure
Determines which error measure is to use to select the "best" solution w.r.t. to the validation data ...
Definition: VKOGA.m:70
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
Base class for adaptive component-wise kernel approximation algorithms.
Definition: AAdaptiveBase.m:19
#define Y(i, j)
Global configuration class for all KerMor run-time settings.
Definition: KerMor.m:17
ApproxTrainData: Data class for approximation training data, containing several useful bounding box p...
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
A MatLab character array.
double MaxRelErr
Stopping condition property. Maximum relative error that may occur.
Definition: AAdaptiveBase.m:70
ProcessIndicator: A simple class that indicates process either via waitbar or text output...
integer MaxExpansionSize
The maximum size of the expansion to produce.
Definition: AAdaptiveBase.m:50
static const MAX_SIZE
Maximum size reached.
Definition: StopFlag.m:56
StopFlag: Flags that algorithms can use to specify the reason for their termination.
Definition: StopFlag.m:17