OpendTect  6.3
polynd.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: Kristofer Tingdahl
8  Date: 10-12-1999
9 ________________________________________________________________________
10 
11 @$*/
12 
13 #include "linsolv.h"
14 #include "arrayndimpl.h"
15 #include "arrayndalgo.h"
16 
23 template <class T>
25 {
26 public:
27  PolynomialND( const ArrayNDInfo& );
28  ~PolynomialND( );
29 
30  bool fit( const ArrayND<T>& );
31 
32  void setCoeff( const int* pos, T val )
33  { coeffs(pos) = val; }
34 
35  T getCoeff( const int* pos ) const
36  { return coeffs.get( pos ); }
37 
38  T getValue( const TypeSet<float>& ) const;
39  T getValue3D( float x0, float x1, float x2 ) const;
40 
41 protected:
44 };
45 
46 
47 template <class T>
49  : coeffs( size_ )
50  , solver( 0 )
51 {}
52 
53 
54 template <class T>
56 { delete solver; }
57 
58 
59 template <class T> inline
61 {
62  ArrayNDIter coeffiter( coeffs.info() );
63 
64  const int ndim = coeffs.info().getNDim();
65 
66  T res = 0;
67 
68  do
69  {
70  float posproduct = 1;
71  for ( int idx=0; idx<ndim; idx++ )
72  posproduct *= Math::IntPowerOf( pos[idx], coeffiter[idx] );
73 
74  res += posproduct * coeffs.getND( coeffiter.getPos() );
75  } while ( coeffiter.next() );
76 
77  return res;
78 }
79 
80 template <class T> inline
81 T PolynomialND<T>::getValue3D( float p0, float p1, float p2 ) const
82 {
83  const ArrayNDInfo& size = coeffs.info();
84  if ( size.getNDim() != 3 || size.getTotalSz() != 64 )
85  {
86  TypeSet<float> pos( 3,0 );
87  pos[0] = p0; pos[1] = p1; pos[2] = p2;
88 
89  return getValue( pos );
90  }
91 
92  float p0_2 = p0 * p0; float p0_3 = p0_2 * p0;
93  float p1_2 = p1 * p1; float p1_3 = p1_2 * p1;
94  float p2_2 = p2 * p2; float p2_3 = p2_2 * p2;
95 
96  const float p0p1 = p0 * p1;
97  const float p0p1_2 = p0p1 * p1;
98  const float p0p1_3 = p0p1_2 * p1;
99  const float p0_2p1 = p0_2 * p1;
100  const float p0_2p1_2 = p0_2p1 * p1;
101  const float p0_2p1_3 = p0_2p1_2 * p1;
102  const float p0_3p1 = p0_3 * p1;
103  const float p0_3p1_2 = p0_3p1 * p1;
104  const float p0_3p1_3 = p0_3p1_2 * p1;
105 
106  const T* ptr = coeffs.getData();
107 
108  T res = ptr[0] +
109  ptr[1] * p2 +
110  ptr[2] * p2_2 +
111  ptr[3] * p2_3 +
112 
113  ptr[4] * p1 +
114  ptr[5] * p1 * p2 +
115  ptr[6] * p1 * p2_2 +
116  ptr[7] * p1 * p2_3 +
117 
118  ptr[8] * p1_2 +
119  ptr[9] * p1_2 * p2 +
120  ptr[10] * p1_2 * p2_2 +
121  ptr[11] * p1_2 * p2_3 +
122 
123  ptr[12] * p1_3 +
124  ptr[13] * p1_3 * p2 +
125  ptr[14] * p1_3 * p2_2 +
126  ptr[15] * p1_3 * p2_3 +
127 
128 
129  ptr[16] * p0 +
130  ptr[17] * p0 * p2 +
131  ptr[18] * p0 * p2_2 +
132  ptr[19] * p0 * p2_3 +
133 
134  ptr[20] * p0p1 +
135  ptr[21] * p0p1 * p2 +
136  ptr[22] * p0p1 * p2_2 +
137  ptr[23] * p0p1 * p2_3 +
138 
139  ptr[24] * p0p1_2 +
140  ptr[25] * p0p1_2 * p2 +
141  ptr[26] * p0p1_2 * p2_2 +
142  ptr[27] * p0p1_2 * p2_3 +
143 
144  ptr[28] * p0p1_3 +
145  ptr[29] * p0p1_3 * p2 +
146  ptr[30] * p0p1_3 * p2_2 +
147  ptr[31] * p0p1_3 * p2_3 +
148 
149 
150  ptr[32] * p0_2 +
151  ptr[33] * p0_2 * p2 +
152  ptr[34] * p0_2 * p2_2 +
153  ptr[35] * p0_2 * p2_3 +
154 
155  ptr[36] * p0_2p1 +
156  ptr[37] * p0_2p1 * p2 +
157  ptr[38] * p0_2p1 * p2_2 +
158  ptr[39] * p0_2p1 * p2_3 +
159 
160  ptr[40] * p0_2p1_2 +
161  ptr[41] * p0_2p1_2 * p2 +
162  ptr[42] * p0_2p1_2 * p2_2 +
163  ptr[43] * p0_2p1_2 * p2_3 +
164 
165  ptr[44] * p0_2p1_3 +
166  ptr[45] * p0_2p1_3 * p2 +
167  ptr[46] * p0_2p1_3 * p2_2 +
168  ptr[47] * p0_2p1_3 * p2_3 +
169 
170 
171 
172  ptr[48] * p0_3 +
173  ptr[49] * p0_3 * p2 +
174  ptr[50] * p0_3 * p2_2 +
175  ptr[51] * p0_3 * p2_3 +
176 
177  ptr[52] * p0_3p1 +
178  ptr[53] * p0_3p1 * p2 +
179  ptr[54] * p0_3p1 * p2_2 +
180  ptr[55] * p0_3p1 * p2_3 +
181 
182  ptr[56] * p0_3p1_2 +
183  ptr[57] * p0_3p1_2 * p2 +
184  ptr[58] * p0_3p1_2 * p2_2 +
185  ptr[59] * p0_3p1_2 * p2_3 +
186 
187  ptr[60] * p0_3p1_3 +
188  ptr[61] * p0_3p1_3 * p2 +
189  ptr[62] * p0_3p1_3 * p2_2 +
190  ptr[63] * p0_3p1_3 * p2_3;
191 
192  return res;
193 }
194 
195 
196 template<class T>
197 bool PolynomialND<T>::fit( const ArrayND<T>& input )
198 {
199  const int totalsz = mCast( int, input.info().getTotalSz() );
200 
201  if ( !solver || solver->size() != totalsz )
202  {
203  if ( solver ) delete solver;
204 
205  Array2DImpl<T> poscoeffs(totalsz,totalsz);
206 
207  ArrayNDIter positer( input.info() );
208  const int ndim = input.info().getNDim();
209  int row = 0;
210  do
211  {
212  int col = 0;
213  ArrayNDIter powiter( input.info() );
214 
215  do
216  {
217  int coeff = 1;
218  for ( int idx=0; idx<ndim; idx++ )
219  coeff *= Math::IntPowerOf( positer[idx], powiter[idx] );
220 
221  poscoeffs.set( row, col, (T)coeff );
222  col++;
223  } while ( powiter.next() );
224 
225  row++;
226  } while ( positer.next() );
227 
228  solver = new LinSolver<T>( poscoeffs );
229  if ( !solver->init() )
230  return false;
231  }
232 
233  solver->apply( input.getData(), coeffs.getData() );
234 
235  return true;
236 }
virtual uint64_t getTotalSz() const
virtual int getNDim() const =0
LinSolver< T > * solver
Definition: polynd.h:43
T getValue3D(float x0, float x1, float x2) const
Definition: polynd.h:81
#define mCast(tp, v)
Definition: commondefs.h:120
Implementation of Array2D.
Definition: arrayndimpl.h:101
Contains the information about the size of ArrayND, and in what order the data is stored (if accessab...
Definition: arrayndinfo.h:21
ArrayNDImpl< T > coeffs
Definition: polynd.h:42
const T * getData() const
Definition: arraynd.h:51
LinSolver - Solves linear systems of equations on the form A*x=B. A is a matrix of the size N*N...
Definition: gridder2d.h:22
PolynomialND(const ArrayNDInfo &)
Definition: polynd.h:48
Implementation of ArrayND.
Definition: arrayndimpl.h:199
T getValue(const TypeSet< float > &) const
Definition: polynd.h:60
An ArrayND is an array with a given number of dimensions and a size.
Definition: arraynd.h:29
Iterates through all samples in an ArrayND.
Definition: arraynd.h:175
void setCoeff(const int *pos, T val)
Definition: polynd.h:32
void set(int, int, T)
Definition: arrayndimpl.h:447
bool fit(const ArrayND< T > &)
Definition: polynd.h:197
T getCoeff(const int *pos) const
Definition: polynd.h:35
~PolynomialND()
Definition: polynd.h:55
virtual const ArrayNDInfo & info() const =0
#define mClass(module)
Definition: commondefs.h:161
iT IntPowerOf(iT i, iPOW p)
Definition: math2.h:126
PolynomialND is a N-dimensional polynomial with arbitary orders in each dimension. It can be fitted any ArrayND. To access the polynomial&#39;s data use getValue. getValue3D is optimized for third order, tree-dimensional cases.
Definition: polynd.h:24

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