factor: Fix return type of do_factor_by_matrix().
[pspp] / src / language / stats / factor.c
index 6100279555f5c21b8ae13a9276dd94372f3a0e32..fc3eb5b4d279446d7057559a707a664d3298e2a8 100644 (file)
@@ -266,10 +266,6 @@ idata_free (struct idata *id)
   gsl_vector_free (id->msr);
   gsl_vector_free (id->eval);
   gsl_matrix_free (id->evec);
-  if (id->mm.cov != NULL)
-    gsl_matrix_free (id->mm.cov);
-  if (id->mm.corr != NULL)
-    gsl_matrix_free (CONST_CAST (gsl_matrix *, id->mm.corr));
 
   free (id);
 }
@@ -1471,6 +1467,12 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
   if (factor.n_vars < 2)
     msg (MW, _("Factor analysis on a single variable is not useful."));
 
+  if (factor.n_vars < 1)
+    {
+      msg (ME, _("Factor analysis without variables is not possible."));
+      goto error;
+    }
+
   if (matrix_reader)
     {
       struct idata *id = idata_alloc (factor.n_vars);
@@ -1480,7 +1482,9 @@ cmd_factor (struct lexer *lexer, struct dataset *ds)
        {
          do_factor_by_matrix (&factor, id);
 
+         gsl_matrix_free (id->mm.corr);
          id->mm.corr = NULL;
+         gsl_matrix_free (id->mm.cov);
          id->mm.cov = NULL;
        }
 
@@ -1556,14 +1560,14 @@ the_communality (const gsl_matrix *evec, const gsl_vector *eval, int n, int n_fa
 
 /* Return the communality of variable N, calculated to N_FACTORS */
 static double
-communality (struct idata *idata, int n, int n_factors)
+communality (const struct idata *idata, int n, int n_factors)
 {
   return the_communality (idata->evec, idata->eval, n, n_factors);
 }
 
 
 static void
-show_scree (const struct cmd_factor *f, struct idata *idata)
+show_scree (const struct cmd_factor *f, const struct idata *idata)
 {
   struct scree *s;
   const char *label ;
@@ -1648,7 +1652,7 @@ show_communalities (const struct cmd_factor * factor,
 
 
 static void
-show_factor_matrix (const struct cmd_factor *factor, struct idata *idata, const char *title, const gsl_matrix *fm)
+show_factor_matrix (const struct cmd_factor *factor, const struct idata *idata, const char *title, const gsl_matrix *fm)
 {
   int i;
 
@@ -1741,7 +1745,8 @@ show_factor_matrix (const struct cmd_factor *factor, struct idata *idata, const
 
 
 static void
-show_explained_variance (const struct cmd_factor * factor, struct idata *idata,
+show_explained_variance (const struct cmd_factor * factor,
+                        const struct idata *idata,
                         const gsl_vector *initial_eigenvalues,
                         const gsl_vector *extracted_eigenvalues,
                         const gsl_vector *rotated_loadings)
@@ -2106,7 +2111,6 @@ show_covariance_matrix (const struct cmd_factor *factor, const struct idata *ida
   struct tab_table *t ;
   size_t i, j;
   int y_pos_corr = -1;
-  int y_pos_sig = -1;
   int suffix_rows = 0;
 
   const int heading_rows = 1;
@@ -2193,7 +2197,7 @@ do_factor (const struct cmd_factor *factor, struct casereader *r)
   struct idata *idata = idata_alloc (factor->n_vars);
 
   idata->cvm = covariance_1pass_create (factor->n_vars, factor->vars,
-                                             factor->wv, factor->exclude);
+                                       factor->wv, factor->exclude, true);
 
   for ( ; (c = casereader_read (r) ); case_unref (c))
     {
@@ -2216,6 +2220,9 @@ do_factor (const struct cmd_factor *factor, struct casereader *r)
   do_factor_by_matrix (factor, idata);
 
  finish:
+  gsl_matrix_free (idata->mm.corr);
+  gsl_matrix_free (idata->mm.cov);
+
   idata_free (idata);
   casereader_destroy (r);
 }
@@ -2223,6 +2230,12 @@ 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)
+    {
+      msg (ME, _("The dataset has no complete covariance or correlation matrix."));
+      return;
+    }
+
   if (idata->mm.cov && !idata->mm.corr)
     idata->mm.corr = correlation_from_covariance (idata->mm.cov, idata->mm.var_matrix);
   if (idata->mm.corr && !idata->mm.cov)
@@ -2401,7 +2414,7 @@ do_factor_by_matrix (const struct cmd_factor *factor, struct idata *idata)
   if (idata->n_extractions == 0)
     {
       msg (MW, _("The %s criteria result in zero factors extracted. Therefore no analysis will be performed."), "FACTOR");
-      goto finish;
+      return;
     }
 
   if (idata->n_extractions > factor->n_vars)
@@ -2409,7 +2422,7 @@ do_factor_by_matrix (const struct cmd_factor *factor, struct idata *idata)
       msg (MW,
           _("The %s criteria result in more factors than variables, which is not meaningful. No analysis will be performed."),
           "FACTOR");
-      goto finish;
+      return;
     }
 
   {
@@ -2530,9 +2543,6 @@ do_factor_by_matrix (const struct cmd_factor *factor, struct idata *idata)
     gsl_vector_free (initial_communalities);
     gsl_vector_free (extracted_communalities);
   }
-
- finish:
-  return;
 }