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: 762087 $ $Date: 2009-04-05 10:20:18 -0400 (Sun, 05 Apr 2009) $
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<Object> 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<Object>());
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<Object> 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<Object> list, NumberTransformer transformer) {
67 super();
68 this.list = list;
69 this.transformer = transformer;
70 }
71
72 /** {@inheritDoc} */
73 @Override
74 public double[] getValues() {
75
76 int length = list.size();
77
78 // If the window size is not INFINITE_WINDOW AND
79 // the current list is larger that the window size, we need to
80 // take into account only the last n elements of the list
81 // as definied by windowSize
82
83 if (windowSize != DescriptiveStatistics.INFINITE_WINDOW &&
84 windowSize < list.size())
85 {
86 length = list.size() - Math.max(0, list.size() - windowSize);
87 }
88
89 // Create an array to hold all values
90 double[] copiedArray = new double[length];
91
92 for (int i = 0; i < copiedArray.length; i++) {
93 copiedArray[i] = getElement(i);
94 }
95 return copiedArray;
96 }
97
98 /** {@inheritDoc} */
99 @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 }