15 #include <type_traits>
21 constexpr
unsigned int NSUMS(
unsigned int ND ) {
return 1 + ND + ND * ( ND + 1 ) / 2; }
23 template <
typename Arithmetic, atomicity Atomicity,
unsigned int ND>
25 using InputType = std::conditional_t<ND == 1, Arithmetic, std::array<Arithmetic, ND>>;
31 for (
unsigned int i = 0; i <
NSUMS( ND ); i++ ) { ( *this )[i] = other[i]; }
35 for (
unsigned int i = 0; i <
NSUMS( ND ); i++ ) { ( *this )[i] = other[i]; }
41 for (
unsigned int i = 0; i <
NSUMS( ND ); i++ ) {
out[i] = ( *this )[i].load( std::memory_order_relaxed ); }
45 using InternalType = std::conditional_t<Atomicity == atomicity::full, OutputTypeTS, OutputType>;
53 for (
unsigned int i = 0; i <
NSUMS( ND ); i++ ) { old[i] =
v[i].exchange( newv[i] ); }
56 return std::exchange(
v, newv );
62 for (
unsigned int i = 0; i <
NSUMS( ND ); i++ ) {
fetch_add( a[i], b[i] ); }
64 for (
unsigned int i = 0; i < ND * ( ND + 3 ); i++ ) a[i] += b[i];
71 if constexpr ( ND == 1 ) {
76 for (
unsigned int i = 0; i < ND; i++ ) diff[i + 1] += b[i];
77 unsigned int n = 1 + ND;
78 for (
unsigned int i = 0; i < ND; i++ ) {
79 for (
unsigned int j = i;
j < ND;
j++ ) {
80 diff[
n] = b[i] * b[
j];
87 for (
unsigned int i = 0; i <
NSUMS( ND ); i++ ) {
fetch_add( a[i], diff[i] ); }
89 for (
unsigned int i = 0; i <
NSUMS( ND ); i++ ) a[i] += diff[i];
94 template <
typename Arithmetic, atomicity Atomicity,
unsigned int ND>
96 :
GenericAccumulator<std::array<Arithmetic, ND>, std::array<Arithmetic, NSUMS( ND )>, Atomicity, Identity,
97 Identity, SigmasValueHandler<Arithmetic, Atomicity, ND>> {
102 template <
typename Arithmetic, atomicity Atomicity>
104 :
GenericAccumulator<Arithmetic, std::array<Arithmetic, 3>, Atomicity, Identity, Identity,
105 SigmasValueHandler<Arithmetic, Atomicity, 1>> {
114 template <atomicity Atomicity,
typename Arithmetic,
unsigned int ND>
117 std::integral_constant<int, ND>, IntegralAccumulator> {
123 template <atomicity,
typename,
unsigned int>
126 static_assert( ND <= 3,
"Root on supports histogrmas with dimension <= 3" );
141 using Parent::Parent;
153 template <atomicity ato>
180 template <
typename Arithmetic>
181 Arithmetic stddev( Arithmetic
n, Arithmetic
s, Arithmetic
s2 ) {
184 auto v = (
n > 0 ) ? ( (
s2 -
s * (
s /
n ) ) /
n ) : Arithmetic{};
185 return ( Arithmetic{ 0 } >
v ) ? Arithmetic{} :
sqrt(
v );
192 template <atomicity Atomicity,
typename Arithmetic,
typename ND>
195 template <atomicity Atomicity,
typename Arithmetic>
200 Arithmetic
nEntries()
const {
return this->sums2()[0]; }
201 Arithmetic
sum()
const {
return this->sums2()[1]; }
202 Arithmetic
sum2()
const {
return this->sums2()[2]; }
207 template <atomicity Atomicity,
typename Arithmetic>
212 Arithmetic
nEntries()
const {
return this->sums2()[0]; }
213 Arithmetic
sumx()
const {
return this->sums2()[1]; }
214 Arithmetic
sumy()
const {
return this->sums2()[2]; }
215 Arithmetic
sumx2()
const {
return this->sums2()[3]; }
216 Arithmetic
sumy2()
const {
return this->sums2()[5]; }
217 Arithmetic
sumxy()
const {
return this->sums2()[4]; }
224 template <atomicity Atomicity,
typename Arithmetic>
229 Arithmetic
nEntries()
const {
return this->sums2()[0]; }
230 Arithmetic
sumx()
const {
return this->sums2()[1]; }
231 Arithmetic
sumy()
const {
return this->sums2()[2]; }
232 Arithmetic
sumz()
const {
return this->sums2()[3]; }
233 Arithmetic
sumx2()
const {
return this->sums2()[4]; }
234 Arithmetic
sumy2()
const {
return this->sums2()[7]; }
235 Arithmetic
sumz2()
const {
return this->sums2()[9]; }
236 Arithmetic
sumxy()
const {
return this->sums2()[5]; }
237 Arithmetic
sumxz()
const {
return this->sums2()[6]; }
238 Arithmetic
sumyz()
const {
return this->sums2()[8]; }
265 template <
unsigned int ND, atomicity Atomicity,
typename Arithmetic, const
char* Type>
268 template <atomicity Atomicity,
typename Arithmetic, const
char* Type>
271 std::make_index_sequence<1>> {
274 std::make_index_sequence<1>>;
275 using Parent::Parent;
279 j[
"nTotEntries"] =
h.nEntries();
281 j[
"mean"] =
h.mean();
282 j[
"sum2"] =
h.sum2();
283 j[
"standard_deviation"] =
h.standard_deviation();
287 template <atomicity Atomicity,
typename Arithmetic, const
char* Type>
290 std::make_index_sequence<2>> {
293 std::make_index_sequence<2>>;
294 using Parent::Parent;
298 j[
"nTotEntries"] =
h.nEntries();
299 j[
"sumx"] =
h.sumx();
300 j[
"sumy"] =
h.sumy();
301 j[
"meanx"] =
h.meanx();
302 j[
"meany"] =
h.meany();
303 j[
"sumx2"] =
h.sumx2();
304 j[
"sumy2"] =
h.sumy2();
305 j[
"sumxy"] =
h.sumxy();
306 j[
"standard_deviationx"] =
h.standard_deviationx();
307 j[
"standard_deviationy"] =
h.standard_deviationy();
311 template <atomicity Atomicity,
typename Arithmetic, const
char* Type>
314 std::make_index_sequence<3>> {
317 std::make_index_sequence<3>>;
318 using Parent::Parent;
322 j[
"nTotEntries"] =
h.nEntries();
323 j[
"sumx"] =
h.sumx();
324 j[
"sumy"] =
h.sumy();
325 j[
"sumz"] =
h.sumz();
326 j[
"meanx"] =
h.meanx();
327 j[
"meany"] =
h.meany();
328 j[
"meanz"] =
h.meanz();
329 j[
"sumx2"] =
h.sumx2();
330 j[
"sumy2"] =
h.sumy2();
331 j[
"sumz2"] =
h.sumz2();
332 j[
"sumxy"] =
h.sumxy();
333 j[
"sumxz"] =
h.sumxz();
334 j[
"sumyz"] =
h.sumyz();
335 j[
"standard_deviationx"] =
h.standard_deviationx();
336 j[
"standard_deviationy"] =
h.standard_deviationy();
337 j[
"standard_deviationz"] =
h.standard_deviationz();
342 template <
unsigned int ND, atomicity Atomicity = atomicity::full,
typename Arithmetic =
double>