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

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