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.rank;
018    
019    import java.io.Serializable;
020    
021    import org.apache.commons.math.exception.NullArgumentException;
022    import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
023    import org.apache.commons.math.util.MathUtils;
024    
025    /**
026     * Returns the minimum of the available values.
027     * <p>
028     * <ul>
029     * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
030     * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
031     * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>,
032     * the result is <code>Double.NEGATIVE_INFINITY.</code></li>
033     * </ul></p>
034     * <p>
035     * <strong>Note that this implementation is not synchronized.</strong> If
036     * multiple threads access an instance of this class concurrently, and at least
037     * one of the threads invokes the <code>increment()</code> or
038     * <code>clear()</code> method, it must be synchronized externally.</p>
039     *
040     * @version $Id: Min.java 1132432 2011-06-05 14:59:29Z luc $
041     */
042    public class Min extends AbstractStorelessUnivariateStatistic implements Serializable {
043    
044        /** Serializable version identifier */
045        private static final long serialVersionUID = -2941995784909003131L;
046    
047        /**Number of values that have been added */
048        private long n;
049    
050        /**Current value of the statistic */
051        private double value;
052    
053        /**
054         * Create a Min instance
055         */
056        public Min() {
057            n = 0;
058            value = Double.NaN;
059        }
060    
061        /**
062         * Copy constructor, creates a new {@code Min} identical
063         * to the {@code original}
064         *
065         * @param original the {@code Min} instance to copy
066         */
067        public Min(Min original) {
068            copy(original, this);
069        }
070    
071        /**
072         * {@inheritDoc}
073         */
074        @Override
075        public void increment(final double d) {
076            if (d < value || Double.isNaN(value)) {
077                value = d;
078            }
079            n++;
080        }
081    
082        /**
083         * {@inheritDoc}
084         */
085        @Override
086        public void clear() {
087            value = Double.NaN;
088            n = 0;
089        }
090    
091        /**
092         * {@inheritDoc}
093         */
094        @Override
095        public double getResult() {
096            return value;
097        }
098    
099        /**
100         * {@inheritDoc}
101         */
102        public long getN() {
103            return n;
104        }
105    
106        /**
107         * Returns the minimum of the entries in the specified portion of
108         * the input array, or <code>Double.NaN</code> if the designated subarray
109         * is empty.
110         * <p>
111         * Throws <code>IllegalArgumentException</code> if the array is null or
112         * the array index parameters are not valid.</p>
113         * <p>
114         * <ul>
115         * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
116         * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
117         * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>,
118         * the result is <code>Double.NEGATIVE_INFINITY.</code></li>
119         * </ul> </p>
120         *
121         * @param values the input array
122         * @param begin index of the first array element to include
123         * @param length the number of elements to include
124         * @return the minimum of the values or Double.NaN if length = 0
125         * @throws IllegalArgumentException if the array is null or the array index
126         *  parameters are not valid
127         */
128        @Override
129        public double evaluate(final double[] values,final int begin, final int length) {
130            double min = Double.NaN;
131            if (test(values, begin, length)) {
132                min = values[begin];
133                for (int i = begin; i < begin + length; i++) {
134                    if (!Double.isNaN(values[i])) {
135                        min = (min < values[i]) ? min : values[i];
136                    }
137                }
138            }
139            return min;
140        }
141    
142        /**
143         * {@inheritDoc}
144         */
145        @Override
146        public Min copy() {
147            Min result = new Min();
148            copy(this, result);
149            return result;
150        }
151    
152        /**
153         * Copies source to dest.
154         * <p>Neither source nor dest can be null.</p>
155         *
156         * @param source Min to copy
157         * @param dest Min to copy to
158         * @throws NullArgumentException if either source or dest is null
159         */
160        public static void copy(Min source, Min dest)
161            throws NullArgumentException {
162            MathUtils.checkNotNull(source);
163            MathUtils.checkNotNull(dest);
164            dest.setData(source.getDataRef());
165            dest.n = source.n;
166            dest.value = source.value;
167        }
168    }