/* * JBoss, Home of Professional Open Source * Copyright [2011], Red Hat, Inc., and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * 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 org.modeshape.jcr.perftests; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.commons.math.stat.descriptive.SummaryStatistics; /** * Class which provides various statistical information based on a number of numerical values. * * @author Horia Chiorean */ public final class StatisticalData { private final double[] values; private final SummaryStatistics summaryStatistics; public StatisticalData( List<? extends Number> valuesList ) { this(valuesList.toArray(valuesList.toArray(new Number[valuesList.size()]))); } public StatisticalData( Number... values ) { if (values == null || values.length == 0) { throw new IllegalArgumentException("The set of values for the statistical data cannot be empty or null"); } this.summaryStatistics = new SummaryStatistics(); for (Number value : values) { this.summaryStatistics.addValue(value.doubleValue()); } this.values = new double[values.length]; for (int i = 0; i < values.length; i++) { this.values[i] = values[i].doubleValue(); } // store the values in ascending order Arrays.sort(this.values); } public long count() { return summaryStatistics.getN(); } public double min() { return summaryStatistics.getMin(); } public double max() { return summaryStatistics.getMax(); } public double standardDeviation() { return summaryStatistics.getStandardDeviation(); } public double lowerQuartile() { if (values.length == 1) { return Double.NaN; } if (values.length == 2) { return values[0]; } int middleIdx = values.length / 2; return median(Arrays.copyOfRange(values, 0, middleIdx)); } public double median() { if (values.length == 1) { return values[0]; } int middleIdx = values.length / 2; return (values.length % 2 == 1) ? median(values[middleIdx]) : median(values[middleIdx - 1], values[middleIdx]); } public double upperQuartile() { if (values.length == 1) { return Double.NaN; } if (values.length == 2) { return values[1]; } int middleIdx = values.length / 2; return (values.length % 2 == 0) ? median(Arrays.copyOfRange(values, middleIdx, values.length)) : median(Arrays.copyOfRange(values, middleIdx + 1, values.length)); } public double[] fiveNumberSummary() { return new double[] {min(), lowerQuartile(), median(), upperQuartile(), max()}; } public List<Double> valuesList() { List<Double> result = new ArrayList<Double>(values.length); for (double value : values) { result.add(value); } return result; } private double median( double... values ) { if (values.length == 1) { return values[0]; } int middleIdx = values.length / 2; if (values.length % 2 == 0) { return avg(values[middleIdx - 1], values[middleIdx]); } return values[middleIdx]; } private double avg( double... values ) { double sum = 0; for (double value : values) { sum += value; } return sum / values.length; } }