releng: Add 2.1.0 baseline and fix API errors
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.timing.core / src / org / eclipse / tracecompass / analysis / timing / core / segmentstore / statistics / SegmentStoreStatistics.java
CommitLineData
ce8319b6 1/*******************************************************************************
658401c8 2 * Copyright (c) 2015, 2016 Ericsson
ce8319b6
BH
3 *
4 * All rights reserved. This program and the accompanying materials are made
5 * available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Bernd Hufmann - Initial API and implementation
11 *******************************************************************************/
5b901f94 12package org.eclipse.tracecompass.analysis.timing.core.segmentstore.statistics;
ce8319b6 13
a1e4b7e8 14import org.eclipse.tracecompass.segmentstore.core.BasicSegment;
ce8319b6
BH
15import org.eclipse.tracecompass.segmentstore.core.ISegment;
16
17/**
53f46dc0 18 * Class to calculate simple segment store statistics (min, max, average)
ce8319b6
BH
19 *
20 * @author Bernd Hufmann
21 */
53f46dc0 22public class SegmentStoreStatistics {
a1e4b7e8
BH
23 private ISegment fMin;
24 private ISegment fMax;
ce8319b6 25 private long fNbSegments;
2d626d38 26 private double fAverage;
381e1541
MK
27 /**
28 * reminder, this is the variance * nb elem, as per the online algorithm
29 */
2d626d38 30 private double fVariance;
c7d7e74e 31 private double fTotal;
ce8319b6
BH
32
33 /**
34 * Constructor
35 */
53f46dc0 36 public SegmentStoreStatistics() {
a1e4b7e8
BH
37 fMin = new BasicSegment(0, Long.MAX_VALUE);
38 fMax = new BasicSegment(Long.MIN_VALUE, 0);
2d626d38
MK
39 fNbSegments = 0;
40 fAverage = 0.0;
41 fVariance = 0.0;
c7d7e74e 42 fTotal = 0.0;
ce8319b6
BH
43 }
44
45 /**
46 * Get minimum value
47 *
48 * @return minimum value
49 */
50 public long getMin() {
a1e4b7e8 51 return fMin.getLength();
ce8319b6
BH
52 }
53
54 /**
55 * Get maximum value
56 *
57 * @return maximum value
58 */
59 public long getMax() {
a1e4b7e8
BH
60 return fMax.getLength();
61 }
62
63 /**
64 * Get segment with minimum length
65 *
66 * @return segment with minimum length
67 */
68 public ISegment getMinSegment() {
69 return fMin;
70 }
71
72 /**
73 * Get segment with maximum length
74 *
75 * @return segment with maximum length
76 */
77 public ISegment getMaxSegment() {
ce8319b6
BH
78 return fMax;
79 }
80
81 /**
82 * Get number of segments analyzed
83 *
84 * @return number of segments analyzed
85 */
86 public long getNbSegments() {
87 return fNbSegments;
88 }
89
90 /**
91 * Gets the arithmetic average
92 *
93 * @return arithmetic average
94 */
95 public double getAverage() {
2d626d38
MK
96 return fAverage;
97 }
98
99 /**
100 * Gets the standard deviation of the segments, uses the online algorithm
101 * shown here <a href=
102 * "https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm">
103 * Wikipedia article of dec 3 2015 </a>
104 *
105 * @return the standard deviation of the segment store, will return NaN if
106 * there are less than 3 elements
107 */
108 public double getStdDev() {
109 return fNbSegments > 2 ? Math.sqrt(fVariance / (fNbSegments - 1)) : Double.NaN;
ce8319b6
BH
110 }
111
381e1541
MK
112 /**
113 * Get total value
114 *
115 * @return total value
116 * @since 1.1
117 */
118 public double getTotal() {
119 return fTotal;
120 }
121
ce8319b6
BH
122 /**
123 * Update the statistics based on a given segment
2d626d38
MK
124 * <p>
125 * This is an online algorithm and must retain a complexity of O(1)
ce8319b6
BH
126 *
127 * @param segment
128 * the segment used for the update
129 */
2d626d38 130 public void update(ISegment segment) {
ce8319b6 131 long value = segment.getLength();
2d626d38
MK
132 /*
133 * Min and max are trivial, as well as number of segments
134 */
a1e4b7e8
BH
135 long min = fMin.getLength();
136 long max = fMax.getLength();
137 fMin = min <= value ? fMin : segment;
138 fMax = max >= value ? fMax : segment;
2d626d38 139
ce8319b6 140 fNbSegments++;
2d626d38
MK
141 /*
142 * The running mean is not trivial, see proof in javadoc.
143 */
144 double delta = value - fAverage;
145 fAverage += delta / fNbSegments;
146 fVariance += delta * (value - fAverage);
c7d7e74e
MAL
147 fTotal += value;
148 }
149
150 /**
381e1541
MK
151 * Merge two statistics sets. If the pools are large, there may be a slight
152 * approximation error (empirically, the error is at most 0.001 but usually
153 * around 1e-5 for the standard deviation as this uses pooled variance.
c7d7e74e 154 *
381e1541
MK
155 * @param other
156 * The other segment store statistics
f625ccd4 157 * @since 1.2
c7d7e74e 158 */
381e1541
MK
159 public void merge(SegmentStoreStatistics other) {
160 if (other.fNbSegments == 0) {
161 return;
162 } else if (fNbSegments == 0) {
163 copy(other);
164 } else if (other.fNbSegments == 1) {
165 update(other.fMax);
166 } else if (fNbSegments == 1) {
167 SegmentStoreStatistics copyOther = new SegmentStoreStatistics();
168 copyOther.copy(other);
169 copyOther.update(fMax);
170 copy(copyOther);
171 } else {
172 internalMerge(other);
173 }
174 }
175
176 private void internalMerge(SegmentStoreStatistics other) {
177 /*
178 * Min and max are trivial, as well as number of segments
179 */
180 long min = fMin.getLength();
181 long max = fMax.getLength();
182 fMin = min <= other.getMin() ? fMin : other.getMinSegment();
183 fMax = max >= other.getMax() ? fMax : other.getMaxSegment();
184
185 long oldNbSeg = fNbSegments;
186 double oldAverage = fAverage;
187 long otherSegments = other.getNbSegments();
188 double otherAverage = other.getAverage();
189 fNbSegments += otherSegments;
190 fTotal += other.getTotal();
191
192 /*
193 * Average is a weighted average
194 */
195 fAverage = ((oldNbSeg * oldAverage) + (otherAverage * otherSegments)) / fNbSegments;
196
197 /*
198 * This one is a bit tricky.
199 *
200 * The variance is the sum of the deltas from a mean squared.
201 *
202 * So if we add the old mean squared back to to variance and remove the
203 * new mean, the standard deviation can be easily calculated.
204 */
205 double avg1Sq = oldAverage * oldAverage;
206 double avg2sq = otherAverage * otherAverage;
207 double avgtSq = fAverage * fAverage;
208 /*
209 * This is a tricky part, bear in mind that the set is not continuous but discrete,
210 * Therefore, we have for n elements, n-1 intervals between them.
211 * Ergo, n-1 intervals are used for divisions and multiplications.
212 */
213 double variance1 = fVariance / (oldNbSeg - 1);
214 double variance2 = other.fVariance / (otherSegments - 1);
215 fVariance = ((variance1 + avg1Sq - avgtSq) * (oldNbSeg - 1) + (variance2 + avg2sq - avgtSq) * (otherSegments - 1));
216 }
217
218 private void copy(SegmentStoreStatistics copyOther) {
219 fAverage = copyOther.fAverage;
220 fMax = copyOther.fMax;
221 fMin = copyOther.fMin;
222 fNbSegments = copyOther.fNbSegments;
223 fTotal = copyOther.fTotal;
224 fVariance = copyOther.fVariance;
ce8319b6
BH
225 }
226}
This page took 0.056156 seconds and 5 git commands to generate.