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