OpendTect-6_4  6.4
idxable.h
Go to the documentation of this file.
1 #ifndef idxable_h
2 #define idxable_h
3 
4 /*
5 ________________________________________________________________________
6 
7  (C) dGB Beheer B.V.; (LICENSE) http://opendtect.org/OpendTect_license.txt
8  Author: Bert & Kris
9  Date: Mar 2006
10  RCS: $Id$
11 ________________________________________________________________________
12 
13 */
14 
15 #include "gendefs.h"
16 #include "interpol1d.h"
17 #include "mathfunc.h"
18 #include "sorting.h"
19 
30 namespace IdxAble
31 {
32 
37 template <class T1,class T2,class T3>
38 inline T3 indexOf( const T1& arr, T3 sz, const T2& val, T3 notfoundval )
39 {
40  for ( T3 idx=0; idx<sz; idx++ )
41  {
42  if ( arr[idx] == val )
43  return idx;
44  }
45  return notfoundval;
46 }
47 
52 template <class T1,class T2,class T3>
53 inline T3 derefIndexOf( const T1& arr, T3 sz, const T2& val, T3 notfoundval )
54 {
55  for ( T3 idx=0; idx<sz; idx++ )
56  {
57  if ( *arr[idx] == val )
58  return idx;
59  }
60  return notfoundval;
61 }
62 
63 
74 template <class T1,class T2,class T3>
75 bool findPos( const T1& posarr, T3 sz, T2 pos, T3 beforefirst, T3& idx )
76 {
77  idx = beforefirst;
78  if ( sz < 1 || pos < posarr[0] )
79  return false;
80 
81  if ( pos == posarr[0] )
82  { idx = 0; return true; }
83  else if ( pos > posarr[sz-1] || pos == posarr[sz-1] )
84  { idx = sz-1; return pos == posarr[sz-1]; }
85 
86  T3 idx1 = 0;
87  T3 idx2 = sz-1;
88  while ( idx2 - idx1 > 1 )
89  {
90  idx = (idx2 + idx1) / 2;
91  T2 arrval = posarr[idx];
92  if ( arrval == pos ) return true;
93  else if ( arrval > pos ) idx2 = idx;
94  else idx1 = idx;
95  }
96 
97  idx = idx1;
98  return posarr[idx] == pos;
99 }
100 
101 
112 template <class T1,class T2,class T3>
113 bool findFPPos( const T1& posarr, T3 sz, T2 pos, T3 beforefirst, T3& idx,
114  T2 eps=mDefEps )
115 {
116  idx = beforefirst;
117  if ( !sz ) return false;
118  if ( sz < 2 || pos <= posarr[0] )
119  {
120  if ( mIsEqual(pos,posarr[0],eps) )
121  { idx = 0; return true; }
122  else
123  return false;
124  }
125  else if ( pos >= posarr[sz-1] )
126  { idx = sz-1; return mIsEqual(pos,posarr[sz-1],eps); }
127 
128  T3 idx1 = 0;
129  T3 idx2 = sz-1;
130 
131  while ( idx2 - idx1 > 1 )
132  {
133  idx = (idx2 + idx1) / 2;
134  T2 diff = posarr[idx] - pos;
135  if ( mIsZero(diff,eps) ) return true;
136  else if ( diff > 0 ) idx2 = idx;
137  else idx1 = idx;
138  }
139 
140  idx = idx1;
141  return mIsEqual(pos,posarr[idx],eps);
142 }
143 
151 template <class X>
152 inline int getLowIdx( const X& x, int sz, double pos )
153 {
154  int idx; findFPPos( x, sz, pos, -1, idx ); return idx;
155 }
156 
157 
167 template <class X>
168 inline int getUpperIdx( const X& x, int sz, double pos )
169 {
170  int idx;
171  const bool exactmatch = findFPPos( x, sz, pos, -1, idx );
172  return idx < 1 ? 1 : ( exactmatch ? idx : idx+1 );
173 }
174 
175 
181 template <class X,class Y,class RT>
182 inline void interpolatePositioned( const X& x, const Y& y, int sz,
183  float desiredx,
184  RT& ret, bool extrapolate=false )
185 {
186  if ( sz < 1 )
187  ret = mUdf(RT);
188  else if ( sz == 1 )
189  ret = extrapolate ? y[0] : mUdf(RT);
190 
191  else if ( sz == 2 )
192  ret = Interpolate::linear1D( x[0], y[0], x[1], y[1], desiredx );
193  else if ( desiredx < x[0] || desiredx > x[sz-1] )
194  {
195  if ( !extrapolate )
196  ret = mUdf(RT);
197  else
198  ret = desiredx < x[0]
199  ? Interpolate::linear1D( x[0], y[0], x[1], y[1], desiredx )
200  : Interpolate::linear1D( x[sz-2], y[sz-2], x[sz-1], y[sz-1],
201  desiredx );
202  return;
203  }
204 
205  int prevpos = getLowIdx( x, sz, desiredx );
206  int nextpos = prevpos + 1;
207 
208  if ( sz == 3 )
209  ret = Interpolate::linear1D( x[prevpos], y[prevpos],
210  x[nextpos], y[nextpos], desiredx );
211  else
212  {
213  if ( prevpos == 0 )
214  { prevpos++; nextpos++; }
215  else if ( nextpos == sz-1 )
216  { prevpos--; nextpos--; }
217 
218  ret = Interpolate::poly1D( x[prevpos-1], y[prevpos-1],
219  x[prevpos], y[prevpos],
220  x[nextpos], y[nextpos],
221  x[nextpos+1], y[nextpos+1],
222  desiredx );
223  }
224 }
225 
226 
227 template <class X,class Y>
228 inline float interpolatePositioned( const X& x, const Y& y, int sz, float pos,
229  bool extrapolate=false )
230 {
231  float ret = mUdf(float);
232  interpolatePositioned( x, y, sz, pos, ret, extrapolate );
233  return ret;
234 }
235 
236 
240 template <class T>
241 inline int getInterpolateIdxsWithOff( const T& idxabl, od_int64 sz,
242  od_int64 offset, float pos, bool extrap, float snapdist, od_int64 p[4] )
243 {
244  if ( sz < 1
245  || (!extrap && (pos<-snapdist || (pos+offset)>sz-1+snapdist)) )
246  return -1;
247 
248  od_int64 intpos = mNINT64( pos );
249  const float dist = pos - intpos;
250  intpos += offset;
251  if ( dist>-snapdist && dist<snapdist && intpos>-1 && intpos<sz )
252  { p[0] = intpos; return 0; }
253 
254  p[1] = dist > 0 ? intpos : intpos - 1;
255  if ( p[1] < 0 ) p[1] = 0;
256  if ( p[1] >= sz ) p[1] = sz - 1;
257  p[0] = p[1] < 1 ? p[1] : p[1] - 1;
258  p[2] = p[1] < sz-1 ? p[1] + 1 : p[1];
259  p[3] = p[2] < sz-1 ? p[2] + 1 : p[2];
260  return 1;
261 }
262 
263 
264 template <class T>
265 inline int getInterpolateIdxs( const T& idxabl, int sz, float pos, bool extrap,
266  float snapdist, od_int64 p[4] )
267 {
268  return getInterpolateIdxsWithOff<T>(idxabl,sz,0,pos,extrap,snapdist,p);
269 }
270 
271 
272 template <class T,class RT>
273 inline bool interpolateReg( const T& idxabl, int sz, float pos, RT& ret,
274  bool extrapolate=false, float snapdist=mDefEps )
275 {
276  od_int64 p[4];
277  int res = getInterpolateIdxs( idxabl, sz, pos, extrapolate, snapdist, p );
278  if ( res < 0 )
279  { ret = mUdf(RT); return false; }
280  else if ( res == 0 )
281  { ret = idxabl[p[0]]; return true; }
282 
283  const float relpos = pos - p[1];
284  ret = Interpolate::polyReg1D( idxabl[p[0]], idxabl[p[1]], idxabl[p[2]],
285  idxabl[p[3]], relpos );
286  return true;
287 }
288 
289 
293 template <class T,class RT>
294 inline bool interpolateRegWithUdfWithOff( const T& idxabl, od_int64 sz,
295  od_int64 offset, float pos, RT& ret, bool extrapolate=false,
296  float snapdist=mDefEps )
297 {
298  od_int64 p[4];
299  int res = getInterpolateIdxsWithOff<T>( idxabl, sz, offset, pos,
300  extrapolate, snapdist, p );
301  if ( res < 0 )
302  { ret = mUdf(RT); return false; }
303  else if ( res == 0 )
304  { ret = idxabl[p[0]]; return true; }
305 
306  const float relpos = pos - p[1];
307  ret = Interpolate::polyReg1DWithUdf( idxabl[p[0]], idxabl[p[1]],
308  idxabl[p[2]], idxabl[p[3]], relpos );
309  return true;
310 }
311 
312 
313 template <class T,class RT>
314 inline bool interpolateRegWithUdf( const T& idxabl, int sz, float pos, RT& ret,
315  bool extrapolate=false, float snapdist=mDefEps )
316 {
317  return interpolateRegWithUdfWithOff<T,RT>( idxabl, sz, 0, pos, ret,
318  extrapolate, snapdist );
319 }
320 
321 
322 template <class T>
323 inline float interpolateReg( const T& idxabl, int sz, float pos,
324  bool extrapolate=false, float snapdist=mDefEps )
325 {
326  float ret = mUdf(float);
327  interpolateReg( idxabl, sz, pos, ret, extrapolate, snapdist );
328  return ret;
329 }
330 
331 
332 template <class T>
333 inline float interpolateRegWithUdf( const T& idxabl, int sz, float pos,
334  bool extrapolate=false,
335  float snapdist=mDefEps )
336 {
337  float ret = mUdf(float);
338  interpolateRegWithUdf( idxabl, sz, pos, ret, extrapolate, snapdist );
339  return ret;
340 }
341 
342 
343 /*Given an array of values and a number of calibrated values at different
344  positions, compute a n array of values that is calibrated everywhere.
345  Depending on usefactor, the calibration will either be with absolute numbers
346  or with factors. The calibration curve can optionally be output, if
347  so, it should have at least sz samples allocated. */
348 
349 
350 template <class T> inline
351 void calibrateArray( const T* input, int sz,
352  const T* controlpts, const int* controlsamples, int nrcontrols,
353  bool usefactor, T* output,
354  float* calibrationcurve = 0 )
355 {
356  int firstsample = mUdf(int), lastsample = -mUdf(int);
358  for ( int idx=0; idx<nrcontrols; idx++ )
359  {
360  const int sample = controlsamples[idx];
361  if ( sample>=sz )
362  continue;
363 
364  if ( !idx || sample<firstsample )
365  firstsample = sample;
366  if ( !idx || sample>=lastsample )
367  lastsample = sample;
368 
369  const float value = usefactor
370  ? controlpts[idx]/input[sample]
371  : controlpts[idx]-input[sample];
372 
373  func.add( mCast(float,sample), value );
374  }
375 
376  if ( func.isEmpty() )
377  { OD::memCopy( output, input, sizeof(T)*sz ); return; }
378 
379  for ( int idx=0; idx<sz; idx++ )
380  {
381  float calibration;
382  if ( idx<=firstsample )
383  calibration = func.yVals()[0];
384  else if ( idx>=lastsample )
385  calibration = func.yVals()[func.size()-1];
386  else
387  calibration = func.getValue( mCast(float,idx) );
388 
389  output[idx] = usefactor
390  ? input[idx]*calibration
391  : input[idx]+calibration;
392 
393  if ( calibrationcurve )
394  calibrationcurve[idx] = calibration;
395  }
396 }
397 
398 
399 } // namespace IdxAble
400 
401 #endif
int getInterpolateIdxsWithOff(const T &idxabl, od_int64 sz, od_int64 offset, float pos, bool extrap, float snapdist, od_int64 p[4])
Definition: idxable.h:241
int getUpperIdx(const X &x, int sz, double pos)
Definition: idxable.h:168
T poly1D(float x0, T v0, float x1, T v1, float x2, T v2, float x3, T v3, float x)
Definition: interpol1d.h:218
int getInterpolateIdxs(const T &idxabl, int sz, float pos, bool extrap, float snapdist, od_int64 p[4])
Definition: idxable.h:265
#define mIsZero(x, eps)
Definition: commondefs.h:53
void interpolatePositioned(const X &x, const Y &y, int sz, float desiredx, RT &ret, bool extrapolate=false)
Definition: idxable.h:182
#define mCast(tp, v)
Definition: commondefs.h:124
bool interpolateReg(const T &idxabl, int sz, float pos, RT &ret, bool extrapolate=false, float snapdist=mDefEps)
Definition: idxable.h:273
#define od_int64
Definition: plftypes.h:36
bool isEmpty() const
Definition: mathfunc.h:165
T polyReg1D(T vm1, T v0, T v1, T v2, float x)
Definition: interpol1d.h:130
bool findFPPos(const T1 &posarr, T3 sz, T2 pos, T3 beforefirst, T3 &idx, T2 eps=mDefEps)
Definition: idxable.h:113
#define mIsEqual(x, y, eps)
Definition: commondefs.h:54
const TypeSet< yT > & yVals() const
Definition: mathfunc.h:172
int getLowIdx(const X &x, int sz, double pos)
Definition: idxable.h:152
T3 indexOf(const T1 &arr, T3 sz, const T2 &val, T3 notfoundval)
Definition: idxable.h:38
T polyReg1DWithUdf(T vm1, T v0, T v1, T v2, float x)
Definition: interpol1d.h:189
#define mUdf(type)
Use this macro to get the undefined for simple types.
Definition: undefval.h:272
#define mNINT64(x)
Definition: commondefs.h:46
bool interpolateRegWithUdf(const T &idxabl, int sz, float pos, RT &ret, bool extrapolate=false, float snapdist=mDefEps)
Definition: idxable.h:314
T3 derefIndexOf(const T1 &arr, T3 sz, const T2 &val, T3 notfoundval)
Definition: idxable.h:53
#define mDefEps
Definition: commondefs.h:58
void add(xT x, yT y)
Definition: mathfunc.h:406
Position-sorted indexable objects.
Definition: idxable.h:30
bool interpolateRegWithUdfWithOff(const T &idxabl, od_int64 sz, od_int64 offset, float pos, RT &ret, bool extrapolate=false, float snapdist=mDefEps)
Definition: idxable.h:294
T linear1D(float x0, T v0, float x1, T v1, float x)
Definition: interpol1d.h:74
int size() const
Definition: mathfunc.h:164
const RefTree & RT()
void calibrateArray(const T *input, int sz, const T *controlpts, const int *controlsamples, int nrcontrols, bool usefactor, T *output, float *calibrationcurve=0)
Definition: idxable.h:351
MathFunction based on bend points.
Definition: mathfunc.h:151
yT getValue(xT x) const
Definition: mathfunc.h:168
bool findPos(const T1 &posarr, T3 sz, T2 pos, T3 beforefirst, T3 &idx)
Definition: idxable.h:75

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