OpendTect  6.6
datadistribution.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: Bert
8  Date: January 2017
9 ________________________________________________________________________
10 
11 -*/
12 
13 #include "algomod.h"
14 #include "typeset.h"
15 #include "samplingdata.h"
16 #include "sharedobject.h"
17 
18 template <class VT> class DataDistributionChanger;
19 template <class VT> class DataDistributionInfoExtracter;
20 template <class VT> class DataDistributionIter;
21 
22 
41 template <class VT>
43 {
44 public:
46  : sampling_(VT(0),VT(1)) {}
47  inline DataDistribution(int);
48  inline DataDistribution(SamplingData<VT>,int n=256);
49  inline DataDistribution(const TypeSet<VT>&);
50  inline DataDistribution(const TypeSet<VT>&,
53 
54  inline int size() const;
55  inline bool isEmpty() const { return size() < 1; }
56  inline void setEmpty();
57  mImplSimpleMonitoredGetSet( inline,sampling,setSampling,SamplingData<VT>,
58  sampling_,cSamplingChange());
59  void setSize(int);
60 
61  inline VT get(int,bool cumulative=false) const;
62  inline VT operator[](int) const;
63  inline VT binPos(int) const;
64  inline VT valueAt(VT,bool cumulative) const;
65  inline int getBinNr(VT) const;
66  inline TypeSet<VT> getSet( bool cum ) const
67  { mLock4Read(); return cum ? cumdata_ : data_; }
68 
69  inline void set(int,VT);
70  inline void set(const VT*);
71  inline void add(const VT*);
72 
73  inline bool isNormalised() const
74  { return sumOfValues() == VT(1); }
75  inline VT sumOfValues() const;
76  inline VT maxValue() const;
77  inline Interval<VT> dataRange() const;
78 
79  inline VT positionForCumulative(VT) const;
80  inline VT medianPosition() const;
81  inline void getAvgStd(VT& avg,VT& std) const;
82  inline VT* getArr( bool cum ) const
83  { return cum ? cumdata_.arr() : data_.arr(); }
85 
86  static ChangeType cDataChange() { return 2; }
87  static ChangeType cSamplingChange() { return 3; }
88 
89  static const DataDistribution<VT>& getEmptyDistrib();
90  static inline int getBinNrFor(VT,const SamplingData<VT>&,
91  int nrbins);
92 
93 protected:
94 
95  inline ~DataDistribution();
96 
100 
101  void setCumData(int);
102  inline VT gtMax(int* idxat=0) const;
103 
104  friend class DataDistributionChanger<VT>;
105  friend class DataDistributionInfoExtracter<VT>;
106  friend class DataDistributionIter<VT>;
107 
108 };
109 
111 
112 
113 template <class VT> inline
115  : SharedObject(oth)
116  , data_(oth.data_)
117  , cumdata_(oth.cumdata_)
118  , sampling_(oth.sampling_)
119 {
120 }
121 
122 
123 template <class VT> inline
125  : data_(nrbins,0)
126  , cumdata_(nrbins,0)
127  , sampling_(VT(0),VT(1))
128 {
129 }
130 
131 
132 template <class VT> inline
134  : data_(nrbins,0)
135  , cumdata_(nrbins,0)
136  , sampling_(sd)
137 {
138 }
139 
140 
141 template <class VT> inline
143  : data_(d.size(),0)
144  , cumdata_(d.size(),0)
145  , sampling_(VT(0),VT(1))
146 {
147  set( d.arr() );
148 }
149 
150 
151 template <class VT> inline
153  : data_(d.size(),0)
154  , cumdata_(d.size(),0)
155  , sampling_(sd)
156 {
157  set( d.arr() );
158 }
159 
160 
161 template <class VT> inline
163 {
164  sendDelNotif();
165 }
166 
167 
169  SharedObject);
170 
171 
172 template <class VT> inline
174 {
175  data_ = oth.data_;
176  cumdata_ = oth.cumdata_;
177  sampling_ = oth.sampling_;
178 }
179 
180 
181 template <class VT> inline
183  const DataDistribution<VT>& oth ) const
184 {
186  mHandleMonitorableCompare( data_, cDataChange() );
187  mHandleMonitorableCompare( sampling_, cSamplingChange() );
189 }
190 
191 
192 template <class VT> inline
194 {
195  mLock4Read();
196  return data_.size();
197 }
198 
199 
200 template <class VT> inline
202  VT pos, const SamplingData<VT>& sd, int nbins )
203 {
204  const float fbin = sd.getfIndex( pos );
205  int ret;
206  if ( fbin < 0 )
207  ret = 0;
208  else
209  {
210  ret = (int)( fbin + 0.5f );
211  if ( ret >= nbins )
212  ret = nbins - 1;
213  }
214  return ret;
215 }
216 
217 
218 template <class VT> inline
220 {
221  mLock4Read();
222  return getBinNrFor( p, sampling_, data_.size() );
223 }
224 
225 
226 template <class VT> inline
228 {
229  return get( idx, false );
230 }
231 
232 
233 template <class VT> inline
234 VT DataDistribution<VT>::get( int idx, bool cumulative ) const
235 {
236  mLock4Read();
237  return cumulative ? cumdata_[idx] : data_[idx];
238 }
239 
240 
241 template <class VT> inline
242 VT DataDistribution<VT>::binPos( int idx ) const
243 {
244  mLock4Read();
245  return sampling_.atIndex( idx );
246 }
247 
248 
249 template <class VT> inline
250 VT DataDistribution<VT>::valueAt( VT pos, bool cumulative ) const
251 {
252  mLock4Read();
253  const TypeSet<VT>& vals = cumulative ? cumdata_ : data_;
254  const int sz = vals.size();
255  if ( sz < 1 )
256  return mUdf(VT);
257 
258  VT fidx = sampling_.getfIndex( pos );
259  if ( fidx < -0.5f )
260  fidx = -0.5f;
261  else if ( fidx > vals.size()-0.5f )
262  fidx = vals.size()-0.5f;
263  if ( cumulative )
264  fidx -= 0.5f;
265 
266  const int aftidx = getLimited( ((int)fidx + 1), 0, sz );
267  const int beforeidx = aftidx - 1;
268 
269  const VT valbefore = beforeidx<0 ? (cumulative?VT(0):vals[0])
270  : vals[ beforeidx ];
271  const VT valafter = aftidx>sz-2 ? vals.last() : vals[ aftidx ] ;
272  const VT relpos = (fidx - beforeidx);
273  return valbefore + (valafter-valbefore) * relpos;
274 }
275 
276 
277 template <class VT> inline
279 {
280  mLock4Read();
281  if ( data_.isEmpty() )
282  return;
283  if ( !mLock2Write() && data_.isEmpty() )
284  return;
285 
286  data_.setEmpty();
288 }
289 
290 
291 template <class VT> inline
292 void DataDistribution<VT>::set( int isamp, VT val )
293 {
294  mLock4Read();
295  if ( !data_.validIdx(isamp) || data_[isamp] == val )
296  return;
297  if ( !mLock2Write() && (isamp>=data_.size() || data_[isamp] == val) )
298  return;
299 
300  const VT diff = val - data_[isamp];
301  data_[isamp] = val;
302  const int sz = data_.size();
303  for ( int idx=isamp+1; idx<sz; idx++ )
304  data_[idx] += diff;
305  mSendChgNotif( cDataChange(), isamp );
306 }
307 
308 
309 template <class VT> inline
310 void DataDistribution<VT>::add( const VT* vals )
311 {
312  mLock4Write();
313  const int sz = data_.size();
314  VT add2cumulative = 0;
315  for ( int idx=0; idx<sz; idx++ )
316  {
317  add2cumulative += vals[idx];
318  data_[idx] += vals[idx];
319  cumdata_[idx] += add2cumulative;
320  }
321 
322  mSendChgNotif( cDataChange(), cUnspecChgID() );
323 }
324 
325 
326 template <class VT> inline
328 {
329  cumdata_[idx] = data_[idx] + (idx<1 ? VT(0) : cumdata_[idx-1]);
330 }
331 
332 
333 template <class VT> inline
334 void DataDistribution<VT>::set( const VT* vals )
335 {
336  mLock4Write();
337  const int sz = data_.size();
338  for ( int idx=0; idx<sz; idx++ )
339  {
340  data_[idx] = vals[idx];
341  setCumData( idx );
342  }
343 
344  mSendChgNotif( cDataChange(), cUnspecChgID() );
345 }
346 
347 
348 template <class VT> inline
350 {
351  mLock4Read();
352  return cumdata_.last();
353 }
354 
355 
356 template <class VT> inline
358 {
359  mLock4Read();
360  return gtMax();
361 }
362 
363 
364 template <class VT> inline
366 {
367  mLock4Read();
368  const VT hstep = sampling_.step * VT(0.5);
369  return Interval<VT>( sampling_.start - hstep,
370  sampling_.atIndex(data_.size()-1) + hstep );
371 }
372 
373 
374 template <class VT> inline
375 VT DataDistribution<VT>::gtMax( int* idxat ) const
376 {
377  const int sz = data_.size();
378  if ( idxat )
379  *idxat = 0;
380 
381  if ( sz < 2 )
382  return sz == 1 ? data_[0] : VT(0);
383 
384  VT ret = data_[0];
385  for ( int idx=1; idx<sz; idx++ )
386  {
387  const VT val = data_[idx];
388  if ( val > ret )
389  {
390  ret = val;
391  if ( idxat )
392  *idxat = idx;
393  }
394  }
395 
396  return ret;
397 }
398 
399 
400 template <class VT> inline
402 {
403  if ( mIsUdf(val) )
404  return VT(1);
405 
406  mLock4Read();
407  const int sz = cumdata_.size();
408  if ( sz < 2 )
409  return sz == 1 ? sampling_.start : mUdf(VT);
410  else if ( val <= VT(0) )
411  return sampling_.start - VT(0.5) * sampling_.step;
412  else if ( val >= cumdata_.last() )
413  return sampling_.start + VT(sz-0.5) * sampling_.step;
414 
415  // this function is mostly used for clipping which is at start or end
416  // simple bisection may then not be optimal.
417  // if not, then this will still be 2 times faster (on average)
418 
419  if ( val < cumdata_[sz/2] )
420  {
421  for ( int idx=0; idx<sz; idx++ )
422  {
423  const VT nextval = cumdata_[idx];
424  if ( val <= nextval )
425  {
426  VT prevpos = sampling_.start + VT(idx-0.5)
427  * sampling_.step;
428  if ( val == nextval )
429  return prevpos + sampling_.step;
430 
431  const VT prevval = idx ? cumdata_[idx-1] : VT(0);
432  const VT relpos = (val - prevval) / (nextval - prevval);
433  return prevpos + sampling_.step * relpos;
434  }
435  }
436  }
437  else
438  {
439  for ( int idx=sz-1; idx>0; idx-- )
440  {
441  const VT prevval = cumdata_[idx-1];
442  if ( val >= prevval )
443  {
444  VT prevpos = sampling_.start + VT(idx-0.5)
445  * sampling_.step;
446  if ( prevval == val )
447  return prevpos;
448 
449  const VT nextval = cumdata_[idx];
450  const VT relpos = (val - prevval) / (nextval - prevval);
451  return prevpos + sampling_.step * relpos;
452  }
453  }
454  }
455 
456  // should not reach
457  return VT(0);
458 }
459 
460 
461 template <class VT> inline
463 {
464  mLock4Read();
465  if ( cumdata_.size() < 2 )
466  return sampling_.start;
467 
468  return positionForCumulative( cumdata_.last() * VT(0.5) );
469 }
470 
471 
472 template <class VT> inline
473 void DataDistribution<VT>::getAvgStd( VT& avg, VT& std ) const
474 {
475  mLock4Read();
476  const auto sz = cumdata_.size();
477  if ( sz < 2 )
478  { avg = sampling_.start; std = (VT)0; return; }
479 
480  VT wtsum = (VT)0;
481  for ( auto idx=0; idx<sz; idx++ )
482  wtsum += data_[idx] * sampling_.atIndex( idx );
483  avg = wtsum / cumdata_[sz-1];
484 
485  VT sumsqdiffs = (VT)0;
486  for ( auto idx=0; idx<sz; idx++ )
487  {
488  const auto diff = sampling_.atIndex(idx) - avg;
489  sumsqdiffs += data_[idx] * diff * diff;
490  }
491  std = Math::Sqrt( sumsqdiffs / cumdata_[sz-1] );
492 }
493 
494 
495 template <class VT> inline
497 {
499  = new DataDistribution<VT> );
500  return *theempty;
501 }
DataDistribution::cumdata_
TypeSet< VT > cumdata_
Definition: datadistribution.h:98
DataDistribution::get
VT get(int, bool cumulative=false) const
Definition: datadistribution.h:234
DataDistribution::data_
TypeSet< VT > data_
Definition: datadistribution.h:97
DataDistribution
Sharable data distribution. Sampling defaults to 0 step 1.
Definition: datadistribution.h:43
DataDistribution::DataDistribution
DataDistribution()
Definition: datadistribution.h:45
DataDistribution::getArr
VT * getArr(bool cum) const
for fast non-shared usage
Definition: datadistribution.h:82
FloatDistrib
DataDistribution< float > FloatDistrib
Definition: datadistribution.h:110
mIsUdf
#define mIsUdf(val)
Use mIsUdf to check for undefinedness of simple types.
Definition: undefval.h:289
DataDistribution::cDataChange
static ChangeType cDataChange()
Definition: datadistribution.h:86
DataDistribution::mDeclMonitorableAssignment
mDeclMonitorableAssignment(DataDistribution)
samplingdata.h
DataDistribution::sumOfValues
VT sumOfValues() const
Definition: datadistribution.h:349
DataDistribution::getAvgStd
void getAvgStd(VT &avg, VT &std) const
Definition: datadistribution.h:473
DataDistributionChanger
Definition: datadistribution.h:18
DataDistribution::positionForCumulative
VT positionForCumulative(VT) const
Definition: datadistribution.h:401
sharedobject.h
typeset.h
getLimited
T getLimited(T v, T min, T max)
Definition: commondefs.h:42
DataDistribution::getEmptyDistrib
static const DataDistribution< VT > & getEmptyDistrib()
Definition: datadistribution.h:496
DataDistribution::setSize
void setSize(int)
SharedObject
Definition: sharedobject.h:20
mStartMonitorableCompare
#define mStartMonitorableCompare()
Helper macro to easily implement your compareClassData() in standard situations.
Definition: monitor.h:244
DataDistribution::gtMax
VT gtMax(int *idxat=0) const
Definition: datadistribution.h:375
MonitoredObject::ChangeType
int ChangeType
Definition: monitoredobject.h:84
DataDistribution::setEmpty
void setEmpty()
Definition: datadistribution.h:278
mLock2Write
#define mLock2Write()
Definition: monitor.h:71
DataDistribution::set
void set(int, VT)
slow, O(N)
Definition: datadistribution.h:292
DataDistribution::isEmpty
bool isEmpty() const
Definition: datadistribution.h:55
DataDistribution::getBinNrFor
static int getBinNrFor(VT, const SamplingData< VT > &, int nrbins)
Definition: datadistribution.h:201
DataDistribution::size
int size() const
Definition: datadistribution.h:193
DataDistribution::getBinNr
int getBinNr(VT) const
Definition: datadistribution.h:219
mClass
#define mClass(module)
Definition: commondefs.h:181
mLock4Write
#define mLock4Write()
Definition: monitor.h:70
mSendChgNotif
#define mSendChgNotif(typ, id)
Definition: monitor.h:75
DataDistribution::operator[]
VT operator[](int) const
Definition: datadistribution.h:227
DataDistribution::add
void add(const VT *)
fast, no checks
Definition: datadistribution.h:310
SamplingData< VT >
SamplingData::getfIndex
float getfIndex(FT) const
Definition: samplingdata.h:126
DataDistribution::setCumData
void setCumData(int)
Definition: datadistribution.h:327
DataDistribution::isNormalised
bool isNormalised() const
Definition: datadistribution.h:73
mDeliverMonitorableCompare
#define mDeliverMonitorableCompare()
Definition: monitor.h:264
mGenImplMonitorableAssignment
mGenImplMonitorableAssignment(template< class VT > inline, DataDistribution< VT >, SharedObject)
Conv::set
void set(T &_to, const F &fr)
template based type conversion
Definition: convert.h:27
DataDistribution::sampling_
SamplingData< VT > sampling_
Definition: datadistribution.h:99
DataDistribution::dataRange
Interval< VT > dataRange() const
Definition: datadistribution.h:365
mHandleMonitorableCompare
#define mHandleMonitorableCompare(memb, val)
Definition: monitor.h:246
DataDistribution::medianPosition
VT medianPosition() const
Definition: datadistribution.h:462
DataDistribution::maxValue
VT maxValue() const
Definition: datadistribution.h:357
SharedObject::copyClassData
void copyClassData(const SharedObject &)
DataDistribution::binPos
VT binPos(int) const
Definition: datadistribution.h:242
std
Definition: fixedstreambuf.h:20
DataDistribution::mImplSimpleMonitoredGetSet
mImplSimpleMonitoredGetSet(inline, sampling, setSampling, SamplingData< VT >, sampling_, cSamplingChange())
DataDistributionIter
Definition: datadistribution.h:20
SharedObject::compareClassData
ChangeType compareClassData(const SharedObject &) const
mUdf
#define mUdf(type)
Use this macro to get the undefined for simple types.
Definition: undefval.h:274
DataDistribution::valueAt
VT valueAt(VT, bool cumulative) const
Definition: datadistribution.h:250
mDefineStaticLocalObject
#define mDefineStaticLocalObject(type, var, init)
Definition: commondefs.h:203
DataDistribution::cSamplingChange
static ChangeType cSamplingChange()
Definition: datadistribution.h:87
Math::Sqrt
float Sqrt(float)
mSendEntireObjChgNotif
#define mSendEntireObjChgNotif()
Definition: monitor.h:76
Interval
Interval of values.
Definition: commontypes.h:30
DataDistribution::~DataDistribution
~DataDistribution()
Definition: datadistribution.h:162
DataDistribution::getSet
TypeSet< VT > getSet(bool cum) const
Definition: datadistribution.h:66
TypeSet< VT >
DataDistributionInfoExtracter
Definition: datadistribution.h:19
mLock4Read
#define mLock4Read()
Definition: monitor.h:69
RefMan
Definition: ptrman.h:206

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