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

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