001: /* ===========================================================
002: * JFreeChart : a free chart library for the Java(tm) platform
003: * ===========================================================
004: *
005: * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
006: *
007: * Project Info: http://www.jfree.org/jfreechart/index.html
008: *
009: * This library is free software; you can redistribute it and/or modify it
010: * under the terms of the GNU Lesser General Public License as published by
011: * the Free Software Foundation; either version 2.1 of the License, or
012: * (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but
015: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017: * License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
022: * USA.
023: *
024: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025: * in the United States and other countries.]
026: *
027: * ---------------
028: * Regression.java
029: * ---------------
030: * (C) Copyright 2002-2005, by Object Refinery Limited.
031: *
032: * Original Author: David Gilbert (for Object Refinery Limited);
033: * Contributor(s): -;
034: *
035: * $Id: Regression.java,v 1.3.2.1 2005/10/25 21:34:46 mungady Exp $
036: *
037: * Changes
038: * -------
039: * 30-Sep-2002 : Version 1 (DG);
040: * 18-Aug-2003 : Added 'abstract' (DG);
041: * 15-Jul-2004 : Switched getX() with getXValue() and getY() with
042: * getYValue() (DG);
043: *
044: */
045:
046: package org.jfree.data.statistics;
047:
048: import org.jfree.data.xy.XYDataset;
049:
050: /**
051: * A utility class for fitting regression curves to data.
052: */
053: public abstract class Regression {
054:
055: /**
056: * Returns the parameters 'a' and 'b' for an equation y = a + bx, fitted to
057: * the data using ordinary least squares regression. The result is
058: * returned as a double[], where result[0] --> a, and result[1] --> b.
059: *
060: * @param data the data.
061: *
062: * @return The parameters.
063: */
064: public static double[] getOLSRegression(double[][] data) {
065:
066: int n = data.length;
067: if (n < 2) {
068: throw new IllegalArgumentException("Not enough data.");
069: }
070:
071: double sumX = 0;
072: double sumY = 0;
073: double sumXX = 0;
074: double sumXY = 0;
075: for (int i = 0; i < n; i++) {
076: double x = data[i][0];
077: double y = data[i][1];
078: sumX += x;
079: sumY += y;
080: double xx = x * x;
081: sumXX += xx;
082: double xy = x * y;
083: sumXY += xy;
084: }
085: double sxx = sumXX - (sumX * sumX) / n;
086: double sxy = sumXY - (sumX * sumY) / n;
087: double xbar = sumX / n;
088: double ybar = sumY / n;
089:
090: double[] result = new double[2];
091: result[1] = sxy / sxx;
092: result[0] = ybar - result[1] * xbar;
093:
094: return result;
095:
096: }
097:
098: /**
099: * Returns the parameters 'a' and 'b' for an equation y = a + bx, fitted to
100: * the data using ordinary least squares regression. The result is returned
101: * as a double[], where result[0] --> a, and result[1] --> b.
102: *
103: * @param data the data.
104: * @param series the series (zero-based index).
105: *
106: * @return The parameters.
107: */
108: public static double[] getOLSRegression(XYDataset data, int series) {
109:
110: int n = data.getItemCount(series);
111: if (n < 2) {
112: throw new IllegalArgumentException("Not enough data.");
113: }
114:
115: double sumX = 0;
116: double sumY = 0;
117: double sumXX = 0;
118: double sumXY = 0;
119: for (int i = 0; i < n; i++) {
120: double x = data.getXValue(series, i);
121: double y = data.getYValue(series, i);
122: sumX += x;
123: sumY += y;
124: double xx = x * x;
125: sumXX += xx;
126: double xy = x * y;
127: sumXY += xy;
128: }
129: double sxx = sumXX - (sumX * sumX) / n;
130: double sxy = sumXY - (sumX * sumY) / n;
131: double xbar = sumX / n;
132: double ybar = sumY / n;
133:
134: double[] result = new double[2];
135: result[1] = sxy / sxx;
136: result[0] = ybar - result[1] * xbar;
137:
138: return result;
139:
140: }
141:
142: /**
143: * Returns the parameters 'a' and 'b' for an equation y = ax^b, fitted to
144: * the data using a power regression equation. The result is returned as
145: * an array, where double[0] --> a, and double[1] --> b.
146: *
147: * @param data the data.
148: *
149: * @return The parameters.
150: */
151: public static double[] getPowerRegression(double[][] data) {
152:
153: int n = data.length;
154: if (n < 2) {
155: throw new IllegalArgumentException("Not enough data.");
156: }
157:
158: double sumX = 0;
159: double sumY = 0;
160: double sumXX = 0;
161: double sumXY = 0;
162: for (int i = 0; i < n; i++) {
163: double x = Math.log(data[i][0]);
164: double y = Math.log(data[i][1]);
165: sumX += x;
166: sumY += y;
167: double xx = x * x;
168: sumXX += xx;
169: double xy = x * y;
170: sumXY += xy;
171: }
172: double sxx = sumXX - (sumX * sumX) / n;
173: double sxy = sumXY - (sumX * sumY) / n;
174: double xbar = sumX / n;
175: double ybar = sumY / n;
176:
177: double[] result = new double[2];
178: result[1] = sxy / sxx;
179: result[0] = Math.pow(Math.exp(1.0), ybar - result[1] * xbar);
180:
181: return result;
182:
183: }
184:
185: /**
186: * Returns the parameters 'a' and 'b' for an equation y = ax^b, fitted to
187: * the data using a power regression equation. The result is returned as
188: * an array, where double[0] --> a, and double[1] --> b.
189: *
190: * @param data the data.
191: * @param series the series to fit the regression line against.
192: *
193: * @return The parameters.
194: */
195: public static double[] getPowerRegression(XYDataset data, int series) {
196:
197: int n = data.getItemCount(series);
198: if (n < 2) {
199: throw new IllegalArgumentException("Not enough data.");
200: }
201:
202: double sumX = 0;
203: double sumY = 0;
204: double sumXX = 0;
205: double sumXY = 0;
206: for (int i = 0; i < n; i++) {
207: double x = Math.log(data.getXValue(series, i));
208: double y = Math.log(data.getYValue(series, i));
209: sumX += x;
210: sumY += y;
211: double xx = x * x;
212: sumXX += xx;
213: double xy = x * y;
214: sumXY += xy;
215: }
216: double sxx = sumXX - (sumX * sumX) / n;
217: double sxy = sumXY - (sumX * sumY) / n;
218: double xbar = sumX / n;
219: double ybar = sumY / n;
220:
221: double[] result = new double[2];
222: result[1] = sxy / sxx;
223: result[0] = Math.pow(Math.exp(1.0), ybar - result[1] * xbar);
224:
225: return result;
226:
227: }
228:
229: }
|