// We don't compute fractional MutableDistribution, it's either whole or none. internal override void Combine(MutableAggregation other, double fraction) { MutableDistribution mutableDistribution = other as MutableDistribution; if (mutableDistribution == null) { throw new ArgumentException("MutableDistribution expected."); } if (Math.Abs(1.0 - fraction) > TOLERANCE) { return; } if (!(this.BucketBoundaries.Equals(mutableDistribution.BucketBoundaries))) { throw new ArgumentException("Bucket boundaries should match."); } // Algorithm for calculating the combination of sum of squared deviations: // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Parallel_algorithm. if (this.Count + mutableDistribution.Count > 0) { double delta = mutableDistribution.Mean - this.Mean; this.SumOfSquaredDeviations = this.SumOfSquaredDeviations + mutableDistribution.SumOfSquaredDeviations + Math.Pow(delta, 2) * this.Count * mutableDistribution.Count / (this.Count + mutableDistribution.Count); } this.Count += mutableDistribution.Count; this.Sum += mutableDistribution.Sum; this.Mean = this.Sum / this.Count; if (mutableDistribution.Min < this.Min) { this.Min = mutableDistribution.Min; } if (mutableDistribution.Max > this.Max) { this.Max = mutableDistribution.Max; } long[] bucketCounts = mutableDistribution.BucketCounts; for (int i = 0; i < bucketCounts.Length; i++) { this.BucketCounts[i] += bucketCounts[i]; } }
private static void Sum(MutableAggregation combined, IAggregationData data) { data.Match <object>( (arg) => { MutableSum sum = combined as MutableSum; if (sum != null) { sum.Add(arg.Sum); } return(null); }, (arg) => { MutableSum sum = combined as MutableSum; if (sum != null) { sum.Add(arg.Sum); } return(null); }, (arg) => { MutableCount count = combined as MutableCount; if (count != null) { count.Add(arg.Count); } return(null); }, (arg) => { MutableMean mean = combined as MutableMean; if (mean != null) { mean.Count = mean.Count + arg.Count; mean.Sum = mean.Sum + (arg.Count * arg.Mean); if (arg.Min < mean.Min) { mean.Min = arg.Min; } if (arg.Max > mean.Max) { mean.Max = arg.Max; } } return(null); }, (arg) => { MutableDistribution dist = combined as MutableDistribution; if (dist != null) { // Algorithm for calculating the combination of sum of squared deviations: // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Parallel_algorithm. if (dist.Count + arg.Count > 0) { double delta = arg.Mean - dist.Mean; dist.SumOfSquaredDeviations = dist.SumOfSquaredDeviations + arg.SumOfSquaredDeviations + Math.Pow(delta, 2) * dist.Count * arg.Count / (dist.Count + arg.Count); } dist.Count += arg.Count; dist.Sum += (arg.Mean * arg.Count); dist.Mean = dist.Sum / dist.Count; if (arg.Min < dist.Min) { dist.Min = arg.Min; } if (arg.Max > dist.Max) { dist.Max = arg.Max; } IList <long> bucketCounts = arg.BucketCounts; for (int i = 0; i < bucketCounts.Count; i++) { dist.BucketCounts[i] += bucketCounts[i]; } } return(null); }, (arg) => { MutableLastValue lastValue = combined as MutableLastValue; if (lastValue != null) { lastValue.initialized = true; if (Double.IsNaN(lastValue.LastValue)) { lastValue.LastValue = arg.LastValue; } else { lastValue.LastValue += arg.LastValue; } } return(null); }, (arg) => { MutableLastValue lastValue = combined as MutableLastValue; if (lastValue != null) { lastValue.initialized = true; if (Double.IsNaN(lastValue.LastValue)) { lastValue.LastValue = arg.LastValue; } else { lastValue.LastValue += arg.LastValue; } } return(null); }, (arg) => { throw new ArgumentException(); }); }