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

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