| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.android.tradefed.util; |
| |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| /** |
| * A small utility class that calculates a few statistical measures given a numerical dataset. The |
| * values are stored internally as {@link Double}s. |
| */ |
| public class SimpleStats { |
| private List<Double> mData = new LinkedList<Double>(); |
| |
| // cached values |
| private double mSum = 0; |
| |
| /** |
| * Add a number of measurements to the dataset. |
| * |
| * @throws NullPointerException if the collection contains any {@code null} elements |
| */ |
| public void addAll(Collection<? extends Double> c) { |
| for (Double meas : c) { |
| if (meas == null) { |
| throw new NullPointerException(); |
| } |
| add(meas); |
| } |
| } |
| |
| /** |
| * Add a measurement to the dataset. |
| */ |
| public void add(double meas) { |
| mData.add(meas); |
| mSum += meas; |
| } |
| |
| /** |
| * Retrieve the dataset. |
| */ |
| public List<Double> getData() { |
| return mData; |
| } |
| |
| /** |
| * Check if the dataset is empty. |
| */ |
| public boolean isEmpty() { |
| return mData.isEmpty(); |
| } |
| |
| /** |
| * Check how many elements are in the dataset. |
| */ |
| public int size() { |
| return mData.size(); |
| } |
| |
| /** |
| * Calculate and return the mean of the dataset, or {@code null} if the dataset is empty. |
| */ |
| public Double mean() { |
| if (isEmpty()) { |
| return null; |
| } |
| |
| return mSum / size(); |
| } |
| |
| /** |
| * Calculate and return the median of the dataset, or {@code null} if the dataset is empty. |
| */ |
| public Double median() { |
| if (isEmpty()) { |
| return null; |
| } |
| |
| Collections.sort(mData); |
| if ((mData.size() & 0x1) == 1) { |
| // odd count of items, pick the middle element. Note that we don't +1 since indices |
| // are zero-based rather than one-based |
| int idx = size() / 2; |
| return mData.get(idx); |
| } else { |
| // even count of items, average the two middle elements |
| int idx = size() / 2; |
| return (mData.get(idx - 1) + mData.get(idx)) / 2; |
| } |
| } |
| |
| /** |
| * Return the minimum value in the dataset, or {@code null} if the dataset is empty. |
| */ |
| public Double min() { |
| if (isEmpty()) { |
| return null; |
| } |
| |
| Collections.sort(mData); |
| return mData.get(0); |
| } |
| |
| /** |
| * Return the maximum value in the dataset, or {@code null} if the dataset is empty. |
| */ |
| public Double max() { |
| if (isEmpty()) { |
| return null; |
| } |
| |
| Collections.sort(mData); |
| return mData.get(size() - 1); |
| } |
| |
| /** |
| * Return the standard deviation of the dataset, or {@code null} if the dataset is empty. |
| * <p /> |
| * Note that this method calculates the population standard deviation, not the sample standard |
| * deviation. That is, it assumes that the dataset is entirely contained in the |
| * {@link SimpleStats} instance. |
| */ |
| public Double stdev() { |
| if (isEmpty()) { |
| return null; |
| } |
| |
| Double avg = mean(); |
| Double ssd = 0.0; // sum of squared differences |
| for (Double meas : mData) { |
| Double diff = meas - avg; |
| ssd += diff * diff; |
| } |
| |
| return Math.sqrt(ssd / size()); |
| } |
| |
| /** |
| * return the average value of the samples that are within one stdev |
| * e.g |
| * 2.55 50.3 50.4 48.5 50.1 29.8 30 46 48 49 |
| * average: 40.45, stdev: 15.54 |
| * average of the values within one stdev is: 44.67 |
| * @return |
| */ |
| public Double meanOverOneStandardDeviationRange() { |
| if (isEmpty()) { |
| return null; |
| } |
| |
| Double avg = mean(); |
| Double std = stdev(); |
| Double upper = avg + std; |
| Double lower = avg - std; |
| Double sum = 0.0; |
| int count = 0; |
| for (Double meas : mData) { |
| if (meas > lower && meas < upper) { |
| sum += meas; |
| count++; |
| } |
| } |
| return sum / count; |
| } |
| } |
| |