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

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