    1   /*
    2    * Copyright 2003-2004 The Apache Software Foundation.
    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  package org.apache.commons.math.stat.descriptive;
    17
    18  import java.io.Serializable;
    19  import java.util.ArrayList;
    20  import java.util.List;
    21
    22  import org.apache.commons.math.MathException;
    23  import org.apache.commons.math.stat.descriptive.UnivariateStatistic;
    24  import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
    25  import org.apache.commons.math.util.DefaultTransformer;
    26  import org.apache.commons.math.util.NumberTransformer;
    27
    28  /***
    29   * @version $Revision: 348519 $ $Date: 2005-11-23 12:12:18 -0700 (Wed, 23 Nov 2005) $
    30   */
    31  public class ListUnivariateImpl extends DescriptiveStatistics implements Serializable {
    32
    33      /*** Serializable version identifier */
    34      private static final long serialVersionUID = -8837442489133392138L;
    35
    36      /***
    37       * Holds a reference to a list - GENERICs are going to make
    38       * out lives easier here as we could only accept List<Number>
    39       */
    40      protected List list;
    41
    42      /*** Number Transformer maps Objects to Number for us. */
    43      protected NumberTransformer transformer;
    44
    45      /*** hold the window size **/
    46      protected int windowSize = DescriptiveStatistics.INFINITE_WINDOW;
    47
    48      /***
    49       * No argument Constructor
    50       */
    51      public ListUnivariateImpl(){
    52          this(new ArrayList());
    53      }
    54
    55      /***
    56       * Construct a ListUnivariate with a specific List.
    57       * @param list The list that will back this DescriptiveStatistics
    58       */
    59      public ListUnivariateImpl(List list) {
    60          this(list, new DefaultTransformer());
    61      }
    62
    63      /***
    64       * Construct a ListUnivariate with a specific List.
    65       * @param list The list that will back this DescriptiveStatistics
    66       * @param transformer the number transformer used to convert the list items.
    67       */
    68      public ListUnivariateImpl(List list, NumberTransformer transformer) {
    69          super();
    70          this.list = list;
    71          this.transformer = transformer;
    72      }
    73
    74      /***
    75       * @see org.apache.commons.math.stat.descriptive.DescriptiveStatistics#getValues()
    76       */
    77      public double[] getValues() {
    78
    79          int length = list.size();
    80
    81          // If the window size is not INFINITE_WINDOW AND
    82          // the current list is larger that the window size, we need to
    83          // take into account only the last n elements of the list
    84          // as definied by windowSize
    85
    86          if (windowSize != DescriptiveStatistics.INFINITE_WINDOW &&
    87              windowSize < list.size())
    88          {
    89              length = list.size() - Math.max(0, list.size() - windowSize);
    90          }
    91
    92          // Create an array to hold all values
    93          double[] copiedArray = new double[length];
    94
    95          for (int i = 0; i < copiedArray.length; i++) {
    96              copiedArray[i] = getElement(i);
    97          }
    98          return copiedArray;
    99      }
    100
    101     /***
    102      * @see org.apache.commons.math.stat.descriptive.DescriptiveStatistics#getElement(int)
    103      */
    104     public double getElement(int index) {
    105
    106         double value = Double.NaN;
    107
    108         int calcIndex = index;
    109
    110         if (windowSize != DescriptiveStatistics.INFINITE_WINDOW &&
    111             windowSize < list.size())
    112         {
    113             calcIndex = (list.size() - windowSize) + index;
    114         }
    115
    116
    117         try {
    118             value = transformer.transform(list.get(calcIndex));
    119         } catch (MathException e) {
    120             e.printStackTrace();
    121         }
    122
    123         return value;
    124     }
    125
    126     /***
    127      * @see org.apache.commons.math.stat.descriptive.DescriptiveStatistics#getN()
    128      */
    129     public long getN() {
    130         int n = 0;
    131
    132         if (windowSize != DescriptiveStatistics.INFINITE_WINDOW) {
    133             if (list.size() > windowSize) {
    134                 n = windowSize;
    135             } else {
    136                 n = list.size();
    137             }
    138         } else {
    139             n = list.size();
    140         }
    141         return n;
    142     }
    143
    144     /***
    145      * @see org.apache.commons.math.stat.descriptive.DescriptiveStatistics#addValue(double)
    146      */
    147     public void addValue(double v) {
    148         list.add(new Double(v));
    149     }
    150
    151     /***
    152      * Adds an object to this list.
    153      * @param o Object to add to the list
    154      */
    155     public void addObject(Object o) {
    156         list.add(o);
    157     }
    158
    159     /***
    160      * Clears all statistics.
    161      * <p>
    162      * <strong>N.B.: </strong> This method has the side effect of clearing the underlying list.
    163      */
    164     public void clear() {
    165         list.clear();
    166     }
    167
    168     /***
    169      * Apply the given statistic to this univariate collection.
    170      * @param stat the statistic to apply
    171      * @return the computed value of the statistic.
    172      */
    173     public double apply(UnivariateStatistic stat) {
    174         double[] v = this.getValues();
    175
    176         if (v != null) {
    177             return stat.evaluate(v, 0, v.length);
    178         }
    179         return Double.NaN;
    180     }
    181
    182     /***
    183      * Access the number transformer.
    184      * @return the number transformer.
    185      */
    186     public NumberTransformer getTransformer() {
    187         return transformer;
    188     }
    189
    190     /***
    191      * Modify the number transformer.
    192      * @param transformer the new number transformer.
    193      */
    194     public void setTransformer(NumberTransformer transformer) {
    195         this.transformer = transformer;
    196     }
    197
    198     /***
    199      * @see org.apache.commons.math.stat.descriptive.DescriptiveStatistics#setWindowSize(int)
    200      */
    201     public synchronized void setWindowSize(int windowSize) {
    202         this.windowSize = windowSize;
    203         //Discard elements from the front of the list if the windowSize is less than
    204         // the size of the list.
    205         int extra = list.size() - windowSize;
    206         for (int i = 0; i < extra; i++) {
    207             list.remove(0);
    208         }
    209     }
    210
    211     /***
    212      * @see org.apache.commons.math.stat.descriptive.DescriptiveStatistics#getWindowSize
    213      */
    214     public int getWindowSize() {
    215         return windowSize;
    216     }
    217
    218 }