From e385eeb8a2ea75fb2d9c1c628619baa03c914dae Mon Sep 17 00:00:00 2001
From: Jason H Stover <jhs@math.gcsu.edu>
Date: Fri, 5 Feb 2010 15:21:17 -0500
Subject: [PATCH] Set final element in covariance matrix. Use accessor
 functions for linreg struct. Initialize total sums of squares.

---
 src/language/stats/regression.q | 12 +++++++-----
 src/math/linreg.c               | 20 ++++++++++++++++----
 src/math/linreg.h               |  5 +++--
 3 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/src/language/stats/regression.q b/src/language/stats/regression.q
index 4841c66e..0718b8d4 100644
--- a/src/language/stats/regression.q
+++ b/src/language/stats/regression.q
@@ -144,8 +144,8 @@ reg_stats_r (linreg * c)
   double std_error;
 
   assert (c != NULL);
-  rsq = c->ssm / c->sst;
-  adjrsq = 1.0 - (1.0 - rsq) * (c->n_obs - 1.0) / (c->n_obs - c->n_indeps);
+  rsq = linreg_ssreg (c) / linreg_sst (c);
+  adjrsq = 1.0 - (1.0 - rsq) * (linreg_n_obs (c) - 1.0) / (linreg_n_obs (c) - linreg_n_coeffs (c));
   std_error = sqrt (linreg_mse (c));
   t = tab_create (n_cols, n_rows, 0);
   tab_dim (t, tab_natural_dimensions, NULL);
@@ -293,9 +293,9 @@ reg_stats_anova (linreg * c)
   tab_text (t, 1, 3, TAB_LEFT | TAT_TITLE, _("Total"));
 
   /* Sums of Squares */
-  tab_double (t, 2, 1, 0, c->ssm, NULL);
-  tab_double (t, 2, 3, 0, c->sst, NULL);
-  tab_double (t, 2, 2, 0, c->sse, NULL);
+  tab_double (t, 2, 1, 0, linreg_ssreg (c), NULL);
+  tab_double (t, 2, 3, 0, linreg_sst (c), NULL);
+  tab_double (t, 2, 2, 0, linreg_sse (c), NULL);
 
 
   /* Degrees of freedom */
@@ -858,6 +858,8 @@ fill_covariance (gsl_matrix *cov, struct covariance *all_cov,
 	  result = gsl_matrix_get (ssizes, rows[i], dep_subscript);
 	}
     }
+  gsl_matrix_set (cov, cov->size1 - 1, cov->size1 - 1, 
+		  gsl_matrix_get (cm, dep_subscript, dep_subscript));
   free (rows);
   return result;
 }
diff --git a/src/math/linreg.c b/src/math/linreg.c
index c5ecf5ac..6a0d57f4 100644
--- a/src/math/linreg.c
+++ b/src/math/linreg.c
@@ -72,7 +72,7 @@ linreg_alloc (const struct variable *depvar, const struct variable **indep_vars,
   linreg *c;
   size_t i;
 
-  c = xmalloc (sizeof (linreg));
+  c = xmalloc (sizeof (*c));
   c->depvar = depvar;
   c->indep_vars = xnmalloc (p, sizeof (*indep_vars));
   for (i = 0; i < p; i++)
@@ -100,8 +100,8 @@ linreg_alloc (const struct variable *depvar, const struct variable **indep_vars,
      Default settings.
    */
   c->method = LINREG_SWEEP;
-  c->resid = NULL;		/* The variable storing my residuals. */
-  c->pred = NULL;		/* The variable storing my predicted values. */
+  c->pred = NULL;
+  c->resid = NULL;
 
   return c;
 }
@@ -365,6 +365,7 @@ linreg_fit (const gsl_matrix *cov, linreg *l)
 
   params = gsl_matrix_calloc (cov->size1, cov->size2);
   gsl_matrix_memcpy (params, cov);
+  l->sst = gsl_matrix_get (cov, cov->size1 - 1, cov->size2 - 1);
 
   if (l->method == LINREG_SWEEP)
     {
@@ -419,10 +420,21 @@ linreg_n_obs (const linreg *c)
   return c->n_obs;
 }
 
+double
+linreg_sse (const linreg *c)
+{
+  return c->sse;
+}
+
 double
 linreg_ssreg (const linreg *c)
 {
-  return c->ssm;
+  return (c->sst - c->sse);
+}
+
+double linreg_sst (const linreg *c)
+{
+  return c->sst;
 }
 
 double 
diff --git a/src/math/linreg.h b/src/math/linreg.h
index f6c7e2e8..17fe3c73 100644
--- a/src/math/linreg.h
+++ b/src/math/linreg.h
@@ -151,9 +151,8 @@ struct linreg_struct
    */
   gsl_matrix *hat;
 
-  struct variable *resid;
   struct variable *pred;
-
+  struct variable *resid;
 };
 
 typedef struct linreg_struct linreg;
@@ -199,6 +198,8 @@ double linreg_coeff (const linreg *, size_t);
 const struct variable * linreg_indep_var (const linreg *, size_t);
 size_t linreg_n_coeffs (const linreg *);
 size_t linreg_n_obs (const linreg *);
+double linreg_sse (const linreg *);
 double linreg_ssreg (const linreg *);
 double linreg_dfmodel (const linreg *);
+double linreg_sst (const linreg *);
 #endif
-- 
2.30.2