X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fmath%2Fcoefficient.c;h=f78895f8214e4b70b89668477ac1dfe1abc98fe2;hb=5c3291dc396b795696e94f47780308fd7ace6fc4;hp=f5d0eb56a52697b52f9e735fc1287ddc5fc994da;hpb=c21a0f82e238fe80b61d8ab00e21ec32c753ca2f;p=pspp-builds.git diff --git a/src/math/coefficient.c b/src/math/coefficient.c index f5d0eb56..f78895f8 100644 --- a/src/math/coefficient.c +++ b/src/math/coefficient.c @@ -1,28 +1,24 @@ -/* - 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. -*/ +/* PSPP - a program for statistical analysis. + Copyright (C) 2005, 2009 Free Software Foundation, Inc. + + 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 3 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, see . */ /* Accessor functions for matching coefficients and variables. */ +#include #include -#include #include "src/math/design-matrix.h" #include @@ -39,10 +35,12 @@ struct varinfo const union value *val; /* Value of the variable v which this varinfo refers to. This member is relevant only to categorical variables. */ + double mean; /* Mean for this variable */ + double sd; /* Standard deviation for this variable */ }; void -pspp_linreg_coeff_free (struct pspp_linreg_coeff *c) +pspp_coeff_free (struct pspp_coeff *c) { free (c->v_info); free (c); @@ -50,94 +48,89 @@ pspp_linreg_coeff_free (struct pspp_linreg_coeff *c) /* Initialize the variable and value pointers inside the - coefficient structures for the linear model. + coefficient structures for the model. */ void -pspp_linreg_coeff_init (pspp_linreg_cache * c, struct design_matrix *X) +pspp_coeff_init (struct pspp_coeff ** coeff, const struct design_matrix *X) { size_t i; - size_t j; int n_vals = 1; - struct pspp_linreg_coeff *coeff; - c->coeff = xnmalloc (X->m->size2 + 1, sizeof (*c->coeff)); - c->coeff[0] = xmalloc (sizeof (*c->coeff[0])); - c->coeff[0]->v_info = NULL; /* Intercept has no associated variable. */ + assert (coeff != NULL); for (i = 0; i < X->m->size2; i++) { - j = i + 1; /* The first coefficient is the intercept. */ - c->coeff[j] = xmalloc (sizeof (*c->coeff[j])); - coeff = c->coeff[j]; - coeff->n_vars = n_vals; /* Currently, no procedures allow - interactions. This line will have to - change when procedures that allow - interaction terms are written. - */ - coeff->v_info = xnmalloc (coeff->n_vars, sizeof (*coeff->v_info)); - assert (coeff->v_info != NULL); - coeff->v_info->v = - (const struct variable *) design_matrix_col_to_var (X, i); - - if (coeff->v_info->v->type == ALPHA) + coeff[i] = xmalloc (sizeof (*coeff[i])); + coeff[i]->n_vars = n_vals; /* Currently, no procedures allow + interactions. This line will have to + change when procedures that allow + interaction terms are written. + */ + coeff[i]->v_info = xnmalloc (coeff[i]->n_vars, sizeof (*coeff[i]->v_info)); + assert (coeff[i]->v_info != NULL); + coeff[i]->v_info->v = design_matrix_col_to_var (X, i); + + if (var_is_alpha (coeff[i]->v_info->v)) { size_t k; - k = design_matrix_var_to_column (X, coeff->v_info->v); + k = design_matrix_var_to_column (X, coeff[i]->v_info->v); assert (k <= i); k = i - k; - coeff->v_info->val = - cat_subscript_to_value (k, (struct variable *) coeff->v_info->v); + coeff[i]->v_info->val = + cat_subscript_to_value (k, coeff[i]->v_info->v); } + coeff[i]->v_info->mean = 0.0; + coeff[i]->v_info->sd = 0.0; } } void -pspp_linreg_coeff_set_estimate (struct pspp_linreg_coeff *c, double estimate) +pspp_coeff_set_estimate (struct pspp_coeff *coef, double estimate) { - c->estimate = estimate; + coef->estimate = estimate; } void -pspp_linreg_coeff_set_std_err (struct pspp_linreg_coeff *c, double std_err) +pspp_coeff_set_std_err (struct pspp_coeff *coef, double std_err) { - c->std_err = std_err; + coef->std_err = std_err; } /* Return the estimated value of the coefficient. */ double -pspp_linreg_coeff_get_est (const struct pspp_linreg_coeff *c) +pspp_coeff_get_est (const struct pspp_coeff *coef) { - if (c == NULL) + if (coef == NULL) { return 0.0; } - return c->estimate; + return coef->estimate; } /* Return the standard error of the estimated coefficient. */ double -pspp_linreg_coeff_get_std_err (const struct pspp_linreg_coeff *c) +pspp_coeff_get_std_err (const struct pspp_coeff *coef) { - if (c == NULL) + if (coef == NULL) { return 0.0; } - return c->std_err; + return coef->std_err; } /* How many variables are associated with this coefficient? */ int -pspp_linreg_coeff_get_n_vars (struct pspp_linreg_coeff *c) +pspp_coeff_get_n_vars (struct pspp_coeff *coef) { - if (c == NULL) + if (coef == NULL) { return 0; } - return c->n_vars; + return coef->n_vars; } /* @@ -145,40 +138,93 @@ pspp_linreg_coeff_get_n_vars (struct pspp_linreg_coeff *c) 0 unless the coefficient refers to an interaction term. */ const struct variable * -pspp_linreg_coeff_get_var (struct pspp_linreg_coeff *c, int i) +pspp_coeff_get_var (struct pspp_coeff *coef, int i) { - if (c == NULL) + if (coef == NULL) { return NULL; } - assert (i < c->n_vars); - return (c->v_info + i)->v; + assert (i < coef->n_vars); + return (coef->v_info + i)->v; +} + +/* + Which coefficient does this variable match? If the variable is + categorical, and has more than one coefficient, use the VAL to find + its coefficient. + */ +struct pspp_coeff * +pspp_coeff_var_to_coeff (const struct variable *v, struct pspp_coeff **coefs, + size_t n_coef, const union value *val) +{ + size_t i = 0; + size_t j = 0; + size_t v_idx; + + struct pspp_coeff *result = NULL; + + if (v != NULL) + { + v_idx = var_get_dict_index (v); + while (i < n_coef) + { + if (coefs[i]->v_info != NULL) + { + if (var_get_dict_index (coefs[i]->v_info->v) == v_idx) + { + break; + } + } + i++; + } + result = coefs[i]; + if (var_is_alpha (v)) + { + /* + Use the VAL to find the coefficient. + */ + if (val != NULL) + { + int width = var_get_width (v); + + j = i; + while (j < n_coef + && value_compare_3way (pspp_coeff_get_value (coefs[j], v), + val, width) != 0) + { + j++; + } + result = ((j < n_coef) ? coefs[j] : NULL); + } + } + } + return result; } /* Which value is associated with this coefficient/variable combination? */ const union value * -pspp_linreg_coeff_get_value (struct pspp_linreg_coeff *c, +pspp_coeff_get_value (struct pspp_coeff *coef, const struct variable *v) { int i = 0; const struct variable *candidate; - if (c == NULL || v == NULL) + if (coef == NULL || v == NULL) { return NULL; } - if (v->type == NUMERIC) + if (var_is_numeric (v)) { return NULL; } - while (i < c->n_vars) + while (i < coef->n_vars) { - candidate = pspp_linreg_coeff_get_var (c, i); - if (v->index == candidate->index) + candidate = pspp_coeff_get_var (coef, i); + if (v == candidate) { - return (c->v_info + i)->val; + return (coef->v_info + i)->val; } i++; } @@ -186,61 +232,27 @@ pspp_linreg_coeff_get_value (struct pspp_linreg_coeff *c, } /* - Which coefficient is associated with V? The VAL argument is relevant - only to categorical variables. + Get or set the standard deviation of the variable associated with this coefficient. */ -const struct pspp_linreg_coeff * -pspp_linreg_get_coeff (const pspp_linreg_cache * c, - const struct variable *v, const union value *val) +double pspp_coeff_get_sd (const struct pspp_coeff *coef) +{ + return coef->v_info->sd; +} +void pspp_coeff_set_sd (struct pspp_coeff *coef, double s) { - int i = 1; - struct pspp_linreg_coeff *result = NULL; - const struct variable *tmp = NULL; + coef->v_info->sd = s; +} - if (c == NULL) - { - return NULL; - } - if (c->coeff == NULL || c->n_indeps == 0 || v == NULL) - { - return NULL; - } +/* + Get or set the mean for the variable associated with this coefficient. +*/ +double pspp_coeff_get_mean (const struct pspp_coeff *coef) +{ + return coef->v_info->mean; +} - result = c->coeff[i]; - tmp = pspp_linreg_coeff_get_var (result, 0); - while (tmp->index != v->index && i < c->n_coeffs) - { - result = c->coeff[i]; - tmp = pspp_linreg_coeff_get_var (result, 0); - i++; - } - if (i > c->n_coeffs) - { - return NULL; - } - if (v->type == NUMERIC) - { - return result; - } - else if (val != NULL) - { - /* - If v is categorical, we need to ensure the coefficient - matches the VAL. - */ - while (tmp->index != v->index && i < c->n_coeffs - && compare_values (pspp_linreg_coeff_get_value (result, tmp), - val, v->width)) - { /* FIX THIS */ - i++; - result = c->coeff[i]; - tmp = pspp_linreg_coeff_get_var (result, 0); - } - if (i == c->n_coeffs) - { - return NULL; - } - return result; - } - return NULL; +void pspp_coeff_set_mean (struct pspp_coeff *coef, double m) +{ + coef->v_info->mean = m; } +