OpendTect  6.3
mathfunc.h
Go to the documentation of this file.
1 #pragma once
2 
3 /*+
4 ________________________________________________________________________
5 
6  (C) dGB Beheer B.V.; (LICENSE) http://opendtect.org/OpendTect_license.txt
7  Author: A.H.Bril
8  Date: 17-11-1999
9  Contents: Mathematical Functions
10 ________________________________________________________________________
11 
12 -*/
13 
14 
15 #include "algomod.h"
16 #include "interpol1d.h"
17 #include "ptrman.h"
18 #include "samplingdata.h"
19 #include "varlenarray.h"
20 #include "typeset.h"
21 #include "math2.h"
22 
23 #include <math.h>
24 
25 template <class T> class LineParameters;
26 template <class T> class ValueSeries;
27 
28 
37 template <class RT,class PT>
39 {
40 public:
41  virtual ~MathFunctionND() {}
42 
43  virtual RT getNDValue(const PT*) const = 0;
44  virtual int getNrDim() const = 0;
45 };
46 
48 
49 
58 template <class RT,class PT>
60 {
61 public:
62 
63  virtual RT getNDValue( const PT* pos ) const
64  { return getValue(*pos); }
65  virtual int getNrDim() const { return 1; }
66 
67  virtual RT getValue( PT ) const = 0;
68 
69 };
70 
73 
74 
79 template <class RT,class PT>
81 {
82 public:
84  : func_( f )
85  {}
86  RT operator[](int idx) const
87  { return func_.getValue( sd.atIndex(idx) ); }
88 
90 
91 protected:
92 
94 
95 };
96 
97 
102 template <class RT,class PT>
104 {
105 public:
106 
107  virtual RT getValue(PT,PT) const = 0;
108 
109  RT getNDValue( const PT* pos ) const
110  { return getValue(pos[0],pos[1]);}
111  int getNrDim() const { return 2; }
112 
113 };
114 
115 
119 template <class RT,class PT>
121 {
122 public:
123 
124  virtual RT getValue(PT,PT,PT) const = 0;
125 
126  RT getNDValue( const PT* pos ) const
127  { return getValue(pos[0],pos[1],pos[2]);}
128  int getNrDim() const { return 3; }
129 
130 };
131 
132 
133 
148 template <class xT,class yT>
150 {
151 public:
152 
153  enum InterpolType { Linear, Poly, Snap };
154  enum ExtrapolType { None, EndVal, ExtraPolGradient };
155 
157  ExtrapolType extr=EndVal )
158  : itype_(t)
159  , extrapol_(extr) {}
160 
161  void setEmpty() { x_.setSize(0); y_.setSize(0);}
162  int size() const { return x_.size(); }
163  bool isEmpty() const { return x_.isEmpty(); }
164  void add(xT x,yT y);
165  void remove(int idx);
166  yT getValue( xT x ) const
167  { return itype_ == Snap ? snapVal(x) : interpVal(x); }
168 
169  const TypeSet<xT>& xVals() const { return x_; }
170  const TypeSet<yT>& yVals() const { return y_; }
171 
172  InterpolType interpolType() const { return itype_; }
173  ExtrapolType extrapolateType() const { return extrapol_; }
174  bool extrapolate() const { return extrapol_ != None; }
175  void setInterpolType( InterpolType t ) { itype_ = t; }
176  void setExtrapolateType( ExtrapolType t ) { extrapol_ = t; }
177  virtual yT getNDValue( const xT* p ) const { return getValue(*p); }
178 
179 protected:
180 
185 
186  int baseIdx(xT) const;
187  yT snapVal(xT) const;
188  yT interpVal(xT) const;
189  yT outsideVal(xT) const;
190 
191 public:
192 
193  void setXValue(int idx,xT x);
197 };
198 
200 
201 
212 template <class RT,class PT>
214 {
215 public:
217  const PT* P_, const PT* N_)
218  : P( P_ )
219  , N( N_ )
220  , func( func_ )
221  {}
222 
223  RT getValue( PT lambda ) const
224  {
225  const int nrdim = func.getNrDim();
226  mAllocVarLenArr( PT, pos, nrdim );
227  for ( int idx=0; idx<nrdim; idx++ )
228  pos[idx] = P[idx] + N[idx]*lambda;
229 
230  return func.getNDValue( pos );
231  }
232 
233 protected:
234 
235  const PT* P;
236  const PT* N;
238 };
239 
240 
246 {
247 public:
248  SecondOrderPoly( float a_=0, float b_=0, float c_=0 )
249  : a( a_ ), b( b_ ), c( c_ )
250  {}
251 
256  void setFromSamples(float y0,float y1,float y2)
257  {
258  c = y1;
259  a = ( (y0+y2) / 2 ) - y1;
260  b = ( y2-y0 ) / 2;
261  }
262 
263  float getValue( float pos ) const
264  {
265  if ( Values::isUdf(pos) ) return mUdf(float);
266  return pos*pos * a + pos * b + c;
267  }
268 
269  float getExtremePos() const
270  {
271  if ( mIsZero(a,mDefEps) ) return mUdf(float);
272  return -b / (2*a);
273  }
274 
275  int getRoots( float& pos0, float& pos1 ) const
276  {
277  pos0 = pos1 = mUdf(float);
278 
279  if ( mIsZero(a,mDefEps) )
280  {
281  if ( mIsZero(b,mDefEps) )
282  return 0;
283 
284  pos0 = -c/b;
285  return 1;
286  }
287 
288  const double halfp = b/a/2;
289  const double q = c/a;
290 
291  const double squareterm = halfp*halfp-q;
292  if ( squareterm<0 )
293  return 0;
294 
295  const double sq = Math::Sqrt(squareterm);
296 
297 
298  pos0 = (float)(-halfp+sq);
299  pos1 = (float)(-halfp-sq);
300  return 2;
301  }
302 
303  LineParameters<float>* createDerivative() const;
304 
305  float a, b, c;
306 };
307 
308 
314 {
315 public:
316  ThirdOrderPoly( float a_=0, float b_=0,
317  float c_=0, float d_=0 )
318  : a( a_ ), b( b_ ), c( c_ ), d( d_ )
319  {}
320 
325  void setFromSamples(float y0,float y1,float y2,float y3)
326  {
327  b = ( (y2+y0) / 2 ) - y1;
328  c = y2 - ( ( 2*y0 + 3*y1 + y3 ) / 6 );
329  a = ( (y2-y0) / 2 ) - c;
330  d = y1;
331  }
332 
333  float getValue( float pos ) const
334  {
335  if ( Values::isUdf(pos) ) return mUdf(float);
336  const float possq = pos * pos;
337  return possq * pos * a + possq * b + pos * c + d;
338  }
339 
341  { return new SecondOrderPoly( a*3, b*2, c ); }
342 
343  int getExtremePos( float& pos0, float& pos1 ) const
344  {
345  pos0 = pos1 = mUdf(float);
346  if ( mIsZero(a,mDefEps) && mIsZero(b,mDefEps) )
347  return 0;
348  else if ( mIsZero(a,mDefEps) )
349  {
350  pos0 = -c / ( 2*b );
351  return 1;
352  }
353 
354  SecondOrderPoly derivate( a*3, b*2, c );
355  return derivate.getRoots(pos0, pos1);
356  }
357 
358  float a, b, c, d;
359 };
360 
361 
362 
364 {
365 public:
366  ValSeriesMathFunc(const ValueSeries<float>&,int sz);
367 
368  float getValue(float) const;
369 
370 protected:
372  int sz_;
373 };
374 
375 
376 
377 template <class mXT, class mYT> inline
379 {
380  const int sz = x_.size();
381  if ( sz < 1 ) return -1;
382  const mXT x0 = x_[0];
383  if ( x < x0 ) return -1;
384  if ( sz == 1 ) return x >= x0 ? 0 : -1;
385  const mXT xlast = x_[sz-1];
386  if ( x >= xlast ) return sz-1;
387  if ( sz == 2 ) return 0;
388 
389  int ilo = 0; int ihi = sz - 1;
390  while ( ihi - ilo > 1 )
391  {
392  int imid = (ihi+ilo) / 2;
393  if ( x < x_[imid] )
394  ihi = imid;
395  else
396  ilo = imid;
397  }
398 
399  return ilo;
400 }
401 
402 
403 template <class mXT, class mYT> inline
405 {
406  if ( mIsUdf(x) ) return;
407  if ( x_.isPresent(x) ) return;
408 
409  const int baseidx = baseIdx( x );
410  x_ += x; y_ += y;
411 
412  const int sz = x_.size();
413  if ( baseidx > sz - 3 )
414  return;
415 
416  mXT prevx = x; mYT prevy = y;
417  for ( int idx=baseidx+1; idx<sz; idx++ )
418  {
419  mXT tmpx = x_[idx]; mYT tmpy = y_[idx];
420  x_[idx] = prevx; y_[idx] = prevy;
421  prevx = tmpx; prevy = tmpy;
422  }
423 }
424 
425 
426 template <class mXT, class mYT> inline
428 {
429  if ( idx<0 || idx >= size() )
430  return;
431 
432  x_[idx] = x;
433 }
434 
435 
436 template <class mXT, class mYT> inline
438 {
439  if ( idx<0 || idx>=size() )
440  return;
441 
442  x_.removeSingle( idx );
443  y_.removeSingle( idx );
444 }
445 
446 
447 template <class mXT, class mYT> inline
449 {
450  if ( extrapol_ == None )
451  return mUdf(mYT);
452 
453  const int sz = x_.size();
454 
455  if ( extrapol_==EndVal || sz<2 )
456  return x-x_[0] < x_[sz-1]-x ? y_[0] : y_[sz-1];
457 
458  if ( x < x_[0] )
459  {
460  const mYT gradient = (mYT)(y_[1]-y_[0]) / (mYT) (x_[1]-x_[0]);
461  return (mYT)(y_[0] + (x-x_[0]) * gradient);
462  }
463 
464  const mYT gradient = (mYT)(y_[sz-1]-y_[sz-2]) / (mYT) (x_[sz-1]-x_[sz-2]);
465  return (mYT)(y_[sz-1] + (x-x_[sz-1]) * gradient);
466 }
467 
468 
469 
470 
471 template <class mXT, class mYT> inline
473 {
474  const int sz = x_.size();
475  if ( sz < 1 ) return mUdf(mYT);
476 
477  if ( x < x_[0] || x > x_[sz-1] )
478  return outsideVal(x);
479 
480  const int baseidx = baseIdx( x );
481 
482  if ( baseidx < 0 )
483  return y_[0];
484  if ( baseidx > sz-2 )
485  return y_[sz - 1];
486  return x - x_[baseidx] < x_[baseidx+1] - x ? y_[baseidx] : y_[baseidx+1];
487 }
488 
489 
490 template <class mXT, class mYT> inline
492 {
493  const int sz = x_.size();
494  if ( sz < 1 ) return mUdf(mYT);
495 
496  if ( x < x_[0] || x > x_[sz-1] )
497  return outsideVal(x);
498  else if ( sz < 2 )
499  return y_[0];
500 
501  const int i0 = baseIdx( x );
502  const mYT v0 = y_[i0];
503  if ( i0 == sz-1 )
504  return v0;
505 
506  const mXT x0 = x_[i0];
507  const int i1 = i0 + 1; const mXT x1 = x_[i1]; const mYT v1 = y_[i1];
508  const mXT dx = x1 - x0;
509  if ( dx == 0 ) return v0;
510 
511  const mXT relx = (x - x0) / dx;
512  if ( mIsUdf(v0) || mIsUdf(v1) )
513  return relx < 0.5 ? v0 : v1;
514 
515  // OK - we have 2 nearest points and they:
516  // - are not undef
517  // - don't coincide
518 
519  if ( itype_ == Linear )
520  return (mYT)(v1 * relx + v0 * (1-relx));
521 
522  const int im1 = i0 > 0 ? i0 - 1 : i0;
523  const mXT xm1 = im1 == i0 ? x0 - dx : x_[im1];
524  const mYT vm1 = mIsUdf(y_[im1]) ? v0 : y_[im1];
525 
526  const int i2 = i1 < sz-1 ? i1 + 1 : i1;
527  const mXT x2 = i2 == i1 ? x1 + dx : x_[i2];
528  const mYT v2 = mIsUdf(y_[i2]) ? v1 : y_[i2];
529 
530  return (mYT)Interpolate::poly1D( (float) xm1, vm1, (float) x0, v0,
531  (float) x1, v1,
532  (float) x2, v2, (float) x );
533 }
#define mExpClass(module)
Definition: commondefs.h:157
ExtrapolType
Definition: mathfunc.h:154
#define mIsUdf(val)
Use mIsUdf to check for undefinedness of simple types.
Definition: undefval.h:285
SecondOrderPoly * createDerivative() const
Definition: mathfunc.h:340
RT operator[](int idx) const
Definition: mathfunc.h:86
const TypeSet< xT > & xVals() const
Definition: mathfunc.h:169
yT outsideVal(xT) const
Definition: mathfunc.h:448
void setExtrapolateType(ExtrapolType t)
Definition: mathfunc.h:176
A class for 3rd order polynomials on the form: a x^3 + b x^2 + c x + d.
Definition: mathfunc.h:313
float getValue(float pos) const
Definition: mathfunc.h:333
T poly1D(float x0, T v0, float x1, T v1, float x2, T v2, float x3, T v3, float x)
Definition: interpol1d.h:216
InterpolType
Definition: mathfunc.h:153
MathFunctionND< float, float > FloatMathFunctionND
Definition: mathfunc.h:47
const PT * N
Definition: mathfunc.h:236
Steepness and intercept.
Definition: linear.h:25
#define mIsZero(x, eps)
Definition: commondefs.h:55
TypeSet< xT > x_
Definition: mathfunc.h:183
MathFunction< float, float > FloatMathFunction
Definition: mathfunc.h:71
virtual yT getNDValue(const xT *p) const
Definition: mathfunc.h:177
float d
Definition: mathfunc.h:358
int getNrDim() const
Definition: mathfunc.h:128
void setXValue(int idx, xT x)
Definition: mathfunc.h:427
float getExtremePos() const
Definition: mathfunc.h:269
Mathematical function.
Definition: mathfunc.h:59
SecondOrderPoly(float a_=0, float b_=0, float c_=0)
Definition: mathfunc.h:248
void remove(int idx)
Definition: mathfunc.h:437
bool isEmpty() const
Definition: mathfunc.h:163
void setFromSamples(float y0, float y1, float y2, float y3)
Definition: mathfunc.h:325
Makes a MathFunction indexable through an operator[].
Definition: mathfunc.h:80
InterpolType interpolType() const
Definition: mathfunc.h:172
float c
Definition: mathfunc.h:305
void setInterpolType(InterpolType t)
Definition: mathfunc.h:175
SamplingData< PT > sd
Definition: mathfunc.h:89
FixedString None()
Definition: keystrs.h:90
RT getNDValue(const PT *pos) const
Definition: mathfunc.h:126
const TypeSet< yT > & yVals() const
Definition: mathfunc.h:170
ThirdOrderPoly(float a_=0, float b_=0, float c_=0, float d_=0)
Definition: mathfunc.h:316
bool extrapolate() const
Definition: mathfunc.h:174
virtual RT getNDValue(const PT *pos) const
Definition: mathfunc.h:63
const MathFunctionND< RT, PT > & func
Definition: mathfunc.h:237
int sz_
Definition: mathfunc.h:372
Definition: seistype.h:59
#define mUdf(type)
Use this macro to get the undefined for simple types.
Definition: undefval.h:270
const PT * P
Definition: mathfunc.h:235
A Math Function as in F(x,y,z).
Definition: mathfunc.h:120
void setEmpty()
Definition: mathfunc.h:161
Interface to a series of values.
Definition: odmemory.h:15
yT interpVal(xT) const
Definition: mathfunc.h:491
int getExtremePos(float &pos0, float &pos1) const
Definition: mathfunc.h:343
BendPointBasedMathFunction< float, float > PointBasedMathFunction
Definition: mathfunc.h:199
Multidimensional Mathematical function.
Definition: mathfunc.h:38
virtual int getNrDim() const
Definition: mathfunc.h:65
#define mAllocVarLenArr(type, varnm, __size)
Definition: varlenarray.h:52
#define mDefEps
Definition: commondefs.h:60
void add(xT x, yT y)
Definition: mathfunc.h:404
AlongVectorFunction(const MathFunctionND< RT, PT > &func_, const PT *P_, const PT *N_)
Definition: mathfunc.h:216
Definition: mathfunc.h:363
RT getNDValue(const PT *pos) const
Definition: mathfunc.h:109
ExtrapolType extrapolateType() const
Definition: mathfunc.h:173
ExtrapolType extrapol_
Definition: mathfunc.h:182
BendPointBasedMathFunction(InterpolType t=Linear, ExtrapolType extr=EndVal)
Definition: mathfunc.h:156
A Math Function as in F(x,y).
Definition: mathfunc.h:103
virtual ~MathFunctionND()
Definition: mathfunc.h:41
yT snapVal(xT) const
Definition: mathfunc.h:472
int size() const
Definition: mathfunc.h:162
const ValueSeries< float > & vs_
Definition: mathfunc.h:371
int getNrDim() const
Definition: mathfunc.h:111
Definition: simpnumer.h:188
RT getValue(PT lambda) const
Definition: mathfunc.h:223
const RefTree & RT()
float getValue(float pos) const
Definition: mathfunc.h:263
void setFromSamples(float y0, float y1, float y2)
Definition: mathfunc.h:256
A MathFunction that cuts through another mathfunction with higher number of dimensions.
Definition: mathfunc.h:213
MathFunction based on bend points.
Definition: mathfunc.h:149
TypeSet< yT > y_
Definition: mathfunc.h:184
#define mClass(module)
Definition: commondefs.h:161
MathFunctionSampler(const MathFunction< RT, PT > &f)
Definition: mathfunc.h:83
bool isUdf(const T &t)
Definition: undefval.h:241
const MathFunction< RT, PT > & func_
Definition: mathfunc.h:93
MathFunction< double, double > DoubleMathFunction
Definition: mathfunc.h:72
float Sqrt(float)
int baseIdx(xT) const
Definition: mathfunc.h:378
InterpolType itype_
Definition: mathfunc.h:181
A class for 2nd order polynomials of the form: a x^2 + b x + c.
Definition: mathfunc.h:245
yT getValue(xT x) const
Definition: mathfunc.h:166
Definition: mathfunc.h:154
int getRoots(float &pos0, float &pos1) const
Definition: mathfunc.h:275

Generated at for the OpendTect seismic interpretation project. Copyright (C): dGB Beheer B. V. 2017