1ab2618dfe95f509f246817a289334bdb606d367
[pspp] / src / language / stats / factor.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18
19 #include <gsl/gsl_vector.h>
20 #include <gsl/gsl_linalg.h>
21 #include <gsl/gsl_matrix.h>
22 #include <gsl/gsl_eigen.h> 
23 #include <gsl/gsl_blas.h> 
24 #include <gsl/gsl_sort_vector.h>
25 #include <gsl/gsl_cdf.h>
26
27 #include "data/casegrouper.h"
28 #include "data/casereader.h"
29 #include "data/casewriter.h"
30 #include "data/dataset.h"
31 #include "data/dictionary.h"
32 #include "data/format.h"
33 #include "data/subcase.h"
34 #include "language/command.h"
35 #include "language/lexer/lexer.h"
36 #include "language/lexer/value-parser.h"
37 #include "language/lexer/variable-parser.h"
38 #include "libpspp/cast.h"
39 #include "libpspp/message.h"
40 #include "libpspp/misc.h"
41 #include "math/correlation.h"
42 #include "math/covariance.h"
43 #include "math/moments.h"
44 #include "output/chart-item.h"
45 #include "output/charts/scree.h"
46 #include "output/tab.h"
47
48 #include "gettext.h"
49 #define _(msgid) gettext (msgid)
50 #define N_(msgid) msgid
51
52 enum method
53   {
54     METHOD_CORR,
55     METHOD_COV
56   };
57
58 enum missing_type
59   {
60     MISS_LISTWISE,
61     MISS_PAIRWISE,
62     MISS_MEANSUB,
63   };
64
65 enum extraction_method
66   {
67     EXTRACTION_PC,
68     EXTRACTION_PAF,
69   };
70
71 enum plot_opts
72   {
73     PLOT_SCREE = 0x0001,
74     PLOT_ROTATION = 0x0002
75   };
76
77 enum print_opts
78   {
79     PRINT_UNIVARIATE  = 0x0001,
80     PRINT_DETERMINANT = 0x0002,
81     PRINT_INV         = 0x0004,
82     PRINT_AIC         = 0x0008,
83     PRINT_SIG         = 0x0010,
84     PRINT_COVARIANCE  = 0x0020,
85     PRINT_CORRELATION = 0x0040,
86     PRINT_ROTATION    = 0x0080,
87     PRINT_EXTRACTION  = 0x0100,
88     PRINT_INITIAL     = 0x0200,
89     PRINT_KMO         = 0x0400,
90     PRINT_REPR        = 0x0800, 
91     PRINT_FSCORE      = 0x1000
92   };
93
94 enum rotation_type
95   {
96     ROT_VARIMAX = 0,
97     ROT_EQUAMAX,
98     ROT_QUARTIMAX,
99     ROT_NONE
100   };
101
102 typedef void (*rotation_coefficients) (double *x, double *y,
103                                     double a, double b, double c, double d,
104                                     const gsl_matrix *loadings );
105
106
107 static void
108 varimax_coefficients (double *x, double *y,
109                       double a, double b, double c, double d,
110                       const gsl_matrix *loadings )
111 {
112   *x = d - 2 * a * b / loadings->size1;
113   *y = c - (a * a - b * b) / loadings->size1;
114 }
115
116 static void
117 equamax_coefficients (double *x, double *y,
118                       double a, double b, double c, double d,
119                       const gsl_matrix *loadings )
120 {
121   *x = d - loadings->size2 * a * b / loadings->size1;
122   *y = c - loadings->size2 * (a * a - b * b) / (2 * loadings->size1);
123 }
124
125 static void
126 quartimax_coefficients (double *x, double *y,
127                       double a UNUSED, double b UNUSED, double c, double d,
128                       const gsl_matrix *loadings UNUSED)
129 {
130   *x = d ;
131   *y = c ;
132 }
133
134 static const rotation_coefficients rotation_coeff[3] = {
135   varimax_coefficients,
136   equamax_coefficients,
137   quartimax_coefficients
138 };
139
140
141 struct cmd_factor 
142 {
143   size_t n_vars;
144   const struct variable **vars;
145
146   const struct variable *wv;
147
148   enum method method;
149   enum missing_type missing_type;
150   enum mv_class exclude;
151   enum print_opts print;
152   enum extraction_method extraction;
153   enum plot_opts plot;
154   enum rotation_type rotation;
155   int rotation_iterations;
156
157   /* Extraction Criteria */
158   int n_factors;
159   double min_eigen;
160   double econverge;
161   int extraction_iterations;
162
163   double rconverge;
164
165   /* Format */
166   double blank;
167   bool sort;
168 };
169
170 struct idata
171 {
172   /* Intermediate values used in calculation */
173
174   const gsl_matrix *corr ;  /* The correlation matrix */
175   gsl_matrix *cov ;         /* The covariance matrix */
176   const gsl_matrix *n ;     /* Matrix of number of samples */
177
178   gsl_vector *eval ;  /* The eigenvalues */
179   gsl_matrix *evec ;  /* The eigenvectors */
180
181   int n_extractions;
182
183   gsl_vector *msr ;  /* Multiple Squared Regressions */
184
185   double detR;  /* The determinant of the correlation matrix */
186 };
187
188 static struct idata *
189 idata_alloc (size_t n_vars)
190 {
191   struct idata *id = xzalloc (sizeof (*id));
192
193   id->n_extractions = 0;
194   id->msr = gsl_vector_alloc (n_vars);
195
196   id->eval = gsl_vector_alloc (n_vars);
197   id->evec = gsl_matrix_alloc (n_vars, n_vars);
198
199   return id;
200 }
201
202 static void
203 idata_free (struct idata *id)
204 {
205   gsl_vector_free (id->msr);
206   gsl_vector_free (id->eval);
207   gsl_matrix_free (id->evec);
208   if (id->cov != NULL)
209     gsl_matrix_free (id->cov);
210   if (id->corr != NULL)
211     gsl_matrix_free (CONST_CAST (gsl_matrix *, id->corr));
212
213   free (id);
214 }
215
216
217 static gsl_matrix *
218 anti_image (const gsl_matrix *m)
219 {
220   int i, j;
221   gsl_matrix *a;
222   assert (m->size1 == m->size2);
223
224   a = gsl_matrix_alloc (m->size1, m->size2);
225   
226   for (i = 0; i < m->size1; ++i)
227     {
228       for (j = 0; j < m->size2; ++j)
229         {
230           double *p = gsl_matrix_ptr (a, i, j);
231           *p = gsl_matrix_get (m, i, j);
232           *p /= gsl_matrix_get (m, i, i);
233           *p /= gsl_matrix_get (m, j, j);
234         }
235     }
236
237   return a;
238 }
239
240
241 /* Return the sum of all the elements excluding row N */
242 static double
243 ssq_od_n (const gsl_matrix *m, int n)
244 {
245   int i, j;
246   double ss = 0;
247   assert (m->size1 == m->size2);
248
249   assert (n < m->size1);
250   
251   for (i = 0; i < m->size1; ++i)
252     {
253       if (i == n ) continue;
254       for (j = 0; j < m->size2; ++j)
255         {
256           ss += pow2 (gsl_matrix_get (m, i, j));
257         }
258     }
259
260   return ss;
261 }
262
263
264
265 #if 0
266 static void
267 dump_matrix (const gsl_matrix *m)
268 {
269   size_t i, j;
270
271   for (i = 0 ; i < m->size1; ++i)
272     {
273       for (j = 0 ; j < m->size2; ++j)
274         printf ("%02f ", gsl_matrix_get (m, i, j));
275       printf ("\n");
276     }
277 }
278
279 static void
280 dump_matrix_permute (const gsl_matrix *m, const gsl_permutation *p)
281 {
282   size_t i, j;
283
284   for (i = 0 ; i < m->size1; ++i)
285     {
286       for (j = 0 ; j < m->size2; ++j)
287         printf ("%02f ", gsl_matrix_get (m, gsl_permutation_get (p, i), j));
288       printf ("\n");
289     }
290 }
291
292
293 static void
294 dump_vector (const gsl_vector *v)
295 {
296   size_t i;
297   for (i = 0 ; i < v->size; ++i)
298     {
299       printf ("%02f\n", gsl_vector_get (v, i));
300     }
301   printf ("\n");
302 }
303 #endif
304
305
306 static int 
307 n_extracted_factors (const struct cmd_factor *factor, struct idata *idata)
308 {
309   int i;
310   
311   /* If there is a cached value, then return that. */
312   if ( idata->n_extractions != 0)
313     return idata->n_extractions;
314
315   /* Otherwise, if the number of factors has been explicitly requested,
316      use that. */
317   if (factor->n_factors > 0)
318     {
319       idata->n_extractions = factor->n_factors;
320       goto finish;
321     }
322   
323   /* Use the MIN_EIGEN setting. */
324   for (i = 0 ; i < idata->eval->size; ++i)
325     {
326       double evali = fabs (gsl_vector_get (idata->eval, i));
327
328       idata->n_extractions = i;
329
330       if (evali < factor->min_eigen)
331         goto finish;
332     }
333
334  finish:
335   return idata->n_extractions;
336 }
337
338
339 /* Returns a newly allocated matrix identical to M.
340    It it the callers responsibility to free the returned value.
341 */
342 static gsl_matrix *
343 matrix_dup (const gsl_matrix *m)
344 {
345   gsl_matrix *n =  gsl_matrix_alloc (m->size1, m->size2);
346
347   gsl_matrix_memcpy (n, m);
348
349   return n;
350 }
351
352
353 struct smr_workspace
354 {
355   /* Copy of the subject */
356   gsl_matrix *m;
357   
358   gsl_matrix *inverse;
359
360   gsl_permutation *perm;
361
362   gsl_matrix *result1;
363   gsl_matrix *result2;
364 };
365
366
367 static struct smr_workspace *ws_create (const gsl_matrix *input)
368 {
369   struct smr_workspace *ws = xmalloc (sizeof (*ws));
370   
371   ws->m = gsl_matrix_alloc (input->size1, input->size2);
372   ws->inverse = gsl_matrix_calloc (input->size1 - 1, input->size2 - 1);
373   ws->perm = gsl_permutation_alloc (input->size1 - 1);
374   ws->result1 = gsl_matrix_calloc (input->size1 - 1, 1);
375   ws->result2 = gsl_matrix_calloc (1, 1);
376
377   return ws;
378 }
379
380 static void
381 ws_destroy (struct smr_workspace *ws)
382 {
383   gsl_matrix_free (ws->result2);
384   gsl_matrix_free (ws->result1);
385   gsl_permutation_free (ws->perm);
386   gsl_matrix_free (ws->inverse);
387   gsl_matrix_free (ws->m);
388
389   free (ws);
390 }
391
392
393 /* 
394    Return the square of the regression coefficient for VAR regressed against all other variables.
395  */
396 static double
397 squared_multiple_correlation (const gsl_matrix *corr, int var, struct smr_workspace *ws)
398 {
399   /* For an explanation of what this is doing, see 
400      http://www.visualstatistics.net/Visual%20Statistics%20Multimedia/multiple_regression_analysis.htm
401   */
402
403   int signum = 0;
404   gsl_matrix_view rxx;
405
406   gsl_matrix_memcpy (ws->m, corr);
407
408   gsl_matrix_swap_rows (ws->m, 0, var);
409   gsl_matrix_swap_columns (ws->m, 0, var);
410
411   rxx = gsl_matrix_submatrix (ws->m, 1, 1, ws->m->size1 - 1, ws->m->size1 - 1); 
412
413   gsl_linalg_LU_decomp (&rxx.matrix, ws->perm, &signum);
414
415   gsl_linalg_LU_invert (&rxx.matrix, ws->perm, ws->inverse);
416
417   {
418     gsl_matrix_const_view rxy = gsl_matrix_const_submatrix (ws->m, 1, 0, ws->m->size1 - 1, 1);
419     gsl_matrix_const_view ryx = gsl_matrix_const_submatrix (ws->m, 0, 1, 1, ws->m->size1 - 1);
420
421     gsl_blas_dgemm (CblasNoTrans,  CblasNoTrans,
422                     1.0, ws->inverse, &rxy.matrix, 0.0, ws->result1);
423
424     gsl_blas_dgemm (CblasNoTrans,  CblasNoTrans,
425                     1.0, &ryx.matrix, ws->result1, 0.0, ws->result2);
426   }
427
428   return gsl_matrix_get (ws->result2, 0, 0);
429 }
430
431
432
433 static double the_communality (const gsl_matrix *evec, const gsl_vector *eval, int n, int n_factors);
434
435
436 struct factor_matrix_workspace
437 {
438   size_t n_factors;
439   gsl_eigen_symmv_workspace *eigen_ws;
440
441   gsl_vector *eval ;
442   gsl_matrix *evec ;
443
444   gsl_matrix *gamma ;
445
446   gsl_matrix *r;
447 };
448
449 static struct factor_matrix_workspace *
450 factor_matrix_workspace_alloc (size_t n, size_t nf)
451 {
452   struct factor_matrix_workspace *ws = xmalloc (sizeof (*ws));
453
454   ws->n_factors = nf;
455   ws->gamma = gsl_matrix_calloc (nf, nf);
456   ws->eigen_ws = gsl_eigen_symmv_alloc (n);
457   ws->eval = gsl_vector_alloc (n);
458   ws->evec = gsl_matrix_alloc (n, n);
459   ws->r  = gsl_matrix_alloc (n, n);
460   
461   return ws;
462 }
463
464 static void
465 factor_matrix_workspace_free (struct factor_matrix_workspace *ws)
466 {
467   gsl_eigen_symmv_free (ws->eigen_ws);
468   gsl_vector_free (ws->eval);
469   gsl_matrix_free (ws->evec);
470   gsl_matrix_free (ws->gamma);
471   gsl_matrix_free (ws->r);
472   free (ws);
473 }
474
475 /*
476   Shift P left by OFFSET places, and overwrite TARGET
477   with the shifted result.
478   Positions in TARGET less than OFFSET are unchanged.
479 */
480 static void
481 perm_shift_apply (gsl_permutation *target, const gsl_permutation *p,
482                   size_t offset)
483 {
484   size_t i;
485   assert (target->size == p->size);
486   assert (offset <= target->size);
487
488   for (i = 0; i < target->size - offset; ++i)
489     {
490       target->data[i] = p->data [i + offset];
491     }
492 }
493
494
495 /* 
496    Indirectly sort the rows of matrix INPUT, storing the sort order in PERM.
497    The sort criteria are as follows:
498    
499    Rows are sorted on the first column, until the absolute value of an
500    element in a subsequent column  is greater than that of the first
501    column.  Thereafter, rows will be sorted on the second column,
502    until the absolute value of an element in a subsequent column
503    exceeds that of the second column ...
504 */
505 static void
506 sort_matrix_indirect (const gsl_matrix *input, gsl_permutation *perm)
507 {
508   const size_t n = perm->size;
509   const size_t m = input->size2;
510   int i, j;
511   gsl_matrix *mat ;
512   int column_n = 0;
513   int row_n = 0;
514   gsl_permutation *p;
515
516   assert (perm->size == input->size1);
517
518   p = gsl_permutation_alloc (n);
519
520   /* Copy INPUT into MAT, discarding the sign */
521   mat = gsl_matrix_alloc (n, m);
522   for (i = 0 ; i < mat->size1; ++i)
523     {
524       for (j = 0 ; j < mat->size2; ++j)
525         {
526           double x = gsl_matrix_get (input, i, j);
527           gsl_matrix_set (mat, i, j, fabs (x));
528         }
529     }
530
531   while (column_n < m && row_n < n) 
532     {
533       gsl_vector_const_view columni = gsl_matrix_const_column (mat, column_n);
534       gsl_sort_vector_index (p, &columni.vector);
535
536       for (i = 0 ; i < n; ++i)
537         {
538           gsl_vector_view row = gsl_matrix_row (mat, p->data[n - 1 - i]);
539           size_t maxindex = gsl_vector_max_index (&row.vector);
540           
541           if ( maxindex > column_n )
542             break;
543
544           /* All subsequent elements of this row, are of no interest.
545              So set them all to a highly negative value */
546           for (j = column_n + 1; j < row.vector.size ; ++j)
547             gsl_vector_set (&row.vector, j, -DBL_MAX);
548         }
549
550       perm_shift_apply (perm, p, row_n);
551       row_n += i;
552
553       column_n++;
554     }
555
556   gsl_permutation_free (p);
557   gsl_matrix_free (mat);
558   
559   assert ( 0 == gsl_permutation_valid (perm));
560
561   /* We want the biggest value to be first */
562   gsl_permutation_reverse (perm);    
563 }
564
565
566 static void
567 drot_go (double phi, double *l0, double *l1)
568 {
569   double r0 = cos (phi) * *l0 + sin (phi) * *l1;
570   double r1 = - sin (phi) * *l0 + cos (phi) * *l1;
571
572   *l0 = r0;
573   *l1 = r1;
574 }
575
576
577 static gsl_matrix *
578 clone_matrix (const gsl_matrix *m)
579 {
580   int j, k;
581   gsl_matrix *c = gsl_matrix_calloc (m->size1, m->size2);
582
583   for (j = 0 ; j < c->size1; ++j)
584     {
585       for (k = 0 ; k < c->size2; ++k)
586         {
587           const double *v = gsl_matrix_const_ptr (m, j, k);
588           gsl_matrix_set (c, j, k, *v);
589         }
590     }
591
592   return c;
593 }
594
595
596 static double 
597 initial_sv (const gsl_matrix *fm)
598 {
599   int j, k;
600
601   double sv = 0.0;
602   for (j = 0 ; j < fm->size2; ++j)
603     {
604       double l4s = 0;
605       double l2s = 0;
606
607       for (k = j + 1 ; k < fm->size2; ++k)
608         {
609           double lambda = gsl_matrix_get (fm, k, j);
610           double lambda_sq = lambda * lambda;
611           double lambda_4 = lambda_sq * lambda_sq;
612
613           l4s += lambda_4;
614           l2s += lambda_sq;
615         }
616       sv += ( fm->size1 * l4s - (l2s * l2s) ) / (fm->size1 * fm->size1 );
617     }
618   return sv;
619 }
620
621 static void
622 rotate (const struct cmd_factor *cf, const gsl_matrix *unrot,
623         const gsl_vector *communalities,
624         gsl_matrix *result,
625         gsl_vector *rotated_loadings
626         )
627 {
628   int j, k;
629   int i;
630   double prev_sv;
631
632   /* First get a normalised version of UNROT */
633   gsl_matrix *normalised = gsl_matrix_calloc (unrot->size1, unrot->size2);
634   gsl_matrix *h_sqrt = gsl_matrix_calloc (communalities->size, communalities->size);
635   gsl_matrix *h_sqrt_inv ;
636
637   /* H is the diagonal matrix containing the absolute values of the communalities */
638   for (i = 0 ; i < communalities->size ; ++i)
639     {
640       double *ptr = gsl_matrix_ptr (h_sqrt, i, i);
641       *ptr = fabs (gsl_vector_get (communalities, i));
642     }
643
644   /* Take the square root of the communalities */
645   gsl_linalg_cholesky_decomp (h_sqrt);
646
647
648   /* Save a copy of h_sqrt and invert it */
649   h_sqrt_inv = clone_matrix (h_sqrt);
650   gsl_linalg_cholesky_decomp (h_sqrt_inv);
651   gsl_linalg_cholesky_invert (h_sqrt_inv);
652
653   /* normalised vertion is H^{1/2} x UNROT */
654   gsl_blas_dgemm (CblasNoTrans,  CblasNoTrans, 1.0, h_sqrt_inv, unrot, 0.0, normalised);
655
656   gsl_matrix_free (h_sqrt_inv);
657
658
659   /* Now perform the rotation iterations */
660
661   prev_sv = initial_sv (normalised);
662   for (i = 0 ; i < cf->rotation_iterations ; ++i)
663     {
664       double sv = 0.0;
665       for (j = 0 ; j < normalised->size2; ++j)
666         {
667           /* These variables relate to the convergence criterium */
668           double l4s = 0;
669           double l2s = 0;
670
671           for (k = j + 1 ; k < normalised->size2; ++k)
672             {
673               int p;
674               double a = 0.0;
675               double b = 0.0;
676               double c = 0.0;
677               double d = 0.0;
678               double x, y;
679               double phi;
680
681               for (p = 0; p < normalised->size1; ++p)
682                 {
683                   double jv = gsl_matrix_get (normalised, p, j);
684                   double kv = gsl_matrix_get (normalised, p, k);
685               
686                   double u = jv * jv - kv * kv;
687                   double v = 2 * jv * kv;
688                   a += u;
689                   b += v;
690                   c +=  u * u - v * v;
691                   d += 2 * u * v;
692                 }
693
694               rotation_coeff [cf->rotation] (&x, &y, a, b, c, d, normalised);
695
696               phi = atan2 (x,  y) / 4.0 ;
697
698               /* Don't bother rotating if the angle is small */
699               if ( fabs (sin (phi) ) <= pow (10.0, -15.0))
700                   continue;
701
702               for (p = 0; p < normalised->size1; ++p)
703                 {
704                   double *lambda0 = gsl_matrix_ptr (normalised, p, j);
705                   double *lambda1 = gsl_matrix_ptr (normalised, p, k);
706                   drot_go (phi, lambda0, lambda1);
707                 }
708
709               /* Calculate the convergence criterium */
710               {
711                 double lambda = gsl_matrix_get (normalised, k, j);
712                 double lambda_sq = lambda * lambda;
713                 double lambda_4 = lambda_sq * lambda_sq;
714
715                 l4s += lambda_4;
716                 l2s += lambda_sq;
717               }
718             }
719           sv += ( normalised->size1 * l4s - (l2s * l2s) ) / (normalised->size1 * normalised->size1 );
720         }
721
722       if ( fabs (sv - prev_sv) <= cf->rconverge)
723         break;
724
725       prev_sv = sv;
726     }
727
728   gsl_blas_dgemm (CblasNoTrans,  CblasNoTrans, 1.0,
729                   h_sqrt, normalised,  0.0,   result);
730
731   gsl_matrix_free (h_sqrt);
732   gsl_matrix_free (normalised);
733
734
735   /* reflect negative sums and populate the rotated loadings vector*/
736   for (i = 0 ; i < result->size2; ++i)
737     {
738       double ssq = 0.0;
739       double sum = 0.0;
740       for (j = 0 ; j < result->size1; ++j)
741         {
742           double s = gsl_matrix_get (result, j, i);
743           ssq += s * s;
744           sum += gsl_matrix_get (result, j, i);
745         }
746
747       gsl_vector_set (rotated_loadings, i, ssq);
748
749       if ( sum < 0 )
750         for (j = 0 ; j < result->size1; ++j)
751           {
752             double *lambda = gsl_matrix_ptr (result, j, i);
753             *lambda = - *lambda;
754           }
755     }
756 }
757
758
759 /*
760   Get an approximation for the factor matrix into FACTORS, and the communalities into COMMUNALITIES.
761   R is the matrix to be analysed.
762   WS is a pointer to a structure which must have been initialised with factor_matrix_workspace_init.
763  */
764 static void
765 iterate_factor_matrix (const gsl_matrix *r, gsl_vector *communalities, gsl_matrix *factors, 
766                        struct factor_matrix_workspace *ws)
767 {
768   size_t i;
769   gsl_matrix_view mv ;
770
771   assert (r->size1 == r->size2);
772   assert (r->size1 == communalities->size);
773
774   assert (factors->size1 == r->size1);
775   assert (factors->size2 == ws->n_factors);
776
777   gsl_matrix_memcpy (ws->r, r);
778
779   /* Apply Communalities to diagonal of correlation matrix */
780   for (i = 0 ; i < communalities->size ; ++i)
781     {
782       double *x = gsl_matrix_ptr (ws->r, i, i);
783       *x = gsl_vector_get (communalities, i);
784     }
785
786   gsl_eigen_symmv (ws->r, ws->eval, ws->evec, ws->eigen_ws);
787
788   mv = gsl_matrix_submatrix (ws->evec, 0, 0, ws->evec->size1, ws->n_factors);
789
790   /* Gamma is the diagonal matrix containing the absolute values of the eigenvalues */
791   for (i = 0 ; i < ws->n_factors ; ++i)
792     {
793       double *ptr = gsl_matrix_ptr (ws->gamma, i, i);
794       *ptr = fabs (gsl_vector_get (ws->eval, i));
795     }
796
797   /* Take the square root of gamma */
798   gsl_linalg_cholesky_decomp (ws->gamma);
799
800   gsl_blas_dgemm (CblasNoTrans,  CblasNoTrans, 1.0, &mv.matrix, ws->gamma, 0.0, factors);
801
802   for (i = 0 ; i < r->size1 ; ++i)
803     {
804       double h = the_communality (ws->evec, ws->eval, i, ws->n_factors);
805       gsl_vector_set (communalities, i, h);
806     }
807 }
808
809
810
811 static bool run_factor (struct dataset *ds, const struct cmd_factor *factor);
812
813
814 int
815 cmd_factor (struct lexer *lexer, struct dataset *ds)
816 {
817   const struct dictionary *dict = dataset_dict (ds);
818   int n_iterations = 25;
819   struct cmd_factor factor;
820   factor.n_vars = 0;
821   factor.vars = NULL;
822   factor.method = METHOD_CORR;
823   factor.missing_type = MISS_LISTWISE;
824   factor.exclude = MV_ANY;
825   factor.print = PRINT_INITIAL | PRINT_EXTRACTION | PRINT_ROTATION;
826   factor.extraction = EXTRACTION_PC;
827   factor.n_factors = 0;
828   factor.min_eigen = SYSMIS;
829   factor.extraction_iterations = 25;
830   factor.rotation_iterations = 25;
831   factor.econverge = 0.001;
832
833   factor.blank = 0;
834   factor.sort = false;
835   factor.plot = 0;
836   factor.rotation = ROT_VARIMAX;
837
838   factor.rconverge = 0.0001;
839
840   factor.wv = dict_get_weight (dict);
841
842   lex_match (lexer, T_SLASH);
843
844   if (!lex_force_match_id (lexer, "VARIABLES"))
845     {
846       goto error;
847     }
848
849   lex_match (lexer, T_EQUALS);
850
851   if (!parse_variables_const (lexer, dict, &factor.vars, &factor.n_vars,
852                               PV_NO_DUPLICATE | PV_NUMERIC))
853     goto error;
854
855   if (factor.n_vars < 2)
856     msg (MW, _("Factor analysis on a single variable is not useful."));
857
858   while (lex_token (lexer) != T_ENDCMD)
859     {
860       lex_match (lexer, T_SLASH);
861
862       if (lex_match_id (lexer, "PLOT"))
863         {
864           lex_match (lexer, T_EQUALS);
865           while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
866             {
867               if (lex_match_id (lexer, "EIGEN"))
868                 {
869                   factor.plot |= PLOT_SCREE;
870                 }
871 #if FACTOR_FULLY_IMPLEMENTED
872               else if (lex_match_id (lexer, "ROTATION"))
873                 {
874                 }
875 #endif
876               else
877                 {
878                   lex_error (lexer, NULL);
879                   goto error;
880                 }
881             }
882         }
883       else if (lex_match_id (lexer, "METHOD"))
884         {
885           lex_match (lexer, T_EQUALS);
886           while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
887             {
888               if (lex_match_id (lexer, "COVARIANCE"))
889                 {
890                   factor.method = METHOD_COV;
891                 }
892               else if (lex_match_id (lexer, "CORRELATION"))
893                 {
894                   factor.method = METHOD_CORR;
895                 }
896               else
897                 {
898                   lex_error (lexer, NULL);
899                   goto error;
900                 }
901             }
902         }
903       else if (lex_match_id (lexer, "ROTATION"))
904         {
905           lex_match (lexer, T_EQUALS);
906           while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
907             {
908               /* VARIMAX and DEFAULT are defaults */
909               if (lex_match_id (lexer, "VARIMAX") || lex_match_id (lexer, "DEFAULT"))
910                 {
911                   factor.rotation = ROT_VARIMAX;
912                 }
913               else if (lex_match_id (lexer, "EQUAMAX"))
914                 {
915                   factor.rotation = ROT_EQUAMAX;
916                 }
917               else if (lex_match_id (lexer, "QUARTIMAX"))
918                 {
919                   factor.rotation = ROT_QUARTIMAX;
920                 }
921               else if (lex_match_id (lexer, "NOROTATE"))
922                 {
923                   factor.rotation = ROT_NONE;
924                 }
925               else
926                 {
927                   lex_error (lexer, NULL);
928                   goto error;
929                 }
930             }
931           factor.rotation_iterations = n_iterations;
932         }
933       else if (lex_match_id (lexer, "CRITERIA"))
934         {
935           lex_match (lexer, T_EQUALS);
936           while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
937             {
938               if (lex_match_id (lexer, "FACTORS"))
939                 {
940                   if ( lex_force_match (lexer, T_LPAREN))
941                     {
942                       lex_force_int (lexer);
943                       factor.n_factors = lex_integer (lexer);
944                       lex_get (lexer);
945                       lex_force_match (lexer, T_RPAREN);
946                     }
947                 }
948               else if (lex_match_id (lexer, "MINEIGEN"))
949                 {
950                   if ( lex_force_match (lexer, T_LPAREN))
951                     {
952                       lex_force_num (lexer);
953                       factor.min_eigen = lex_number (lexer);
954                       lex_get (lexer);
955                       lex_force_match (lexer, T_RPAREN);
956                     }
957                 }
958               else if (lex_match_id (lexer, "ECONVERGE"))
959                 {
960                   if ( lex_force_match (lexer, T_LPAREN))
961                     {
962                       lex_force_num (lexer);
963                       factor.econverge = lex_number (lexer);
964                       lex_get (lexer);
965                       lex_force_match (lexer, T_RPAREN);
966                     }
967                 }
968               else if (lex_match_id (lexer, "RCONVERGE"))
969                 {
970                   if ( lex_force_match (lexer, T_LPAREN))
971                     {
972                       lex_force_num (lexer);
973                       factor.rconverge = lex_number (lexer);
974                       lex_get (lexer);
975                       lex_force_match (lexer, T_RPAREN);
976                     }
977                 }
978               else if (lex_match_id (lexer, "ITERATE"))
979                 {
980                   if ( lex_force_match (lexer, T_LPAREN))
981                     {
982                       lex_force_int (lexer);
983                       n_iterations = lex_integer (lexer);
984                       lex_get (lexer);
985                       lex_force_match (lexer, T_RPAREN);
986                     }
987                 }
988               else if (lex_match_id (lexer, "DEFAULT"))
989                 {
990                   factor.n_factors = 0;
991                   factor.min_eigen = 1;
992                   n_iterations = 25;
993                 }
994               else
995                 {
996                   lex_error (lexer, NULL);
997                   goto error;
998                 }
999             }
1000         }
1001       else if (lex_match_id (lexer, "EXTRACTION"))
1002         {
1003           lex_match (lexer, T_EQUALS);
1004           while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
1005             {
1006               if (lex_match_id (lexer, "PAF"))
1007                 {
1008                   factor.extraction = EXTRACTION_PAF;
1009                 }
1010               else if (lex_match_id (lexer, "PC"))
1011                 {
1012                   factor.extraction = EXTRACTION_PC;
1013                 }
1014               else if (lex_match_id (lexer, "PA1"))
1015                 {
1016                   factor.extraction = EXTRACTION_PC;
1017                 }
1018               else if (lex_match_id (lexer, "DEFAULT"))
1019                 {
1020                   factor.extraction = EXTRACTION_PC;
1021                 }
1022               else
1023                 {
1024                   lex_error (lexer, NULL);
1025                   goto error;
1026                 }
1027             }
1028           factor.extraction_iterations = n_iterations;
1029         }
1030       else if (lex_match_id (lexer, "FORMAT"))
1031         {
1032           lex_match (lexer, T_EQUALS);
1033           while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
1034             {
1035               if (lex_match_id (lexer, "SORT"))
1036                 {
1037                   factor.sort = true;
1038                 }
1039               else if (lex_match_id (lexer, "BLANK"))
1040                 {
1041                   if ( lex_force_match (lexer, T_LPAREN))
1042                     {
1043                       lex_force_num (lexer);
1044                       factor.blank = lex_number (lexer);
1045                       lex_get (lexer);
1046                       lex_force_match (lexer, T_RPAREN);
1047                     }
1048                 }
1049               else if (lex_match_id (lexer, "DEFAULT"))
1050                 {
1051                   factor.blank = 0;
1052                   factor.sort = false;
1053                 }
1054               else
1055                 {
1056                   lex_error (lexer, NULL);
1057                   goto error;
1058                 }
1059             }
1060         }
1061       else if (lex_match_id (lexer, "PRINT"))
1062         {
1063           factor.print = 0;
1064           lex_match (lexer, T_EQUALS);
1065           while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
1066             {
1067               if (lex_match_id (lexer, "UNIVARIATE"))
1068                 {
1069                   factor.print |= PRINT_UNIVARIATE;
1070                 }
1071               else if (lex_match_id (lexer, "DET"))
1072                 {
1073                   factor.print |= PRINT_DETERMINANT;
1074                 }
1075 #if FACTOR_FULLY_IMPLEMENTED
1076               else if (lex_match_id (lexer, "INV"))
1077                 {
1078                 }
1079               else if (lex_match_id (lexer, "AIC"))
1080                 {
1081                 }
1082 #endif
1083               else if (lex_match_id (lexer, "SIG"))
1084                 {
1085                   factor.print |= PRINT_SIG;
1086                 }
1087               else if (lex_match_id (lexer, "CORRELATION"))
1088                 {
1089                   factor.print |= PRINT_CORRELATION;
1090                 }
1091 #if FACTOR_FULLY_IMPLEMENTED
1092               else if (lex_match_id (lexer, "COVARIANCE"))
1093                 {
1094                 }
1095 #endif
1096               else if (lex_match_id (lexer, "ROTATION"))
1097                 {
1098                   factor.print |= PRINT_ROTATION;
1099                 }
1100               else if (lex_match_id (lexer, "EXTRACTION"))
1101                 {
1102                   factor.print |= PRINT_EXTRACTION;
1103                 }
1104               else if (lex_match_id (lexer, "INITIAL"))
1105                 {
1106                   factor.print |= PRINT_INITIAL;
1107                 }
1108               else if (lex_match_id (lexer, "KMO"))
1109                 {
1110                   factor.print |= PRINT_KMO;
1111                 }
1112 #if FACTOR_FULLY_IMPLEMENTED
1113               else if (lex_match_id (lexer, "REPR"))
1114                 {
1115                 }
1116               else if (lex_match_id (lexer, "FSCORE"))
1117                 {
1118                 }
1119 #endif
1120               else if (lex_match (lexer, T_ALL))
1121                 {
1122                   factor.print = 0xFFFF;
1123                 }
1124               else if (lex_match_id (lexer, "DEFAULT"))
1125                 {
1126                   factor.print |= PRINT_INITIAL ;
1127                   factor.print |= PRINT_EXTRACTION ;
1128                   factor.print |= PRINT_ROTATION ;
1129                 }
1130               else
1131                 {
1132                   lex_error (lexer, NULL);
1133                   goto error;
1134                 }
1135             }
1136         }
1137       else if (lex_match_id (lexer, "MISSING"))
1138         {
1139           lex_match (lexer, T_EQUALS);
1140           while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
1141             {
1142               if (lex_match_id (lexer, "INCLUDE"))
1143                 {
1144                   factor.exclude = MV_SYSTEM;
1145                 }
1146               else if (lex_match_id (lexer, "EXCLUDE"))
1147                 {
1148                   factor.exclude = MV_ANY;
1149                 }
1150               else if (lex_match_id (lexer, "LISTWISE"))
1151                 {
1152                   factor.missing_type = MISS_LISTWISE;
1153                 }
1154               else if (lex_match_id (lexer, "PAIRWISE"))
1155                 {
1156                   factor.missing_type = MISS_PAIRWISE;
1157                 }
1158               else if (lex_match_id (lexer, "MEANSUB"))
1159                 {
1160                   factor.missing_type = MISS_MEANSUB;
1161                 }
1162               else
1163                 {
1164                   lex_error (lexer, NULL);
1165                   goto error;
1166                 }
1167             }
1168         }
1169       else
1170         {
1171           lex_error (lexer, NULL);
1172           goto error;
1173         }
1174     }
1175
1176   if ( factor.rotation == ROT_NONE )
1177     factor.print &= ~PRINT_ROTATION;
1178
1179   if ( ! run_factor (ds, &factor)) 
1180     goto error;
1181
1182   free (factor.vars);
1183   return CMD_SUCCESS;
1184
1185  error:
1186   free (factor.vars);
1187   return CMD_FAILURE;
1188 }
1189
1190 static void do_factor (const struct cmd_factor *factor, struct casereader *group);
1191
1192
1193 static bool
1194 run_factor (struct dataset *ds, const struct cmd_factor *factor)
1195 {
1196   struct dictionary *dict = dataset_dict (ds);
1197   bool ok;
1198   struct casereader *group;
1199
1200   struct casegrouper *grouper = casegrouper_create_splits (proc_open (ds), dict);
1201
1202   while (casegrouper_get_next_group (grouper, &group))
1203     {
1204       if ( factor->missing_type == MISS_LISTWISE )
1205         group  = casereader_create_filter_missing (group, factor->vars, factor->n_vars,
1206                                                    factor->exclude,
1207                                                    NULL,  NULL);
1208       do_factor (factor, group);
1209     }
1210
1211   ok = casegrouper_destroy (grouper);
1212   ok = proc_commit (ds) && ok;
1213
1214   return ok;
1215 }
1216
1217
1218 /* Return the communality of variable N, calculated to N_FACTORS */
1219 static double
1220 the_communality (const gsl_matrix *evec, const gsl_vector *eval, int n, int n_factors)
1221 {
1222   size_t i;
1223
1224   double comm = 0;
1225
1226   assert (n >= 0);
1227   assert (n < eval->size);
1228   assert (n < evec->size1);
1229   assert (n_factors <= eval->size);
1230
1231   for (i = 0 ; i < n_factors; ++i)
1232     {
1233       double evali = fabs (gsl_vector_get (eval, i));
1234
1235       double eveci = gsl_matrix_get (evec, n, i);
1236
1237       comm += pow2 (eveci) * evali;
1238     }
1239
1240   return comm;
1241 }
1242
1243 /* Return the communality of variable N, calculated to N_FACTORS */
1244 static double
1245 communality (struct idata *idata, int n, int n_factors)
1246 {
1247   return the_communality (idata->evec, idata->eval, n, n_factors);
1248 }
1249
1250
1251 static void
1252 show_scree (const struct cmd_factor *f, struct idata *idata)
1253 {
1254   struct scree *s;
1255   const char *label ;
1256
1257   if ( !(f->plot & PLOT_SCREE) )
1258     return;
1259
1260
1261   label = f->extraction == EXTRACTION_PC ? _("Component Number") : _("Factor Number");
1262
1263   s = scree_create (idata->eval, label);
1264
1265   scree_submit (s);
1266 }
1267
1268 static void
1269 show_communalities (const struct cmd_factor * factor,
1270                     const gsl_vector *initial, const gsl_vector *extracted)
1271 {
1272   int i;
1273   int c = 0;
1274   const int heading_columns = 1;
1275   int nc = heading_columns;
1276   const int heading_rows = 1;
1277   const int nr = heading_rows + factor->n_vars;
1278   struct tab_table *t;
1279
1280   if (factor->print & PRINT_EXTRACTION)
1281     nc++;
1282
1283   if (factor->print & PRINT_INITIAL)
1284     nc++;
1285
1286   /* No point having a table with only headings */
1287   if (nc <= 1)
1288     return;
1289
1290   t = tab_create (nc, nr);
1291
1292   tab_title (t, _("Communalities"));
1293
1294   tab_headers (t, heading_columns, 0, heading_rows, 0);
1295
1296   c = 1;
1297   if (factor->print & PRINT_INITIAL)
1298     tab_text (t, c++, 0, TAB_CENTER | TAT_TITLE, _("Initial"));
1299
1300   if (factor->print & PRINT_EXTRACTION)
1301     tab_text (t, c++, 0, TAB_CENTER | TAT_TITLE, _("Extraction"));
1302
1303   /* Outline the box */
1304   tab_box (t,
1305            TAL_2, TAL_2,
1306            -1, -1,
1307            0, 0,
1308            nc - 1, nr - 1);
1309
1310   /* Vertical lines */
1311   tab_box (t,
1312            -1, -1,
1313            -1, TAL_1,
1314            heading_columns, 0,
1315            nc - 1, nr - 1);
1316
1317   tab_hline (t, TAL_1, 0, nc - 1, heading_rows);
1318   tab_vline (t, TAL_2, heading_columns, 0, nr - 1);
1319
1320   for (i = 0 ; i < factor->n_vars; ++i)
1321     {
1322       c = 0;
1323       tab_text (t, c++, i + heading_rows, TAT_TITLE, var_to_string (factor->vars[i]));
1324
1325       if (factor->print & PRINT_INITIAL)
1326         tab_double (t, c++, i + heading_rows, 0, gsl_vector_get (initial, i), NULL);
1327
1328       if (factor->print & PRINT_EXTRACTION)
1329         tab_double (t, c++, i + heading_rows, 0, gsl_vector_get (extracted, i), NULL);
1330     }
1331
1332   tab_submit (t);
1333 }
1334
1335
1336 static void
1337 show_factor_matrix (const struct cmd_factor *factor, struct idata *idata, const char *title, const gsl_matrix *fm)
1338 {
1339   int i;
1340   const int n_factors = idata->n_extractions;
1341
1342   const int heading_columns = 1;
1343   const int heading_rows = 2;
1344   const int nr = heading_rows + factor->n_vars;
1345   const int nc = heading_columns + n_factors;
1346   gsl_permutation *perm;
1347
1348   struct tab_table *t = tab_create (nc, nr);
1349
1350   /* 
1351   if ( factor->extraction == EXTRACTION_PC )
1352     tab_title (t, _("Component Matrix"));
1353   else 
1354     tab_title (t, _("Factor Matrix"));
1355   */
1356
1357   tab_title (t, "%s", title);
1358
1359   tab_headers (t, heading_columns, 0, heading_rows, 0);
1360
1361   if ( factor->extraction == EXTRACTION_PC )
1362     tab_joint_text (t,
1363                     1, 0,
1364                     nc - 1, 0,
1365                     TAB_CENTER | TAT_TITLE, _("Component"));
1366   else
1367     tab_joint_text (t,
1368                     1, 0,
1369                     nc - 1, 0,
1370                     TAB_CENTER | TAT_TITLE, _("Factor"));
1371
1372
1373   tab_hline (t, TAL_1, heading_columns, nc - 1, 1);
1374
1375
1376   /* Outline the box */
1377   tab_box (t,
1378            TAL_2, TAL_2,
1379            -1, -1,
1380            0, 0,
1381            nc - 1, nr - 1);
1382
1383   /* Vertical lines */
1384   tab_box (t,
1385            -1, -1,
1386            -1, TAL_1,
1387            heading_columns, 1,
1388            nc - 1, nr - 1);
1389
1390   tab_hline (t, TAL_1, 0, nc - 1, heading_rows);
1391   tab_vline (t, TAL_2, heading_columns, 0, nr - 1);
1392
1393
1394   /* Initialise to the identity permutation */
1395   perm = gsl_permutation_calloc (factor->n_vars);
1396
1397   if ( factor->sort)
1398     sort_matrix_indirect (fm, perm);
1399
1400   for (i = 0 ; i < n_factors; ++i)
1401     {
1402       tab_text_format (t, heading_columns + i, 1, TAB_CENTER | TAT_TITLE, _("%d"), i + 1);
1403     }
1404
1405   for (i = 0 ; i < factor->n_vars; ++i)
1406     {
1407       int j;
1408       const int matrix_row = perm->data[i];
1409       tab_text (t, 0, i + heading_rows, TAT_TITLE, var_to_string (factor->vars[matrix_row]));
1410
1411       for (j = 0 ; j < n_factors; ++j)
1412         {
1413           double x = gsl_matrix_get (fm, matrix_row, j);
1414
1415           if ( fabs (x) < factor->blank)
1416             continue;
1417
1418           tab_double (t, heading_columns + j, heading_rows + i, 0, x, NULL);
1419         }
1420     }
1421
1422   gsl_permutation_free (perm);
1423
1424   tab_submit (t);
1425 }
1426
1427
1428 static void
1429 show_explained_variance (const struct cmd_factor * factor, struct idata *idata,
1430                          const gsl_vector *initial_eigenvalues,
1431                          const gsl_vector *extracted_eigenvalues,
1432                          const gsl_vector *rotated_loadings)
1433 {
1434   size_t i;
1435   int c = 0;
1436   const int heading_columns = 1;
1437   const int heading_rows = 2;
1438   const int nr = heading_rows + factor->n_vars;
1439
1440   struct tab_table *t ;
1441
1442   double i_total = 0.0;
1443   double i_cum = 0.0;
1444
1445   double e_total = 0.0;
1446   double e_cum = 0.0;
1447
1448   double r_cum = 0.0;
1449
1450   int nc = heading_columns;
1451
1452   if (factor->print & PRINT_EXTRACTION)
1453     nc += 3;
1454
1455   if (factor->print & PRINT_INITIAL)
1456     nc += 3;
1457
1458   if (factor->print & PRINT_ROTATION)
1459     nc += 3;
1460
1461   /* No point having a table with only headings */
1462   if ( nc <= heading_columns)
1463     return;
1464
1465   t = tab_create (nc, nr);
1466
1467   tab_title (t, _("Total Variance Explained"));
1468
1469   tab_headers (t, heading_columns, 0, heading_rows, 0);
1470
1471   /* Outline the box */
1472   tab_box (t,
1473            TAL_2, TAL_2,
1474            -1, -1,
1475            0, 0,
1476            nc - 1, nr - 1);
1477
1478   /* Vertical lines */
1479   tab_box (t,
1480            -1, -1,
1481            -1, TAL_1,
1482            heading_columns, 0,
1483            nc - 1, nr - 1);
1484
1485   tab_hline (t, TAL_1, 0, nc - 1, heading_rows);
1486   tab_hline (t, TAL_1, 1, nc - 1, 1);
1487
1488   tab_vline (t, TAL_2, heading_columns, 0, nr - 1);
1489
1490
1491   if ( factor->extraction == EXTRACTION_PC)
1492     tab_text (t, 0, 1, TAB_LEFT | TAT_TITLE, _("Component"));
1493   else
1494     tab_text (t, 0, 1, TAB_LEFT | TAT_TITLE, _("Factor"));
1495
1496   c = 1;
1497   if (factor->print & PRINT_INITIAL)
1498     {
1499       tab_joint_text (t, c, 0, c + 2, 0, TAB_CENTER | TAT_TITLE, _("Initial Eigenvalues"));
1500       c += 3;
1501     }
1502
1503   if (factor->print & PRINT_EXTRACTION)
1504     {
1505       tab_joint_text (t, c, 0, c + 2, 0, TAB_CENTER | TAT_TITLE, _("Extraction Sums of Squared Loadings"));
1506       c += 3;
1507     }
1508
1509   if (factor->print & PRINT_ROTATION)
1510     {
1511       tab_joint_text (t, c, 0, c + 2, 0, TAB_CENTER | TAT_TITLE, _("Rotation Sums of Squared Loadings"));
1512       c += 3;
1513     }
1514
1515   for (i = 0; i < (nc - heading_columns) / 3 ; ++i)
1516     {
1517       tab_text (t, i * 3 + 1, 1, TAB_CENTER | TAT_TITLE, _("Total"));
1518       /* xgettext:no-c-format */
1519       tab_text (t, i * 3 + 2, 1, TAB_CENTER | TAT_TITLE, _("% of Variance"));
1520       tab_text (t, i * 3 + 3, 1, TAB_CENTER | TAT_TITLE, _("Cumulative %"));
1521
1522       tab_vline (t, TAL_2, heading_columns + i * 3, 0, nr - 1);
1523     }
1524
1525   for (i = 0 ; i < initial_eigenvalues->size; ++i)
1526     i_total += gsl_vector_get (initial_eigenvalues, i);
1527
1528   if ( factor->extraction == EXTRACTION_PAF)
1529     {
1530       e_total = factor->n_vars;
1531     }
1532   else
1533     {
1534       e_total = i_total;
1535     }
1536
1537   for (i = 0 ; i < factor->n_vars; ++i)
1538     {
1539       const double i_lambda = gsl_vector_get (initial_eigenvalues, i);
1540       double i_percent = 100.0 * i_lambda / i_total ;
1541
1542       const double e_lambda = gsl_vector_get (extracted_eigenvalues, i);
1543       double e_percent = 100.0 * e_lambda / e_total ;
1544
1545       c = 0;
1546
1547       tab_text_format (t, c++, i + heading_rows, TAB_LEFT | TAT_TITLE, _("%zu"), i + 1);
1548
1549       i_cum += i_percent;
1550       e_cum += e_percent;
1551
1552       /* Initial Eigenvalues */
1553       if (factor->print & PRINT_INITIAL)
1554       {
1555         tab_double (t, c++, i + heading_rows, 0, i_lambda, NULL);
1556         tab_double (t, c++, i + heading_rows, 0, i_percent, NULL);
1557         tab_double (t, c++, i + heading_rows, 0, i_cum, NULL);
1558       }
1559
1560
1561       if (factor->print & PRINT_EXTRACTION)
1562         {
1563           if (i < idata->n_extractions)
1564             {
1565               /* Sums of squared loadings */
1566               tab_double (t, c++, i + heading_rows, 0, e_lambda, NULL);
1567               tab_double (t, c++, i + heading_rows, 0, e_percent, NULL);
1568               tab_double (t, c++, i + heading_rows, 0, e_cum, NULL);
1569             }
1570         }
1571
1572       if (rotated_loadings != NULL)
1573         {
1574           const double r_lambda = gsl_vector_get (rotated_loadings, i);
1575           double r_percent = 100.0 * r_lambda / e_total ;
1576
1577           if (factor->print & PRINT_ROTATION)
1578             {
1579               if (i < idata->n_extractions)
1580                 {
1581                   r_cum += r_percent;
1582                   tab_double (t, c++, i + heading_rows, 0, r_lambda, NULL);
1583                   tab_double (t, c++, i + heading_rows, 0, r_percent, NULL);
1584                   tab_double (t, c++, i + heading_rows, 0, r_cum, NULL);
1585                 }
1586             }
1587         }
1588     }
1589
1590   tab_submit (t);
1591 }
1592
1593
1594 static void
1595 show_correlation_matrix (const struct cmd_factor *factor, const struct idata *idata)
1596 {
1597   struct tab_table *t ;
1598   size_t i, j;
1599   int y_pos_corr = -1;
1600   int y_pos_sig = -1;
1601   int suffix_rows = 0;
1602
1603   const int heading_rows = 1;
1604   const int heading_columns = 2;
1605
1606   int nc = heading_columns ;
1607   int nr = heading_rows ;
1608   int n_data_sets = 0;
1609
1610   if (factor->print & PRINT_CORRELATION)
1611     {
1612       y_pos_corr = n_data_sets;
1613       n_data_sets++;
1614       nc = heading_columns + factor->n_vars;
1615     }
1616
1617   if (factor->print & PRINT_SIG)
1618     {
1619       y_pos_sig = n_data_sets;
1620       n_data_sets++;
1621       nc = heading_columns + factor->n_vars;
1622     }
1623
1624   nr += n_data_sets * factor->n_vars;
1625
1626   if (factor->print & PRINT_DETERMINANT)
1627     suffix_rows = 1;
1628
1629   /* If the table would contain only headings, don't bother rendering it */
1630   if (nr <= heading_rows && suffix_rows == 0)
1631     return;
1632
1633   t = tab_create (nc, nr + suffix_rows);
1634
1635   tab_title (t, _("Correlation Matrix"));
1636
1637   tab_hline (t, TAL_1, 0, nc - 1, heading_rows);
1638
1639   if (nr > heading_rows)
1640     {
1641       tab_headers (t, heading_columns, 0, heading_rows, 0);
1642
1643       tab_vline (t, TAL_2, 2, 0, nr - 1);
1644
1645       /* Outline the box */
1646       tab_box (t,
1647                TAL_2, TAL_2,
1648                -1, -1,
1649                0, 0,
1650                nc - 1, nr - 1);
1651
1652       /* Vertical lines */
1653       tab_box (t,
1654                -1, -1,
1655                -1, TAL_1,
1656                heading_columns, 0,
1657                nc - 1, nr - 1);
1658
1659
1660       for (i = 0; i < factor->n_vars; ++i)
1661         tab_text (t, heading_columns + i, 0, TAT_TITLE, var_to_string (factor->vars[i]));
1662
1663
1664       for (i = 0 ; i < n_data_sets; ++i)
1665         {
1666           int y = heading_rows + i * factor->n_vars;
1667           size_t v;
1668           for (v = 0; v < factor->n_vars; ++v)
1669             tab_text (t, 1, y + v, TAT_TITLE, var_to_string (factor->vars[v]));
1670
1671           tab_hline (t, TAL_1, 0, nc - 1, y);
1672         }
1673
1674       if (factor->print & PRINT_CORRELATION)
1675         {
1676           const double y = heading_rows + y_pos_corr;
1677           tab_text (t, 0, y, TAT_TITLE, _("Correlations"));
1678
1679           for (i = 0; i < factor->n_vars; ++i)
1680             {
1681               for (j = 0; j < factor->n_vars; ++j)
1682                 tab_double (t, heading_columns + i,  y + j, 0, gsl_matrix_get (idata->corr, i, j), NULL);
1683             }
1684         }
1685
1686       if (factor->print & PRINT_SIG)
1687         {
1688           const double y = heading_rows + y_pos_sig * factor->n_vars;
1689           tab_text (t, 0, y, TAT_TITLE, _("Sig. (1-tailed)"));
1690
1691           for (i = 0; i < factor->n_vars; ++i)
1692             {
1693               for (j = 0; j < factor->n_vars; ++j)
1694                 {
1695                   double rho = gsl_matrix_get (idata->corr, i, j);
1696                   double w = gsl_matrix_get (idata->n, i, j);
1697
1698                   if (i == j)
1699                     continue;
1700
1701                   tab_double (t, heading_columns + i,  y + j, 0, significance_of_correlation (rho, w), NULL);
1702                 }
1703             }
1704         }
1705     }
1706
1707   if (factor->print & PRINT_DETERMINANT)
1708     {
1709       tab_text (t, 0, nr, TAB_LEFT | TAT_TITLE, _("Determinant"));
1710
1711       tab_double (t, 1, nr, 0, idata->detR, NULL);
1712     }
1713
1714   tab_submit (t);
1715 }
1716
1717
1718
1719 static void
1720 do_factor (const struct cmd_factor *factor, struct casereader *r)
1721 {
1722   struct ccase *c;
1723   const gsl_matrix *var_matrix;
1724   const gsl_matrix *mean_matrix;
1725
1726   const gsl_matrix *analysis_matrix;
1727   struct idata *idata = idata_alloc (factor->n_vars);
1728
1729   struct covariance *cov = covariance_1pass_create (factor->n_vars, factor->vars,
1730                                               factor->wv, factor->exclude);
1731
1732   for ( ; (c = casereader_read (r) ); case_unref (c))
1733     {
1734       covariance_accumulate (cov, c);
1735     }
1736
1737   idata->cov = covariance_calculate (cov);
1738
1739   if (idata->cov == NULL)
1740     {
1741       msg (MW, _("The dataset contains no complete observations. No analysis will be performed."));
1742       covariance_destroy (cov);
1743       goto finish;
1744     }
1745
1746   var_matrix = covariance_moments (cov, MOMENT_VARIANCE);
1747   mean_matrix = covariance_moments (cov, MOMENT_MEAN);
1748   idata->n = covariance_moments (cov, MOMENT_NONE);
1749   
1750
1751   if ( factor->method == METHOD_CORR)
1752     {
1753       idata->corr = correlation_from_covariance (idata->cov, var_matrix);
1754       
1755       analysis_matrix = idata->corr;
1756     }
1757   else
1758     analysis_matrix = idata->cov;
1759
1760
1761   if (factor->print & PRINT_DETERMINANT
1762       || factor->print & PRINT_KMO)
1763     {
1764       int sign = 0;
1765
1766       const int size = idata->corr->size1;
1767       gsl_permutation *p = gsl_permutation_calloc (size);
1768       gsl_matrix *tmp = gsl_matrix_calloc (size, size);
1769       gsl_matrix_memcpy (tmp, idata->corr);
1770
1771       gsl_linalg_LU_decomp (tmp, p, &sign);
1772       idata->detR = gsl_linalg_LU_det (tmp, sign);
1773       gsl_permutation_free (p);
1774       gsl_matrix_free (tmp);
1775     }
1776
1777   if ( factor->print & PRINT_UNIVARIATE)
1778     {
1779       const struct fmt_spec *wfmt = factor->wv ? var_get_print_format (factor->wv) : & F_8_0;
1780       const int nc = 4;
1781       int i;
1782
1783       const int heading_columns = 1;
1784       const int heading_rows = 1;
1785
1786       const int nr = heading_rows + factor->n_vars;
1787
1788       struct tab_table *t = tab_create (nc, nr);
1789       tab_title (t, _("Descriptive Statistics"));
1790
1791       tab_headers (t, heading_columns, 0, heading_rows, 0);
1792
1793       /* Outline the box */
1794       tab_box (t,
1795                TAL_2, TAL_2,
1796                -1, -1,
1797                0, 0,
1798                nc - 1, nr - 1);
1799
1800       /* Vertical lines */
1801       tab_box (t,
1802                -1, -1,
1803                -1, TAL_1,
1804                heading_columns, 0,
1805                nc - 1, nr - 1);
1806
1807       tab_hline (t, TAL_1, 0, nc - 1, heading_rows);
1808       tab_vline (t, TAL_2, heading_columns, 0, nr - 1);
1809
1810       tab_text (t, 1, 0, TAB_CENTER | TAT_TITLE, _("Mean"));
1811       tab_text (t, 2, 0, TAB_CENTER | TAT_TITLE, _("Std. Deviation"));
1812       tab_text (t, 3, 0, TAB_CENTER | TAT_TITLE, _("Analysis N"));
1813
1814       for (i = 0 ; i < factor->n_vars; ++i)
1815         {
1816           const struct variable *v = factor->vars[i];
1817           tab_text (t, 0, i + heading_rows, TAB_LEFT | TAT_TITLE, var_to_string (v));
1818
1819           tab_double (t, 1, i + heading_rows, 0, gsl_matrix_get (mean_matrix, i, i), NULL);
1820           tab_double (t, 2, i + heading_rows, 0, sqrt (gsl_matrix_get (var_matrix, i, i)), NULL);
1821           tab_double (t, 3, i + heading_rows, 0, gsl_matrix_get (idata->n, i, i), wfmt);
1822         }
1823
1824       tab_submit (t);
1825     }
1826
1827   if (factor->print & PRINT_KMO)
1828     {
1829       int i;
1830       double sum_ssq_r = 0;
1831       double sum_ssq_a = 0;
1832
1833       double df = factor->n_vars * ( factor->n_vars - 1) / 2;
1834
1835       double w = 0;
1836
1837
1838       double xsq;
1839
1840       const int heading_columns = 2;
1841       const int heading_rows = 0;
1842
1843       const int nr = heading_rows + 4;
1844       const int nc = heading_columns + 1;
1845
1846       gsl_matrix *a, *x;
1847
1848       struct tab_table *t = tab_create (nc, nr);
1849       tab_title (t, _("KMO and Bartlett's Test"));
1850
1851       x  = clone_matrix (idata->corr);
1852       gsl_linalg_cholesky_decomp (x);
1853       gsl_linalg_cholesky_invert (x);
1854
1855       a = anti_image (x);
1856
1857       for (i = 0; i < x->size1; ++i)
1858         {
1859           sum_ssq_r += ssq_od_n (x, i);
1860           sum_ssq_a += ssq_od_n (a, i);
1861         }
1862
1863       gsl_matrix_free (a);
1864       gsl_matrix_free (x);
1865
1866       tab_headers (t, heading_columns, 0, heading_rows, 0);
1867
1868       /* Outline the box */
1869       tab_box (t,
1870                TAL_2, TAL_2,
1871                -1, -1,
1872                0, 0,
1873                nc - 1, nr - 1);
1874
1875       tab_vline (t, TAL_2, heading_columns, 0, nr - 1);
1876
1877       tab_text (t, 0, 0, TAT_TITLE | TAB_LEFT, _("Kaiser-Meyer-Olkin Measure of Sampling Adequacy"));
1878
1879       tab_double (t, 2, 0, 0, sum_ssq_r /  (sum_ssq_r + sum_ssq_a), NULL);
1880
1881       tab_text (t, 0, 1, TAT_TITLE | TAB_LEFT, _("Bartlett's Test of Sphericity"));
1882
1883       tab_text (t, 1, 1, TAT_TITLE, _("Approx. Chi-Square"));
1884       tab_text (t, 1, 2, TAT_TITLE, _("df"));
1885       tab_text (t, 1, 3, TAT_TITLE, _("Sig."));
1886
1887
1888       /* The literature doesn't say what to do for the value of W when 
1889          missing values are involved.  The best thing I can think of
1890          is to take the mean average. */
1891       w = 0;
1892       for (i = 0; i < idata->n->size1; ++i)
1893         w += gsl_matrix_get (idata->n, i, i);
1894       w /= idata->n->size1;
1895
1896       xsq = w - 1 - (2 * factor->n_vars + 5) / 6.0;
1897       xsq *= -log (idata->detR);
1898
1899       tab_double (t, 2, 1, 0, xsq, NULL);
1900       tab_double (t, 2, 2, 0, df, &F_8_0);
1901       tab_double (t, 2, 3, 0, gsl_cdf_chisq_Q (xsq, df), NULL);
1902       
1903
1904       tab_submit (t);
1905     }
1906
1907   show_correlation_matrix (factor, idata);
1908   covariance_destroy (cov);
1909
1910   {
1911     gsl_matrix *am = matrix_dup (analysis_matrix);
1912     gsl_eigen_symmv_workspace *workspace = gsl_eigen_symmv_alloc (factor->n_vars);
1913     
1914     gsl_eigen_symmv (am, idata->eval, idata->evec, workspace);
1915
1916     gsl_eigen_symmv_free (workspace);
1917     gsl_matrix_free (am);
1918   }
1919
1920   gsl_eigen_symmv_sort (idata->eval, idata->evec, GSL_EIGEN_SORT_ABS_DESC);
1921
1922   idata->n_extractions = n_extracted_factors (factor, idata);
1923
1924   if (idata->n_extractions == 0)
1925     {
1926       msg (MW, _("The %s criteria result in zero factors extracted. Therefore no analysis will be performed."), "FACTOR");
1927       goto finish;
1928     }
1929
1930   if (idata->n_extractions > factor->n_vars)
1931     {
1932       msg (MW, 
1933            _("The %s criteria result in more factors than variables, which is not meaningful. No analysis will be performed."), 
1934            "FACTOR");
1935       goto finish;
1936     }
1937     
1938   {
1939     gsl_matrix *rotated_factors = NULL;
1940     gsl_vector *rotated_loadings = NULL;
1941
1942     const gsl_vector *extracted_eigenvalues = NULL;
1943     gsl_vector *initial_communalities = gsl_vector_alloc (factor->n_vars);
1944     gsl_vector *extracted_communalities = gsl_vector_alloc (factor->n_vars);
1945     size_t i;
1946     struct factor_matrix_workspace *fmw = factor_matrix_workspace_alloc (idata->msr->size, idata->n_extractions);
1947     gsl_matrix *factor_matrix = gsl_matrix_calloc (factor->n_vars, fmw->n_factors);
1948
1949     if ( factor->extraction == EXTRACTION_PAF)
1950       {
1951         gsl_vector *diff = gsl_vector_alloc (idata->msr->size);
1952         struct smr_workspace *ws = ws_create (analysis_matrix);
1953
1954         for (i = 0 ; i < factor->n_vars ; ++i)
1955           {
1956             double r2 = squared_multiple_correlation (analysis_matrix, i, ws);
1957
1958             gsl_vector_set (idata->msr, i, r2);
1959           }
1960         ws_destroy (ws);
1961
1962         gsl_vector_memcpy (initial_communalities, idata->msr);
1963
1964         for (i = 0; i < factor->extraction_iterations; ++i)
1965           {
1966             double min, max;
1967             gsl_vector_memcpy (diff, idata->msr);
1968
1969             iterate_factor_matrix (analysis_matrix, idata->msr, factor_matrix, fmw);
1970       
1971             gsl_vector_sub (diff, idata->msr);
1972
1973             gsl_vector_minmax (diff, &min, &max);
1974       
1975             if ( fabs (min) < factor->econverge && fabs (max) < factor->econverge)
1976               break;
1977           }
1978         gsl_vector_free (diff);
1979
1980
1981
1982         gsl_vector_memcpy (extracted_communalities, idata->msr);
1983         extracted_eigenvalues = fmw->eval;
1984       }
1985     else if (factor->extraction == EXTRACTION_PC)
1986       {
1987         for (i = 0; i < factor->n_vars; ++i)
1988           gsl_vector_set (initial_communalities, i, communality (idata, i, factor->n_vars));
1989
1990         gsl_vector_memcpy (extracted_communalities, initial_communalities);
1991
1992         iterate_factor_matrix (analysis_matrix, extracted_communalities, factor_matrix, fmw);
1993
1994
1995         extracted_eigenvalues = idata->eval;
1996       }
1997
1998
1999     show_communalities (factor, initial_communalities, extracted_communalities);
2000
2001
2002     if ( factor->rotation != ROT_NONE)
2003       {
2004         rotated_factors = gsl_matrix_calloc (factor_matrix->size1, factor_matrix->size2);
2005         rotated_loadings = gsl_vector_calloc (factor_matrix->size2);
2006
2007         rotate (factor, factor_matrix, extracted_communalities, rotated_factors, rotated_loadings);
2008       }
2009
2010     show_explained_variance (factor, idata, idata->eval, extracted_eigenvalues, rotated_loadings);
2011
2012     factor_matrix_workspace_free (fmw);
2013
2014     show_scree (factor, idata);
2015
2016     show_factor_matrix (factor, idata,
2017                         factor->extraction == EXTRACTION_PC ? _("Component Matrix") : _("Factor Matrix"),
2018                         factor_matrix);
2019
2020     if ( factor->rotation != ROT_NONE)
2021       {
2022         show_factor_matrix (factor, idata,
2023                             factor->extraction == EXTRACTION_PC ? _("Rotated Component Matrix") : _("Rotated Factor Matrix"),
2024                             rotated_factors);
2025
2026         gsl_matrix_free (rotated_factors);
2027       }
2028
2029
2030
2031     gsl_matrix_free (factor_matrix);
2032     gsl_vector_free (rotated_loadings);
2033     gsl_vector_free (initial_communalities);
2034     gsl_vector_free (extracted_communalities);
2035   }
2036
2037  finish:
2038
2039   idata_free (idata);
2040
2041   casereader_destroy (r);
2042 }
2043
2044
2045