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

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