1:
50:
51: package ;
52:
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58:
59:
62: public abstract class Statistics {
63:
64:
72: public static double calculateMean(Number[] values) {
73: return calculateMean(values, true);
74: }
75:
76:
89: public static double calculateMean(Number[] values,
90: boolean includeNullAndNaN) {
91:
92: if (values == null) {
93: throw new IllegalArgumentException("Null 'values' argument.");
94: }
95: double sum = 0.0;
96: double current;
97: int counter = 0;
98: for (int i = 0; i < values.length; i++) {
99:
100: if (values[i] != null) {
101: current = values[i].doubleValue();
102: }
103: else {
104: current = Double.NaN;
105: }
106:
107: if (includeNullAndNaN || !Double.isNaN(current)) {
108: sum = sum + current;
109: counter++;
110: }
111: }
112: double result = (sum / counter);
113: return result;
114: }
115:
116:
123: public static double calculateMean(Collection values) {
124: return calculateMean(values, true);
125: }
126:
127:
140: public static double calculateMean(Collection values,
141: boolean includeNullAndNaN) {
142:
143: if (values == null) {
144: throw new IllegalArgumentException("Null 'values' argument.");
145: }
146: int count = 0;
147: double total = 0.0;
148: Iterator iterator = values.iterator();
149: while (iterator.hasNext()) {
150: Object object = iterator.next();
151: if (object == null) {
152: if (includeNullAndNaN) {
153: return Double.NaN;
154: }
155: }
156: else {
157: if (object instanceof Number) {
158: Number number = (Number) object;
159: double value = number.doubleValue();
160: if (Double.isNaN(value)) {
161: if (includeNullAndNaN) {
162: return Double.NaN;
163: }
164: }
165: else {
166: total = total + number.doubleValue();
167: count = count + 1;
168: }
169: }
170: }
171: }
172: return total / count;
173: }
174:
175:
186: public static double calculateMedian(List values) {
187: return calculateMedian(values, true);
188: }
189:
190:
201: public static double calculateMedian(List values, boolean copyAndSort) {
202:
203: double result = Double.NaN;
204: if (values != null) {
205: if (copyAndSort) {
206: int itemCount = values.size();
207: List copy = new ArrayList(itemCount);
208: for (int i = 0; i < itemCount; i++) {
209: copy.add(i, values.get(i));
210: }
211: Collections.sort(copy);
212: values = copy;
213: }
214: int count = values.size();
215: if (count > 0) {
216: if (count % 2 == 1) {
217: if (count > 1) {
218: Number value = (Number) values.get((count - 1) / 2);
219: result = value.doubleValue();
220: }
221: else {
222: Number value = (Number) values.get(0);
223: result = value.doubleValue();
224: }
225: }
226: else {
227: Number value1 = (Number) values.get(count / 2 - 1);
228: Number value2 = (Number) values.get(count / 2);
229: result = (value1.doubleValue() + value2.doubleValue())
230: / 2.0;
231: }
232: }
233: }
234: return result;
235: }
236:
237:
248: public static double calculateMedian(List values, int start, int end) {
249: return calculateMedian(values, start, end, true);
250: }
251:
252:
265: public static double calculateMedian(List values, int start, int end,
266: boolean copyAndSort) {
267:
268: double result = Double.NaN;
269: if (copyAndSort) {
270: List working = new ArrayList(end - start + 1);
271: for (int i = start; i <= end; i++) {
272: working.add(values.get(i));
273: }
274: Collections.sort(working);
275: result = calculateMedian(working, false);
276: }
277: else {
278: int count = end - start + 1;
279: if (count > 0) {
280: if (count % 2 == 1) {
281: if (count > 1) {
282: Number value
283: = (Number) values.get(start + (count - 1) / 2);
284: result = value.doubleValue();
285: }
286: else {
287: Number value = (Number) values.get(start);
288: result = value.doubleValue();
289: }
290: }
291: else {
292: Number value1 = (Number) values.get(start + count / 2 - 1);
293: Number value2 = (Number) values.get(start + count / 2);
294: result
295: = (value1.doubleValue() + value2.doubleValue()) / 2.0;
296: }
297: }
298: }
299: return result;
300:
301: }
302:
303:
311: public static double getStdDev(Number[] data) {
312: if (data == null) {
313: throw new IllegalArgumentException("Null 'data' array.");
314: }
315: if (data.length == 0) {
316: throw new IllegalArgumentException("Zero length 'data' array.");
317: }
318: double avg = calculateMean(data);
319: double sum = 0.0;
320:
321: for (int counter = 0; counter < data.length; counter++) {
322: double diff = data[counter].doubleValue() - avg;
323: sum = sum + diff * diff;
324: }
325: return Math.sqrt(sum / (data.length - 1));
326: }
327:
328:
337: public static double[] getLinearFit(Number[] xData, Number[] yData) {
338:
339: if (xData == null) {
340: throw new IllegalArgumentException("Null 'xData' argument.");
341: }
342: if (yData == null) {
343: throw new IllegalArgumentException("Null 'yData' argument.");
344: }
345: if (xData.length != yData.length) {
346: throw new IllegalArgumentException(
347: "Statistics.getLinearFit(): array lengths must be equal.");
348: }
349:
350: double[] result = new double[2];
351:
352: result[1] = getSlope(xData, yData);
353:
354: result[0] = calculateMean(yData) - result[1] * calculateMean(xData);
355:
356: return result;
357:
358: }
359:
360:
368: public static double getSlope(Number[] xData, Number[] yData) {
369:
370: if (xData == null) {
371: throw new IllegalArgumentException("Null 'xData' argument.");
372: }
373: if (yData == null) {
374: throw new IllegalArgumentException("Null 'yData' argument.");
375: }
376: if (xData.length != yData.length) {
377: throw new IllegalArgumentException("Array lengths must be equal.");
378: }
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389: double sx = 0.0, sxx = 0.0, sxy = 0.0, sy = 0.0;
390: int counter;
391: for (counter = 0; counter < xData.length; counter++) {
392: sx = sx + xData[counter].doubleValue();
393: sxx = sxx + Math.pow(xData[counter].doubleValue(), 2);
394: sxy = sxy + yData[counter].doubleValue()
395: * xData[counter].doubleValue();
396: sy = sy + yData[counter].doubleValue();
397: }
398: return (sxy - (sx * sy) / counter) / (sxx - (sx * sx) / counter);
399:
400: }
401:
402:
415: public static double getCorrelation(Number[] data1, Number[] data2) {
416: if (data1 == null) {
417: throw new IllegalArgumentException("Null 'data1' argument.");
418: }
419: if (data2 == null) {
420: throw new IllegalArgumentException("Null 'data2' argument.");
421: }
422: if (data1.length != data2.length) {
423: throw new IllegalArgumentException(
424: "'data1' and 'data2' arrays must have same length."
425: );
426: }
427: int n = data1.length;
428: double sumX = 0.0;
429: double sumY = 0.0;
430: double sumX2 = 0.0;
431: double sumY2 = 0.0;
432: double sumXY = 0.0;
433: for (int i = 0; i < n; i++) {
434: double x = 0.0;
435: if (data1[i] != null) {
436: x = data1[i].doubleValue();
437: }
438: double y = 0.0;
439: if (data2[i] != null) {
440: y = data2[i].doubleValue();
441: }
442: sumX = sumX + x;
443: sumY = sumY + y;
444: sumXY = sumXY + (x * y);
445: sumX2 = sumX2 + (x * x);
446: sumY2 = sumY2 + (y * y);
447: }
448: return (n * sumXY - sumX * sumY) / Math.pow((n * sumX2 - sumX * sumX)
449: * (n * sumY2 - sumY * sumY), 0.5);
450: }
451:
452:
462: public static double[][] getMovingAverage(Number[] xData,
463: Number[] yData,
464: int period) {
465:
466:
467: if (xData.length != yData.length) {
468: throw new IllegalArgumentException("Array lengths must be equal.");
469: }
470:
471: if (period > xData.length) {
472: throw new IllegalArgumentException(
473: "Period can't be longer than dataset."
474: );
475: }
476:
477: double[][] result = new double[xData.length - period][2];
478: for (int i = 0; i < result.length; i++) {
479: result[i][0] = xData[i + period].doubleValue();
480:
481: double sum = 0.0;
482: for (int j = 0; j < period; j++) {
483: sum += yData[i + j].doubleValue();
484: }
485: sum = sum / period;
486: result[i][1] = sum;
487: }
488: return result;
489:
490: }
491:
492: }