From c17ea35a73b7a690a54c5c6a213de19f0376e74f Mon Sep 17 00:00:00 2001 From: Jason Stover Date: Sun, 12 Aug 2007 02:36:50 +0000 Subject: [PATCH] Added scope and explanation of use of conditional inverse; added appropriate enum constant --- src/math/linreg/ChangeLog | 8 ++++++++ src/math/linreg/linreg.c | 14 +++++++++++++- src/math/linreg/linreg.h | 3 ++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/math/linreg/ChangeLog b/src/math/linreg/ChangeLog index 5f5a617b..a45216fd 100644 --- a/src/math/linreg/ChangeLog +++ b/src/math/linreg/ChangeLog @@ -1,3 +1,11 @@ +2007-08-11 Jason Stover + + * linreg.h (enum): Dropped ambiguous PSPP_LINREG_SVD in favor of + PSPP_LINREG_QR. Added PSPP_LINREG_CONDITIONAL_INVERSE. + + * linreg.c (pspp_linreg): Added scope and comment for use of + generalized inverse to solve normal equations. + 2007-04-12 Jason Stover * linreg.c: (pspp_linreg_cache_free) Check for null pointer before diff --git a/src/math/linreg/linreg.c b/src/math/linreg/linreg.c index 9ba84f60..3c086a98 100644 --- a/src/math/linreg/linreg.c +++ b/src/math/linreg/linreg.c @@ -110,7 +110,7 @@ pspp_linreg_get_vars (const void *c_, const struct variable **v) /* Start at c->coeff[1] to avoid the intercept. */ - v[result] = pspp_coeff_get_var (c->coeff[1], 0); + v[result] = pspp_coeff_get_var (c->coeff[1], 0); result = (v[result] == NULL) ? 0 : 1; for (coef = c->coeff[2]; coef < c->coeff[c->n_coeffs]; coef++) @@ -366,6 +366,18 @@ pspp_linreg (const gsl_vector * Y, const gsl_matrix * X, } gsl_matrix_free (sw); } + else if (cache->method == PSPP_LINREG_CONDITIONAL_INVERSE) + { + /* + Use the SVD of X^T X to find a conditional inverse of X^TX. If + the SVD is X^T X = U D V^T, then set the conditional inverse + to (X^T X)^c = V D^- U^T. D^- is defined as follows: If entry + (i, i) has value sigma_i, then entry (i, i) of D^- is 1 / + sigma_i if sigma_i > 0, and 0 otherwise. Then solve the normal + equations by setting the estimated parameter vector to + (X^TX)^c X^T Y. + */ + } else { gsl_multifit_linear_workspace *wk; diff --git a/src/math/linreg/linreg.h b/src/math/linreg/linreg.h index f256ef9d..d09752a2 100644 --- a/src/math/linreg/linreg.h +++ b/src/math/linreg/linreg.h @@ -27,8 +27,9 @@ union value; enum { + PSPP_LINREG_CONDITIONAL_INVERSE, + PSPP_LINREG_QR, PSPP_LINREG_SWEEP, - PSPP_LINREG_SVD }; -- 2.30.2