OpendTect  6.6
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 RCS: $Id$
10 ________________________________________________________________________
11 
12 -*/
13 
14 #include "algomod.h"
15 
16 #include "math2.h"
17 #include "paralleltask.h"
18 #include "statruncalc.h"
19 #include "uistrings.h"
20 
21 namespace Stats
22 {
23 
33 template <class T>
36 public:
37 
38  mUseType(CalcSetup,idx_type);
39  mUseType(CalcSetup,size_type);
40 
41  ParallelCalc(const CalcSetup& s,const T* data,
42  size_type sz,const T* weights = 0)
43  : BaseCalc<T>(s)
44  { setValues(data,sz,weights); }
45  ParallelCalc( const CalcSetup& s )
46  : BaseCalc<T>(s) { setValues(0,0,0); }
47 
48  inline void setValues(const T* inp,size_type sz,
49  const T* wght=0);
50  inline void setEmpty();
51 
52  const uiString errMsg() const { return errmsg_; }
53 
54  virtual inline double variance() const;
55 
57 
58 protected:
59 
60  od_int64 nrIterations() const { return nradded_; }
61 
62  inline bool doPrepare(int);
63  inline bool doWork(od_int64,od_int64,int);
64  inline bool doFinish(bool);
65 
66  virtual const T* sort(idx_type* index_of_median =nullptr);
67 
69 
71 
72  const T* data_ = nullptr;
73  const T* weights_ = nullptr;
74  bool* udfarr_ = nullptr;
75 
80 
81  using BaseCalc<T>::setup_;
88  using BaseCalc<T>::sum_x_;
90  using BaseCalc<T>::sum_w_;
93  using BaseCalc<T>::clss_;
96 };
97 
98 
99 template <class T>
101 {
102  this->clear();
103  nradded_ = 0; data_ = nullptr; weights_ = nullptr;
104  deleteAndZeroPtr( udfarr_ );
105 }
106 
107 
108 template <class T>
109 inline void ParallelCalc<T>::setValues( const T* data, size_type sz,
110  const T* wght )
111 {
112  this->clear();
113  nradded_ = sz;
114  data_ = data;
115  weights_ = wght;
116 }
117 
118 
119 template <class T>
120 inline bool ParallelCalc<T>::doPrepare( int nrthreads )
121 {
122  if ( !data_ )
123  {
124  errmsg_ = tr("No data given to compute statistics");
125  return false;
126  }
127  if ( nradded_ < 1 )
128  {
129  errmsg_ = tr("Data array is empty");
130  return false;
131  }
132 
133  const size_type nradded = nradded_;
135  nradded_ = nradded;
136  meanval_ = meanval_w_ = 0.;
137  variance_ = variance_w_ = 0.;
138  delete udfarr_;
139  mTryAlloc( udfarr_, bool[nradded] );
140  if ( !udfarr_ )
141  {
143  return false;
144  }
145 
146  barrier_.setNrThreads( nrthreads );
147 
148  return true;
149 }
150 
151 
152 template <class T>
153 inline bool ParallelCalc<T>::doWork( od_int64 start, od_int64 stop, int thread )
154 {
155  double sum_w = 0;
156  double sum_wx = 0;
157  double sum_wxx = 0;
158  double sum_x = 0;
159  double sum_xx = 0;
160  idx_type minidx = 0;
161  idx_type maxidx = 0;
162  idx_type nrused = 0;
163 
164  bool* udfptr = udfarr_ + start;
165  for ( ; start<=stop && mIsUdf(data_[start] ); start++ )
166  *udfptr++ = true;
167 
168  idx_type idx = start;
169  const T* dataptr = data_ + start;
170  const T* stopptr = dataptr + (stop-start+1);
171 
172  T val = *dataptr;
173  T tmin = val;
174  T tmax = val;
175 
176  while ( dataptr < stopptr )
177  {
178  val = *dataptr++;
179  idx ++;
180  *udfptr = mIsUdf(val);
181  if ( *udfptr++ )
182  continue;
183 
184  sum_x += val;
185  sum_xx += val*val;
186  if ( val < tmin )
187  { tmin = val; minidx = idx; }
188  if ( val > tmax )
189  { tmax = val; maxidx = idx; }
190 
191  nrused ++;
192  }
193 
194  if ( setup_.weighted_ && weights_ )
195  {
196  dataptr = data_ + start;
197  udfptr = udfarr_ + start;
198  const T* weightptr = weights_ ? weights_ + start : 0;
199  while ( dataptr < stopptr )
200  {
201  const T weight = *weightptr;
202  val = *dataptr;
203 
204  dataptr ++;
205  weightptr ++;
206 
207  if ( *udfptr++ )
208  continue;
209 
210  sum_w += weight;
211  sum_wx += weight * val;
212  sum_wxx += weight * val * val;
213  }
214  }
215 
216  barrier_.waitForAll( false );
217 
218  nrused_ += nrused;
219  sum_x_ += (T)sum_x;
220  sum_xx_ += (T)sum_xx;
221  if ( setup_.weighted_ )
222  {
223  sum_w_ += (T)sum_w;
224  sum_wx_ += (T)sum_wx;
225  sum_wxx_ += (T)sum_wxx;
226  }
227 
228  if ( ( mIsUdf(minval_) || minval_ > tmin ) && !mIsUdf(tmin ) )
229  { minval_ = tmin; minidx_ = minidx; }
230  if ( ( mIsUdf(maxval_) || maxval_ < tmax ) && !mIsUdf(tmax) )
231  { maxval_ = tmax; maxidx_ = maxidx; }
232 
233  barrier_.mutex().unLock();
234 
235  barrier_.waitForAll( false );
236 
237  if ( nrused_ != 0 )
238  {
239  meanval_ = sum_x_ / nrused_;
240  meanval_w_ = sum_wx_ / nrused_;
241  }
242 
243  barrier_.mutex().unLock();
244 
245  barrier_.waitForAll( true );
246 
247  //The 2nd pass of the 2 pass variance
248  if ( setup_.needvariance_ )
249  {
250  T tvariance = 0;
251  T tvariance_w = 0;
252  const int nrthreads = barrier_.nrThreads();
253  const int nrperthread = nradded_/nrthreads;
254  const idx_type startidx = thread*nrperthread;
255  const idx_type stopidx = mMIN( startidx + nrperthread, nradded_)-1;
256 
257  dataptr = data_ + startidx;
258  stopptr = dataptr + ( stopidx-startidx + 1 );
259  udfptr = udfarr_ + startidx;
260 
261  if ( setup_.weighted_ && weights_ )
262  {
263  const T* weightptr = weights_ ? weights_ + startidx : 0;
264  while ( dataptr < stopptr )
265  {
266  const T weight = *weightptr++;
267  val = *dataptr++;
268  if ( *udfptr++ )
269  continue;
270 
271  T varval = val*weight - meanval_w_;
272  varval *= varval;
273  tvariance_w += varval;
274  }
275  }
276  else
277  {
278  while ( dataptr < stopptr )
279  {
280  val = *dataptr++;
281  if ( *udfptr++ )
282  continue;
283 
284  T varval = val - meanval_;
285  varval *= varval;
286  tvariance += varval;
287  }
288  }
289  barrier_.waitForAll( false );
290 
291  variance_ += tvariance / (nrused_-1);
292  variance_w_ += tvariance_w / (nrused_-1);
293 
294  barrier_.mutex().unLock();
295  }
296 
297  return true;
298 }
299 
300 
301 template <>
303 {
304  pErrMsg("Undefined operation for float_complex in template");
305  return false;
306 }
307 
308 
309 template <class T>
310 inline bool ParallelCalc<T>::doFinish( bool success )
311 {
312  if ( !success )
313  return false;
314 
315  if ( setup_.needmostfreq_ )
316  {
317  clss_.setSize( nrused_ );
318  clsswt_.setSize( nrused_ );
319  clsswt_.setAll( 1 );
320 
321  const bool* udfptr = udfarr_;
322  for ( idx_type idx=0; idx<nradded_; idx++ )
323  {
324  if ( *udfptr++ )
325  continue;
326 
327  const T val = data_[idx];
328  const T wt = weights_[idx];
329  idx_type ival; Conv::set( ival, val );
330  idx_type setidx = clss_.indexOf( ival );
331 
332  if ( setidx < 0 )
333  { clss_[idx] = ival; clsswt_[idx] = wt; }
334  else
335  clsswt_[setidx] = wt;
336  }
337  }
338 
339  if ( setup_.needmed_ || setup_.needsorted_ )
340  {
341  medvals_.setSize( nrused_, mUdf(float) );
342  T* medvalsarr = medvals_.arr();
343  const bool* udfptr = udfarr_;
344  for ( idx_type idx=0; idx<nradded_; idx++ )
345  {
346  if ( *udfptr++ )
347  continue;
348 
349  *medvalsarr++ = data_[idx];
350  }
351  }
352 
353  return true;
354 }
355 
356 
357 template <>
359 {
360  pErrMsg("Undefined operation for float_complex in template");
361  return false;
362 }
363 
364 
365 template <class T> inline
366 const T* ParallelCalc<T>::sort( idx_type* idx_of_med )
367 {
368  return BaseCalc<T>::sort( idx_of_med );
369 
370 /* TODO: uncomment when the ParallelSorter works
371  T* valarr = medvals_.arr();
372  const size_type sz = nrused_;
373  LargeValVec<idx_type>& medidxs = BaseCalc<T>::medidxs_;
374  const bool withidxs = idx_of_med || setup_.weighted_;
375  if ( BaseCalc<T>::issorted_ &&
376  ( (withidxs && medidxs.size()==sz) || (!withidxs) ) )
377  return valarr;
378 
379  ParallelSorter<T>* sorter = nullptr;
380  if ( withidxs )
381  {
382  if ( medidxs.size() != sz )
383  {
384  medidxs.setSize( sz, 0 );
385  for ( idx_type idx=0; idx<sz; idx++ )
386  medidxs[idx] = idx;
387  }
388 
389  sorter = new ParallelSorter<T>( valarr, medidxs.arr(), sz );
390  }
391  else
392  sorter = new ParallelSorter<T>( valarr, sz );
393 
394  sorter->execute();
395  delete sorter;
396 
397  return valarr; */
398 }
399 
400 
401 template <> inline
402 const float_complex* ParallelCalc<float_complex>::sort( idx_type* idx_of_med )
403 {
404  pErrMsg("Undefined operation for float_complex in template");
405  return nullptr;
406 }
407 
408 
409 template <class T>
410 inline double ParallelCalc<T>::variance() const
411 {
412  return setup_.weighted_ ? variance_w_ : variance_ ;
413 }
414 
415 
416 template <>
418 {
419  pErrMsg("Undefined operation for float_complex in template");
420  return mUdf(double);
421 }
422 
423 } //namespace Stats
Stats::ParallelCalc::variance
virtual double variance() const
Definition: statparallelcalc.h:410
Stats::ParallelCalc::ParallelCalc
ParallelCalc(const CalcSetup &s, const T *data, size_type sz, const T *weights=0)
Definition: statparallelcalc.h:41
Stats::ParallelCalc::variance_w_
T variance_w_
Definition: statparallelcalc.h:79
float_complex
std::complex< float > float_complex
Definition: odcomplex.h:17
Stats::ParallelCalc::errMsg
const uiString errMsg() const
Definition: statparallelcalc.h:52
statruncalc.h
Stats::ParallelCalc::doPrepare
bool doPrepare(int)
Definition: statparallelcalc.h:120
mIsUdf
#define mIsUdf(val)
Use mIsUdf to check for undefinedness of simple types.
Definition: undefval.h:289
od_int64
#define od_int64
Definition: plftypes.h:35
Stats::ParallelCalc::meanval_
T meanval_
Definition: statparallelcalc.h:76
Stats::BaseCalc::clear
void clear()
Definition: statruncalc.h:317
Stats::BaseCalc
Base class to calculate mean, min, max, etc.. can be used either as running values (Stats::RunCalc) o...
Definition: statruncalc.h:108
Stats::BaseCalc::sort
virtual const T * sort(idx_type *index_of_median=nullptr)
Definition: statruncalc.h:502
Stats::ParallelCalc::barrier_
Threads::Barrier barrier_
Definition: statparallelcalc.h:70
uiStrings::phrCannotAllocateMemory
static uiString phrCannotAllocateMemory(int64_t reqsz=-1)
Stats::ParallelCalc::mODTextTranslationClass
mODTextTranslationClass(ParallelCalc)
Stats::ParallelCalc::doFinish
bool doFinish(bool)
Definition: statparallelcalc.h:310
deleteAndZeroPtr
void deleteAndZeroPtr(T *&ptr, bool isowner=true)
Definition: ptrman.h:27
Stats::ParallelCalc::nrIterations
od_int64 nrIterations() const
Definition: statparallelcalc.h:60
Stats::ParallelCalc::doWork
bool doWork(od_int64, od_int64, int)
Definition: statparallelcalc.h:153
Stats::ParallelCalc::setEmpty
void setEmpty()
Definition: statparallelcalc.h:100
Stats::ParallelCalc
Stats computation running in parallel.
Definition: statparallelcalc.h:35
mClass
#define mClass(module)
Definition: commondefs.h:181
Stats::ParallelCalc::variance_
T variance_
Definition: statparallelcalc.h:78
uistrings.h
mTryAlloc
#define mTryAlloc(var, stmt)
Catches bad_alloc and sets ptr to null as normal.
Definition: commondefs.h:246
Stats::ParallelCalc::mUseType
mUseType(CalcSetup, size_type)
pErrMsg
#define pErrMsg(msg)
Usual access point for programmer error messages.
Definition: errmsg.h:37
Conv::set
void set(T &_to, const F &fr)
template based type conversion
Definition: convert.h:27
Stats::ParallelCalc::mUseType
mUseType(CalcSetup, idx_type)
ParallelTask
Generalization of a task that can be run in parallel.
Definition: paralleltask.h:66
Stats::ParallelCalc::ParallelCalc
ParallelCalc(const CalcSetup &s)
Definition: statparallelcalc.h:45
Threads::Barrier
Waits for a number of threads to reach a certain point (i.e. the call to Barrier::waitForAll)....
Definition: thread.h:239
uiString
String that is able to hold international (UTF-8) strings for the user interface.
Definition: uistring.h:121
mMIN
#define mMIN(x, y)
Definition: commondefs.h:62
MPE::errmsg_
BufferString errmsg_
Definition: horizontracker.h:118
Stats::CalcSetup
Setup for the Stats::RunCalc and Stats::ParallelCalc objects.
Definition: statruncalc.h:38
Stats::ParallelCalc::setValues
void setValues(const T *inp, size_type sz, const T *wght=0)
Definition: statparallelcalc.h:109
mUdf
#define mUdf(type)
Use this macro to get the undefined for simple types.
Definition: undefval.h:274
Stats
Statistics.
Definition: array2dinterpol.h:27
Stats::ParallelCalc::errmsg_
uiString errmsg_
Definition: statparallelcalc.h:68
Stats::ParallelCalc::sort
virtual const T * sort(idx_type *index_of_median=nullptr)
Definition: statparallelcalc.h:366
paralleltask.h
math2.h
StrmOper::clear
void clear(std::ios &)
Stats::ParallelCalc::meanval_w_
T meanval_w_
Definition: statparallelcalc.h:77

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