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 java.io.Serializable; 020 import java.util.ArrayList; 021 import java.util.List; 022 023 import org.apache.commons.math.MathException; 024 import org.apache.commons.math.stat.descriptive.UnivariateStatistic; 025 import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; 026 import org.apache.commons.math.util.DefaultTransformer; 027 import org.apache.commons.math.util.NumberTransformer; 028 029 /** 030 * @version $Revision: 762087 $ $Date: 2009-04-05 10:20:18 -0400 (Sun, 05 Apr 2009) $ 031 */ 032 public class ListUnivariateImpl extends DescriptiveStatistics implements Serializable { 033 034 /** Serializable version identifier */ 035 private static final long serialVersionUID = -8837442489133392138L; 036 037 /** 038 * Holds a reference to a list - GENERICs are going to make 039 * our lives easier here as we could only accept List<Number> 040 */ 041 protected List<Object> list; 042 043 /** Number Transformer maps Objects to Number for us. */ 044 protected NumberTransformer transformer; 045 046 /** 047 * No argument Constructor 048 */ 049 public ListUnivariateImpl(){ 050 this(new ArrayList<Object>()); 051 } 052 053 /** 054 * Construct a ListUnivariate with a specific List. 055 * @param list The list that will back this DescriptiveStatistics 056 */ 057 public ListUnivariateImpl(List<Object> list) { 058 this(list, new DefaultTransformer()); 059 } 060 061 /** 062 * Construct a ListUnivariate with a specific List. 063 * @param list The list that will back this DescriptiveStatistics 064 * @param transformer the number transformer used to convert the list items. 065 */ 066 public ListUnivariateImpl(List<Object> list, NumberTransformer transformer) { 067 super(); 068 this.list = list; 069 this.transformer = transformer; 070 } 071 072 /** {@inheritDoc} */ 073 @Override 074 public double[] getValues() { 075 076 int length = list.size(); 077 078 // If the window size is not INFINITE_WINDOW AND 079 // the current list is larger that the window size, we need to 080 // take into account only the last n elements of the list 081 // as definied by windowSize 082 083 if (windowSize != DescriptiveStatistics.INFINITE_WINDOW && 084 windowSize < list.size()) 085 { 086 length = list.size() - Math.max(0, list.size() - windowSize); 087 } 088 089 // Create an array to hold all values 090 double[] copiedArray = new double[length]; 091 092 for (int i = 0; i < copiedArray.length; i++) { 093 copiedArray[i] = getElement(i); 094 } 095 return copiedArray; 096 } 097 098 /** {@inheritDoc} */ 099 @Override 100 public double getElement(int index) { 101 102 double value = Double.NaN; 103 104 int calcIndex = index; 105 106 if (windowSize != DescriptiveStatistics.INFINITE_WINDOW && 107 windowSize < list.size()) 108 { 109 calcIndex = (list.size() - windowSize) + index; 110 } 111 112 113 try { 114 value = transformer.transform(list.get(calcIndex)); 115 } catch (MathException e) { 116 e.printStackTrace(); 117 } 118 119 return value; 120 } 121 122 /** {@inheritDoc} */ 123 @Override 124 public long getN() { 125 int n = 0; 126 127 if (windowSize != DescriptiveStatistics.INFINITE_WINDOW) { 128 if (list.size() > windowSize) { 129 n = windowSize; 130 } else { 131 n = list.size(); 132 } 133 } else { 134 n = list.size(); 135 } 136 return n; 137 } 138 139 /** {@inheritDoc} */ 140 @Override 141 public void addValue(double v) { 142 list.add(Double.valueOf(v)); 143 } 144 145 /** 146 * Adds an object to this list. 147 * @param o Object to add to the list 148 */ 149 public void addObject(Object o) { 150 list.add(o); 151 } 152 153 /** 154 * Clears all statistics. 155 * <p> 156 * <strong>N.B.: </strong> This method has the side effect of clearing the underlying list. 157 */ 158 @Override 159 public void clear() { 160 list.clear(); 161 } 162 163 /** 164 * Apply the given statistic to this univariate collection. 165 * @param stat the statistic to apply 166 * @return the computed value of the statistic. 167 */ 168 @Override 169 public double apply(UnivariateStatistic stat) { 170 double[] v = this.getValues(); 171 172 if (v != null) { 173 return stat.evaluate(v, 0, v.length); 174 } 175 return Double.NaN; 176 } 177 178 /** 179 * Access the number transformer. 180 * @return the number transformer. 181 */ 182 public NumberTransformer getTransformer() { 183 return transformer; 184 } 185 186 /** 187 * Modify the number transformer. 188 * @param transformer the new number transformer. 189 */ 190 public void setTransformer(NumberTransformer transformer) { 191 this.transformer = transformer; 192 } 193 194 /** {@inheritDoc} */ 195 @Override 196 public synchronized void setWindowSize(int windowSize) { 197 this.windowSize = windowSize; 198 //Discard elements from the front of the list if the windowSize is less than 199 // the size of the list. 200 int extra = list.size() - windowSize; 201 for (int i = 0; i < extra; i++) { 202 list.remove(0); 203 } 204 } 205 206 /** {@inheritDoc} */ 207 @Override 208 public synchronized int getWindowSize() { 209 return windowSize; 210 } 211 212 }