1 /*
2  * Copyright (c) 2016 Google Inc. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you
5  * may not use this file except in compliance with the License. You may
6  * obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13  * implied. See the License for the specific language governing
14  * permissions and limitations under the License.
15  */
16 
17 package com.android.vts.util;
18 
19 import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode;
20 
21 /** Helper object for storing statistics. */
22 public class StatSummary {
23     private String label;
24     private double min;
25     private double max;
26     private double mean;
27     private double sumSq;
28     private int n;
29     private VtsProfilingRegressionMode regression_mode;
30 
31     /**
32      * Create a statistical summary.
33      *
34      * <p>Sets the label, min, max, mean, sum of squared error, n, and mode as provided.
35      *
36      * @param label The (String) label to assign to the summary.
37      * @param min The minimum observed value.
38      * @param max The maximum observed value.
39      * @param mean The average observed value.
40      * @param sumSq The sum of squared error.
41      * @param n The number of values observed.
42      * @param mode The VtsProfilingRegressionMode to use when analyzing performance.
43      */
StatSummary( String label, double min, double max, double mean, double sumSq, int n, VtsProfilingRegressionMode mode)44     public StatSummary(
45             String label,
46             double min,
47             double max,
48             double mean,
49             double sumSq,
50             int n,
51             VtsProfilingRegressionMode mode) {
52         this.label = label;
53         this.min = min;
54         this.max = max;
55         this.mean = mean;
56         this.sumSq = sumSq;
57         this.n = n;
58         this.regression_mode = mode;
59     }
60 
61     /**
62      * Initializes the statistical summary.
63      *
64      * <p>Sets the label as provided. Initializes the mean, variance, and n (number of values seen)
65      * to 0.
66      *
67      * @param label The (String) label to assign to the summary.
68      * @param mode The VtsProfilingRegressionMode to use when analyzing performance.
69      */
StatSummary(String label, VtsProfilingRegressionMode mode)70     public StatSummary(String label, VtsProfilingRegressionMode mode) {
71         this(label, Double.MAX_VALUE, Double.MIN_VALUE, 0, 0, 0, mode);
72     }
73 
74     /**
75      * Update the mean and variance using Welford's single-pass method.
76      *
77      * @param value The observed value in the stream.
78      */
updateStats(double value)79     public void updateStats(double value) {
80         n += 1;
81         double oldMean = mean;
82         mean = oldMean + (value - oldMean) / n;
83         sumSq = sumSq + (value - mean) * (value - oldMean);
84         if (value < min) min = value;
85         if (value > max) max = value;
86     }
87 
88     /**
89      * Combine the mean and variance with another StatSummary.
90      *
91      * @param stat The StatSummary to combine with.
92      */
merge(StatSummary stat)93     public void merge(StatSummary stat) {
94         double delta = stat.getMean() - mean;
95         int newN = n + stat.getCount();
96         sumSq = sumSq + stat.getSumSq() + delta / newN * delta * n * stat.getCount();
97         double recipN = 1.0 / newN;
98         mean = n * recipN * mean + stat.getCount() * recipN * stat.getMean();
99         n = newN;
100     }
101 
102     /**
103      * Gets the best case of the stream.
104      *
105      * @return The min or max.
106      */
getBestCase()107     public double getBestCase() {
108         switch (regression_mode) {
109             case VTS_REGRESSION_MODE_DECREASING:
110                 return getMax();
111             default:
112                 return getMin();
113         }
114     }
115 
116     /**
117      * Gets the calculated min of the stream.
118      *
119      * @return The min.
120      */
getMin()121     public double getMin() {
122         return min;
123     }
124 
125     /**
126      * Gets the calculated max of the stream.
127      *
128      * @return The max.
129      */
getMax()130     public double getMax() {
131         return max;
132     }
133 
134     /**
135      * Gets the calculated mean of the stream.
136      *
137      * @return The mean.
138      */
getMean()139     public double getMean() {
140         return mean;
141     }
142 
143     /**
144      * Gets the calculated sum of squared error of the stream.
145      *
146      * @return The sum of squared error.
147      */
getSumSq()148     public double getSumSq() {
149         return sumSq;
150     }
151 
152     /**
153      * Gets the calculated standard deviation of the stream.
154      *
155      * @return The standard deviation.
156      */
getStd()157     public double getStd() {
158         return Math.sqrt(sumSq / (n - 1));
159     }
160 
161     /**
162      * Gets the number of elements that have passed through the stream.
163      *
164      * @return Number of elements.
165      */
getCount()166     public int getCount() {
167         return n;
168     }
169 
170     /**
171      * Gets the label for the summarized statistics.
172      *
173      * @return The (string) label.
174      */
getLabel()175     public String getLabel() {
176         return label;
177     }
178 
179     /**
180      * Gets the regression mode.
181      *
182      * @return The VtsProfilingRegressionMode value.
183      */
getRegressionMode()184     public VtsProfilingRegressionMode getRegressionMode() {
185         return regression_mode;
186     }
187 }
188