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);
}
}
- 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;
}
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
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)
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);
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);
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);
}
}