tt_GEOMEAN function
tt_GEOMEAN(values): geometric mean
Implementation
dynamic tt_GEOMEAN(List<dynamic> values) {
final n = values.length;
if (n == 0) return 0.0;
double logSum = 0;
for (final v in values) {
final x = varToDouble(v);
if (x <= 0) return 0.0;
logSum += log(x);
}
final r = exp(logSum / n);
// @@@ a log/exp round trip produces tiny floating-point noise (e.g.
// (1*3*9)^(1/3) is theoretically exactly 3, but actually computes
// to 3.0000000000000004) -- rounded to 12 decimal places to clear
// the noise. The log/exp algorithm itself is kept (rather than
// switching to direct multiply-then-root) because with many input
// values at large magnitudes, direct multiplication can overflow;
// log/exp is more numerically robust.
return double.parse(r.toStringAsFixed(12));
}