OpendTect  6.6
simpnumer.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: Bert Bril & Kris Tingdahl
8  Date: 12-4-1999
9  Contents: 'Simple' numerical functions
10  RCS: $Id$
11 ________________________________________________________________________
12 
13 */
14 
15 #include "algomod.h"
16 #include "typeset.h"
17 #include "undefval.h"
18 #include "ranges.h"
19 #include "math2.h"
20 
21 
25 namespace Interpolate
26 {
27 
28 inline int getArrIdxPosition( const float farridx, const int arrsz,
29  float& relpos, const float eps=1e-4 )
30 {
31  int arridx = (int)farridx;
32  relpos = farridx - arridx;
33 
34  if ( arridx==-1 && mIsEqual(relpos,1,1e-4) )
35  { arridx = 0; relpos = 0; }
36  else if ( arridx==arrsz-1 && mIsZero(relpos,1e-4) )
37  { arridx = arrsz-2; relpos = 1; }
38 
39  return arridx;
40 }
41 
42 } // namespace Interpolate
43 
44 
48 template <class T> inline
50 {
51  T shift = 0;
52 
53  if ( !val0 ) return val1;
54  if ( !val1 ) return val0;
55 
56  while ( (val0&1)==0 && (val1&1)==0 )
57  {
58  val0 >>= 1;
59  val1 >>= 1;
60  shift++;
61  }
62 
63  do
64  {
65  if ((val0 & 1) == 0)
66  val0 >>= 1;
67  else if ((val1 & 1) == 0)
68  val1 >>= 1;
69  else if (val0 >= val1)
70  val0 = (val0-val1) >> 1;
71  else
72  val1 = (val1-val0) >> 1;
73  } while ( val0 );
74 
75  return val1 << shift;
76 }
77 
78 
82 template <class T> inline
84  const StepInterval<T>& b )
85 {
86  const T start = mMIN( a.start, b.start );
87 
88  T step = greatestCommonDivisor( a.step, b.step );
89  step = greatestCommonDivisor( step, (T) Math::Abs(a.start-b.start) );
90 
91  const T stop = mMAX( a.start+((T)a.nrSteps())*a.step,
92  b.start+((T)b.nrSteps())*b.step );
93  return StepInterval<T>( start, stop, step );
94 }
95 
96 
103 template <class iT>
104 inline iT exactPower( iT val, iT base )
105 {
106  if ( val==base ) return 1;
107 
108  if ( val%base )
109  return 0;
110 
111  iT res = exactPower( val/base, base );
112  if ( res ) return 1 + res;
113 
114  return 0;
115 }
116 
117 
118 template <class iT>
119 inline iT nextPower( iT val, iT base )
120 {
121  iT res = 1;
122  while ( res<val ) res *= base;
123  return res;
124 }
125 
126 
127 template <class iT>
128 inline iT getPow2Sz( iT actsz, const bool above=true,
129  iT minsz=1, iT maxsz=0 )
130 {
131  char npow = 0; char npowextra = actsz == 1 ? 1 : 0;
132  iT sz = actsz;
133  while ( sz>1 )
134  {
135  if ( above && !npowextra && sz % 2 )
136  npowextra = 1;
137  sz /= 2; npow++;
138  }
139 
140  sz = Math::IntPowerOf( 2, npow + npowextra );
141  if ( sz<minsz ) sz = minsz;
142  if ( maxsz && sz>maxsz ) sz = maxsz;
143  return sz;
144 }
145 
146 
147 template <class iT>
148 inline iT nextPower2( iT nr, iT minnr, iT maxnr )
149 {
150  if ( nr>maxnr )
151  return maxnr;
152 
153  iT newnr = minnr;
154  while ( nr > newnr )
155  newnr *= 2;
156 
157  return newnr;
158 }
159 
160 
166 template <class iT>
167 inline iT nrBlocks( iT totalsamples, iT basesize, iT overlapsize )
168 {
169  iT res = 0;
170  while ( totalsamples>basesize )
171  {
172  res++;
173  totalsamples = totalsamples - basesize + overlapsize;
174  }
175 
176  return res+1;
177 }
178 
179 
187 namespace Taper
188 {
189  enum Type { Cosine, Linear };
190 };
191 
192 
193 template <class T>
194 bool taperArray( T* array, int sz, int lowpos, int highpos, Taper::Type type )
195 {
196  if ( lowpos >= sz || lowpos < 0 ||
197  highpos >= sz || highpos < 0 ||
198  highpos == lowpos )
199  return false;
200 
201  int pos = lowpos < highpos ? 0 : sz - 1 ;
202  int inc = lowpos < highpos ? 1 : -1 ;
203 
204  while ( pos != lowpos )
205  {
206  array[pos] = 0;
207  pos += inc;
208  }
209 
210  int tapersz = abs( highpos - lowpos );
211  float taperfactor = type == Taper::Cosine ? M_PI : 0;
212  float taperfactorinc = ( type == Taper::Cosine ? M_PI : 1 ) / tapersz;
213 
214 
215  while ( pos != highpos )
216  {
217  array[pos] *= type == Taper::Cosine ? .5 + .5 * cos( taperfactor )
218  : taperfactor;
219  pos += inc;
220  taperfactor += taperfactorinc;
221  }
222 
223  return true;
224 }
225 
226 
235 template <class T>
236 inline T sampledGradient( T ym2, T ym1, T y0_, T y1_, T y2 )
237 {
238  bool um1 = Values::isUdf(ym1), u0 = Values::isUdf(y0_),
239  u1 = Values::isUdf(y1_);
240 
241  if ( Values::isUdf(ym2) || Values::isUdf(y2) )
242  {
243  if ( um1 || u1 )
244  { if ( !u0 && !(um1 && u1) ) return um1 ? y1_ - y0_ : y0_ - ym1; }
245  else
246  return (y1_-ym1) * .5;
247  }
248  else if ( (um1 && u1) || (u0 && (um1 || u1)) )
249  return (y2-ym2) * .25;
250  else if ( um1 || u1 )
251  {
252  return um1 ? ((16*y1_) - 3*y2 - ym2) / 12 - y0_
253  : ((-16*ym1) + 3*ym2 + y2) / 12 + y0_;
254  }
255  else
256  return (8 * ( y1_ - ym1 ) - y2 + ym2) / 12;
257 
258  return mUdf(T);
259 }
260 
261 
262 template <class X, class Y, class RT>
263 inline void getGradient( const X& x, const Y& y, int sz, int firstx, int firsty,
264  RT* gradptr=0, RT* interceptptr=0 )
265 {
266  RT xy_sum = 0, x_sum=0, y_sum=0, xx_sum=0;
267 
268  for ( int idx=0; idx<sz; idx++ )
269  {
270  RT xval = x[idx+firstx];
271  RT yval = y[idx+firsty];
272 
273  x_sum += xval;
274  y_sum += yval;
275  xx_sum += xval*xval;
276  xy_sum += xval*yval;
277  }
278 
279  RT grad = ( sz*xy_sum - x_sum*y_sum ) / ( sz*xx_sum - x_sum*x_sum );
280  if ( gradptr ) *gradptr = grad;
281 
282  if ( interceptptr ) *interceptptr = (y_sum - grad*x_sum)/sz;
283 }
284 
285 
286 template <class X>
287 inline float variance( const X& x, int sz )
288 {
289  if ( sz < 2 ) return mUdf(float);
290 
291  float sum=0;
292  float sqsum=0;
293 
294  for ( int idx=0; idx<sz; idx++ )
295  {
296  float val = x[idx];
297 
298  sum += val;
299  sqsum += val*val;
300  }
301 
302  return (sqsum - sum * sum / sz)/ (sz -1);
303 }
304 
305 
317 inline int solve3DPoly( double a, double b, double c,
318  double& root0,
319  double& root1,
320  double& root2 )
321 {
322  const double a2 = a*a;
323  const double q = (a2-3*b)/9;
324  const double r = (2*a2*a-9*a*b+27*c)/54;
325  const double q3 = q*q*q;
326  const double r2 = r*r;
327 
328 
329  const double minus_a_through_3 = -a/3;
330 
331  if ( r2<q3 )
332  {
333  const double minus_twosqrt_q = -2*Math::Sqrt(q);
334  const double theta = Math::ACos(r/Math::Sqrt(q3));
335  const double twopi = M_2PI;
336 
337 
338  root0 = minus_twosqrt_q*cos(theta/3)+minus_a_through_3;
339  root1=minus_twosqrt_q*cos((theta-twopi)/3)+minus_a_through_3;
340  root2=minus_twosqrt_q*cos((theta+twopi)/3)+minus_a_through_3;
341  return 3;
342  }
343 
344  const double A=(r>0?-1:1)*pow(fabs(r)+Math::Sqrt(r2-q3),1/3);
345  const double B=mIsZero(A,mDefEps)?0:q/A;
346 
347  root0 = A+B+minus_a_through_3;
348 
361  return 1;
362 }
363 
364 
365 template <class T>
366 inline bool holdsClassValue( const T val, const unsigned int maxclss=50 )
367 {
368  if ( mIsUdf(val) ) return true;
369  if ( val < -mDefEps ) return false;
370  const int ival = (int)(val + .5);
371  return ival <= maxclss && mIsEqual(val,ival,mDefEps);
372 }
373 
374 
375 template <class T>
376 inline bool holdsClassValues( const T* vals, od_int64 sz,
377  const unsigned int maxclss=50,
378  const unsigned int samplesz=100 )
379 {
380  if ( sz < 1 ) return true;
381  if ( sz <= samplesz )
382  {
383  for ( int idx=0; idx<sz; idx++ )
384  {
385  if ( !holdsClassValue(vals[idx],maxclss) )
386  return false;
387  }
388  return true;
389  }
390 
392  seed *= seed + 1; // Clumsy but cheap sort-of random generation
393 
394  for ( int idx=0; idx<samplesz; idx++ )
395  {
396  od_int64 arridx = ((1+idx) * seed) % samplesz;
397  if ( arridx<0 )
398  arridx = -arridx;
399 
400  if ( !holdsClassValue(vals[arridx],maxclss) )
401  return false;
402  }
403  return true;
404 }
405 
406 
407 template <class T>
408 inline bool isSigned8BitesValue( const T val )
409 {
410  if ( val>127 || val<-128 )
411  return false;
412 
413  const int ival = (int)(val>0 ? val+.5 : val-.5);
414  return mIsEqual(val,ival,mDefEps);
415 }
416 
417 
418 template <class T>
419 inline bool is8BitesData( const T* vals, od_int64 sz,
420  const unsigned int samplesz=100 )
421 {
422  if ( holdsClassValues(vals,sz,255,samplesz) )
423  return true;
424 
425  if ( sz <= samplesz )
426  {
427  for ( int idx=0; idx<sz; idx++ )
428  {
429  if ( !isSigned8BitesValue(vals[idx]) )
430  return false;
431  }
432  return true;
433  }
434 
436  seed *= seed + 1; // Clumsy but cheap sort-of random generation
437 
438  for ( int idx=0; idx<samplesz; idx++ )
439  {
440  od_int64 arridx = ((1+idx) * seed) % samplesz;
441  if ( arridx<0 )
442  arridx = -arridx;
443 
444  if ( !isSigned8BitesValue(vals[arridx]) )
445  return false;
446  }
447  return true;
448 }
449 
sKey::X
FixedString X()
Definition: keystrs.h:188
exactPower
iT exactPower(iT val, iT base)
Definition: simpnumer.h:104
getCommonStepInterval
StepInterval< T > getCommonStepInterval(const StepInterval< T > &a, const StepInterval< T > &b)
Definition: simpnumer.h:83
ArrayMath::val1
const T val1
Definition: arrayndalgo.h:1706
getPow2Sz
iT getPow2Sz(iT actsz, const bool above=true, iT minsz=1, iT maxsz=0)
Definition: simpnumer.h:128
above
@ above
Definition: i_layout.h:28
mIsEqual
#define mIsEqual(x, y, eps)
Definition: commondefs.h:67
greatestCommonDivisor
T greatestCommonDivisor(T val0, T val1)
Definition: simpnumer.h:49
taperArray
bool taperArray(T *array, int sz, int lowpos, int highpos, Taper::Type type)
Definition: simpnumer.h:194
mIsUdf
#define mIsUdf(val)
Use mIsUdf to check for undefinedness of simple types.
Definition: undefval.h:289
StepInterval::nrSteps
int nrSteps() const
Definition: ranges.h:791
od_int64
#define od_int64
Definition: plftypes.h:35
mMAX
#define mMAX(x, y)
Definition: commondefs.h:61
nextPower2
iT nextPower2(iT nr, iT minnr, iT maxnr)
Definition: simpnumer.h:148
mDefEps
#define mDefEps
Definition: commondefs.h:71
typeset.h
is8BitesData
bool is8BitesData(const T *vals, od_int64 sz, const unsigned int samplesz=100)
Definition: simpnumer.h:419
Math::Abs
unsigned int Abs(unsigned int i)
Definition: math2.h:79
Math::IntPowerOf
iT IntPowerOf(iT i, iPOW p)
Definition: math2.h:121
Interpolate::getArrIdxPosition
int getArrIdxPosition(const float farridx, const int arrsz, float &relpos, const float eps=1e-4)
Definition: simpnumer.h:28
undefval.h
Taper
Taper an indexable array from 1 to taperfactor. If lowpos is less than highpos, the samples array[0] ...
Definition: simpnumer.h:188
M_2PI
#define M_2PI
Definition: commondefs.h:83
StepInterval
Interval with step.
Definition: commontypes.h:32
Values::isUdf
bool isUdf(const T &t)
Definition: undefval.h:245
Strat::RT
const RefTree & RT()
nextPower
iT nextPower(iT val, iT base)
Definition: simpnumer.h:119
mIsZero
#define mIsZero(x, eps)
Definition: commondefs.h:66
solve3DPoly
int solve3DPoly(double a, double b, double c, double &root0, double &root1, double &root2)
Definition: simpnumer.h:317
Taper::Linear
@ Linear
Definition: simpnumer.h:189
isSigned8BitesValue
bool isSigned8BitesValue(const T val)
Definition: simpnumer.h:408
holdsClassValues
bool holdsClassValues(const T *vals, od_int64 sz, const unsigned int maxclss=50, const unsigned int samplesz=100)
Definition: simpnumer.h:376
mMIN
#define mMIN(x, y)
Definition: commondefs.h:62
getGradient
void getGradient(const X &x, const Y &y, int sz, int firstx, int firsty, RT *gradptr=0, RT *interceptptr=0)
Definition: simpnumer.h:263
Taper::Type
Type
Definition: simpnumer.h:189
variance
float variance(const X &x, int sz)
Definition: simpnumer.h:287
nrBlocks
iT nrBlocks(iT totalsamples, iT basesize, iT overlapsize)
Definition: simpnumer.h:167
M_PI
#define M_PI
Definition: commondefs.h:77
mUdf
#define mUdf(type)
Use this macro to get the undefined for simple types.
Definition: undefval.h:274
sKey::Y
FixedString Y()
Definition: keystrs.h:193
mDefineStaticLocalObject
#define mDefineStaticLocalObject(type, var, init)
Definition: commondefs.h:203
Interpolate
Definition: interpol1d.h:38
ranges.h
Math::Sqrt
float Sqrt(float)
Taper::Cosine
@ Cosine
Definition: simpnumer.h:189
sampledGradient
T sampledGradient(T ym2, T ym1, T y0_, T y1_, T y2)
Definition: simpnumer.h:236
math2.h
holdsClassValue
bool holdsClassValue(const T val, const unsigned int maxclss=50)
Definition: simpnumer.h:366
Math::ACos
float ACos(float)
StepInterval::step
T step
Definition: ranges.h:200

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