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

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