Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may 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 implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.cts.util;
     18 
     19 import java.util.Arrays;
     20 
     21 /**
     22  * Utilities for doing statistics
     23  *
     24  */
     25 public class Stat {
     26 
     27     /**
     28      * Collection of statistical propertirs like average, max, min, and stddev
     29      */
     30     public static class StatResult {
     31         public double mAverage;
     32         public double mMin;
     33         public double mMax;
     34         public double mStddev;
     35         public int mDataCount;
     36         public StatResult(double average, double min, double max, double stddev, int dataCount) {
     37             mAverage = average;
     38             mMin = min;
     39             mMax = max;
     40             mStddev = stddev;
     41             mDataCount = dataCount;
     42         }
     43     }
     44 
     45     /**
     46      * Calculate statistics properties likes average, min, max, and stddev for the given array
     47      */
     48     public static StatResult getStat(double[] data) {
     49         double average = data[0];
     50         double min = data[0];
     51         double max = data[0];
     52         double eX2 = data[0] * data[0]; // will become E[X^2]
     53         for (int i = 1; i < data.length; i++) {
     54             average += data[i];
     55             eX2 += data[i] * data[i];
     56             if (data[i] > max) {
     57                 max = data[i];
     58             }
     59             if (data[i] < min) {
     60                 min = data[i];
     61             }
     62         }
     63         average /= data.length;
     64         eX2 /= data.length;
     65         // stddev = sqrt(E[X^2] - (E[X])^2)
     66         double stddev = Math.sqrt(eX2 - average * average);
     67         return new StatResult(average, min, max, stddev, data.length);
     68     }
     69 
     70     /**
     71      * Calculate statistics properties likes average, min, max, and stddev for the given array
     72      * while rejecting outlier +/- median * rejectionThreshold.
     73      * rejectionThreshold should be bigger than 0.0 and be lowerthan 1.0
     74      */
     75     public static StatResult getStatWithOutlierRejection(double[] data, double rejectionThreshold) {
     76         double[] dataCopied = Arrays.copyOf(data, data.length);
     77         Arrays.sort(dataCopied);
     78         int medianIndex = dataCopied.length / 2;
     79         double median;
     80         if (dataCopied.length % 2 == 1) {
     81             median = dataCopied[medianIndex];
     82         } else {
     83             median = (dataCopied[medianIndex - 1] + dataCopied[medianIndex]) / 2.0;
     84         }
     85         double thresholdMin = median * (1.0 - rejectionThreshold);
     86         double thresholdMax = median * (1.0 + rejectionThreshold);
     87 
     88         double average = 0.0;
     89         double min = median;
     90         double max = median;
     91         double eX2 = 0.0; // will become E[X^2]
     92         int validDataCounter = 0;
     93         for (int i = 0; i < data.length; i++) {
     94             if ((data[i] > thresholdMin) && (data[i] < thresholdMax)) {
     95                 validDataCounter++;
     96                 average += data[i];
     97                 eX2 += data[i] * data[i];
     98                 if (data[i] > max) {
     99                     max = data[i];
    100                 }
    101                 if (data[i] < min) {
    102                     min = data[i];
    103                 }
    104             }
    105             //TODO report rejected data
    106         }
    107         double stddev;
    108         if (validDataCounter > 0) {
    109             average /= validDataCounter;
    110             eX2 /= validDataCounter;
    111             // stddev = sqrt(E[X^2] - (E[X])^2)
    112             stddev = Math.sqrt(eX2 - average * average);
    113         } else { // both median is showing too much diff
    114             average = median;
    115             stddev = 0; // don't care
    116         }
    117 
    118         return new StatResult(average, min, max, stddev, validDataCounter);
    119     }
    120 
    121     /**
    122      * return the average value of the passed array
    123      */
    124     public static double getAverage(double[] data) {
    125         double sum = data[0];
    126         for (int i = 1; i < data.length; i++) {
    127             sum += data[i];
    128         }
    129         return sum / data.length;
    130     }
    131 
    132     /**
    133      * return the minimum value of the passed array
    134      */
    135     public static double getMin(double[] data) {
    136         double min = data[0];
    137         for (int i = 1; i < data.length; i++) {
    138             if (data[i] < min) {
    139                 min = data[i];
    140             }
    141         }
    142         return min;
    143     }
    144 
    145     /**
    146      * return the maximum value of the passed array
    147      */
    148     public static double getMax(double[] data) {
    149         double max = data[0];
    150         for (int i = 1; i < data.length; i++) {
    151             if (data[i] > max) {
    152                 max = data[i];
    153             }
    154         }
    155         return max;
    156     }
    157 }
    158