added residual computation; improved handling of bad input
authorJason Stover <jhs@math.gcsu.edu>
Fri, 7 Apr 2006 19:37:13 +0000 (19:37 +0000)
committerJason Stover <jhs@math.gcsu.edu>
Fri, 7 Apr 2006 19:37:13 +0000 (19:37 +0000)
src/math/linreg/ChangeLog
src/math/linreg/coefficient.c
src/math/linreg/linreg.h
src/math/linreg/predict.c

index 7b6ee73d3f28ac46cb6572ec3b9efe426b03427b..5c8b9c1f1090298c4abd5e01ca1bd9f8c4c7a1dd 100644 (file)
@@ -1,3 +1,12 @@
+2006-04-07  Jason Stover  <jhs@math.gcsu.edu>
+
+       * predict.c (pspp_linreg_predict): Improved handling of null
+       pointer args.
+
+       * predict.c (pspp_linreg_residuals): New function.
+
+       * coefficient.c: Improved handling of null pointer args.
+
 2006-04-05  Jason Stover  <jhs@math.gcsu.edu>
 
        * predict.c: New file. pspp_linreg_predict() uses a linear model
index d09432b33d5d24430d0c9cb014485d4b81a35b5b..cca02bcba81363cb4329b3d685ebf45a251746dd 100644 (file)
@@ -105,7 +105,10 @@ pspp_linreg_coeff_set_std_err (struct pspp_linreg_coeff *c, double std_err)
 double
 pspp_linreg_coeff_get_est (const struct pspp_linreg_coeff *c)
 {
-  assert (c != NULL);
+  if (c == NULL)
+    {
+      return 0.0;
+    }
   return c->estimate;
 }
 /*
@@ -114,7 +117,10 @@ pspp_linreg_coeff_get_est (const struct pspp_linreg_coeff *c)
 double 
 pspp_linreg_coeff_get_std_err (const struct pspp_linreg_coeff *c)
 {
-  assert (c != NULL);
+  if (c == NULL)
+    {
+      return 0.0;
+    }
   return c->std_err;
 }
 /*
@@ -123,6 +129,10 @@ pspp_linreg_coeff_get_std_err (const struct pspp_linreg_coeff *c)
 int
 pspp_linreg_coeff_get_n_vars (struct pspp_linreg_coeff *c)
 {
+  if (c == NULL)
+    {
+      return 0;
+    }
   return c->n_vars;
 }
 
@@ -132,6 +142,10 @@ pspp_linreg_coeff_get_n_vars (struct pspp_linreg_coeff *c)
 const struct variable *
 pspp_linreg_coeff_get_var (struct pspp_linreg_coeff *c, int i)
 {
+  if (c == NULL)
+    {
+      return NULL;
+    }
   assert (i < c->n_vars);
   return (c->v_info + i)->v;
 }
@@ -146,6 +160,10 @@ pspp_linreg_coeff_get_value (struct pspp_linreg_coeff *c,
   int i = 0;
   const struct variable *candidate;
 
+  if (c == NULL || v == NULL)
+    {
+      return NULL;
+    }
   while (i < c->n_vars)
     {
       candidate = pspp_linreg_coeff_get_var (c, i);
@@ -170,11 +188,10 @@ pspp_linreg_get_coeff (const pspp_linreg_cache *c,
   struct pspp_linreg_coeff *result;
   const struct variable *tmp;
 
-  assert (c != NULL);
-  assert (c->coeff != NULL);
-  assert (c->n_indeps > 0);
-  assert (v != NULL);
-  assert (val != NULL);
+  if (c == NULL || c->coeff == NULL || c->n_indeps == NULL || v == NULL)
+    {
+      return NULL;
+    }
   
   result = c->coeff + i;
   tmp = pspp_linreg_coeff_get_var (result, 0);
@@ -192,7 +209,7 @@ pspp_linreg_get_coeff (const pspp_linreg_cache *c,
     {
       return result;
     }
-  else
+  else if (val != NULL)
     {
       /*
        If v is categorical, we need to ensure the coefficient
@@ -211,5 +228,6 @@ pspp_linreg_get_coeff (const pspp_linreg_cache *c,
        }
       return result;
     }
+  return NULL;
 }
 
index 2852dd77829ad69f6b53aa993c4386dfd57c1bea..be5803fd9d36b921a1498429fcf553ede5d54776 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef LINREG_H
 #define LINREG_H
 
-
+#include <gsl/gsl_math.h>
 #include <gsl/gsl_vector.h>
 #include <gsl/gsl_matrix.h>
 
@@ -181,4 +181,7 @@ int pspp_linreg (const gsl_vector * Y, const gsl_matrix * X,
 double
 pspp_linreg_predict (const struct variable *, const union value *, 
                     const pspp_linreg_cache *, int);
+double
+pspp_linreg_residual (const struct variable *, const union value *,
+                     const union value *, const pspp_linreg_cache *, int);
 #endif
index f2539c0e1c2d9ae4fab3f470adfe49b157ba4c67..fdd940972943c0d7a8b5b6d0f9777968f24641ec 100644 (file)
@@ -38,10 +38,15 @@ pspp_linreg_predict (const struct variable *predictors,
   double result;
   double tmp;
   
-  assert (predictors != NULL);
-  assert (vals != NULL);
-  assert (c != NULL);
-
+  if (predictors == NULL || vals == NULL || c == NULL)
+    {
+      return GSL_NAN;
+    }
+  if (c->coeff == NULL)
+    {
+      /* The stupid model: just guess the mean. */
+      return c->depvar_mean;
+    }
   result = c->coeff->estimate; /* Intercept. */
 
   /*
@@ -60,3 +65,24 @@ pspp_linreg_predict (const struct variable *predictors,
     }
   return result;
 }
+
+double
+pspp_linreg_residual (const struct variable *predictors,
+                     const union value *vals,
+                     const union value *obs,
+                     const pspp_linreg_cache *c,
+                     int n_vals)
+{
+  double pred;
+  double result;
+
+  if (predictors == NULL || vals == NULL || c == NULL || obs == NULL)
+    {
+      return GSL_NAN;
+    }
+  
+  pred = pspp_linreg_predict (predictors, vals, c, n_vals);
+  
+  result = gsl_isnan (pred) ? GSL_NAN : (obs->f - pred);
+  return result;
+}