001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.math.stat.descriptive;
018    
019    import org.apache.commons.math.MathRuntimeException;
020    
021    /**
022     * Abstract base class for all implementations of the 
023     * {@link UnivariateStatistic} interface.
024     * <p>
025     * Provides a default implementation of <code>evaluate(double[]),</code> 
026     * delegating to <code>evaluate(double[], int, int)</code> in the natural way.
027     * </p>
028     * <p>
029     * Also includes a <code>test</code> method that performs generic parameter
030     * validation for the <code>evaluate</code> methods.</p>
031     * 
032     * @version $Revision: 780541 $ $Date: 2009-05-31 20:47:02 -0400 (Sun, 31 May 2009) $
033     */
034    public abstract class AbstractUnivariateStatistic
035        implements UnivariateStatistic {
036    
037        /**
038         * {@inheritDoc}
039         */
040        public double evaluate(final double[] values) {
041            test(values, 0, 0);
042            return evaluate(values, 0, values.length);
043        }
044    
045        /**
046         * {@inheritDoc}
047         */
048        public abstract double evaluate(final double[] values, final int begin, final int length);
049        
050        /**
051         * {@inheritDoc}
052         */
053        public abstract UnivariateStatistic copy();
054    
055        /**
056         * This method is used by <code>evaluate(double[], int, int)</code> methods
057         * to verify that the input parameters designate a subarray of positive length.
058         * <p>
059         * <ul>
060         * <li>returns <code>true</code> iff the parameters designate a subarray of 
061         * positive length</li>
062         * <li>throws <code>IllegalArgumentException</code> if the array is null or
063         * or the indices are invalid</li>
064         * <li>returns <code>false</li> if the array is non-null, but 
065         * <code>length</code> is 0.
066         * </ul></p>
067         *
068         * @param values the input array
069         * @param begin index of the first array element to include
070         * @param length the number of elements to include
071         * @return true if the parameters are valid and designate a subarray of positive length
072         * @throws IllegalArgumentException if the indices are invalid or the array is null
073         */
074        protected boolean test(
075            final double[] values,
076            final int begin,
077            final int length) {
078    
079            if (values == null) {
080                throw MathRuntimeException.createIllegalArgumentException("input values array is null");
081            }
082            
083            if (begin < 0) {
084                throw MathRuntimeException.createIllegalArgumentException(
085                      "start position cannot be negative ({0})", begin);
086            }
087            
088            if (length < 0) {
089                throw MathRuntimeException.createIllegalArgumentException(
090                      "length cannot be negative ({0})", length);
091            }
092            
093            if (begin + length > values.length) {
094                throw MathRuntimeException.createIllegalArgumentException(
095                      "subarray ends after array end");
096            }
097    
098            if (length == 0) {
099                return false;
100            }
101    
102            return true;
103    
104        }
105    }