pivot-table: New functions for setting captions, etc.
[pspp] / src / language / stats / factor.c
index f37930aca5b292f4483333e01e9deed60ea4835f..3c1ce6094e5a2854be019066efdffae0e6afa618 100644 (file)
@@ -45,7 +45,6 @@
 #include "math/correlation.h"
 #include "math/covariance.h"
 #include "math/moments.h"
-#include "output/chart-item.h"
 #include "output/charts/scree.h"
 #include "output/pivot-table.h"
 
@@ -251,7 +250,7 @@ struct idata
 static struct idata *
 idata_alloc (size_t n_vars)
 {
-  struct idata *id = xzalloc (sizeof (*id));
+  struct idata *id = XZALLOC (struct idata);
 
   id->n_extractions = 0;
   id->msr = gsl_vector_alloc (n_vars);
@@ -1146,8 +1145,9 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
       if (! lex_force_match (lexer, T_RPAREN))
        goto error;
 
-      mr = create_matrix_reader_from_case_reader (dict, matrix_reader,
-                                                 &factor.vars, &factor.n_vars);
+      mr = matrix_reader_create (dict, matrix_reader);
+      factor.vars = xmemdup (mr->cvars, mr->n_cvars * sizeof *mr->cvars);
+      factor.n_vars = mr->n_cvars;
     }
   else
     {
@@ -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"))
        {
@@ -1315,7 +1322,7 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
              else if (lex_match_id (lexer, "ITERATE"))
                {
                  if (lex_force_match (lexer, T_LPAREN)
-                       && lex_force_int (lexer))
+                      && lex_force_int_range (lexer, "ITERATE", 0, INT_MAX))
                    {
                      n_iterations = lex_integer (lexer);
                      lex_get (lexer);
@@ -1528,8 +1535,7 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
     {
       struct idata *id = idata_alloc (factor.n_vars);
 
-      while (next_matrix_from_reader (&id->mm, mr,
-                                     factor.vars, factor.n_vars))
+      while (matrix_reader_next (&id->mm, mr, NULL))
        {
          do_factor_by_matrix (&factor, id);
 
@@ -1537,10 +1543,8 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
           id->ai_cov = NULL;
           gsl_matrix_free (id->ai_cor);
           id->ai_cor = NULL;
-         gsl_matrix_free (id->mm.corr);
-         id->mm.corr = NULL;
-         gsl_matrix_free (id->mm.cov);
-         id->mm.cov = NULL;
+
+          matrix_material_uninit (&id->mm);
        }
 
       idata_free (id);
@@ -1549,13 +1553,12 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
     if (! run_factor (ds, &factor))
       goto error;
 
-
-  destroy_matrix_reader (mr);
+  matrix_reader_destroy (mr);
   free (factor.vars);
   return CMD_SUCCESS;
 
  error:
-  destroy_matrix_reader (mr);
+  matrix_reader_destroy (mr);
   free (factor.vars);
   return CMD_FAILURE;
 }
@@ -1750,12 +1753,12 @@ show_explained_variance (const struct cmd_factor * factor,
 
   struct pivot_table *table = pivot_table_create (
     N_("Total Variance Explained"));
-  table->omit_empty = true;
 
-  /* xgettext:no-c-format */
   pivot_dimension_create (table, PIVOT_AXIS_COLUMN, N_("Statistics"),
                           N_("Total"), PIVOT_RC_OTHER,
+                          /* xgettext:no-c-format */
                           N_("% of Variance"), PIVOT_RC_PERCENT,
+                         /* xgettext:no-c-format */
                           N_("Cumulative %"), PIVOT_RC_PERCENT);
 
   struct pivot_dimension *phase = pivot_dimension_create (
@@ -1942,8 +1945,11 @@ show_correlation_matrix (const struct cmd_factor *factor, const struct idata *id
     }
 
   if (factor->print & PRINT_DETERMINANT)
-    table->caption = pivot_value_new_user_text_nocopy (
-      xasprintf ("%s: %.2f", _("Determinant"), idata->detR));
+    {
+      struct pivot_value *caption = pivot_value_new_user_text_nocopy (
+        xasprintf ("%s: %.2f", _("Determinant"), idata->detR));
+      pivot_table_set_caption (table, caption);
+    }
 
   pivot_table_submit (table);
 }
@@ -2008,9 +2014,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;
     }
 
@@ -2058,7 +2065,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"));
@@ -2092,7 +2100,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"));