From: Ben Pfaff Date: Mon, 27 Sep 2021 02:26:14 +0000 (-0700) Subject: some more mconvert X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3e1e3dc5be78ea1a0987e24c241a845e42eae100;p=pspp some more mconvert --- diff --git a/src/language/data-io/matrix-reader.c b/src/language/data-io/matrix-reader.c index a1ef1e2331..c2d06a071d 100644 --- a/src/language/data-io/matrix-reader.c +++ b/src/language/data-io/matrix-reader.c @@ -119,6 +119,15 @@ matrix_reader_create (const struct dictionary *dict, if (!varname || !rowtype) return NULL; + size_t varname_idx = var_get_dict_index (varname); + size_t rowtype_idx = var_get_dict_index (rowtype); + if (varname_idx < rowtype_idx) + { + msg (ME, _("Variable %s must precede %s in matrix file dictionary."), + "ROWTYPE_", "VARNAME_"); + return NULL; + } + for (size_t i = 0; i < dict_get_var_cnt (dict); i++) { const struct variable *v = dict_get_var (dict, i); @@ -130,32 +139,38 @@ matrix_reader_create (const struct dictionary *dict, } } - size_t dvarcnt; - const struct variable **dvars = NULL; - dict_get_vars (dict, &dvars, &dvarcnt, DC_SCRATCH); - - /* Continuous variables and split variables. */ - const struct variable **cvars = dvars + var_get_dict_index (varname) + 1; - size_t n_cvars = dvarcnt - var_get_dict_index (varname) - 1; - const struct variable **svars = dvars; - size_t n_svars = var_get_dict_index (rowtype); + size_t n_vars; + const struct variable **vars; + dict_get_vars (dict, &vars, &n_vars, DC_SCRATCH); + + /* Different kinds of variables. */ + size_t first_svar = 0; + size_t n_svars = rowtype_idx; + size_t first_fvar = rowtype_idx + 1; + size_t n_fvars = varname_idx - rowtype_idx - 1; + size_t first_cvar = varname_idx + 1; + size_t n_cvars = n_vars - varname_idx - 1; if (!n_cvars) { msg (ME, _("Matrix dataset does not have any continuous variables.")); - free (dvars); + free (vars); return NULL; } struct matrix_reader *mr = xmalloc (sizeof *mr); *mr = (struct matrix_reader) { - .n_cvars = n_cvars, - .cvars = xmemdup (cvars, n_cvars * sizeof *cvars), + .dict = dict, + .grouper = casegrouper_create_vars (in_reader, &vars[first_svar], n_svars), + .svars = xmemdup (vars + first_svar, n_svars * sizeof *mr->svars), + .n_svars = n_svars, .rowtype = rowtype, + .fvars = xmemdup (vars + first_fvar, n_fvars * sizeof *mr->fvars), + .n_fvars = n_fvars, .varname = varname, - .dict = dict, - .grouper = casegrouper_create_vars (in_reader, svars, n_svars) + .cvars = xmemdup (vars + first_cvar, n_cvars * sizeof *mr->cvars), + .n_cvars = n_cvars, }; - free (dvars); + free (vars); return mr; } diff --git a/src/language/data-io/matrix-reader.h b/src/language/data-io/matrix-reader.h index a0e0bb8ea2..5aec05e009 100644 --- a/src/language/data-io/matrix-reader.h +++ b/src/language/data-io/matrix-reader.h @@ -32,10 +32,14 @@ struct matrix_reader struct casegrouper *grouper; /* Variables in 'dict'. */ - const struct variable **cvars; /* Continuous variables. */ - size_t n_cvars; + const struct variable **svars; /* Split variables. */ + size_t n_svars; const struct variable *rowtype; /* ROWTYPE_. */ + const struct variable **fvars; /* Factor variables. */ + size_t n_fvars; const struct variable *varname; /* VARNAME_. */ + const struct variable **cvars; /* Continuous variables. */ + size_t n_cvars; }; struct matrix_material diff --git a/src/language/data-io/mconvert.c b/src/language/data-io/mconvert.c index 78a0d212d9..1e24464709 100644 --- a/src/language/data-io/mconvert.c +++ b/src/language/data-io/mconvert.c @@ -35,7 +35,7 @@ int cmd_mconvert (struct lexer *lexer, struct dataset *ds) { - bool append UNUSED = false; + bool append = false; struct file_handle *in = NULL; struct file_handle *out = NULL; while (lex_token (lexer) != T_ENDCMD) @@ -116,28 +116,31 @@ cmd_mconvert (struct lexer *lexer, struct dataset *ds) if (!matrix_reader_next (&mm, mr, &group)) break; - struct ccase *model = NULL; + bool add_corr = mm.cov && !mm.corr; + bool add_cov = mm.corr && !mm.cov; + bool remove_corr = add_cov && !append; + bool remove_cov = add_corr && !append; + + struct ccase *model = casereader_peek (group, 0); + for (size_t i = 0; i < mr->n_fvars; i++) + *case_num_rw (model, mr->fvars[i]) = SYSMIS; + for (;;) { struct ccase *c = casereader_read (group); if (!c) break; - if (!model) - { - struct substring rowtype - = matrix_reader_get_string (c, mr->rowtype); - if (ss_equals_case (rowtype, ss_cstr ("COV")) - || ss_equals_case (rowtype, ss_cstr ("CORR"))) - model = case_ref (c); - } - casewriter_write (cw, c); + struct substring rowtype = matrix_reader_get_string (c, mr->rowtype); + if ((remove_cov && ss_equals_case (rowtype, ss_cstr ("COV"))) + || (remove_corr && ss_equals_case (rowtype, ss_cstr ("CORR")))) + case_unref (c); + else + casewriter_write (cw, c); } + casereader_destroy (group); - if (!model) - continue; - - if (mm.cov && !mm.corr) + if (add_corr) { assert (mm.cov->size1 == mr->n_cvars); assert (mm.cov->size2 == mr->n_cvars); @@ -169,7 +172,7 @@ cmd_mconvert (struct lexer *lexer, struct dataset *ds) casewriter_write (cw, c); } - if (mm.corr && !mm.cov) + if (add_cov) { assert (mm.corr->size1 == mr->n_cvars); assert (mm.corr->size2 == mr->n_cvars); @@ -184,6 +187,9 @@ cmd_mconvert (struct lexer *lexer, struct dataset *ds) double corr = gsl_matrix_get (mm.corr, y, x); *case_num_rw (c, mr->cvars[x]) = corr * sqrt (d1 * d2); } + matrix_reader_set_string (c, mr->rowtype, ss_cstr ("COV")); + matrix_reader_set_string (c, mr->varname, + ss_cstr (var_get_name (mr->cvars[y]))); casewriter_write (cw, c); } }