OpendTect  6.3
sincinterpolator.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "algomod.h"
4 #include "arrayndimpl.h"
5 #include "mathfunc.h"
6 #include "objectset.h"
7 #include "thread.h"
8 
9 class KaiserWindow;
10 
19 {
20 public:
22 
23  static SincTableManager& STM();
24 
25  mExpClass(Algo) Table /*Table of sinc interpolator coefficients.*/
26  {
27  public:
28  Table(int lsinc,int nsinc,float emax,float fmax,
29  int lmax);
30 
31  bool isOK() const { return asinc_.get2DData(); }
32 
33  void setValue(int,int,float);
34 
35  bool hasSameDesign(float fmax,int lmax) const;
36  float getMaximumError() const { return emax_; }
37  float getMaximumFrequency() const { return fmax_; }
38  int getMaximumLength() const { return lmax_; }
39  od_int64 getTableBytes() const;
40  int getNumbers() const; // number of sinc approximations
41  int getLength() const; // length of sinc approximations
42  int getShift() const;
43 
44  protected:
45 
46  Array2DImpl<float> asinc_; // array of sinc approximations
47 
48  private:
49 
50  float emax_;
51  float fmax_;
52  int lmax_;
53 
54  friend class SincInterpolator;
55  friend class RotatorExecutor;
56 
57  };
58 
59  const Table* getTable(float fmax,int lmax);
60 
61 protected:
64  //Protects tables_
65  int getTableIdx(float fmax,int lmax) const;
66 
67  // Builds a table based on design parameters.
68  static const Table* makeTable(float fmax,int lmax);
69  static float sinc(float x);
70 
71 };
72 
73 
74 
124 {
125 public:
126  ~SincInterpolator();
127 
130  virtual bool initTable(float fmax,int lmax);
131  inline bool isTableOK() const;
132 
133  inline od_int64 getTableBytes() const;
134  inline float getMaximumError() const;
135  inline float getMaximumFrequency() const;
136  inline int getMaximumLength() const;
137 
138  enum Extrapolation { NONE=0, CONSTANT=1 };
139  Extrapolation getExtrapolation();
140  void setExtrapolation(Extrapolation);
141 
142 protected:
143  SincInterpolator();
144  bool init() { return initTable( 0.3f, 8 ); }
145 
146  template <class RT>
147  bool initUndefTable(const RT*,od_int64 sz);
148 
149  bool* isudfarr_;
150  int lsinc_;
151  int nsincm1_;
152  int ishift_;
154 
155  static const float snapdist;
158 
159  /*Table of sinc interpolation coefficients.*/
161  const float** asinc_; // only a cached shortcut
162 };
163 
164 
165 template <class RT, class PT>
167  public MathFunction<RT,PT>
168 {
169 public:
170  SincInterpolator1D(const RT* =0,int sz=-1);
171 
172  bool setSize(int);
173  void setInput(const RT*,bool datahasnoudf=false);
174  bool isOK() const { return data_ && isTableOK(); }
175  bool initTable(float fmax,int lmax);
176 
177  RT getValue(PT) const;
178 
179 private:
180 
181  const RT* data_;
182  int nx_;
183  int nxm_;
184 };
185 
186 
187 template <class RT, class PT>
189  public MathXYFunction<RT,PT>
190 {
191 public:
192  SincInterpolator2D(const RT*,int nx,int ny);
193  bool isOK() const { return isTableOK(); }
194  bool initTable(float fmax,int lmax);
195 
196  RT getValue(PT,PT) const;
197 
198 private:
199 
200  const RT* data_;
201  int nx_;
202  int ny_;
203  int nxm_;
204  int nym_;
205 
206 };
207 
208 
209 template <class RT, class PT>
211  public MathXYZFunction<RT,PT>
212 {
213 public:
214  SincInterpolator3D(const RT* data,int nx,int ny,int nz);
215  bool isOK() const { return isTableOK(); }
216  bool initTable(float fmax,int lmax);
217 
218  RT getValue(PT,PT,PT) const;
219 
220 private:
221 
222  const RT* data_;
223  int nx_;
224  int ny_;
225  int nz_;
226  int nxm_;
227  int nym_;
228  int nzm_;
229 
230 };
231 
232 
233 
234 inline bool SincInterpolator::isTableOK() const
235 { return table_; }
236 
238 { return table_->getMaximumError(); }
239 
241 { return table_->getMaximumFrequency(); }
242 
244 { return table_->getMaximumLength(); }
245 
247 { return table_->getTableBytes(); }
248 
249 
250 template <class RT>
252 {
254  if ( !vals )
255  return true;
256 
257  mTryAlloc( isudfarr_, bool[sz] );
258  if ( !isudfarr_ )
259  return false;
260 
261  bool hasudfs = false;
262  for ( int idx=0; idx<sz; idx++ )
263  {
264  isudfarr_[idx] = mIsUdf(vals[idx]);
265  if ( isudfarr_[idx] )
266  hasudfs = true;
267  }
268 
269  if ( !hasudfs )
271 
272  return true;
273 }
274 
275 
276 
277 template <class RT, class PT>
279  : SincInterpolator()
280  , data_( 0 )
281  , nx_(nx)
282 {
283  init();
284  setInput( data );
285 }
286 
287 
288 template <class RT, class PT>
289 void SincInterpolator1D<RT,PT>::setInput( const RT* data, bool datahasnoudf )
290 {
291  data_ = data;
292  if ( datahasnoudf )
294  else
296 }
297 
298 
299 template <class RT, class PT>
301 {
302  if ( nx < 1 )
303  return false;
304 
305  nx_ = nx;
306  return init();
307 }
308 
309 
310 template <class RT, class PT>
311 bool SincInterpolator1D<RT,PT>::initTable( float fmax, int lmax )
312 {
313  if ( !SincInterpolator::initTable(fmax,lmax) )
314  return false;
315 
316  nxm_ = nx_ - lsinc_;
317  return true;
318 }
319 
320 #define mKSinc(frac) ( mCast(int,frac*nsincm1_+0.5) )
321 #define mValidPos(is,ns) ( (is > -1 && is < ns) )
322 #define mCheckUdf(totidx) \
323 { \
324  if ( isudfarr_ && isudfarr_[totidx] ) \
325  continue; \
326 }
327 #define mAddVal(val,weight,totidx,outval) \
328 { \
329  mCheckUdf(totidx) \
330  outval += val * weight; \
331 }
332 #define mAddValW(val,totidx,weight,outval,sumweights) \
333 { \
334  mCheckUdf(totidx) \
335  outval += val * weight; \
336  sumweights += weight; \
337 }
338 
339 template <class RT,class PT>
341 {
342  int idx0 = mNINT32(x);
343  PT fracx = x - idx0;
344  if ( fracx > -snapdist && fracx < snapdist && mValidPos(idx0,nx_) &&
345  ( !isudfarr_ || (isudfarr_ && !isudfarr_[idx0]) ) )
346  return data_[idx0];
347 
348  const PT floorx = floor(x);
349  fracx = x - floorx;
350  const float* asinc = asinc_[mKSinc(fracx)];
351  idx0 = mCast(int,floorx) + ishift_;
352 
353  float out = 0.f;
354  if ( mValidPos(idx0,nxm_) )
355  {
356  for ( int isinc=0,idx=idx0; isinc<lsinc_; isinc++,idx++ )
357  mAddVal(data_[idx],asinc[isinc],idx,out)
358  }
359  else if ( extrapcst_ )
360  {
361  for ( int isinc=0,idx=idx0; isinc<lsinc_; isinc++,idx++ )
362  {
363  const int idx1 = getLimited( idx, 0, nx_-1 );
364  mAddVal(data_[idx1],asinc[isinc],idx,out)
365  }
366  }
367  else
368  {
369  float sumweights = 0.f;
370  for ( int isinc=0,idx=idx0; isinc<lsinc_; isinc++,idx++ )
371  {
372  if ( !mValidPos(idx,nx_) )
373  continue;
374 
375  mAddValW(data_[idx],idx,asinc[isinc],out,sumweights)
376  }
377  if ( !mIsZero(sumweights,mDefEpsF) ) out /= sumweights;
378  }
379 
380  return mCast(RT,out);
381 }
382 
383 
384 
385 template <class RT, class PT>
386 SincInterpolator2D<RT,PT>::SincInterpolator2D( const RT* data, int nx, int ny )
387  : SincInterpolator()
388  , data_(data)
389  , nx_(nx)
390  , ny_(ny)
391 {
392  init();
394 }
395 
396 
397 template <class RT, class PT>
398 bool SincInterpolator2D<RT,PT>::initTable( float fmax, int lmax )
399 {
400  if ( !SincInterpolator::initTable(fmax,lmax) )
401  return false;
402 
403  nxm_ = nx_ - lsinc_;
404  nym_ = ny_ - lsinc_;
405  return true;
406 }
407 
408 
409 template <class RT, class PT>
411 {
412  int idx0 = mNINT32(x);
413  int idy0 = mNINT32(y);
414  PT fracx = x - idx0;
415  PT fracy = y - idy0;
416  if ( fracx > -snapdist && fracx < snapdist && mValidPos(idx0,nx_) &&
417  fracy > -snapdist && fracy < snapdist && mValidPos(idy0,ny_) &&
418  ( !isudfarr_ || (isudfarr_ && !isudfarr_[idx0*ny_+idy0]) ) )
419  return data_[idx0*ny_+idy0];
420 
421  const PT floorx = floor(x);
422  const PT floory = floor(y);
423  fracx = x - floorx;
424  fracy = y - floory;
425  const float* asincx = asinc_[mKSinc(fracx)];
426  const float* asincy = asinc_[mKSinc(fracy)];
427  idx0 = mCast(int,floorx) + ishift_;
428  idy0 = mCast(int,floory) + ishift_;
429 
430  double out = 0., outx;
431  if ( mValidPos(idx0,nxm_) && mValidPos(idy0,nym_) )
432  {
433  for ( int ixsinc=0,idx=idx0; ixsinc<lsinc_; ixsinc++,idx++ )
434  {
435  outx = 0.;
436  const float asincxval = asincx[ixsinc];
437  if ( mIsZero(asincxval,mDefEpsF) )
438  continue;
439 
440  for ( int iysinc=0,idy=idy0; iysinc<lsinc_; iysinc++,idy++ )
441  {
442  const od_int64 off = idx*ny_+idy;
443  mAddVal(data_[off],asincy[iysinc],off,outx)
444  }
445  out += outx * asincxval;
446  }
447  }
448  else if ( extrapcst_ )
449  {
450  for ( int ixsinc=0,idx=idx0; ixsinc<lsinc_; ixsinc++,idx++ )
451  {
452  outx = 0.;
453  const float asincxval = asincx[ixsinc];
454  if ( mIsZero(asincxval,mDefEpsF) )
455  continue;
456 
457  const int idx1 = getLimited( idx, 0, nx_-1 );
458  for ( int iysinc=0,idy=idy0; iysinc<lsinc_; iysinc++,idy++ )
459  {
460  const int idy1 = getLimited( idy, 0, ny_-1 );
461  const od_int64 off = idx1*ny_+idy1;
462  mAddVal(data_[off],asincy[iysinc],off,outx)
463  }
464  out += outx * asincxval;
465  }
466  }
467  else
468  {
469  double sumweights = 0., sumx;
470  for ( int ixsinc=0,idx=idx0; ixsinc<lsinc_; ixsinc++,idx++ )
471  {
472  outx = 0.; sumx = 0.;
473  const float asincxval = asincx[ixsinc];
474  if ( mIsZero(asincxval,mDefEpsF) || !mValidPos(idx,nx_) )
475  continue;
476 
477  for ( int iysinc=0,idy=idy0; iysinc<lsinc_; iysinc++,idy++ )
478  {
479  if ( !mValidPos(idy,ny_) )
480  continue;
481 
482  const od_int64 off = idx*ny_+idy;
483  mAddValW(data_[off],off,asincy[iysinc],outx,sumx)
484  }
485  out += outx * asincxval;
486  sumweights += sumx;
487  }
488  if ( !mIsZero(sumweights,mDefEps) ) out /= sumweights;
489  }
490 
491  return mCast(RT,out);
492 }
493 
494 
495 
496 template <class RT, class PT>
498  int nz )
499  : SincInterpolator()
500  , data_(data)
501  , nx_(nx)
502  , ny_(ny)
503  , nz_(nz)
504 {
505  init();
507 }
508 
509 
510 template <class RT, class PT>
511 bool SincInterpolator3D<RT,PT>::initTable( float fmax, int lmax )
512 {
513  if ( !SincInterpolator::initTable(fmax,lmax) )
514  return false;
515 
516  nxm_ = nx_ - lsinc_;
517  nym_ = ny_ - lsinc_;
518  nzm_ = nz_ - lsinc_;
519  return true;
520 }
521 
522 
523 #undef mGetOffset
524 #define mGetOffset(idx,idy,idz) ( idz + nz_*( idy + ny_*idx ) )
525 template <class RT, class PT>
526 RT SincInterpolator3D<RT,PT>::getValue( PT x, PT y, PT z ) const
527 {
528  int idx0 = mNINT32(x);
529  int idy0 = mNINT32(y);
530  int idz0 = mNINT32(z);
531  PT fracx = x - idx0;
532  PT fracy = y - idy0;
533  PT fracz = z - idz0;
534  if ( fracx > -snapdist && fracx < snapdist && mValidPos(idx0,nx_) &&
535  fracy > -snapdist && fracy < snapdist && mValidPos(idy0,ny_) &&
536  fracz > -snapdist && fracz < snapdist && mValidPos(idz0,nz_) &&
537  ( !isudfarr_ || (isudfarr_ && !isudfarr_[mGetOffset(idx0,idy0,idz0)])))
538  return data_[mGetOffset(idx0,idy0,idz0)];
539 
540  const PT floorx = floor(x);
541  const PT floory = floor(y);
542  const PT floorz = floor(z);
543  fracx = x - floorx;
544  fracy = y - floory;
545  fracz = z - floorz;
546  const float* asincx = asinc_[mKSinc(fracx)];
547  const float* asincy = asinc_[mKSinc(fracy)];
548  const float* asincz = asinc_[mKSinc(fracz)];
549  idx0 = mCast(int,floorx) + ishift_;
550  idy0 = mCast(int,floory) + ishift_;
551  idz0 = mCast(int,floorz) + ishift_;
552 
553  double out = 0.;
554  double outx, outy;
555  if ( mValidPos(idx0,nxm_) && mValidPos(idy0,nym_) && mValidPos(idz0,nzm_) )
556  {
557  for ( int ixsinc=0,idx=idx0; ixsinc<lsinc_; ixsinc++,idx++ )
558  {
559  outx = 0.;
560  const float asincxval = asincx[ixsinc];
561  if ( mIsZero(asincxval,mDefEpsF) )
562  continue;
563 
564  for ( int iysinc=0,idy=idy0; iysinc<lsinc_; iysinc++,idy++ )
565  {
566  outy = 0.;
567  const float asincyval = asincy[iysinc];
568  if ( mIsZero(asincyval,mDefEpsF) )
569  continue;
570 
571  for ( int izsinc=0,idz=idz0; izsinc<lsinc_; izsinc++,idz++ )
572  {
573  const od_int64 off = mGetOffset(idx,idy,idz);
574  mAddVal(data_[off],asincz[izsinc],off,outy)
575  }
576  outx += outy * asincyval;
577  }
578  out += asincxval * outx;
579  }
580  }
581  else if ( extrapcst_ )
582  {
583  for ( int ixsinc=0,idx=idx0; ixsinc<lsinc_; ixsinc++,idx++ )
584  {
585  outx = 0.;
586  const float asincxval = asincx[ixsinc];
587  if ( mIsZero(asincxval,mDefEpsF) )
588  continue;
589 
590  const int idx1 = getLimited( idx, 0, nx_-1 );
591  for ( int iysinc=0,idy=idy0; iysinc<lsinc_; iysinc++,idy++ )
592  {
593  outy = 0.;
594  const float asincyval = asincy[iysinc];
595  if ( mIsZero(asincyval,mDefEpsF) )
596  continue;
597 
598  const int idy1 = getLimited( idy, 0, ny_-1 );
599  for ( int izsinc=0,idz=idz0; izsinc<lsinc_; izsinc++,idz++ )
600  {
601  const int idz1 = getLimited( idz, 0, nz_-1 );
602  const od_int64 off = mGetOffset(idx1,idy1,idz1);
603  mAddVal(data_[off],asincz[izsinc],off,outy)
604  }
605  outx += outy * asincyval;
606  }
607  out += asincxval * outx;
608  }
609  }
610  else
611  {
612  double sumweights = 0., sumx, sumy;
613  for ( int ixsinc=0,idx=idx0; ixsinc<lsinc_; ixsinc++,idx++ )
614  {
615  outx = 0.; sumx = 0.;
616  const float asincxval = asincx[ixsinc];
617  if ( mIsZero(asincxval,mDefEpsF) || !mValidPos(idx,nx_) )
618  continue;
619 
620  for ( int iysinc=0,idy=idy0; iysinc<lsinc_; iysinc++,idy++ )
621  {
622  outy = 0.; sumy = 0.;
623  const float asincyval = asincy[iysinc];
624  if ( mIsZero(asincyval,mDefEpsF) || !mValidPos(idy,ny_) )
625  continue;
626 
627  for ( int izsinc=0,idz=idz0; izsinc<lsinc_; izsinc++,idz++ )
628  {
629  if ( !mValidPos(idz,nz_) ) continue;
630  const od_int64 off = mGetOffset(idx,idy,idz);
631  mAddValW(data_[off],off,asincz[izsinc],outy,sumy)
632  }
633  outx += outy * asincyval;
634  sumx += sumy;
635  }
636  out += asincxval * outx;
637  sumweights += sumx;
638  }
639  if ( !mIsZero(sumweights,mDefEps) ) out /= sumweights;
640  }
641 
642  return mCast(RT,out);
643 }
#define mExpClass(module)
Definition: commondefs.h:157
#define mIsUdf(val)
Use mIsUdf to check for undefinedness of simple types.
Definition: undefval.h:285
bool isOK() const
Definition: sincinterpolator.h:31
Kaiser Window Function.
Definition: windowfunction.h:105
Extrapolation
Definition: sincinterpolator.h:138
int nx_
Definition: sincinterpolator.h:182
Definition: file.h:109
int nx_
Definition: sincinterpolator.h:223
od_int64 getTableBytes() const
Definition: sincinterpolator.h:246
static const float snapdist
Definition: sincinterpolator.h:155
int getLength() const
Definition: windowfunction.h:122
int nsincm1_
Definition: sincinterpolator.h:151
bool initTable(float fmax, int lmax)
Definition: sincinterpolator.h:311
#define mIsZero(x, eps)
Definition: commondefs.h:55
bool isTableOK() const
Definition: sincinterpolator.h:234
bool initTable(float fmax, int lmax)
Definition: sincinterpolator.h:398
#define mCast(tp, v)
Definition: commondefs.h:120
int nx_
Definition: sincinterpolator.h:201
RT getValue(PT, PT) const
Definition: sincinterpolator.h:410
Array2DImpl< float > asinc_
Definition: sincinterpolator.h:46
#define od_int64
Definition: plftypes.h:34
int ny_
Definition: sincinterpolator.h:224
ObjectSet< const Table > tables_
Definition: sincinterpolator.h:62
int nym_
Definition: sincinterpolator.h:204
SincInterpolator3D(const RT *data, int nx, int ny, int nz)
Definition: sincinterpolator.h:497
Mathematical function.
Definition: mathfunc.h:59
int getMaximumLength() const
Definition: sincinterpolator.h:243
bool initUndefTable(const RT *, od_int64 sz)
Definition: sincinterpolator.h:251
Definition: sincinterpolator.h:166
SincTableManager()
Definition: sincinterpolator.h:21
int ishift_
Definition: sincinterpolator.h:152
void deleteAndZeroArrPtr(T *&ptr, bool isowner=true)
Definition: ptrman.h:32
int nxm_
Definition: sincinterpolator.h:226
int lmax_
Definition: sincinterpolator.h:52
int getMaximumLength() const
Definition: sincinterpolator.h:38
Definition: sincinterpolator.h:210
Set of pointers to objects.
Definition: commontypes.h:28
float getMaximumFrequency() const
Definition: sincinterpolator.h:240
int nzm_
Definition: sincinterpolator.h:228
#define mNINT32(x)
Definition: commondefs.h:48
float getMaximumError() const
Definition: sincinterpolator.h:237
SincInterpolator2D(const RT *, int nx, int ny)
Definition: sincinterpolator.h:386
A manager used for constructing the table necessary for Sinc interpolations. The manager creates one ...
Definition: sincinterpolator.h:18
Definition: geom2dascio.h:18
#define mAddVal(val, weight, totidx, outval)
Definition: sincinterpolator.h:327
float getMaximumError() const
Definition: sincinterpolator.h:36
#define mKSinc(frac)
Definition: sincinterpolator.h:320
virtual bool initTable(float fmax, int lmax)
bool isOK() const
Definition: sincinterpolator.h:193
bool * isudfarr_
Definition: sincinterpolator.h:149
A Math Function as in F(x,y,z).
Definition: mathfunc.h:120
int nz_
Definition: sincinterpolator.h:225
#define mTryAlloc(var, stmt)
Catches bad_alloc and sets ptr to null as normal.
Definition: commondefs.h:244
void setInput(const RT *, bool datahasnoudf=false)
Definition: sincinterpolator.h:289
#define mValidPos(is, ns)
Definition: sincinterpolator.h:321
const float ** asinc_
Definition: sincinterpolator.h:161
bool setSize(int)
Definition: sincinterpolator.h:300
int nxm_
Definition: sincinterpolator.h:203
#define mDefEps
Definition: commondefs.h:60
bool isOK() const
Definition: sincinterpolator.h:215
Threads::Mutex lock_
Definition: sincinterpolator.h:63
#define mDefEpsF
Definition: commondefs.h:58
A sinc interpolator for bandlimited uniformly-sampled functions y(x). Interpolators can be designed f...
Definition: sincinterpolator.h:123
A Math Function as in F(x,y).
Definition: mathfunc.h:103
int nym_
Definition: sincinterpolator.h:227
od_int64 getTableBytes() const
#define mGetOffset(idx, idy, idz)
Definition: sincinterpolator.h:524
bool extrapcst_
Definition: sincinterpolator.h:153
bool initTable(float fmax, int lmax)
Definition: sincinterpolator.h:511
bool isOK() const
Definition: sincinterpolator.h:174
int lsinc_
Definition: sincinterpolator.h:150
int nxm_
Definition: sincinterpolator.h:183
bool init()
Definition: sincinterpolator.h:144
T getLimited(T v, T min, T max)
Definition: commondefs.h:43
Is a lock that allows a thread to have exlusive rights to something.
Definition: thread.h:43
SincInterpolator1D(const RT *=0, int sz=-1)
Definition: sincinterpolator.h:278
const RefTree & RT()
const RT * data_
Definition: sincinterpolator.h:181
RT getValue(PT, PT, PT) const
Definition: sincinterpolator.h:526
RT getValue(PT) const
Definition: sincinterpolator.h:340
Definition: sincinterpolator.h:25
int ny_
Definition: sincinterpolator.h:202
Definition: sincinterpolator.h:188
#define mClass(module)
Definition: commondefs.h:161
SceneTransformManager & STM()
const RT * data_
Definition: sincinterpolator.h:222
float fmax_
Definition: sincinterpolator.h:51
float emax_
Definition: sincinterpolator.h:50
const SincTableManager::Table * table_
Definition: sincinterpolator.h:160
float getMaximumFrequency() const
Definition: sincinterpolator.h:37
const RT * data_
Definition: sincinterpolator.h:200
#define mAddValW(val, totidx, weight, outval, sumweights)
Definition: sincinterpolator.h:332

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