OpendTect-6_4  6.4
statparallelcalc.h
Go to the documentation of this file.
1 #ifndef statparallelcalc_h
2 #define statparallelcalc_h
3 
4 /*+
5 ________________________________________________________________________
6 
7 (C) dGB Beheer B.V.; (LICENSE) http://opendtect.org/OpendTect_license.txt
8 Author: Kris and Bruno
9 Date: Oct 2011
10 RCS: $Id$
11 ________________________________________________________________________
12 
13 -*/
14 
15 #include "algomod.h"
16 #include "math2.h"
17 #include "paralleltask.h"
18 #include "statruncalc.h"
19 
20 namespace Stats
21 {
22 
32 template <class T>
33 mClass(Algo) ParallelCalc : public ParallelTask, public BaseCalc<T>
35 public:
36  ParallelCalc(const CalcSetup& s,const T* data,
37  int sz,const T* weights = 0)
38  : BaseCalc<T>(s)
39  { setValues(data,sz,weights); }
40  ParallelCalc( const CalcSetup& s )
41  : BaseCalc<T>(s) { setValues(0,0,0); }
42 
43  inline void setValues(const T* inp,int sz,const T* wght=0);
44  inline void setEmpty();
45 
46  const uiString errMsg() const { return errmsg_; }
47 
48  virtual inline double variance() const;
49 
51 
52 protected:
53 
54  od_int64 nrIterations() const { return nradded_;}
55 
56  inline bool doPrepare(int);
57  inline bool doWork(od_int64,od_int64,int);
58  inline bool doFinish(bool);
59 
61 
63 
64  const T* data_;
65  const T* weights_;
66 
71 
72  using BaseCalc<T>::setup_;
79  using BaseCalc<T>::sum_x_;
81  using BaseCalc<T>::sum_w_;
84  using BaseCalc<T>::clss_;
87 };
88 
89 
90 template <class T>
92 {
93  this->clear();
94  nradded_ = 0; data_ = 0; weights_ = 0;
95 }
96 
97 
98 template <class T>
99 inline void ParallelCalc<T>::setValues( const T* data, int sz, const T* wght )
100 {
101  this->clear();
102  nradded_ = sz;
103  data_ = data;
104  weights_ = wght;
105 }
106 
107 
108 template <class T>
109 inline bool ParallelCalc<T>::doPrepare( int nrthreads )
110 {
111  if ( !data_ )
112  {
113  errmsg_ = od_static_tr("Stats_Parallel_Calc",
114  "No data given to compute statistics");
115  return false;
116  }
117  if ( nradded_ < 1 )
118  {
119  errmsg_ = od_static_tr("Stats_Parallel_Calc",
120  "Data array is empty");
121  return false;
122  }
123 
124  const int nradded = nradded_;
126  nradded_ = nradded;
127  variance_ = variance_w_ =0;
128 
129  barrier_.setNrThreads( nrthreads );
130 
131  return true;
132 }
133 
134 
135 template <class T>
136 inline bool ParallelCalc<T>::doWork( od_int64 start, od_int64 stop, int thread )
137 {
138  double sum_w = 0;
139  double sum_wx = 0;
140  double sum_wxx = 0;
141  double sum_x = 0;
142  double sum_xx = 0;
143  int minidx = 0;
144  int maxidx = 0;
145  int nrused = 0;
146 
147  for ( ; start<=stop && mIsUdf(data_[start] ); start++ )
148  /* just skip undefs at start */;
149 
150  int idx = mCast( int, start );
151  const T* dataptr = data_ + start;
152  const T* stopptr = dataptr + (stop-start+1);
153 
154  T val = *dataptr;
155  T tmin = val;
156  T tmax = val;
157 
158  while ( dataptr < stopptr )
159  {
160  val = *dataptr;
161  dataptr++;
162  idx ++;
163 
164  if ( mIsUdf( val ) )
165  continue;
166 
167  sum_x += val;
168  sum_xx += val*val;
169  if ( val < tmin )
170  { tmin = val; minidx = idx; }
171  if ( val > tmax )
172  { tmax = val; maxidx = idx; }
173 
174  nrused ++;
175  }
176 
177  if ( setup_.weighted_ && weights_ )
178  {
179  dataptr = data_ + start;
180  const T* weightptr = weights_ ? weights_ + start : 0;
181  while ( dataptr < stopptr )
182  {
183  const T weight = *weightptr;
184  val = *dataptr;
185 
186  dataptr ++;
187  weightptr ++;
188 
189  if ( mIsUdf( val ) )
190  continue;
191 
192  sum_w += weight;
193  sum_wx += weight * val;
194  sum_wxx += weight * val * val;
195  }
196  }
197 
198  barrier_.waitForAll( false );
199 
200  nrused_ += nrused;
201  sum_x_ += (T)sum_x;
202  sum_xx_ += (T)sum_xx;
203  if ( setup_.weighted_ )
204  {
205  sum_w_ += (T)sum_w;
206  sum_wx_ += (T)sum_wx;
207  sum_wxx_ += (T)sum_wxx;
208  }
209 
210  if ( ( mIsUdf(minval_) || minval_ > tmin ) && !mIsUdf(tmin ) )
211  { minval_ = tmin; minidx_ = minidx; }
212  if ( ( mIsUdf(maxval_) || maxval_ < tmax ) && !mIsUdf(tmax) )
213  { maxval_ = tmax; maxidx_ = maxidx; }
214 
215  barrier_.mutex().unLock();
216 
217  barrier_.waitForAll( false );
218 
219  if ( nrused_ != 0 )
220  {
221  meanval_ = sum_x_ / nrused_;
222  meanval_w_ = sum_wx_ / nrused_;
223  }
224 
225  barrier_.mutex().unLock();
226 
227  barrier_.waitForAll( true );
228 
229 
230  //The 2nd pass of the 2 pass variance
231  if ( setup_.needvariance_ )
232  {
233  T tvariance = 0;
234  T tvariance_w = 0;
235  const int nrthreads = barrier_.nrThreads();
236  const int nrperthread = nradded_/nrthreads;
237  const int startidx = thread*nrperthread;
238  const int stopidx = mMIN( startidx + nrperthread, nradded_)-1;
239 
240  dataptr = data_ + startidx;
241  stopptr = dataptr + ( stopidx-startidx + 1 );
242 
243  if ( setup_.weighted_ && weights_ )
244  {
245  const T* weightptr = weights_ ? weights_ + startidx : 0;
246  while ( dataptr < stopptr )
247  {
248  const T weight = *weightptr;
249  val = *dataptr;
250 
251  dataptr ++;
252  weightptr ++;
253 
254  if ( mIsUdf( val ) )
255  continue;
256  T varval = val*weight - meanval_w_;
257  varval *= varval;
258  tvariance_w += varval;
259  }
260  }
261  else
262  {
263  while ( dataptr < stopptr )
264  {
265  val = *dataptr;
266 
267  dataptr++;
268 
269  if ( mIsUdf( val ) )
270  continue;
271  T varval = val - meanval_;
272  varval *= varval;
273  tvariance += varval;
274  }
275  }
276  barrier_.waitForAll( false );
277 
278  variance_ += tvariance / (nrused_-1);
279  variance_w_ += tvariance_w / (nrused_-1);
280 
281  barrier_.mutex().unLock();
282  }
283 
284  return true;
285 }
286 
287 
288 template <>
290 {
291  pErrMsg("Undefined operation for float_complex in template");
292  return false;
293 }
294 
295 
296 template <class T>
297 inline bool ParallelCalc<T>::doFinish( bool success )
298 {
299  if ( !success )
300  return false;
301 
302  if ( setup_.needmostfreq_ )
303  {
304  clss_.setSize( nrused_ );
305  clsswt_.setSize( nrused_ );
306  clsswt_.setAll( 1 );
307 
308  for ( int idx=0; idx<nradded_; idx++ )
309  {
310  const T val = data_[idx];
311  if ( mIsUdf( val ) )
312  continue;
313 
314  const T wt = weights_[idx];
315  int ival; Conv::set( ival, val );
316  int setidx = clss_.indexOf( ival );
317 
318  if ( setidx < 0 )
319  { clss_[idx] = ival; clsswt_[idx] = wt; }
320  else
321  clsswt_[setidx] = wt;
322  }
323  }
324 
325  if ( setup_.needmed_ )
326  {
327  for ( int idx=0; idx<nradded_; idx++ )
328  {
329  const T val = data_[idx];
330  if ( !mIsUdf( val ) )
331  medvals_ += val;
332  }
333  }
334 
335  return true;
336 }
337 
338 
339 template <>
341 {
342  pErrMsg("Undefined operation for float_complex in template");
343  return false;
344 }
345 
346 
347 template <class T>
348 inline double ParallelCalc<T>::variance() const
349 {
350  return setup_.weighted_ ? variance_w_ : variance_ ;
351 }
352 
353 
354 template <>
356 {
357  pErrMsg("Undefined operation for float_complex in template");
358  return mUdf(double);
359 }
360 
361 } //namespace Stats
362 #endif
#define mIsUdf(val)
Use mIsUdf to check for undefinedness of simple types.
Definition: undefval.h:287
const T * data_
Definition: statparallelcalc.h:64
Setup for the Stats::RunCalc and Stats::ParallelCalc objects.
Definition: statruncalc.h:38
bool doFinish(bool)
Definition: statparallelcalc.h:297
#define mODTextTranslationClass(clss)
Definition: uistring.h:38
void clear()
Definition: statruncalc.h:292
#define mCast(tp, v)
Definition: commondefs.h:124
bool doWork(od_int64, od_int64, int)
Definition: statparallelcalc.h:136
#define od_int64
Definition: plftypes.h:36
void clear(std::ios &)
void set(T &_to, const F &fr)
template based type conversion
Definition: convert.h:29
Definition: uistring.h:89
T variance_
Definition: statparallelcalc.h:69
Stats computation running in parallel.
Definition: statparallelcalc.h:33
od_int64 nrIterations() const
Definition: statparallelcalc.h:54
#define mMIN(x, y)
Definition: commondefs.h:49
float variance(const X &x, int sz)
Definition: simpnumer.h:288
Generalization of a task that can be run in parallel.
Definition: paralleltask.h:66
ParallelCalc(const CalcSetup &s, const T *data, int sz, const T *weights=0)
Definition: statparallelcalc.h:36
void setEmpty()
Definition: statparallelcalc.h:91
bool doPrepare(int)
Definition: statparallelcalc.h:109
void setValues(const T *inp, int sz, const T *wght=0)
Definition: statparallelcalc.h:99
const T * weights_
Definition: statparallelcalc.h:65
ParallelCalc(const CalcSetup &s)
Definition: statparallelcalc.h:40
#define mUdf(type)
Use this macro to get the undefined for simple types.
Definition: undefval.h:272
Waits for a number of threads to reach a certain point (i.e. the call to Barrier::waitForAll). Once everyone has arrived, everyone is released.
Definition: thread.h:240
Threads::Barrier barrier_
Definition: statparallelcalc.h:62
BufferString errmsg_
Definition: horizontracker.h:119
const uiString errMsg() const
Definition: statparallelcalc.h:46
Base class to calculate mean, min, max, etc.. can be used either as running values (Stats::RunCalc) o...
Definition: statruncalc.h:100
T variance_w_
Definition: statparallelcalc.h:70
Statistics.
Definition: array2dinterpol.h:28
uiString errmsg_
Definition: statparallelcalc.h:60
#define mClass(module)
Definition: commondefs.h:164
#define pErrMsg(msg)
Definition: errmsg.h:60
T meanval_w_
Definition: statparallelcalc.h:68
uiString od_static_tr(const char *function, const char *text, const char *disambiguation=0, int pluralnr=-1)
virtual double variance() const
Definition: statparallelcalc.h:348
T meanval_
Definition: statparallelcalc.h:67

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