OpendTect-6_4  6.4
interpol1d.h
Go to the documentation of this file.
1 #ifndef interpol1d_h
2 #define interpol1d_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 "undefval.h"
16 
17 /*\brief Interpolation for regular and irregular sampling.
18 
19  You have to supply the values 'just around' the position.
20  In regular sampling, the sample values are spaced in an equidistant manner.
21 
22  When you have undefs, there may be a utility which behaves as follows:
23  * When the nearest sample value is undefined, return undefined
24  * When another value is undef, use a value from a sample near that sample
25  and continue the interpolation.
26 
27  The position where the interpolation is done is needed.
28  A 'float x' must be provided which will be 0 <= x <= 1 in almost all
29  cases.
30 
31  When things become a bit difficult, the parameters for the interpolation can
32  be calculated up front. Then, you'll find a class with an 'apply' method.
33  The position for apply is usually between v0 and v1, but doesn't
34  _need_ to be. In that case, 0 < pos < 1. For the undef handlign classes and
35  functions, this is _required_.
36 */
37 
38 namespace Interpolate
39 {
40 
45 template <class T>
46 inline T linearReg1D( T v0, T v1, float x )
47 {
48  return x * v1 + (1-x) * v0;
49 }
50 
51 
56 template <class T>
57 inline T linearReg1DWithUdf( T v0, T v1, float x )
58 {
59  if ( mIsUdf(v0) )
60  return x < 0.5 ? mUdf(T) : v1;
61  if ( mIsUdf(v1) )
62  return x >= 0.5 ? mUdf(T) : v0;
63 
64  return linearReg1D( v0, v1, x );
65 }
66 
67 
73 template <class T>
74 inline T linear1D( float x0, T v0, float x1, T v1, float x )
75 {
76  return v0 + (x-x0) * (v1-v0) / (x1-x0);
77 }
78 
80 template <class iT>
81 inline iT linear1Di( float x0, iT v0, float x1, iT v1, float x )
82 {
83  const float tmp = v0 + (x-x0) * (v1-v0) / (x1-x0);
84  return mRounded( iT, tmp );
85 }
86 
87 
88 
91 template <class T>
93 {
94 public:
95 
97 {
98  set( 0, 0, 0, 0 );
99 }
100 
101 PolyReg1D( const T* v )
102 {
103  set( v[0], v[1], v[2], v[3] );
104 }
105 
106 PolyReg1D( T vm1, T v0, T v1, T v2 )
107 {
108  set( vm1, v0, v1, v2 );
109 }
110 
111 inline void set( T vm1, T v0, T v1, T v2 )
112 {
113  a_[0] = v0;
114  a_[1] = v1 - (( 2*vm1 + 3*v0 + v2 ) / 6);
115  a_[2] = (( v1 + vm1 ) / 2) - v0;
116  a_[3] = (( v1 - vm1 ) / 2) - a_[1];
117 }
118 
119 inline T apply( float x ) const
120 {
121  const float xsq = x * x;
122  return xsq * x * a_[3] + xsq * a_[2] + x * a_[1] + a_[0];
123 }
124 
125  T a_[4];
126 };
127 
128 
129 template <class T>
130 inline T polyReg1D( T vm1, T v0, T v1, T v2, float x )
131 {
132  return PolyReg1D<T>(vm1,v0,v1,v2).apply( x );
133 }
134 
135 
144 template <class T>
146 {
147 public:
148 
150 { set ( 0, 0, 0, 0 ); }
151 
152 PolyReg1DWithUdf( const T* v )
153 {
154  set( v[0], v[1], v[2], v[3] );
155 }
156 
157 PolyReg1DWithUdf( T vm1, T v0, T v1, T v2 )
158 {
159  set( vm1, v0, v1, v2 );
160 }
161 
162 inline void set( T vm1, T v0, T v1, T v2 )
163 {
164  v0udf_ = mIsUdf(v0); v1udf_ = mIsUdf(v1);
165  if ( v0udf_ && v1udf_ ) return;
166 
167  if ( mIsUdf(vm1) ) vm1 = v0udf_ ? v1 : v0;
168  if ( mIsUdf(v2) ) v2 = v1udf_ ? v0 : v1;
169  if ( v0udf_ ) v0 = vm1;
170  if ( v1udf_ ) v1 = v2;
171 
172  intp_.set( vm1, v0, v1, v2 );
173 }
174 
175 inline T apply( float x ) const
176 {
177  if ( (v0udf_ && x < 0.5) || (v1udf_ && x >= 0.5) )
178  return mUdf(T);
179  return intp_.apply( x );
180 }
181 
183  bool v0udf_;
184  bool v1udf_;
185 
186 };
187 
188 template <class T>
189 inline T polyReg1DWithUdf( T vm1, T v0, T v1, T v2, float x )
190 {
191  return PolyReg1DWithUdf<T>(vm1,v0,v1,v2).apply( x );
192 }
193 
194 
201 template <class T>
202 inline T parabolic1D( float x0, T v0, float x1, T v1, float x2, T v2, float x )
203 {
204  float xx0 = x - x0, xx1 = x-x1, xx2 = x-x2;
205  return v0 * xx1 * xx2 / ((x0 - x1) * (x0 - x2)) +
206  v1 * xx0 * xx2 / ((x1 - x0) * (x1 - x2)) +
207  v2 * xx0 * xx1 / ((x2 - x0) * (x2 - x1));
208 }
209 
210 
217 template <class T>
218 inline T poly1D( float x0, T v0, float x1, T v1, float x2, T v2,
219  float x3, T v3, float x )
220 {
221  float xx0 = x - x0, xx1 = x-x1, xx2 = x-x2, xx3 = x-x3;
222  return v0 * xx1 * xx2 * xx3 / ((x0 - x1) * (x0 - x2) * (x0 - x3)) +
223  v1 * xx0 * xx2 * xx3 / ((x1 - x0) * (x1 - x2) * (x1 - x3)) +
224  v2 * xx0 * xx1 * xx3 / ((x2 - x0) * (x2 - x1) * (x2 - x3)) +
225  v3 * xx0 * xx1 * xx2 / ((x3 - x0) * (x3 - x1) * (x3 - x2));
226 }
227 
228 
234 template <class T>
235 inline T predictAtZero1D( T vm2, T vm1, T v1, T v2 )
236 {
237  return (-2 * vm2 + 8 * vm1 + 8 * v1 - 2 * v2) / 12;
238 }
239 
240 
246 template <class T>
247 inline T predictAtZero1D( T vm3, T vm2, T vm1, T v1, T v2, T v3 )
248 {
249  return (vm3 - 6 * vm2 + 15 * vm1 + 15 * v1 - 6 * v2 + v3) / 20;
250 }
251 
252 
253 } // namespace Interpolate
254 
255 #endif
Definition: interpol1d.h:38
bool v1udf_
Definition: interpol1d.h:184
#define mIsUdf(val)
Use mIsUdf to check for undefinedness of simple types.
Definition: undefval.h:287
PolyReg1D< T > intp_
Definition: interpol1d.h:182
T apply(float x) const
Definition: interpol1d.h:175
T poly1D(float x0, T v0, float x1, T v1, float x2, T v2, float x3, T v3, float x)
Definition: interpol1d.h:218
#define mRounded(typ, x)
Definition: commondefs.h:44
iT linear1Di(float x0, iT v0, float x1, iT v1, float x)
Interpolate 1D regularly sampled, using a 3rd order polynome.
Definition: interpol1d.h:81
T linearReg1DWithUdf(T v0, T v1, float x)
Definition: interpol1d.h:57
Definition: interpol1d.h:92
T predictAtZero1D(T vm2, T vm1, T v1, T v2)
Definition: interpol1d.h:235
PolyReg1D(const T *v)
Definition: interpol1d.h:101
T polyReg1D(T vm1, T v0, T v1, T v2, float x)
Definition: interpol1d.h:130
PolyReg1D()
Definition: interpol1d.h:96
T apply(float x) const
Definition: interpol1d.h:119
PolyReg1DWithUdf(T vm1, T v0, T v1, T v2)
Definition: interpol1d.h:157
bool v0udf_
Definition: interpol1d.h:183
PolyReg1D(T vm1, T v0, T v1, T v2)
Definition: interpol1d.h:106
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
PolyReg1DWithUdf()
Definition: interpol1d.h:149
T linearReg1D(T v0, T v1, float x)
Definition: interpol1d.h:46
T linear1D(float x0, T v0, float x1, T v1, float x)
Definition: interpol1d.h:74
PolyReg1DWithUdf(const T *v)
Definition: interpol1d.h:152
T parabolic1D(float x0, T v0, float x1, T v1, float x2, T v2, float x)
Definition: interpol1d.h:202
#define mClass(module)
Definition: commondefs.h:164
PolyReg1D which smoothly handles undefined values.
Definition: interpol1d.h:145

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