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
BellFunction.m
Go to the documentation of this file.
1 namespace kernels{
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 
19  :public kernels.ARBFKernel {
59  public: /* ( Dependent, setObservable ) */
60 
61  r0;
75  public: /* ( setObservable ) */
76 
107  public:
108 
109  rm;
120  private: /* ( Transient ) */
121 
122  p;
123 
124  sc;
125 
126  d1;
127 
128  d2;
129 
130 
131  private:
132 
133  fr0;
134 
135 
136  public:
137 
138 
140  this = this@kernels.ARBFKernel;
141  this.registerProps(" r0 "," NewtonTolerance "," MaxNewtonIterations ");
142  }
143 
144 
145  function c = getGlobalLipschitz() {
146  c = abs(this.evaluateD1(this.r0));
147  }
156  function copy = clone(copy) {
157  copy = clone@kernels.ARBFKernel(this, copy);
158  copy.NewtonTolerance= this.NewtonTolerance;
159  copy.MaxNewtonIterations= this.MaxNewtonIterations;
160  copy.fr0= this.fr0;
161  copy.p= this.p;
162  copy.sc= this.sc;
163  copy.d1= this.d1;
164  copy.d2= this.d2;
165  copy.rm= this.rm;
166  copy.r0= this.r0;
167  }
168 
169 
170  function rtmp = ModifiedNewton(rstart,s) {
171  rtmp = rstart+2*this.NewtonTolerance;
172  r = rstart;
173 
174  /* Add eps at division as for zero nominator the expression is zero. (no error made) */
175  n = zeros(3,length(s));
176  n(1,:) = this.d1(1) - (this.sc(1)-this.evaluateScalar(s))./(eps-s);
177  n(2,:) = this.d1(2) - (this.sc(2)-this.evaluateScalar(s))./(this.p(2)-s+eps);
178  n(3,:) = this.d1(3) - (this.sc(3)-this.evaluateScalar(s))./(this.p(3)-s+eps);
179 
180  /* Lim x->y n'(x) = \phi''(x) / 2 (De L'hospital) */
181  dn = zeros(3,length(s));
182  dn(1,:) = this.d2(1) - n(1,:)./-s;
183  dn(1,isnan(dn(1,:))) = this.evaluateD2(0)/2;
184  dn(2,:) = this.d2(2) - n(2,:)./(this.p(2)-s);
185  dn(2,isinf(dn(2,:))) = 0; /* == ddf(x0)/2; */
186 
187  dn(3,:) = this.d2(3) - n(3,:)./(this.p(3)-s);
188  dn(3,isinf(dn(3,:))) = this.d2(3)/2;
189 
190  cnt = 0;
191 
192  /* conv = 1:length(x);
193  *finished = zeros(size(x));
194  *while ~isempty(conv) && cnt < this.MaxNewtonIterations */
195  while any(abs(rtmp-r) > this.NewtonTolerance) && cnt < this.MaxNewtonIterations
196 
197  /* Experimental setting: thinning out the finished values does not improve the
198  * overall performance.
199  * Find indices of finished values
200  * fidx = abs(xtmp-x) <= this.NewtonTolerance;
201  * if any(fidx)
202  * % Store finished values
203  * finished(conv(fidx)) = xtmp(fidx);
204  * conv(fidx) = [];
205  * x(fidx) = []; xtmp(fidx) = []; y(fidx) = [];
206  * n0(fidx) = []; dn0(fidx) = [];
207  * nx0(fidx) = []; dnx0(fidx) = [];
208  * nxr(fidx) = []; dnxr(fidx) = [];
209  * end */
210 
211  [g,dg] = this.optFun(r,s,n,dn);
212 
213  rtmp = r;
214  r = r - g./dg;
215  cnt = cnt + 1;
216 
217  /* if cnt > this.MaxNewtonIterations*.5
218  *showNewton;
219  *end */
220  end
221  if cnt == this.MaxNewtonIterations
222  error(" Bellfunction->ModifiedNewton: Max iterations of %d reached ",this.MaxNewtonIterations);
223  end
224 
225  /* function showNewton %#ok<*DEFNU>
226  * % Fix an identical y for all iterations
227  * si = 200;
228  * for i=1:5
229  *
230  * X = linspace(.5*min(min([x; xtmp],[],1)),2*max(max([x; xtmp],[],1)),si);
231  * gs = zeros(length(y),si);
232  * for idx = 1:length(y)
233  * gs(idx,:) = error.lipfun.ImprovedLocalSecantLipschitz.optFun(X,repmat(y(idx),size(X)),f,df,ddf,this.x0);
234  * end
235  *
236  * [g,dg] = error.lipfun.ImprovedLocalSecantLipschitz.optFun(x,y,f,df,ddf,this.x0);
237  * xtmp = x;
238  * x = x - g./dg;
239  * %plot(xs,gs,'r');%,'LineWidth',2
240  * figure(1);
241  * subplot(1,2,1);
242  * plot(X,gs,'b',X,0,'black-');
243  * hold on;
244  * plot([xtmp; x],[g; zeros(size(g))],x,0,'rx',xtmp,g,'rx');
245  * hold off;
246  * axis tight;
247  *
248  * subplot(1,2,2);
249  * X = linspace(0-this.xR,2*this.xR,si);
250  * gs = zeros(length(y),si);
251  * for idx = 1:length(y)
252  * gs(idx,:) = kernels.BellFunction.optFun(X,repmat(y(idx),size(X)),f,df,ddf,this.x0,this.PenaltyFactor);
253  * end
254  * plot(X,gs);
255  * hold on;
256  * plot(X,0,'black-');
257  * hold off;
258  * pause;
259  * end
260  * end */
261  }
262 
263 
264 
265 #if 0 //mtoc++: 'set.r0'
266 function r0(value) {
267  if ~isreal(value) || value < 0 || ~isscalar(value)
268  error(" r0 must be a scalar greater than zero. ");
269  end
270  this.fr0= value;
271  this.setConstants;
272  }
273 
274 #endif
275 
276 
277 
278 #if 0 //mtoc++: 'get.r0'
279 function value = r0() {
280  value = this.fr0;
281  }
282 
283 #endif
284 
285 
286  private:
287 
288  function setConstants() {
289 
290  /* Set outer bound for 'r_s' positions */
291  this.rm= this.evaluateScalar(0)*this.r0 /...
292  (this.evaluateScalar(0)-this.evaluateScalar(this.r0));
293  /* Set values needed for Newton iteration */
294  q = [0 this.r0 this.rm];
295  this.sc= this.evaluateScalar(q);
296  this.d1= this.evaluateD1(q);
297  this.d2= this.evaluateD2(q);
298  this.p= q;
299  }
307  protected:
308 
309 
310  function [g , dg , pi , pl , pr ] = optFun(r,s,n,dn) {
311  g = zeros(size(r));
312  d = g; c = d; dg = g;
313 
314  a = s < this.r0;
315  pi = a & r < this.r0 | ~a & r > this.r0;
316  pr = a & r > this.rm;
317  pl = ~a & r < 0;
318  std = ~(pi | pl | pr);
319 
320  /* Standard case */
321  rs = r(std); ss = s(std);
322  g(std) = this.evaluateD1(rs) - (this.evaluateScalar(rs)-this.evaluateScalar(ss))./(rs-ss);
323  g(isnan(g)) = 0;
324  dg(std) = this.evaluateD2(rs) - g(std)./(rs-ss);
325  ninf = isinf(dg);
326  dg(ninf) = this.evaluateD2(rs(ninf))/2;
327 
328  /* Penalty case */
329  penalty = ~std;
330  c(pi) = dn(2,pi).^2 ./ (4*n(2,pi));
331  d(pi) = 2*n(2,pi)./dn(2,pi) - this.r0;
332  c(pl) = dn(1,pl).^2 ./ (4*n(1,pl));
333  d(pl) = 2*n(1,pl)./dn(1,pl);
334  c(pr) = dn(3,pr).^2 ./ (4*n(3,pr));
335  d(pr) = 2*n(3,pr)./dn(3,pr) - this.rm;
336 
337  g(penalty) = c(penalty) .* (r(penalty) + d(penalty)).^2;
338  dg(penalty) = 2 * c(penalty) .* (r(penalty) + d(penalty));
339  /* Avoid exact matches! */
340  g(dg == 0) = 0;
341  dg(dg == 0) = 1;
342  }
343 
344 
345  public: /* ( Abstract ) */
346 
347  virtual function dr = evaluateD1() = 0;
355  virtual function ddr = evaluateD2() = 0;
363  public: /* ( Static ) */
364 
365 
366 
367 
368 
369  protected: /* ( Static ) */
370 
371  static function this = loadobj(this,from) {
372  if nargin > 1
373  /* NOTE: r0 must be set via setter in subclass at some stage. */
374  if isfield(from," fr0 ") && ~isempty(from.fr0)
375  this.fr0= from.fr0;
376  end
377  this.MaxNewtonIterations= from.MaxNewtonIterations;
378  this.NewtonTolerance= from.NewtonTolerance;
379  this = loadobj@KerMorObject(this, from);
380  elseif ~isa(this, " kernels.BellFunction ")
381  error(" Object passed is not a kernels.BellFunction instance and no init struct is given. ");
382  end
383  if isempty(this.fr0)
384  error(" Internal r0 field not persisted yet and not initialized in subclass loadobj method. ");
385  end
386  this.setConstants;
387  }
409 };
410 }
411 
412 
413 
function c = getGlobalLipschitz()
Computes the absolute value of the first derivative at x0 Implements the template method from BaseKer...
Definition: BellFunction.m:145
function rtmp = ModifiedNewton(rstart, s)
Definition: BellFunction.m:170
function copy = clone(copy)
The interface method with returns a copy of the current class instance.
Definition: BellFunction.m:156
BELLFUNCTION Summary of this class goes here Detailed explanation goes here.
Definition: BellFunction.m:18
static function this = loadobj(this, from)
As the constant properties are transient, they have to be re-computed upon loading.
Definition: BellFunction.m:371
function registerProps(varargin)
Call this method at any class that defines DPCM observed properties.
Definition: DPCMObject.m:125
virtual function ddr = evaluateD2()
Method for second derivative evaluation.
rm
The maximum ("right") value for any .
Definition: BellFunction.m:109
MaxNewtonIterations
Hard break for iteration count of modified newton algorithm.
Definition: BellFunction.m:92
KerMorObject()
Constructs a new KerMor object.
Definition: KerMorObject.m:55
r0
Point of maximum first derivative on scalar evaluation.
Definition: BellFunction.m:61
NewtonTolerance
Error tolerance for modified newton iteration.
Definition: BellFunction.m:77
virtual function phir = evaluateScalar(matrix< double > r)
Allows the evaluation of the function for scalar directly.
function [ g , dg , pi , pl , pr ] = optFun(r, s, n, dn)
Definition: BellFunction.m:310
virtual function dr = evaluateD1()
Method for first derivative evaluation.
Abstract class for radial basis function / rotation- and translation invariant kernels.
Definition: ARBFKernel.m:18