Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RBinWithError.hxx
Go to the documentation of this file.
1/// \file
2/// \warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes.
3/// Feedback is welcome!
4
5#ifndef ROOT_RBinWithError
6#define ROOT_RBinWithError
7
8#include "RHistUtils.hxx"
9
10#include <cmath>
11
12namespace ROOT {
13namespace Experimental {
14
15/**
16A special bin content type to compute the bin error in weighted filling.
17
18\warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes.
19Feedback is welcome!
20*/
22 double fSum = 0;
23 double fSum2 = 0;
24
25 explicit operator float() const { return fSum; }
26 explicit operator double() const { return fSum; }
27
29 {
30 fSum++;
31 fSum2++;
32 return *this;
33 }
34
36 {
37 RBinWithError old = *this;
38 operator++();
39 return old;
40 }
41
43 {
44 fSum += w;
45 fSum2 += w * w;
46 return *this;
47 }
48
50 {
51 fSum += rhs.fSum;
52 fSum2 += rhs.fSum2;
53 return *this;
54 }
55
56 RBinWithError &operator*=(double factor)
57 {
58 fSum *= factor;
59 fSum2 *= factor * factor;
60 return *this;
61 }
62
63private:
64 void AtomicAdd(double a, double a2)
65 {
66 // The sum of squares is always non-negative. Use the sign bit to implement a cheap spin lock.
67 double origSum2;
69
70 while (true) {
71 // Repeat loads from memory until we see a non-negative value.
72 // NB: do not use origSum2 < 0, it does not work for -0.0!
73 while (std::signbit(origSum2)) {
75 }
76
77 // The variable appears to be unlocked, confirm with a compare-exchange.
78 double negated = std::copysign(origSum2, -1.0);
80 break;
81 }
82 }
83
84 // By using a spin lock, we do not need atomic operations for fSum.
85 fSum += a;
86
87 double sum2 = origSum2 + a2;
89 }
90
91public:
92 void AtomicInc() { AtomicAdd(1.0, 1.0); }
93
94 void AtomicAdd(double w) { AtomicAdd(w, w * w); }
95
96 /// Add another bin content using atomic instructions.
97 ///
98 /// \param[in] rhs another bin content that must not be modified during the operation
99 void AtomicAdd(const RBinWithError &rhs) { AtomicAdd(rhs.fSum, rhs.fSum2); }
100};
101
102} // namespace Experimental
103} // namespace ROOT
104
105#endif
#define a(i)
Definition RSha256.hxx:99
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void AtomicLoad(const T *ptr, T *ret)
void AtomicStoreRelease(T *ptr, T *val)
bool AtomicCompareExchangeAcquire(T *ptr, T *expected, T *desired)
A special bin content type to compute the bin error in weighted filling.
RBinWithError & operator+=(double w)
RBinWithError & operator+=(const RBinWithError &rhs)
RBinWithError & operator*=(double factor)
void AtomicAdd(double a, double a2)
void AtomicAdd(const RBinWithError &rhs)
Add another bin content using atomic instructions.