From: John Darrington Date: Thu, 2 Apr 2009 23:10:28 +0000 (+0800) Subject: Merge branch 'master' of ssh://jmd@git.sv.gnu.org/srv/git/pspp X-Git-Tag: v0.7.3~176^2~8 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=07006e3b80d88f60f3a2af10a805d8bca847a0ef;hp=38df9bd0c6081ca904e2cd5f72d697c1db710be7;p=pspp-builds.git Merge branch 'master' of ssh://jmd@git.sv.gnu.org/srv/git/pspp --- diff --git a/Smake b/Smake index 84537ef0..4c8d83bc 100644 --- a/Smake +++ b/Smake @@ -16,6 +16,7 @@ GNULIB_MODULES = \ environ \ exit \ fatal-signal \ + fcntl \ fpieee \ fprintf-posix \ full-read \ diff --git a/doc/statistics.texi b/doc/statistics.texi index 311f5d7a..98556060 100644 --- a/doc/statistics.texi +++ b/doc/statistics.texi @@ -566,7 +566,7 @@ values. If more than two distinct, non-missing values for a variable under test are encountered then an error occurs. -If the test proportion is equal to 0.5, then a one tailed test is +If the test proportion is equal to 0.5, then a two tailed test is reported. For any other test proportion, a one tailed test is reported. For one tailed tests, if the test proportion is less than diff --git a/src/data/make-file.c b/src/data/make-file.c index 807adc50..2162741a 100644 --- a/src/data/make-file.c +++ b/src/data/make-file.c @@ -185,7 +185,7 @@ replace_file_start (const char *file_name, const char *mode, } /* Create file by that name. */ - fd = open (rf->tmp_name, O_WRONLY | O_CREAT | O_EXCL, permissions); + fd = open (rf->tmp_name, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, permissions); if (fd >= 0) break; if (errno != EEXIST) diff --git a/src/data/por-file-writer.c b/src/data/por-file-writer.c index 77396930..8de293c5 100644 --- a/src/data/por-file-writer.c +++ b/src/data/por-file-writer.c @@ -215,7 +215,8 @@ write_float (struct pfm_writer *w, double d) char buffer[64]; format_trig_double (d, floor (d) == d ? DBL_DIG : w->digits, buffer); buf_write (w, buffer, strlen (buffer)); - buf_write (w, "/", 1); + if (d != SYSMIS) + buf_write (w, "/", 1); } /* Write N to the portable file as an integer field. */ diff --git a/src/data/psql-reader.c b/src/data/psql-reader.c index a54b9f8b..be6d0a60 100644 --- a/src/data/psql-reader.c +++ b/src/data/psql-reader.c @@ -440,6 +440,10 @@ psql_open_reader (struct psql_read_info *info, struct dictionary **dict) break; } + if ( width == 0 && fmt_is_string (fmt.type)) + fmt.w = width = MAX_SHORT_STRING; + + var = create_var (r, &fmt, width, PQfname (qres, i), i); if ( type == NUMERICOID && n_tuples > 0) { diff --git a/src/math/covariance-matrix.c b/src/math/covariance-matrix.c index 82f4b447..95895eae 100644 --- a/src/math/covariance-matrix.c +++ b/src/math/covariance-matrix.c @@ -57,7 +57,7 @@ struct covariance_matrix { struct design_matrix *cov; struct design_matrix *ssize; - struct design_matrix *means; + struct design_matrix *sums; struct hsh_table *ca; struct moments1 **m1; struct moments **m; @@ -148,7 +148,25 @@ covariance_matrix_init (size_t n_variables, return result; } - +static size_t +get_n_rows (size_t n_variables, size_t *v_variables[]) +{ + size_t i; + size_t result = 0; + for (i = 0; i < n_variables; i++) + { + if (var_is_numeric (v_variables[i])) + { + result++; + } + else if (var_is_alpha (v_variables[i])) + { + size_t n_categories = cat_get_n_categories (v_variables[i]); + result += n_categories - 1; + } + } + return result; +} /* The covariances are stored in a DESIGN_MATRIX structure. */ @@ -156,8 +174,8 @@ struct design_matrix * covariance_matrix_create (size_t n_variables, const struct variable *v_variables[]) { - return design_matrix_create (n_variables, v_variables, - (size_t) n_variables); + size_t n_rows = get_n_rows (n_variables, v_variables); + return design_matrix_create (n_variables, v_variables, n_rows); } static void @@ -182,7 +200,7 @@ covariance_matrix_destroy (struct covariance_matrix *cov) assert (cov != NULL); design_matrix_destroy (cov->cov); design_matrix_destroy (cov->ssize); - design_matrix_destroy (cov->means); + design_matrix_destroy (cov->sums); hsh_destroy (cov->ca); if (cov->n_pass == ONE_PASS) { @@ -219,9 +237,9 @@ covariance_update_categorical_numeric (struct design_matrix *cov, double mean, col = design_matrix_var_to_column (cov, v2); assert (val2 != NULL); - tmp = gsl_matrix_get (cov->m, row, col); - gsl_matrix_set (cov->m, row, col, (val2->f - mean) * x + tmp); - gsl_matrix_set (cov->m, col, row, (val2->f - mean) * x + tmp); + tmp = design_matrix_get_element (cov, row, col); + design_matrix_set_element (cov, row, col, (val2->f - mean) * x + tmp); + design_matrix_set_element (cov, col, row, (val2->f - mean) * x + tmp); } static void column_iterate (struct design_matrix *cov, const struct variable *v, @@ -243,9 +261,9 @@ column_iterate (struct design_matrix *cov, const struct variable *v, { y += -1.0; } - tmp = gsl_matrix_get (cov->m, row, col); - gsl_matrix_set (cov->m, row, col, x * y + tmp); - gsl_matrix_set (cov->m, col, row, x * y + tmp); + tmp = design_matrix_get_element (cov, row, col); + design_matrix_set_element (cov, row, col, x * y + tmp); + design_matrix_set_element (cov, col, row, x * y + tmp); } } @@ -306,9 +324,9 @@ covariance_pass_two (struct design_matrix *cov, double mean1, double mean2, row = design_matrix_var_to_column (cov, v1); col = design_matrix_var_to_column (cov, v2); x = (val1->f - mean1) * (val2->f - mean2); - x += gsl_matrix_get (cov->m, col, row); - gsl_matrix_set (cov->m, row, col, x); - gsl_matrix_set (cov->m, col, row, x); + x += design_matrix_get_element (cov, col, row); + design_matrix_set_element (cov, row, col, x); + design_matrix_set_element (cov, col, row, x); } } @@ -778,7 +796,7 @@ covariance_matrix_insert (struct design_matrix *cov, col = get_exact_subscript (cov, v2, val2); if (row != -1u && col != -1u) { - gsl_matrix_set (cov->m, row, col, product); + design_matrix_set_element (cov, row, col, product); } } @@ -853,9 +871,9 @@ update_ssize (struct design_matrix *dm, size_t i, size_t j, struct covariance_ac var = design_matrix_col_to_var (dm, j); if (var_get_dict_index (ca->v2) == var_get_dict_index (var)) { - tmp = gsl_matrix_get (dm->m, i, j); + tmp = design_matrix_get_element (dm, i, j); tmp += ca->ssize; - gsl_matrix_set (dm->m, i, j, tmp); + design_matrix_set_element (dm, i, j, tmp); } } } @@ -872,7 +890,7 @@ covariance_accumulator_to_matrix (struct covariance_matrix *cov) cov->cov = covariance_matrix_create (cov->n_variables, cov->v_variables); cov->ssize = covariance_matrix_create (cov->n_variables, cov->v_variables); - cov->means = covariance_matrix_create (cov->n_variables, cov->v_variables); + cov->sums = covariance_matrix_create (cov->n_variables, cov->v_variables); for (i = 0; i < design_matrix_get_n_cols (cov->cov); i++) { sum_i = get_sum (cov, i); @@ -880,7 +898,7 @@ covariance_accumulator_to_matrix (struct covariance_matrix *cov) { sum_j = get_sum (cov, j); entry = hsh_first (cov->ca, &iter); - + design_matrix_set_element (cov->sums, i, j, sum_i); while (entry != NULL) { update_ssize (cov->ssize, i, j, entry); @@ -889,16 +907,14 @@ covariance_accumulator_to_matrix (struct covariance_matrix *cov) */ if (is_covariance_contributor (entry, cov->cov, i, j)) { - covariance_matrix_insert (cov->cov, entry->v1, entry->v2, entry->val1, entry->val2, entry->dot_product); } entry = hsh_next (cov->ca, &iter); } - tmp = gsl_matrix_get (cov->cov->m, i, j); - tmp -= gsl_matrix_get (cov->means->m, i, j) / gsl_matrix_get (cov->ssize->m, i, j); - gsl_matrix_set (cov->cov->m, i, j, tmp); - + tmp = design_matrix_get_element (cov->cov, i, j); + tmp -= sum_i * sum_j / design_matrix_get_element (cov->ssize, i, j); + design_matrix_set_element (cov->cov, i, j, tmp); } } } @@ -925,3 +941,10 @@ covariance_to_design (const struct covariance_matrix *c) } return NULL; } + +double +covariance_matrix_get_element (const struct covariance_matrix *c, size_t row, size_t col) +{ + return (design_matrix_get_element (c->cov, row, col)); +} + diff --git a/src/math/covariance-matrix.h b/src/math/covariance-matrix.h index b692e7e8..24ce791c 100644 --- a/src/math/covariance-matrix.h +++ b/src/math/covariance-matrix.h @@ -56,4 +56,5 @@ void covariance_matrix_free (struct covariance_matrix *); void covariance_matrix_accumulate (struct covariance_matrix *, const struct ccase *, void **, size_t); struct design_matrix *covariance_to_design (const struct covariance_matrix *); +double covariance_matrix_get_element (const struct covariance_matrix *, size_t, size_t); #endif diff --git a/src/math/design-matrix.c b/src/math/design-matrix.c index 8195a408..b81859aa 100644 --- a/src/math/design-matrix.c +++ b/src/math/design-matrix.c @@ -270,4 +270,14 @@ design_matrix_get_n_rows (const struct design_matrix *d) return d->m->size1; } +double +design_matrix_get_element (const struct design_matrix *d, size_t row, size_t col) +{ + return (gsl_matrix_get (d->m, row, col)); +} +void +design_matrix_set_element (const struct design_matrix *d, size_t row, size_t col, double x) +{ + gsl_matrix_set (d->m, row, col, x); +} diff --git a/src/math/design-matrix.h b/src/math/design-matrix.h index 5250b490..45814580 100644 --- a/src/math/design-matrix.h +++ b/src/math/design-matrix.h @@ -92,4 +92,6 @@ void design_matrix_set_case_count (struct design_matrix *, const struct variable size_t design_matrix_get_case_count (const struct design_matrix *, const struct variable *); size_t design_matrix_get_n_cols (const struct design_matrix *); size_t design_matrix_get_n_rows (const struct design_matrix *); +double design_matrix_get_element (const struct design_matrix *, size_t, size_t); +void design_matrix_set_element (const struct design_matrix *, size_t, size_t, double); #endif diff --git a/tests/command/get-data-psql.sh b/tests/command/get-data-psql.sh index fa61d6d6..1d8afada 100755 --- a/tests/command/get-data-psql.sh +++ b/tests/command/get-data-psql.sh @@ -427,4 +427,44 @@ diff -b $TEMPDIR/pspp.list - << 'EOF' EOF if [ $? -ne 0 ] ; then fail ; fi + + +# Check for a bug caused by having string variables in the database, +# all of which are null. + +activity="populate database 4" +$pgpath/psql -h $TEMPDIR -p $port $dbase > /dev/null << EOF + +-- a table which has a text field containing only null, or zero +-- length entries. + +CREATE TABLE foo (int4 int4, text text); + +INSERT INTO foo VALUES ('12', ''); + +INSERT INTO foo VALUES (null, ''); + +EOF +if [ $? -ne 0 ] ; then fail ; fi + + +activity="create program 4" +cat > $TESTFILE < $TESTFILE <