OpendTect  6.3
linsolv.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: 07-10-1999
9 ________________________________________________________________________
10 
11 @$
12 */
13 
14 #include "arrayndimpl.h"
15 #include "executor.h"
16 #include "uistrings.h"
17 
24 template <class T>
25 mClass(Algo) LinSolver
26 {
27 public:
28  LinSolver(const Array2D<T>& A);
29  LinSolver(const LinSolver&);
30 
31  ~LinSolver();
32 
33  bool init(TaskRunner* =0);
34  bool ready() const { return ready_; }
35  int size() const { return n_; }
36 
37  void apply(const T* b,T* x) const;
38 
39 protected:
41  int* croutsidx_;
42  int n_;
43  bool ready_;
44 
45 };
46 
47 
48 template <class T>
51 public:
54 
55 protected:
56 
57  int nextStep();
58  uiString message() const
59  {
60  return errmsg_.isEmpty()
61  ? tr("Generating linear model")
62  : errmsg_;
63  }
65  { return tr("Nr points processed"); }
66 
67  od_int64 nrDone() const { return curidx_; }
68  od_int64 totalNr() const { return totalnr_; }
69 
70  int curidx_;
71  int totalnr_;
72  int imax_;
73  int* croutsidx_;
77 };
78 
79 
80 template <class T>
82  : Executor("Generating linear model")
83  , croutsmatrix_(A)
84  , totalnr_(A.info().getSize(0))
85  , curidx_(0)
86  , imax_(mUdf(int))
87  , vv_(totalnr_,0)
88  , croutsidx_(croutsidx)
89 {
90  if ( A.info().getSize(0) != A.info().getSize(1) )
91  {
93  return;
94  }
95 
96  for ( int idx=0; idx<totalnr_; idx++ )
97  {
98  T maxval = 0;
99  for ( int idy=0; idy<totalnr_; idy++ )
100  {
101  const T temp = fabs( croutsmatrix_.get(idx,idy) );
102  if ( temp > maxval )
103  maxval = temp;
104  }
105 
106  if ( mIsZero(maxval,mDefEps) )
107  {
109  return;
110  }
111 
112  vv_[idx] = 1.0f/maxval;
113  }
114 }
115 
116 
117 #define TINY 1.0e-20
118 
119 template <class T>
121 {
122  if ( !errmsg_.isEmpty() )
123  return ErrorOccurred();
124 
125  if ( curidx_ >= totalnr_ )
126  return Finished();
127 
128  for (int idx=0; idx<curidx_; idx++ )
129  {
130  T sum = croutsmatrix_.get( idx, curidx_ );
131  for ( int idz=0; idz<idx; idz++ )
132  sum -= croutsmatrix_.get(idx,idz) * croutsmatrix_.get(idz,curidx_);
133 
134  croutsmatrix_.set( idx, curidx_, sum );
135  }
136 
137  T big = 0.0;
138  for ( int idx=curidx_; idx<totalnr_; idx++ )
139  {
140  T sum = croutsmatrix_.get( idx, curidx_ );
141  for ( int idz=0; idz<curidx_; idz++ )
142  {
143  sum -= croutsmatrix_.get(idx,idz)*croutsmatrix_.get(idz,curidx_);
144  }
145 
146  croutsmatrix_.set( idx, curidx_, sum );
147 
148  T dum = vv_[idx]*fabs(sum);
149 
150  if ( dum >= big )
151  {
152  big = dum;
153  imax_ = idx;
154  }
155  }
156 
157  if ( curidx_ != imax_ )
158  {
159  for ( int idz=0; idz<totalnr_; idz++ )
160  {
161  const T dum = croutsmatrix_.get( imax_, idz );
162  croutsmatrix_.set( imax_, idz, croutsmatrix_.get(curidx_,idz) );
163  croutsmatrix_.set( curidx_, idz, dum );
164  }
165 
166  vv_[imax_] = vv_[curidx_];
167  }
168 
170 
171  if ( mIsZero(croutsmatrix_.get(curidx_,curidx_),mDefEps) )
172  croutsmatrix_.set(curidx_,curidx_,TINY);
173 
174  if ( curidx_ != totalnr_-1 )
175  {
176  const T dum = 1.0f/croutsmatrix_.get(curidx_,curidx_);
177  for ( int idx=curidx_+1; idx<totalnr_; idx++ )
178  croutsmatrix_.set(idx, curidx_, dum*croutsmatrix_.get(idx,curidx_));
179  }
180 
181  return ++curidx_>=totalnr_ ? Finished() : MoreToDo();
182 }
183 
184 #undef TINY
185 
186 
187 template <class T> inline
189  : croutsmatrix_(A)
190  , croutsidx_(new int[A.info().getSize(0)])
191  , n_(A.info().getSize(0))
192  , ready_(false)
193 {
194 }
195 
196 
197 template <class T> inline
199 {
201  ready_ = TaskRunner::execute( taskr, task );
202  return ready_;
203 }
204 
205 
206 template <class T> inline
209  , croutsidx_(0)
210  , n_(s.n_)
211  , ready_(s.ready_)
212 {
213  if ( s.croutsidx_ )
214  {
215  croutsidx_ = new int[s.n_];
216  for ( int idx=0; idx<s.n_; idx++ )
217  croutsidx_[idx] = s.croutsidx_[idx];
218  }
219 }
220 
221 
222 template <class T> inline
224 {
225  delete [] croutsidx_;
226 }
227 
228 
229 template <class T> inline
230 void LinSolver<T>::apply( const T* b, T* x ) const
231 {
232  if ( !ready_ )
233  {
234  pErrMsg("Cannot apply. Did you forget to call LinSolver::init()?");
235  return;
236  }
237 
238  for ( int idx=0; idx<n_; idx++ )
239  x[idx] = b[idx];
240 
241  int ii=-1;
242 
243  for ( int i=0; i<n_; i++ )
244  {
245  int ip=croutsidx_[i];
246  T sum=x[ip];
247  x[ip]=x[i];
248 
249  if ( ii != -1 )
250  {
251  for ( int j=ii; j<=i-1; j++ )
252  {
253  sum -= croutsmatrix_.get(i,j)*x[j];
254  }
255  }
256  else if ( !mIsZero(sum,mDefEps) )
257  ii=i;
258 
259  x[i]=sum;
260  }
261 
262  for ( int i=n_-1; i>=0; i-- )
263  {
264  T sum=x[i];
265  for ( int j=i+1; j<n_; j++ )
266  sum -= croutsmatrix_.get(i,j)*x[j];
267 
268  x[i]=sum/croutsmatrix_.get(i,i);
269  }
270 
271 }
int * croutsidx_
Definition: linsolv.h:73
bool isEmpty() const
const Array2DInfo & info() const
Definition: arrayndimpl.h:123
int imax_
Definition: linsolv.h:72
Array2DImpl< T > & croutsmatrix_
Definition: linsolv.h:75
#define mODTextTranslationClass(clss)
Definition: uistring.h:37
static int ErrorOccurred()
Definition: task.h:164
bool init(TaskRunner *=0)
Definition: linsolv.h:198
LinSolverTask(Array2DImpl< T > &, int *)
Definition: linsolv.h:81
#define mIsZero(x, eps)
Definition: commondefs.h:55
~LinSolverTask()
Definition: linsolv.h:53
int * croutsidx_
Definition: linsolv.h:41
#define od_int64
Definition: plftypes.h:34
bool init()
Implementation of Array2D.
Definition: arrayndimpl.h:101
int n_
Definition: linsolv.h:42
static bool execute(TaskRunner *tskr, Task &)
Taskrunner may be zero.
#define TINY
Definition: linsolv.h:117
Definition: uistring.h:88
static int MoreToDo()
Definition: task.h:166
uiString message() const
Definition: linsolv.h:58
virtual int getSize(int dim) const =0
int curidx_
Definition: linsolv.h:70
static int Finished()
Definition: task.h:165
Set of (small) copyable elements.
Definition: commontypes.h:26
Array2D ( Subclass of ArrayND ) is a two dimensional array.
Definition: arraynd.h:127
Class that can execute a task.
Definition: task.h:193
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
#define mUdf(type)
Use this macro to get the undefined for simple types.
Definition: undefval.h:270
od_int64 nrDone() const
Definition: linsolv.h:67
od_int64 totalNr() const
Definition: linsolv.h:68
#define mDefEps
Definition: commondefs.h:60
TypeSet< T > vv_
Definition: linsolv.h:74
int totalnr_
Definition: linsolv.h:71
bool isEmpty() const
Definition: odstring.h:49
BufferString errmsg_
Definition: horizontracker.h:117
static uiString sInput()
int size() const
Definition: linsolv.h:35
Definition: linsolv.h:49
bool ready_
Definition: linsolv.h:43
static uiString phrInvalid(const uiString &string)
"Invalid <string>"
bool ready() const
Definition: linsolv.h:34
#define mClass(module)
Definition: commondefs.h:161
#define pErrMsg(msg)
Usual access point for programmer error messages.
Definition: errmsg.h:34
uiString nrDoneText() const
Definition: linsolv.h:64
LinSolver(const Array2D< T > &A)
Definition: linsolv.h:188
Array2DImpl< T > croutsmatrix_
Definition: linsolv.h:40
Specification to enable chunkwise execution of a process.
Definition: executor.h:38
~LinSolver()
Definition: linsolv.h:223
void apply(const T *b, T *x) const
Definition: linsolv.h:230
uiString errmsg_
Definition: linsolv.h:76
int nextStep()
Definition: linsolv.h:120

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