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

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