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