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

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