X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fdata-io%2Fmatrix-reader.c;h=963f4a24f152a1227955a5a58159bf196c730775;hb=a49b940e58f148bf111c647d9b4822025636ff80;hp=861937d32c7b4da4a81dbbe21331bd270b7fed99;hpb=beecfe79e792dcd2525ec2d839b887dd291c1acf;p=pspp diff --git a/src/language/data-io/matrix-reader.c b/src/language/data-io/matrix-reader.c index 861937d32c..963f4a24f1 100644 --- a/src/language/data-io/matrix-reader.c +++ b/src/language/data-io/matrix-reader.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2017 Free Software Foundation, Inc. + Copyright (C) 2017, 2019 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 @@ -20,12 +20,14 @@ #include -#include #include +#include #include #include #include #include +#include +#include #include "gettext.h" #define _(msgid) gettext (msgid) @@ -85,9 +87,6 @@ struct matrix_reader gsl_matrix *n_vectors; gsl_matrix *mean_vectors; gsl_matrix *var_vectors; - - // gsl_matrix *correlation; - // gsl_matrix *covariance; }; struct matrix_reader * @@ -96,8 +95,8 @@ create_matrix_reader_from_case_reader (const struct dictionary *dict, struct cas { struct matrix_reader *mr = xzalloc (sizeof *mr); - mr->dict = dict; mr->varname = dict_lookup_var (dict, "varname_"); + mr->dict = dict; if (mr->varname == NULL) { msg (ME, _("Matrix dataset lacks a variable called %s."), "VARNAME_"); @@ -105,6 +104,14 @@ create_matrix_reader_from_case_reader (const struct dictionary *dict, struct cas return NULL; } + if (!var_is_alpha (mr->varname)) + { + msg (ME, _("Matrix dataset variable %s should be of string type."), + "VARNAME_"); + free (mr); + return NULL; + } + mr->rowtype = dict_lookup_var (dict, "rowtype_"); if (mr->rowtype == NULL) { @@ -113,6 +120,14 @@ create_matrix_reader_from_case_reader (const struct dictionary *dict, struct cas return NULL; } + if (!var_is_alpha (mr->rowtype)) + { + msg (ME, _("Matrix dataset variable %s should be of string type."), + "ROWTYPE_"); + free (mr); + return NULL; + } + size_t dvarcnt; const struct variable **dvars = NULL; dict_get_vars (dict, &dvars, &dvarcnt, DC_SCRATCH); @@ -198,63 +213,62 @@ next_matrix_from_reader (struct matrix_material *mm, mm->mean_matrix = mr->mean_vectors; mm->var_matrix = mr->var_vectors; - // FIXME: Make this into a hash table. - unsigned long *table = xmalloc (sizeof (*table) * n_vars); - int i; - for (i = 0; i < n_vars; ++i) + struct substring *var_names = xcalloc (n_vars, sizeof *var_names); + for (int i = 0; i < n_vars; ++i) { - const int w = var_get_width (mr->varname); - char s[w]; - memset (s, 0, w); - const char *name = var_get_name (vars[i]); - strcpy (s, name); - unsigned long h = hash_bytes (s, w, 0); - table[i] = h; + ss_alloc_substring (var_names + i, ss_cstr (var_get_name (vars[i]))); } struct ccase *c; for ( ; (c = casereader_read (group) ); case_unref (c)) { - const union value *uv = case_data (c, mr->rowtype); + const union value *uv = case_data (c, mr->rowtype); + const char *row_type = CHAR_CAST (const char *, uv->s); int col, row; for (col = 0; col < n_vars; ++col) { const struct variable *cv = vars[col]; double x = case_data (c, cv)->f; - if (0 == strncasecmp ((char *)value_str (uv, 8), "N ", 8)) + if (0 == strncasecmp (row_type, "N ", 8)) for (row = 0; row < n_vars; ++row) gsl_matrix_set (mr->n_vectors, row, col, x); - else if (0 == strncasecmp ((char *) value_str (uv, 8), "MEAN ", 8)) + else if (0 == strncasecmp (row_type, "MEAN ", 8)) for (row = 0; row < n_vars; ++row) gsl_matrix_set (mr->mean_vectors, row, col, x); - else if (0 == strncasecmp ((char *) value_str (uv, 8), "STDDEV ", 8)) + else if (0 == strncasecmp (row_type, "STDDEV ", 8)) for (row = 0; row < n_vars; ++row) gsl_matrix_set (mr->var_vectors, row, col, x * x); } + const char *enc = dict_get_encoding (mr->dict); + const union value *uvv = case_data (c, mr->varname); - const uint8_t *vs = value_str (uvv, var_get_width (mr->varname)); int w = var_get_width (mr->varname); - unsigned long h = hash_bytes (vs, w, 0); + + struct fmt_spec fmt = {FMT_A, 0, 0}; + fmt.w = w; + char *vname = data_out (uvv, enc, &fmt); + struct substring the_name = ss_cstr (vname); int mrow = -1; - for (i = 0; i < n_vars; ++i) + for (int i = 0; i < n_vars; ++i) { - if (table[i] == h) + if (ss_equals (var_names[i], the_name)) { mrow = i; break; } } + free (vname); if (mrow == -1) continue; - if (0 == strncasecmp ((char *) value_str (uv, 8), "CORR ", 8)) + if (0 == strncasecmp (row_type, "CORR ", 8)) { matrix_fill_row (&mm->corr, c, mrow, vars, n_vars); } - else if (0 == strncasecmp ((char *) value_str (uv, 8), "COV ", 8)) + else if (0 == strncasecmp (row_type, "COV ", 8)) { matrix_fill_row (&mm->cov, c, mrow, vars, n_vars); } @@ -262,7 +276,9 @@ next_matrix_from_reader (struct matrix_material *mm, casereader_destroy (group); - free (table); + for (int i = 0; i < n_vars; ++i) + ss_dealloc (var_names + i); + free (var_names); return true; }