1dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/* 2dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Licensed to the Apache Software Foundation (ASF) under one or more 3dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contributor license agreements. See the NOTICE file distributed with 4dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this work for additional information regarding copyright ownership. 5dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ASF licenses this file to You under the Apache License, Version 2.0 6dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (the "License"); you may not use this file except in compliance with 7dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the License. You may obtain a copy of the License at 8dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 9dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * http://www.apache.org/licenses/LICENSE-2.0 10dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 11dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Unless required by applicable law or agreed to in writing, software 12dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * distributed under the License is distributed on an "AS IS" BASIS, 13dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * See the License for the specific language governing permissions and 15dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * limitations under the License. 16dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpackage org.apache.commons.math.stat.descriptive; 18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.MathRuntimeException; 20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.DimensionMismatchException; 21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.NotPositiveException; 22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.NullArgumentException; 23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.util.LocalizedFormats; 24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/** 26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Abstract base class for all implementations of the 27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@link UnivariateStatistic} interface. 28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Provides a default implementation of <code>evaluate(double[]),</code> 30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * delegating to <code>evaluate(double[], int, int)</code> in the natural way. 31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Also includes a <code>test</code> method that performs generic parameter 34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * validation for the <code>evaluate</code> methods.</p> 35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $ 37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic abstract class AbstractUnivariateStatistic 39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond implements UnivariateStatistic { 40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Stored data. */ 42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private double[] storedData; 43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Set the data array. 46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The stored value is a copy of the parameter array, not the array itself 48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param values data array to store (may be null to remove stored data) 50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @see #evaluate() 51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public void setData(final double[] values) { 53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond storedData = (values == null) ? null : values.clone(); 54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Get a copy of the stored data array. 58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return copy of the stored data array (may be null) 59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double[] getData() { 61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (storedData == null) ? null : storedData.clone(); 62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Get a reference to the stored data array. 66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return reference to the stored data array (may be null) 67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected double[] getDataRef() { 69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return storedData; 70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Set the data array. 74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param values data array to store 75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param begin the index of the first element to include 76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param length the number of elements to include 77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @see #evaluate() 78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public void setData(final double[] values, final int begin, final int length) { 80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond storedData = new double[length]; 81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond System.arraycopy(values, begin, storedData, 0, length); 82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the result of evaluating the statistic over the stored data. 86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The stored array is the one which was set by previous calls to 88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </p> 89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the value of the statistic applied to the stored data 90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double evaluate() { 92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return evaluate(storedData); 93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@inheritDoc} 97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double evaluate(final double[] values) { 99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond test(values, 0, 0); 100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return evaluate(values, 0, values.length); 101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@inheritDoc} 105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public abstract double evaluate(final double[] values, final int begin, final int length); 107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@inheritDoc} 110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public abstract UnivariateStatistic copy(); 112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This method is used by <code>evaluate(double[], int, int)</code> methods 115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to verify that the input parameters designate a subarray of positive length. 116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>returns <code>true</code> iff the parameters designate a subarray of 119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * positive length</li> 120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>throws <code>IllegalArgumentException</code> if the array is null or 121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * or the indices are invalid</li> 122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>returns <code>false</li> if the array is non-null, but 123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>length</code> is 0. 124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul></p> 125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param values the input array 127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param begin index of the first array element to include 128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param length the number of elements to include 129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return true if the parameters are valid and designate a subarray of positive length 130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if the indices are invalid or the array is null 131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected boolean test( 133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double[] values, 134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int begin, 135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int length) { 136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (values == null) { 138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); 139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (begin < 0) { 142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw new NotPositiveException(LocalizedFormats.START_POSITION, begin); 143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (length < 0) { 146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw new NotPositiveException(LocalizedFormats.LENGTH, length); 147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (begin + length > values.length) { 150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.SUBARRAY_ENDS_AFTER_ARRAY_END); 152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (length == 0) { 155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return false; 156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return true; 159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This method is used by <code>evaluate(double[], double[], int, int)</code> methods 164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to verify that the begin and length parameters designate a subarray of positive length 165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * and the weights are all non-negative, non-NaN, finite, and not all zero. 166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul> 168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>returns <code>true</code> iff the parameters designate a subarray of 169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * positive length and the weights array contains legitimate values.</li> 170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>throws <code>IllegalArgumentException</code> if any of the following are true: 171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <ul><li>the values array is null</li> 172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>the weights array is null</li> 173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>the weights array does not have the same length as the values array</li> 174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>the weights array contains one or more infinite values</li> 175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>the weights array contains one or more NaN values</li> 176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>the weights array contains negative values</li> 177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>the start and length arguments do not determine a valid array</li></ul> 178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </li> 179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <li>returns <code>false</li> if the array is non-null, but 180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>length</code> is 0. 181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * </ul></p> 182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param values the input array 184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param weights the weights array 185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param begin index of the first array element to include 186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param length the number of elements to include 187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return true if the parameters are valid and designate a subarray of positive length 188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if the indices are invalid or the array is null 189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.1 190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected boolean test( 192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double[] values, 193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double[] weights, 194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int begin, 195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int length) { 196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (weights == null) { 198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY); 199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (weights.length != values.length) { 202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw new DimensionMismatchException(weights.length, values.length); 203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond boolean containsPositiveWeight = false; 206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = begin; i < begin + length; i++) { 207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isNaN(weights[i])) { 208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.NAN_ELEMENT_AT_INDEX, i); 210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isInfinite(weights[i])) { 212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.INFINITE_ARRAY_ELEMENT, weights[i], i); 214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (weights[i] < 0) { 216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.NEGATIVE_ELEMENT_AT_INDEX, i, weights[i]); 218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (!containsPositiveWeight && weights[i] > 0.0) { 220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond containsPositiveWeight = true; 221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (!containsPositiveWeight) { 225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.WEIGHT_AT_LEAST_ONE_NON_ZERO); 227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return test(values, begin, length); 230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond} 232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 233