more mconvert
authorBen Pfaff <blp@cs.stanford.edu>
Mon, 27 Sep 2021 04:12:44 +0000 (21:12 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Mon, 27 Sep 2021 04:12:44 +0000 (21:12 -0700)
src/language/data-io/matrix-reader.c
src/language/data-io/mconvert.c
src/language/stats/factor.c
tests/language/data-io/matrix-data.at

index c2d06a071dac88cf276657b63591c1321ed2cb17..44ea5b18a88c8929011a4e37947a99725bf128b5 100644 (file)
@@ -259,11 +259,7 @@ matrix_reader_next (struct matrix_material *mm, struct matrix_reader *mr,
   const struct variable **vars = mr->cvars;
   size_t n_vars = mr->n_cvars;
 
-  *mm = (struct matrix_material) {
-    .n = gsl_matrix_calloc (n_vars, n_vars),
-    .mean_matrix = gsl_matrix_calloc (n_vars, n_vars),
-    .var_matrix = gsl_matrix_calloc (n_vars, n_vars),
-  };
+  *mm = (struct matrix_material) { .n = NULL };
 
   struct matrix
     {
@@ -283,20 +279,23 @@ matrix_reader_next (struct matrix_material *mm, struct matrix_reader *mr,
     {
       struct substring rowtype = matrix_reader_get_string (c, mr->rowtype);
 
-      gsl_matrix *v
-        = (ss_equals_case (rowtype, ss_cstr ("N")) ? mm->n
-           : ss_equals_case (rowtype, ss_cstr ("MEAN")) ? mm->mean_matrix
-           : ss_equals_case (rowtype, ss_cstr ("STDDEV")) ? mm->var_matrix
+      gsl_matrix **v
+        = (ss_equals_case (rowtype, ss_cstr ("N")) ? &mm->n
+           : ss_equals_case (rowtype, ss_cstr ("MEAN")) ? &mm->mean_matrix
+           : ss_equals_case (rowtype, ss_cstr ("STDDEV")) ? &mm->var_matrix
            : NULL);
       if (v)
         {
+          if (!*v)
+            *v = gsl_matrix_calloc (n_vars, n_vars);
+
           for (int x = 0; x < n_vars; ++x)
             {
               double n = case_num (c, vars[x]);
-              if (v == mm->var_matrix)
+              if (v == &mm->var_matrix)
                 n *= n;
               for (int y = 0; y < n_vars; ++y)
-                gsl_matrix_set (v, y, x, n);
+                gsl_matrix_set (*v, y, x, n);
             }
           continue;
         }
index 1e24464709e09195b88b8dcb15f7445b471df60b..f15ad9be77983bf91600d9e0c349b2e523b2989a 100644 (file)
@@ -117,7 +117,8 @@ cmd_mconvert (struct lexer *lexer, struct dataset *ds)
         break;
 
       bool add_corr = mm.cov && !mm.corr;
-      bool add_cov = mm.corr && !mm.cov;
+      bool add_cov = mm.corr && !mm.cov && mm.var_matrix;
+      bool add_stddev = add_corr && !mm.var_matrix;
       bool remove_corr = add_cov && !append;
       bool remove_cov = add_corr && !append;
 
@@ -142,9 +143,6 @@ cmd_mconvert (struct lexer *lexer, struct dataset *ds)
 
       if (add_corr)
         {
-          assert (mm.cov->size1 == mr->n_cvars);
-          assert (mm.cov->size2 == mr->n_cvars);
-
           for (size_t y = 0; y < mr->n_cvars; y++)
             {
               struct ccase *c = case_clone (model);
@@ -160,7 +158,10 @@ cmd_mconvert (struct lexer *lexer, struct dataset *ds)
                                         ss_cstr (var_get_name (mr->cvars[y])));
               casewriter_write (cw, c);
             }
+        }
 
+      if (add_stddev)
+        {
           struct ccase *c = case_clone (model);
           for (size_t x = 0; x < mr->n_cvars; x++)
             {
@@ -174,9 +175,6 @@ cmd_mconvert (struct lexer *lexer, struct dataset *ds)
 
       if (add_cov)
         {
-          assert (mm.corr->size1 == mr->n_cvars);
-          assert (mm.corr->size2 == mr->n_cvars);
-
           for (size_t y = 0; y < mr->n_cvars; y++)
             {
               struct ccase *c = case_clone (model);
index 09de685eede7850754fa5465bd5a15dd682de7bb..4feece0da0b813018f63a36a3eb947f7214b0723 100644 (file)
@@ -1178,6 +1178,13 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
           free (factor.vars);
           factor.vars = vars;
           factor.n_vars = n_vars;
+
+          if (mr)
+            {
+              free (mr->cvars);
+              mr->cvars = xmemdup (vars, n_vars * sizeof *vars);
+              mr->n_cvars = n_vars;
+            }
         }
       else if (lex_match_id (lexer, "PLOT"))
        {
@@ -2004,9 +2011,10 @@ do_factor (const struct cmd_factor *factor, struct casereader *r)
 static void
 do_factor_by_matrix (const struct cmd_factor *factor, struct idata *idata)
 {
-  if (!idata->mm.cov && !idata->mm.corr)
+  if (!idata->mm.cov && !(idata->mm.corr && idata->mm.var_matrix))
     {
-      msg (ME, _("The dataset has no complete covariance or correlation matrix."));
+      msg (ME, _("The dataset has no covariance matrix or a "
+                 "correlation matrix along with standard devications."));
       return;
     }
 
@@ -2054,7 +2062,8 @@ do_factor_by_matrix (const struct cmd_factor *factor, struct idata *idata)
       gsl_matrix_free (tmp);
     }
 
-  if (factor->print & PRINT_UNIVARIATE)
+  if (factor->print & PRINT_UNIVARIATE
+      && idata->mm.n && idata->mm.mean_matrix && idata->mm.var_matrix)
     {
       struct pivot_table *table = pivot_table_create (
         N_("Descriptive Statistics"));
@@ -2088,7 +2097,7 @@ do_factor_by_matrix (const struct cmd_factor *factor, struct idata *idata)
       pivot_table_submit (table);
     }
 
-  if (factor->print & PRINT_KMO)
+  if (factor->print & PRINT_KMO && idata->mm.n)
     {
       struct pivot_table *table = pivot_table_create (
         N_("KMO and Bartlett's Test"));
index e66d1aaa16aa22189810f129ddc9b1d6d70f51e7..3c69db6cd4e3bc1d8369fa12a31c74dd32065601 100644 (file)
@@ -561,7 +561,6 @@ Table: Debug Matrix Reader
 ,,var08,81.000,82.000,83.000,84.000,85.000,86.000,87.000,88.000,89.000
 ,,var09,91.000,92.000,93.000,94.000,95.000,96.000,97.000,98.000,99.000
 ,N,Value,1.000,2.000,3.000,4.000,5.000,6.000,7.000,8.000,9.000
-,Mean,Value,.000,.000,.000,.000,.000,.000,.000,.000,.000
 ,Standard Deviation,Value,100.000,200.000,300.000,400.000,500.000,600.000,700.000,800.000,900.000
 
 Table: Data List
@@ -718,7 +717,6 @@ Table: Debug Matrix Reader
 ,,v4xxxxxxxxxxxxxxxxxxxxxzzzzzzzzzzzzzxxxxxxxxx,.   ,.   ,.   ,.   @&t@
 ,N,Value,2.000,3.000,4.000,5.000
 ,Mean,Value,1.000,2.000,3.000,4.000
-,Standard Deviation,Value,.000,.000,.000,.000
 ])
 AT_CLEANUP