@@ -24,7 +24,7 @@ import mir.math.common: fmamath;
2424import mir.math.sum;
2525import mir.ndslice.slice: Slice, SliceKind, hasAsSlice;
2626import mir.primitives;
27- import std.traits : Unqual, isArray, isMutable, isIterable, isIntegral, CommonType;
27+ import std.traits : Unqual, isArray, isMutable, isIterable, isIntegral, CommonType, isNumeric ;
2828
2929// /
3030public import mir.math.sum: Summation;
@@ -939,46 +939,49 @@ Output range for gmean.
939939struct GMeanAccumulator (T)
940940 if (isMutable! T && isFloatingPoint! T)
941941{
942- import mir.math.numeric: ProdAccumulator ;
942+ import mir.bignum.fp: Fp ;
943943
944944 // /
945945 size_t count;
946946 // /
947- ProdAccumulator ! T prodAccumulator;
947+ Fp ! 128 prodAccumulator = 1u ;
948948
949949 // /
950- F gmean (F = T)() @property
950+ F gmean (F = T)() const @property
951951 if (isFloatingPoint! F)
952952 {
953953 import mir.math.common: exp2;
954954
955- return nthroot (cast (F) prodAccumulator.mantissa, count) * exp2(cast (F) prodAccumulator.exp / count);
955+ if (count == 0 )
956+ return 0 ;
957+
958+ long exponent;
959+ Fp! 128 value = prodAccumulator;
960+
961+ if (! value.isSpecial)
962+ {
963+ exponent = value.exponent + 128 ;
964+ value.exponent = - 128 ;
965+ }
966+
967+ return nthroot (cast (F) value, count) * exp2(cast (F) exponent / count);
956968 }
957969
958970 // /
959971 void put (Range )(Range r)
960972 if (isIterable! Range )
961973 {
962- static if (hasShape! Range )
963- {
964- count += r.elementCount;
965- prodAccumulator.put(r);
966- }
967- else
968- {
969- foreach (x; r)
970- {
971- count++ ;
972- prodAccumulator.put(x);
973- }
974- }
974+ import core.lifetime : move;
975+ import mir.algorithm.iteration: each;
976+ each! (e => this .put(e))(move(r));
975977 }
976978
977979 // /
978- void put ()(T x)
980+ void put ()(const T x)
981+ if (isNumeric! T)
979982 {
980983 count++ ;
981- prodAccumulator.put (x);
984+ prodAccumulator *= Fp ! 128 (x);
982985 }
983986}
984987
@@ -1910,7 +1913,7 @@ struct MapSummator(alias fun, T, Summation summation)
19101913 Summator! (T, summation) summator;
19111914
19121915 // /
1913- F sum (F = T)() @property
1916+ F sum (F = T)() const @property
19141917 {
19151918 return cast (F) summator.sum;
19161919 }
@@ -2052,13 +2055,13 @@ struct VarianceAccumulator(T, VarianceAlgo varianceAlgo, Summation summation)
20522055 MeanAccumulator! (T, summation) meanAccumulator;
20532056
20542057 // /
2055- size_t count () @property
2058+ size_t count () const @property
20562059 {
20572060 return meanAccumulator.count;
20582061 }
20592062
20602063 // /
2061- F mean (F = T)() @property
2064+ F mean (F = T)() const @property
20622065 {
20632066 return meanAccumulator.mean;
20642067 }
@@ -2084,7 +2087,7 @@ struct VarianceAccumulator(T, VarianceAlgo varianceAlgo, Summation summation)
20842087 }
20852088
20862089 // /
2087- F variance (F = T)(bool isPopulation) @property
2090+ F variance (F = T)(bool isPopulation) const @property
20882091 {
20892092 if (isPopulation == false )
20902093 return cast (F) sumOfSquares.sum / cast (F) (count - 1 ) -
@@ -2148,13 +2151,13 @@ struct VarianceAccumulator(T, VarianceAlgo varianceAlgo, Summation summation)
21482151 MeanAccumulator! (T, summation) meanAccumulator;
21492152
21502153 // /
2151- size_t count () @property
2154+ size_t count () const @property
21522155 {
21532156 return meanAccumulator.count;
21542157 }
21552158
21562159 // /
2157- F mean (F = T)() @property
2160+ F mean (F = T)() const @property
21582161 {
21592162 return meanAccumulator.mean;
21602163 }
@@ -2362,13 +2365,13 @@ struct VarianceAccumulator(T, VarianceAlgo varianceAlgo, Summation summation)
23622365 MeanAccumulator! (T, summation) meanAccumulator;
23632366
23642367 // /
2365- size_t count () @property
2368+ size_t count () const @property
23662369 {
23672370 return meanAccumulator.count;
23682371 }
23692372
23702373 // /
2371- F mean (F = T)() @property
2374+ F mean (F = T)() const @property
23722375 {
23732376 return meanAccumulator.mean;
23742377 }
@@ -2485,13 +2488,13 @@ struct VarianceAccumulator(T, VarianceAlgo varianceAlgo, Summation summation)
24852488 private size_t _count;
24862489
24872490 // /
2488- size_t count () @property
2491+ size_t count () const @property
24892492 {
24902493 return _count;
24912494 }
24922495
24932496 // /
2494- F mean (F = T)() @property
2497+ F mean (F = T)() const @property
24952498 {
24962499 return cast (F) 0 ;
24972500 }
0 commit comments