KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > data > statistics > BoxAndWhiskerCalculator


1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
6  *
7  * Project Info: http://www.jfree.org/jfreechart/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this library; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22  *
23  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
24  * in the United States and other countries.]
25  *
26  * ----------------------------
27  * BoxAndWhiskerCalculator.java
28  * ----------------------------
29  * (C) Copyright 2003-2005, by Object Refinery Limited and Contributors.
30  *
31  * Original Author: David Gilbert (for Object Refinery Limited);
32  * Contributor(s): -;
33  *
34  * $Id: BoxAndWhiskerCalculator.java,v 1.3 2005/02/09 13:51:57 mungady Exp $
35  *
36  * Changes
37  * -------
38  * 28-Aug-2003 : Version 1 (DG);
39  * 17-Nov-2003 : Fixed bug in calculations of outliers and median (DG);
40  * 10-Jan-2005 : Removed deprecated methods in preparation for 1.0.0
41  * release (DG);
42  *
43  */

44
45 package org.jfree.data.statistics;
46
47 import java.util.ArrayList JavaDoc;
48 import java.util.Collections JavaDoc;
49 import java.util.Iterator JavaDoc;
50 import java.util.List JavaDoc;
51
52 /**
53  * A utility class that calculates the mean, median, quartiles Q1 and Q3, plus
54  * a list of outlier values...all from an arbitrary list of
55  * <code>Number</code> objects.
56  */

57 public abstract class BoxAndWhiskerCalculator {
58     
59     /**
60      * Calculates the statistics required for a {@link BoxAndWhiskerItem}.
61      * <P>
62      * Any items in the list that are not instances of the <code>Number</code>
63      * class are ignored. Likewise, <code>null</code> values are ignored.
64      *
65      * @param values a list of numbers (a <code>null</code> list is not
66      * permitted).
67      *
68      * @return Box-and-whisker statistics.
69      */

70     public static BoxAndWhiskerItem calculateBoxAndWhiskerStatistics(
71                                         List JavaDoc values) {
72         
73         Collections.sort(values);
74         
75         double mean = Statistics.calculateMean(values);
76         double median = Statistics.calculateMedian(values, false);
77         double q1 = calculateQ1(values);
78         double q3 = calculateQ3(values);
79         
80         double interQuartileRange = q3 - q1;
81         
82         double upperOutlierThreshold = q3 + (interQuartileRange * 1.5);
83         double lowerOutlierThreshold = q1 - (interQuartileRange * 1.5);
84         
85         double upperFaroutThreshold = q3 + (interQuartileRange * 2.0);
86         double lowerFaroutThreshold = q1 - (interQuartileRange * 2.0);
87
88         double minRegularValue = Double.POSITIVE_INFINITY;
89         double maxRegularValue = Double.NEGATIVE_INFINITY;
90         double minOutlier = Double.POSITIVE_INFINITY;
91         double maxOutlier = Double.NEGATIVE_INFINITY;
92         List JavaDoc outliers = new ArrayList JavaDoc();
93         
94         Iterator JavaDoc iterator = values.iterator();
95         while (iterator.hasNext()) {
96             Object JavaDoc object = iterator.next();
97             if (object != null && object instanceof Number JavaDoc) {
98                 Number JavaDoc number = (Number JavaDoc) object;
99                 double value = number.doubleValue();
100                 if (value > upperOutlierThreshold) {
101                     outliers.add(number);
102                     if (value > maxOutlier && value <= upperFaroutThreshold) {
103                         maxOutlier = value;
104                     }
105                 }
106                 else if (value < lowerOutlierThreshold) {
107                     outliers.add(number);
108                     if (value < minOutlier && value >= lowerFaroutThreshold) {
109                         minOutlier = value;
110                     }
111                 }
112                 else {
113                     if (minRegularValue == Double.NaN) {
114                         minRegularValue = value;
115                     }
116                     else {
117                         minRegularValue = Math.min(minRegularValue, value);
118                     }
119                     if (maxRegularValue == Double.NaN) {
120                         maxRegularValue = value;
121                     }
122                     else {
123                         maxRegularValue = Math.max(maxRegularValue, value);
124                     }
125                 }
126                 
127             }
128         }
129         minOutlier = Math.min(minOutlier, minRegularValue);
130         maxOutlier = Math.max(maxOutlier, maxRegularValue);
131         
132         return new BoxAndWhiskerItem(
133             new Double JavaDoc(mean),
134             new Double JavaDoc(median),
135             new Double JavaDoc(q1),
136             new Double JavaDoc(q3),
137             new Double JavaDoc(minRegularValue),
138             new Double JavaDoc(maxRegularValue),
139             new Double JavaDoc(minOutlier),
140             new Double JavaDoc(maxOutlier),
141             outliers
142         );
143         
144     }
145
146     /**
147      * Calculates the first quartile for a list of numbers in ascending order.
148      *
149      * @param values the numbers in ascending order.
150      *
151      * @return The first quartile.
152      */

153     public static double calculateQ1(List JavaDoc values) {
154         double result = Double.NaN;
155         int count = values.size();
156         if (count > 0) {
157             if (count % 2 == 1) {
158                 if (count > 1) {
159                     result = Statistics.calculateMedian(values, 0, count / 2);
160                 }
161                 else {
162                     result = Statistics.calculateMedian(values, 0, 0);
163                 }
164             }
165             else {
166                 result = Statistics.calculateMedian(values, 0, count / 2 - 1);
167             }
168             
169         }
170         return result;
171     }
172     
173     /**
174      * Calculates the third quartile for a list of numbers in ascending order.
175      *
176      * @param values the list of values.
177      *
178      * @return The third quartile.
179      */

180     public static double calculateQ3(List JavaDoc values) {
181         double result = Double.NaN;
182         int count = values.size();
183         if (count > 0) {
184             if (count % 2 == 1) {
185                 if (count > 1) {
186                     result = Statistics.calculateMedian(
187                         values, count / 2, count - 1
188                     );
189                 }
190                 else {
191                     result = Statistics.calculateMedian(values, 0, 0);
192                 }
193             }
194             else {
195                 result = Statistics.calculateMedian(
196                     values, count / 2, count - 1
197                 );
198             }
199             
200         }
201         return result;
202     }
203     
204 }
205
Popular Tags