Author: luc
Date: Wed May 21 05:13:27 2008
New Revision: 658645

URL: http://svn.apache.org/viewvc?rev=658645&view=rev
Log:
added error handling for multiple linear-regression
added documentation for multiple linear-regression
JIRA: MATH-203

Modified:
    
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.java
    
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java
    
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.java
    
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java
    commons/proper/math/branches/MATH_2_0/src/site/xdoc/userguide/stat.xml
    
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegressionTest.java
    
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/GLSMultipleLinearRegressionTest.java

Modified: 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.java?rev=658645&r1=658644&r2=658645&view=diff
==============================================================================
--- 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.java
 (original)
+++ 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.java
 Wed May 21 05:13:27 2008
@@ -38,7 +38,7 @@
      * 
      * @param y the [n,1] array representing the y sample
      */
-    protected void addYSampleData(double[] y){
+    protected void addYSampleData(double[] y) {
         this.Y = new RealMatrixImpl(y);
     }
 
@@ -47,22 +47,64 @@
      * 
      * @param x the [n,k] array representing the x sample
      */
-    protected void addXSampleData(double[][] x){
+    protected void addXSampleData(double[][] x) {
         this.X = new RealMatrixImpl(x);
     }
 
     /**
+     * Validates sample data.
+     * 
+     * @param x the [n,k] array representing the x sample
+     * @param y the [n,1] array representing the y sample
+     * @throws IllegalArgumentException if the x and y array data are not
+     *             compatible for the regression
+     */
+    protected void validateSampleData(double[][] x, double[] y) {
+        if (x == null) {
+            throw new IllegalArgumentException("The regressors matrix x cannot 
be null.");
+        }
+        if (y == null) {
+            throw new IllegalArgumentException("The regressand vector y cannot 
be null.");
+        }
+        if (x.length != y.length) {
+            throw new IllegalArgumentException(
+                    "The regressors matrix x columns must have the same length 
of the regressand vector y");
+        }
+    }
+
+    /**
+     * Validates sample data.
+     * 
+     * @param x the [n,k] array representing the x sample
+     * @param covariance the [n,n] array representing the covariance matrix
+     * @throws IllegalArgumentException if the x sample data or covariance
+     *             matrix are not compatible for the regression
+     */
+    protected void validateCovarianceData(double[][] x, double[][] covariance) 
{
+        if (covariance == null) {
+            throw new IllegalArgumentException("Covariance matrix cannot be 
null.");
+        }
+        if (x.length != covariance.length) {
+            throw new IllegalArgumentException(
+                    "The regressors matrix x columns must have the same length 
of the covariance matrix columns");
+        }
+        if (covariance.length > 0 && covariance.length != 
covariance[0].length) {
+            throw new IllegalArgumentException("The covariance matrix must be 
square");
+        }
+    }
+
+    /**
      * [EMAIL PROTECTED]
      */
-    public double[] estimateRegressionParameters(){
+    public double[] estimateRegressionParameters() {
         RealMatrix b = calculateBeta();
         return b.getColumn(0);
-    }    
-    
+    }
+
     /**
      * [EMAIL PROTECTED]
      */
-    public double[] estimateResiduals(){
+    public double[] estimateResiduals() {
         RealMatrix b = calculateBeta();
         RealMatrix e = Y.subtract(X.multiply(b));
         return e.getColumn(0);
@@ -81,36 +123,42 @@
     public double estimateRegressandVariance() {
         return calculateYVariance();
     }
-    
+
     /**
      * Calculates the beta of multiple linear regression in matrix notation.
+     * 
      * @return beta
      */
-    protected abstract RealMatrix calculateBeta();    
-    
+    protected abstract RealMatrix calculateBeta();
+
     /**
-     * Calculates the beta variance of multiple linear regression in matrix 
notation.
+     * Calculates the beta variance of multiple linear regression in matrix
+     * notation.
+     * 
      * @return beta variance
      */
     protected abstract RealMatrix calculateBetaVariance();
-    
+
     /**
      * Calculates the Y variance of multiple linear regression.
+     * 
      * @return Y variance
      */
     protected abstract double calculateYVariance();
 
     /**
-     * Calculates the residuals of multiple linear regression in matrix 
notation.
+     * Calculates the residuals of multiple linear regression in matrix
+     * notation.
+     * 
      * <pre>
-     * u = y - X*b
+     * u = y - X * b
      * </pre>
      * 
-     * @return The residuals [n,1] matrix 
+     * @return The residuals [n,1] matrix
      */
     protected RealMatrix calculateResiduals() {
         RealMatrix b = calculateBeta();
         return Y.subtract(X.multiply(b));
     }
-    
+
 }

Modified: 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java?rev=658645&r1=658644&r2=658645&view=diff
==============================================================================
--- 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java
 (original)
+++ 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java
 Wed May 21 05:13:27 2008
@@ -48,8 +48,10 @@
      * [EMAIL PROTECTED]
      */
     public void addData(double[] y, double[][] x, double[][] covariance) {
+        validateSampleData(x, y);
         addYSampleData(y);
         addXSampleData(x);
+        validateCovarianceData(x, covariance);
         addCovarianceData(covariance);
     }
 

Modified: 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.java?rev=658645&r1=658644&r2=658645&view=diff
==============================================================================
--- 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.java
 (original)
+++ 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.java
 Wed May 21 05:13:27 2008
@@ -37,8 +37,9 @@
      * 
      * @param y the [n,1] array representing the y sample
      * @param x the [n,k] array representing x sample
-     * @param covariance the [n,n] array representing the covariance matrix or 
<code>null</code> if not appropriate for the
+     * @param covariance the [n,n] array representing the covariance matrix or 
<code>null</code> if not required for the
      *          specific implementation
+     * @throws IllegalArgumentException if required data arrays are 
<code>null</code> or their dimensions are not appropriate
      */
     void addData(double[] y, double[][] x, double[][] covariance);
 
@@ -62,7 +63,7 @@
      * @return The [n,1] array representing the residuals
      */
     double[] estimateResiduals();
-    
+
     /**
      * Returns the variance of the regressand, ie Var(y).
      * 

Modified: 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java?rev=658645&r1=658644&r2=658645&view=diff
==============================================================================
--- 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java
 (original)
+++ 
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java
 Wed May 21 05:13:27 2008
@@ -44,6 +44,7 @@
      * [EMAIL PROTECTED]
      */
     public void addData(double[] y, double[][] x, double[][] covariance) {
+        validateSampleData(x, y);
         addYSampleData(y);
         addXSampleData(x);
     }

Modified: commons/proper/math/branches/MATH_2_0/src/site/xdoc/userguide/stat.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/site/xdoc/userguide/stat.xml?rev=658645&r1=658644&r2=658645&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_0/src/site/xdoc/userguide/stat.xml 
(original)
+++ commons/proper/math/branches/MATH_2_0/src/site/xdoc/userguide/stat.xml Wed 
May 21 05:13:27 2008
@@ -398,7 +398,101 @@
          </dl>
         </p>
       </subsection>
-      <subsection name="1.5 Statistical tests" href="tests">
+      <subsection name="1.5 Multiple linear regression" href="regression">
+        <p>
+         <a 
href="../apidocs/org/apache/commons/math/stat/regression/MultipleLinearRegression.html">
+          org.apache.commons.math.stat.regression.MultipleLinearRegression</a>
+          provides ordinary least squares regression with a generic multiple 
variable linear model, which
+          in matrix notation can be expressed as:
+         </p>
+         <p>
+           <code> y=X*b+u </code>
+         </p>
+         <p>
+         where y is an <code>n-vector</code> <b>regressand</b>, X is a 
<code>[n,k]</code> matrix whose <code>k</code> columns are called
+         <b>regressors</b>, b is <code>k-vector</code> of <b>regression 
parameters</b> and <code>u</code> is an <code>n-vector</code> 
+         of <b>error terms</b> or <b>residuals</b>.   The notation is quite 
standard in literature, 
+         cf eg <a href="http://www.econ.queensu.ca/ETM";>Davidson and 
MacKinnon, Econometrics Theory and Methods, 2004</a>.
+         </p>
+         <p>
+          Two implementations are provided: <a 
href="../apidocs/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.html">
+          
org.apache.commons.math.stat.regression.OLSMultipleLinearRegression</a> and 
+          <a 
href="../apidocs/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.html">
+          
org.apache.commons.math.stat.regression.GLSMultipleLinearRegression</a>
+         </p>
+         <p>
+           Observations (x,y and covariance data matrices) can be added to the 
model via the <code>addData(double[] y, double[][] x, double[][] 
covariance)</code> method.
+           The observations are stored in memory until the next time the 
addData method is invoked.  
+         </p>
+         <p>
+           <strong>Usage Notes</strong>: <ul>
+           <li> Data is validated when invoking the <code>addData(double[] y, 
double[][] x, double[][] covariance)</code> method and
+           <code>IllegalArgumentException</code> is thrown when inappropriate. 
+           </li>
+           <li> Only the GLS regressions require the covariance matrix, so in 
the OLS regression it is ignored and can be safely
+           inputted as <code>null</code>.</li>
+          </ul>
+        </p>
+        <p>
+        Here are some examples.
+        <dl>
+         <dt>OLS regression</dt>
+          <br></br>
+          <dd>Instantiate an OLS regression object and load dataset
+          <source>
+MultipleLinearRegression regression = new OLSMultipleLinearRegression();
+double[] y = new double[]{11.0, 12.0, 13.0, 14.0, 15.0, 16.0};
+double[] x = new double[6][];
+x[0] = new double[]{1.0, 0, 0, 0, 0, 0};
+x[1] = new double[]{1.0, 2.0, 0, 0, 0, 0};
+x[2] = new double[]{1.0, 0, 3.0, 0, 0, 0};
+x[3] = new double[]{1.0, 0, 0, 4.0, 0, 0};
+x[4] = new double[]{1.0, 0, 0, 0, 5.0, 0};
+x[5] = new double[]{1.0, 0, 0, 0, 0, 6.0};          
+regression.addData(y, x, null); // we don't need covariance
+          </source>
+          </dd>
+          <dd>Estimate of regression values honours the 
<code>MultipleLinearRegression</code> interface:
+         <source>
+double[] beta = regression.estimateRegressionParameters();        
+
+double[] residuals = regression.estimateResiduals();
+
+double[][] parametersVariance = 
regression.estimateRegressionParametersVariance();
+
+double regressandVariance = regression.estimateRegressandVariance();
+         </source>
+         </dd>
+         <dt>GLS regression</dt>
+          <br></br>
+          <dd>Instantiate an GLS regression object and load dataset
+          <source>
+MultipleLinearRegression regression = new GLSMultipleLinearRegression();
+double[] y = new double[]{11.0, 12.0, 13.0, 14.0, 15.0, 16.0};
+double[] x = new double[6][];
+x[0] = new double[]{1.0, 0, 0, 0, 0, 0};
+x[1] = new double[]{1.0, 2.0, 0, 0, 0, 0};
+x[2] = new double[]{1.0, 0, 3.0, 0, 0, 0};
+x[3] = new double[]{1.0, 0, 0, 4.0, 0, 0};
+x[4] = new double[]{1.0, 0, 0, 0, 5.0, 0};
+x[5] = new double[]{1.0, 0, 0, 0, 0, 6.0};          
+double[][] omega = new double[6][];
+omega[0] = new double[]{1.1, 0, 0, 0, 0, 0};
+omega[1] = new double[]{0, 2.2, 0, 0, 0, 0};
+omega[2] = new double[]{0, 0, 3.3, 0, 0, 0};
+omega[3] = new double[]{0, 0, 0, 4.4, 0, 0};
+omega[4] = new double[]{0, 0, 0, 0, 5.5, 0};
+omega[5] = new double[]{0, 0, 0, 0, 0, 6.6};
+regression.addData(y, x, omega); // we do need covariance
+          </source>
+          </dd>
+          <dd>Estimate of regression values honours the same 
<code>MultipleLinearRegression</code> interface as 
+          the OLS regression.
+         </dd>
+         </dl>
+        </p>
+      </subsection>      
+      <subsection name="1.6 Statistical tests" href="tests">
         <p>
           The interfaces and implementations in the
           <a href="../apidocs/org/apache/commons/math/stat/inference/">

Modified: 
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegressionTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegressionTest.java?rev=658645&r1=658644&r2=658645&view=diff
==============================================================================
--- 
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegressionTest.java
 (original)
+++ 
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegressionTest.java
 Wed May 21 05:13:27 2008
@@ -25,7 +25,7 @@
 
 public abstract class AbstractMultipleLinearRegressionTest {
 
-    private MultipleLinearRegression regression;
+    protected MultipleLinearRegression regression;
 
     @Before
     public void setUp(){
@@ -61,5 +61,23 @@
         double variance = regression.estimateRegressandVariance();
         assertTrue(variance > 0.0);
     }   
+    
+    @Test(expected=IllegalArgumentException.class)
+    public void cannotAddXSampleData() {
+        regression.addData(new double[]{}, null, null);
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void cannotAddNullYSampleData() {
+        regression.addData(null, new double[][]{}, null);
+    }
+    
+    @Test(expected=IllegalArgumentException.class)
+    public void cannotAddSampleDataWithSizeMismatch() {
+        double[] y = new double[]{1.0, 2.0};
+        double[][] x = new double[1][];
+        x[0] = new double[]{1.0, 0};
+        regression.addData(y, x, null);
+    }
 
 }

Modified: 
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/GLSMultipleLinearRegressionTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/GLSMultipleLinearRegressionTest.java?rev=658645&r1=658644&r2=658645&view=diff
==============================================================================
--- 
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/GLSMultipleLinearRegressionTest.java
 (original)
+++ 
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/GLSMultipleLinearRegressionTest.java
 Wed May 21 05:13:27 2008
@@ -17,6 +17,7 @@
 package org.apache.commons.math.stat.regression;
 
 import org.junit.Before;
+import org.junit.Test;
 
 public class GLSMultipleLinearRegressionTest extends 
AbstractMultipleLinearRegressionTest {
 
@@ -44,6 +45,36 @@
         super.setUp();
     }
    
+
+    @Test(expected=IllegalArgumentException.class)
+    public void cannotAddNullCovarianceData() {
+        regression.addData(new double[]{}, new double[][]{}, null);
+    }
+    
+    @Test(expected=IllegalArgumentException.class)
+    public void cannotAddCovarianceDataWithSampleSizeMismatch() {
+        double[] y = new double[]{1.0, 2.0};
+        double[][] x = new double[2][];
+        x[0] = new double[]{1.0, 0};
+        x[1] = new double[]{0, 1.0};
+        double[][] omega = new double[1][];
+        omega[0] = new double[]{1.0, 0};
+        regression.addData(y, x, omega);
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void cannotAddCovarianceDataThatIsNotSquare() {
+        double[] y = new double[]{1.0, 2.0};
+        double[][] x = new double[2][];
+        x[0] = new double[]{1.0, 0};
+        x[1] = new double[]{0, 1.0};
+        double[][] omega = new double[3][];
+        omega[0] = new double[]{1.0, 0};
+        omega[1] = new double[]{0, 1.0};
+        omega[2] = new double[]{0, 2.0};
+        regression.addData(y, x, omega);
+    }
+
     protected MultipleLinearRegression createRegression() {
         MultipleLinearRegression regression = new 
GLSMultipleLinearRegression();
         regression.addData(y, x, omega);
@@ -57,5 +88,5 @@
     protected int getSampleSize() {
         return y.length;
     }
-    
+        
 }


Reply via email to