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

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