From: Jason Stover Date: Fri, 28 Apr 2006 13:23:05 +0000 (+0000) Subject: added function to retrieve variable list used in linear model X-Git-Tag: v0.6.0~929 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b2859987e3e1c67ffd240945f4590bb23d31bdb8;p=pspp-builds.git added function to retrieve variable list used in linear model --- diff --git a/src/math/linreg/ChangeLog b/src/math/linreg/ChangeLog index 274faf41..6b4425c0 100644 --- a/src/math/linreg/ChangeLog +++ b/src/math/linreg/ChangeLog @@ -1,3 +1,14 @@ +2006-04-28 Jason Stover + + * linreg.c (pspp_linreg_get_vars): New function. Fills an array with + pointers to the variables used in the model. + + * linreg.h: Add a pointer called get_vars to pspp_linreg_get_vars() + to access variables in a model. + + * coefficient.c (pspp_linreg_coeff_init): Set the variable + associated with the intercept term to NULL. + 2006-04-26 Jason Stover * linreg.h: Added a pointer to predicted values. diff --git a/src/math/linreg/coefficient.c b/src/math/linreg/coefficient.c index d1fcbfa2..1f5d9ec4 100644 --- a/src/math/linreg/coefficient.c +++ b/src/math/linreg/coefficient.c @@ -60,6 +60,7 @@ pspp_linreg_coeff_init (pspp_linreg_cache * c, struct design_matrix *X) struct pspp_linreg_coeff *coeff; c->coeff = xnmalloc (X->m->size2 + 1, sizeof (*c->coeff)); + c->coeff->v_info = NULL; /* Intercept has no associated variable. */ for (i = 0; i < X->m->size2; i++) { j = i + 1; /* The first coefficient is the intercept. */ @@ -137,7 +138,8 @@ pspp_linreg_coeff_get_n_vars (struct pspp_linreg_coeff *c) } /* - Which variable does this coefficient match? + Which variable does this coefficient match? I should be + 0 unless the coefficient refers to an interaction term. */ const struct variable * pspp_linreg_coeff_get_var (struct pspp_linreg_coeff *c, int i) diff --git a/src/math/linreg/coefficient.h b/src/math/linreg/coefficient.h index c2c7200c..0dc1a035 100644 --- a/src/math/linreg/coefficient.h +++ b/src/math/linreg/coefficient.h @@ -1,23 +1,22 @@ -/* lib/linreg/coefficient.c - - Copyright (C) 2005 Free Software Foundation, Inc. - Written by Jason H Stover. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at - your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02111-1307, USA. - */ +/* + lib/linreg/coefficient.c + + Copyright (C) 2005 Free Software Foundation, Inc. Written by Jason H Stover. + + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 51 + Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. +*/ #ifndef COEFFICIENT_H @@ -38,84 +37,74 @@ struct design_matrix; */ struct pspp_linreg_coeff { - double estimate; /* Estimated coefficient. */ - double std_err; /* Standard error of the estimate. */ - struct varinfo *v_info; /* Information pertaining to the - variable(s) associated with this - coefficient. The calling function - should initialize this value with the - functions in coefficient.c. The - estimation procedure ignores this - member. It is here so the caller can - match parameters with relevant variables - and values. If the coefficient is - associated with an interaction, then - v_info contains information for multiple - variables. - */ - int n_vars; /* Number of variables associated with this coefficient. - Coefficients corresponding to interaction terms will - have more than one variable. - */ + double estimate; /* Estimated coefficient. */ + double std_err; /* Standard error of the estimate. */ + struct varinfo *v_info; /* Information pertaining to the variable(s) + associated with this coefficient. The + calling function should initialize this + value with the functions in coefficient.c. + The estimation procedure ignores this + member. It is here so the caller can match + parameters with relevant variables and + values. If the coefficient is associated + with an interaction, then v_info contains + information for multiple variables. */ + int n_vars; /* Number of variables associated with this + coefficient. Coefficients corresponding to + interaction terms will have more than one + variable. */ }; - -/* - Accessor functions for matching coefficients and variables. - */ - void pspp_linreg_coeff_free (struct pspp_linreg_coeff *); /* Initialize the variable and value pointers inside the coefficient structures for the linear model. */ -void -pspp_linreg_coeff_init (pspp_linreg_cache *, - struct design_matrix *); +void pspp_linreg_coeff_init (pspp_linreg_cache *, struct design_matrix *); void -pspp_linreg_coeff_set_estimate (struct pspp_linreg_coeff *, - double estimate); +pspp_linreg_coeff_set_estimate (struct pspp_linreg_coeff *, double estimate); void -pspp_linreg_coeff_set_std_err (struct pspp_linreg_coeff *, - double std_err); +pspp_linreg_coeff_set_std_err (struct pspp_linreg_coeff *, double std_err); + +/* + Accessor functions for matching coefficients and variables. + */ + /* Return the estimated value of the coefficient. */ -double -pspp_linreg_coeff_get_est (const struct pspp_linreg_coeff *); +double pspp_linreg_coeff_get_est (const struct pspp_linreg_coeff *); /* Return the standard error of the estimated coefficient. */ -double -pspp_linreg_coeff_get_std_err (const struct pspp_linreg_coeff *); +double pspp_linreg_coeff_get_std_err (const struct pspp_linreg_coeff *); /* How many variables are associated with this coefficient? */ -int -pspp_linreg_coeff_get_n_vars (struct pspp_linreg_coeff *); +int pspp_linreg_coeff_get_n_vars (struct pspp_linreg_coeff *); /* - Which variable does this coefficient match? + Which variable does this coefficient match? The int argument is usually + 0, unless the coefficient refers to an interaction. */ -const struct variable * -pspp_linreg_coeff_get_var (struct pspp_linreg_coeff *, int ); - -/* - Which value is associated with this coefficient/variable comination? -*/ -const union value * -pspp_linreg_coeff_get_value (struct pspp_linreg_coeff *, - const struct variable *); - -const struct pspp_linreg_coeff * -pspp_linreg_get_coeff (const pspp_linreg_cache *, - const struct variable *, - const union value *); +const struct variable *pspp_linreg_coeff_get_var (struct pspp_linreg_coeff *, + int); +/* + Which value is associated with this coefficient/variable comination? + */ +const union value *pspp_linreg_coeff_get_value (struct pspp_linreg_coeff *, + const struct variable *); + +const struct pspp_linreg_coeff *pspp_linreg_get_coeff (const pspp_linreg_cache + *, + const struct variable + *, + const union value *); #endif diff --git a/src/math/linreg/linreg.c b/src/math/linreg/linreg.c index a5d09365..ab85e795 100644 --- a/src/math/linreg/linreg.c +++ b/src/math/linreg/linreg.c @@ -87,6 +87,53 @@ linreg_mean_std (gsl_vector_const_view v, double *mp, double *sp, double *ssp) return GSL_SUCCESS; } +/* + Set V to contain an array of pointers to the variables + used in the model. V must be at least C->N_COEFFS in length. + The return value is the number of distinct variables found. + */ +int +pspp_linreg_get_vars (const void *c_, struct variable **v) +{ + const pspp_linreg_cache *c = c_; + struct pspp_linreg_coeff *coef = NULL; + const struct variable *tmp; + int i; + int result = 0; + + /* + Make sure the caller doesn't try to sneak a variable + into V that is not in the model. + */ + for (i = 0; i < c->n_coeffs; i++) + { + v[i] = NULL; + } + /* + Start at c->coeff + 1 to avoid the intercept. + */ + v[result] = (struct variable *) pspp_linreg_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++) + { + tmp = pspp_linreg_coeff_get_var (coef, 0); + assert (tmp != NULL); + /* Repeated variables are likely to bunch together, at the end + of the array. */ + i = result - 1; + while (i >= 0 && (v[i]->index != tmp->index)) + { + i--; + } + if (i < 0 && result < c->n_coeffs) + { + v[result] = (struct variable *) tmp; + result++; + } + } + return result; +} /* Allocate a pspp_linreg_cache and return a pointer @@ -116,7 +163,11 @@ pspp_linreg_cache_alloc (size_t n, size_t p) */ c->method = PSPP_LINREG_SWEEP; c->predict = pspp_linreg_predict; - c->residual = pspp_linreg_residual; /* The procedure to comput my residuals. */ + c->residual = pspp_linreg_residual; /* The procedure to compute my + residuals. */ + c->get_vars = pspp_linreg_get_vars; /* The procedure that returns + pointers to model + variables. */ c->resid = NULL; /* The variable storing my residuals. */ c->pred = NULL; /* The variable storing my predicted values. */ diff --git a/src/math/linreg/linreg.h b/src/math/linreg/linreg.h index 7723187a..f0141f80 100644 --- a/src/math/linreg/linreg.h +++ b/src/math/linreg/linreg.h @@ -163,8 +163,13 @@ struct pspp_linreg_cache_struct const union value **, const union value *, const void *, int); + /* + Returns pointers to the variables used in the model. + */ + int (*get_vars) (const void *, struct variable **); struct variable *resid; struct variable *pred; + }; typedef struct pspp_linreg_cache_struct pspp_linreg_cache; @@ -195,4 +200,8 @@ pspp_linreg_predict (const struct variable **, const union value **, double pspp_linreg_residual (const struct variable **, const union value **, const union value *, const void *, int); +/* + All variables used in the model. + */ +int pspp_linreg_get_vars (const void *, struct variable **); #endif