MATRIX
[pspp] / src / language / stats / matrix.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2021 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_blas.h>
20 #include <gsl/gsl_eigen.h>
21 #include <gsl/gsl_linalg.h>
22 #include <gsl/gsl_matrix.h>
23 #include <gsl/gsl_permutation.h>
24 #include <gsl/gsl_randist.h>
25 #include <gsl/gsl_vector.h>
26 #include <limits.h>
27 #include <math.h>
28 #include <uniwidth.h>
29
30 #include "data/any-reader.h"
31 #include "data/any-writer.h"
32 #include "data/casereader.h"
33 #include "data/casewriter.h"
34 #include "data/data-in.h"
35 #include "data/data-out.h"
36 #include "data/dataset.h"
37 #include "data/dictionary.h"
38 #include "data/file-handle-def.h"
39 #include "language/command.h"
40 #include "language/data-io/data-reader.h"
41 #include "language/data-io/data-writer.h"
42 #include "language/data-io/file-handle.h"
43 #include "language/lexer/format-parser.h"
44 #include "language/lexer/lexer.h"
45 #include "language/lexer/variable-parser.h"
46 #include "libpspp/array.h"
47 #include "libpspp/assertion.h"
48 #include "libpspp/compiler.h"
49 #include "libpspp/hmap.h"
50 #include "libpspp/i18n.h"
51 #include "libpspp/misc.h"
52 #include "libpspp/str.h"
53 #include "libpspp/string-array.h"
54 #include "libpspp/stringi-set.h"
55 #include "libpspp/u8-line.h"
56 #include "math/random.h"
57 #include "output/driver.h"
58 #include "output/output-item.h"
59 #include "output/pivot-table.h"
60
61 #include "gl/c-ctype.h"
62 #include "gl/minmax.h"
63 #include "gl/xsize.h"
64
65 #include "gettext.h"
66 #define _(msgid) gettext (msgid)
67 #define N_(msgid) (msgid)
68
69 struct matrix_var
70   {
71     struct hmap_node hmap_node;
72     const char *name;
73     gsl_matrix *value;
74   };
75
76 struct msave_common
77   {
78     /* Configuration. */
79     struct file_handle *outfile;
80     struct string_array variables;
81     struct string_array fnames;
82     struct string_array snames;
83     bool has_factors;
84     bool has_splits;
85     size_t n_varnames;
86
87     /* Execution state. */
88     struct dictionary *dict;
89     struct casewriter *writer;
90   };
91
92 struct read_file
93   {
94     struct file_handle *file;
95     struct dfm_reader *reader;
96     char *encoding;
97   };
98
99 struct matrix_state
100   {
101     struct dataset *dataset;
102     struct session *session;
103     struct lexer *lexer;
104     struct hmap vars;
105     bool in_loop;
106     struct file_handle *prev_save_outfile;
107     struct file_handle *prev_write_outfile;
108     struct msave_common *common;
109
110     struct file_handle *prev_read_file;
111     struct read_file **read_files;
112     size_t n_read_files;
113   };
114
115 static struct matrix_var *
116 matrix_var_lookup (struct matrix_state *s, struct substring name)
117 {
118   struct matrix_var *var;
119
120   HMAP_FOR_EACH_WITH_HASH (var, struct matrix_var, hmap_node,
121                            utf8_hash_case_substring (name, 0), &s->vars)
122     if (!utf8_sscasecmp (ss_cstr (var->name), name))
123       return var;
124
125   return NULL;
126 }
127
128 static struct matrix_var *
129 matrix_var_create (struct matrix_state *s, struct substring name)
130 {
131   struct matrix_var *var = xmalloc (sizeof *var);
132   *var = (struct matrix_var) { .name = ss_xstrdup (name) };
133   hmap_insert (&s->vars, &var->hmap_node, utf8_hash_case_substring (name, 0));
134   return var;
135 }
136
137 static void
138 matrix_var_set (struct matrix_var *var, gsl_matrix *value)
139 {
140   gsl_matrix_free (var->value);
141   var->value = value;
142 }
143 \f
144 #define MATRIX_FUNCTIONS \
145     F(ABS, m_m) \
146     F(ALL, d_m) \
147     F(ANY, d_m) \
148     F(ARSIN, m_m) \
149     F(ARTAN, m_m) \
150     F(BLOCK, m_any) \
151     F(CHOL, m_m) \
152     F(CMIN, m_m) \
153     F(CMAX, m_m) \
154     F(COS, m_m) \
155     F(CSSQ, m_m) \
156     F(CSUM, m_m) \
157     F(DESIGN, m_m) \
158     F(DET, d_m) \
159     F(DIAG, m_m) \
160     F(EVAL, m_m) \
161     F(EXP, m_m) \
162     F(GINV, m_m) \
163     F(GRADE, m_m) \
164     F(GSCH, m_m) \
165     F(IDENT, IDENT) \
166     F(INV, m_m) \
167     F(KRONEKER, m_mm) \
168     F(LG10, m_m) \
169     F(LN, m_m) \
170     F(MAGIC, m_d) \
171     F(MAKE, m_ddd) \
172     F(MDIAG, m_v) \
173     F(MMAX, d_m) \
174     F(MMIN, d_m) \
175     F(MOD, m_md) \
176     F(MSSQ, d_m) \
177     F(MSUM, d_m) \
178     F(NCOL, d_m) \
179     F(NROW, d_m) \
180     F(RANK, d_m) \
181     F(RESHAPE, m_mdd) \
182     F(RMAX, m_m) \
183     F(RMIN, m_m) \
184     F(RND, m_m) \
185     F(RNKORDER, m_m) \
186     F(RSSQ, m_m) \
187     F(RSUM, m_m) \
188     F(SIN, m_m) \
189     F(SOLVE, m_mm) \
190     F(SQRT, m_m) \
191     F(SSCP, m_m) \
192     F(SVAL, m_m) \
193     F(SWEEP, m_md) \
194     F(T, m_m) \
195     F(TRACE, d_m) \
196     F(TRANSPOS, m_m) \
197     F(TRUNC, m_m) \
198     F(UNIFORM, m_dd)
199
200 enum { m_d_MIN_ARGS = 1, m_d_MAX_ARGS = 1 };
201 enum { m_dd_MIN_ARGS = 2, m_dd_MAX_ARGS = 2 };
202 enum { m_ddd_MIN_ARGS = 3, m_ddd_MAX_ARGS = 3 };
203 enum { m_m_MIN_ARGS = 1, m_m_MAX_ARGS = 1 };
204 enum { m_md_MIN_ARGS = 2, m_md_MAX_ARGS = 2 };
205 enum { m_mdd_MIN_ARGS = 3, m_mdd_MAX_ARGS = 3 };
206 enum { m_mm_MIN_ARGS = 2, m_mm_MAX_ARGS = 2 };
207 enum { m_v_MIN_ARGS = 1, m_v_MAX_ARGS = 1 };
208 enum { d_m_MIN_ARGS = 1, d_m_MAX_ARGS = 1 };
209 enum { m_any_MIN_ARGS = 1, m_any_MAX_ARGS = INT_MAX };
210 enum { IDENT_MIN_ARGS = 1, IDENT_MAX_ARGS = 2 };
211
212 typedef gsl_matrix *matrix_proto_m_d (double);
213 typedef gsl_matrix *matrix_proto_m_dd (double, double);
214 typedef gsl_matrix *matrix_proto_m_ddd (double, double, double);
215 typedef gsl_matrix *matrix_proto_m_m (gsl_matrix *);
216 typedef gsl_matrix *matrix_proto_m_md (gsl_matrix *, double);
217 typedef gsl_matrix *matrix_proto_m_mdd (gsl_matrix *, double, double);
218 typedef gsl_matrix *matrix_proto_m_mm (gsl_matrix *, gsl_matrix *);
219 typedef gsl_matrix *matrix_proto_m_v (gsl_vector *);
220 typedef double matrix_proto_d_m (gsl_matrix *);
221 typedef gsl_matrix *matrix_proto_m_any (gsl_matrix *[], size_t n);
222 typedef gsl_matrix *matrix_proto_IDENT (double, double);
223
224 #define F(NAME, PROTOTYPE) static matrix_proto_##PROTOTYPE matrix_eval_##NAME;
225 MATRIX_FUNCTIONS
226 #undef F
227 \f
228 /* Matrix expressions. */
229
230 struct matrix_expr
231   {
232     enum matrix_op
233       {
234         /* Functions. */
235 #define F(NAME, PROTOTYPE) MOP_F_##NAME,
236         MATRIX_FUNCTIONS
237 #undef F
238
239         /* Elementwise and scalar arithmetic. */
240         MOP_NEGATE,             /* unary - */
241         MOP_ADD_ELEMS,          /* + */
242         MOP_SUB_ELEMS,          /* - */
243         MOP_MUL_ELEMS,          /* &* */
244         MOP_DIV_ELEMS,          /* / and &/ */
245         MOP_EXP_ELEMS,          /* &** */
246         MOP_SEQ,                /* a:b */
247         MOP_SEQ_BY,             /* a:b:c */
248
249         /* Matrix arithmetic. */
250         MOP_MUL_MAT,            /* * */
251         MOP_EXP_MAT,            /* ** */
252
253         /* Relational. */
254         MOP_GT,                 /* > */
255         MOP_GE,                 /* >= */
256         MOP_LT,                 /* < */
257         MOP_LE,                 /* <= */
258         MOP_EQ,                 /* = */
259         MOP_NE,                 /* <> */
260
261         /* Logical. */
262         MOP_NOT,                /* NOT */
263         MOP_AND,                /* AND */
264         MOP_OR,                 /* OR */
265         MOP_XOR,                /* XOR */
266
267         /* {}. */
268         MOP_PASTE_HORZ,         /* a, b, c, ... */
269         MOP_PASTE_VERT,         /* a; b; c; ... */
270         MOP_EMPTY,              /* {} */
271
272         /* Sub-matrices. */
273         MOP_VEC_INDEX,          /* x(y) */
274         MOP_VEC_ALL,            /* x(:) */
275         MOP_MAT_INDEX,          /* x(y,z) */
276         MOP_ROW_INDEX,          /* x(y,:) */
277         MOP_COL_INDEX,          /* x(:,z) */
278
279         /* Literals. */
280         MOP_NUMBER,
281         MOP_VARIABLE,
282
283         /* Oddball stuff. */
284         MOP_EOF,                /* EOF('file') */
285       }
286     op;
287
288     union
289       {
290         struct
291           {
292             struct matrix_expr **subs;
293             size_t n_subs;
294           };
295
296         double number;
297         struct matrix_var *variable;
298         struct read_file *eof;
299       };
300   };
301
302 static void
303 matrix_expr_destroy (struct matrix_expr *e)
304 {
305   if (!e)
306     return;
307
308   switch (e->op)
309     {
310 #define F(NAME, PROTOTYPE) case MOP_F_##NAME:
311 MATRIX_FUNCTIONS
312 #undef F
313     case MOP_NEGATE:
314     case MOP_ADD_ELEMS:
315     case MOP_SUB_ELEMS:
316     case MOP_MUL_ELEMS:
317     case MOP_DIV_ELEMS:
318     case MOP_EXP_ELEMS:
319     case MOP_SEQ:
320     case MOP_SEQ_BY:
321     case MOP_MUL_MAT:
322     case MOP_EXP_MAT:
323     case MOP_GT:
324     case MOP_GE:
325     case MOP_LT:
326     case MOP_LE:
327     case MOP_EQ:
328     case MOP_NE:
329     case MOP_NOT:
330     case MOP_AND:
331     case MOP_OR:
332     case MOP_XOR:
333     case MOP_EMPTY:
334     case MOP_PASTE_HORZ:
335     case MOP_PASTE_VERT:
336     case MOP_VEC_INDEX:
337     case MOP_VEC_ALL:
338     case MOP_MAT_INDEX:
339     case MOP_ROW_INDEX:
340     case MOP_COL_INDEX:
341       for (size_t i = 0; i < e->n_subs; i++)
342         matrix_expr_destroy (e->subs[i]);
343       break;
344
345     case MOP_NUMBER:
346     case MOP_VARIABLE:
347     case MOP_EOF:
348       break;
349     }
350   free (e);
351 }
352
353 static struct matrix_expr *
354 matrix_expr_create_subs (enum matrix_op op, struct matrix_expr **subs,
355                          size_t n_subs)
356 {
357   struct matrix_expr *e = xmalloc (sizeof *e);
358   *e = (struct matrix_expr) {
359     .op = op,
360     .subs = xmemdup (subs, n_subs * sizeof *subs),
361     .n_subs = n_subs
362   };
363   return e;
364 }
365
366 static struct matrix_expr *
367 matrix_expr_create_0 (enum matrix_op op)
368 {
369   struct matrix_expr *sub;
370   return matrix_expr_create_subs (op, &sub, 0);
371 }
372
373 static struct matrix_expr *
374 matrix_expr_create_1 (enum matrix_op op, struct matrix_expr *sub)
375 {
376   return matrix_expr_create_subs (op, &sub, 1);
377 }
378
379 static struct matrix_expr *
380 matrix_expr_create_2 (enum matrix_op op,
381                       struct matrix_expr *sub0, struct matrix_expr *sub1)
382 {
383   struct matrix_expr *subs[] = { sub0, sub1 };
384   return matrix_expr_create_subs (op, subs, sizeof subs / sizeof *subs);
385 }
386
387 static struct matrix_expr *
388 matrix_expr_create_3 (enum matrix_op op, struct matrix_expr *sub0,
389                       struct matrix_expr *sub1, struct matrix_expr *sub2)
390 {
391   struct matrix_expr *subs[] = { sub0, sub1, sub2 };
392   return matrix_expr_create_subs (op, subs, sizeof subs / sizeof *subs);
393 }
394
395 static struct matrix_expr *
396 matrix_expr_create_number (double number)
397 {
398   struct matrix_expr *e = xmalloc (sizeof *e);
399   *e = (struct matrix_expr) { .op = MOP_NUMBER, .number = number };
400   return e;
401 }
402
403 static struct matrix_expr *matrix_parse_or_xor (struct matrix_state *);
404
405 static struct matrix_expr *
406 matrix_parse_curly_comma (struct matrix_state *s)
407 {
408   struct matrix_expr *lhs = matrix_parse_or_xor (s);
409   if (!lhs)
410     return NULL;
411
412   while (lex_match (s->lexer, T_COMMA))
413     {
414       struct matrix_expr *rhs = matrix_parse_or_xor (s);
415       if (!rhs)
416         {
417           matrix_expr_destroy (lhs);
418           return NULL;
419         }
420       lhs = matrix_expr_create_2 (MOP_PASTE_HORZ, lhs, rhs);
421     }
422   return lhs;
423 }
424
425 static struct matrix_expr *
426 matrix_parse_curly_semi (struct matrix_state *s)
427 {
428   if (lex_token (s->lexer) == T_RCURLY)
429     return matrix_expr_create_0 (MOP_EMPTY);
430
431   struct matrix_expr *lhs = matrix_parse_curly_comma (s);
432   if (!lhs)
433     return NULL;
434
435   while (lex_match (s->lexer, T_SEMICOLON))
436     {
437       struct matrix_expr *rhs = matrix_parse_curly_comma (s);
438       if (!rhs)
439         {
440           matrix_expr_destroy (lhs);
441           return NULL;
442         }
443       lhs = matrix_expr_create_2 (MOP_PASTE_VERT, lhs, rhs);
444     }
445   return lhs;
446 }
447
448 #define MATRIX_FOR_ALL_ELEMENTS(D, Y, X, M)                     \
449   for (size_t Y = 0; Y < (M)->size1; Y++)                       \
450     for (size_t X = 0; X < (M)->size2; X++)                     \
451       for (double *D = gsl_matrix_ptr ((M), Y, X); D; D = NULL)
452
453 static bool
454 is_vector (gsl_matrix *m)
455 {
456   return m->size1 <= 1 || m->size2 <= 1;
457 }
458
459 static gsl_vector
460 to_vector (gsl_matrix *m)
461 {
462   return (m->size1 == 1
463           ? gsl_matrix_row (m, 0).vector
464           : gsl_matrix_column (m, 0).vector);
465 }
466
467
468 static gsl_matrix *
469 matrix_eval_ABS (gsl_matrix *m)
470 {
471   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
472     *d = fabs (*d);
473   return m;
474 }
475
476 static double
477 matrix_eval_ALL (gsl_matrix *m)
478 {
479   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
480     if (*d == 0.0)
481       return 0.0;
482   return 1.0;
483 }
484
485 static double
486 matrix_eval_ANY (gsl_matrix *m)
487 {
488   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
489     if (*d != 0.0)
490       return !.0;
491   return 0.0;
492 }
493
494 static gsl_matrix *
495 matrix_eval_ARSIN (gsl_matrix *m)
496 {
497   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
498     *d = asin (*d);
499   return m;
500 }
501
502 static gsl_matrix *
503 matrix_eval_ARTAN (gsl_matrix *m)
504 {
505   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
506     *d = atan (*d);
507   return m;
508 }
509
510 static gsl_matrix *
511 matrix_eval_BLOCK (gsl_matrix *m[], size_t n)
512 {
513   size_t r = 0;
514   size_t c = 0;
515   for (size_t i = 0; i < n; i++)
516     {
517       r += m[i]->size1;
518       c += m[i]->size2;
519     }
520   gsl_matrix *block = gsl_matrix_calloc (r, c);
521   r = c = 0;
522   for (size_t i = 0; i < n; i++)
523     {
524       for (size_t y = 0; y < m[i]->size1; y++)
525         for (size_t x = 0; x < m[i]->size2; x++)
526           gsl_matrix_set (block, r + y, c + x, gsl_matrix_get (m[i], y, x));
527       r += m[i]->size1;
528       c += m[i]->size2;
529     }
530   return block;
531 }
532
533 static gsl_matrix *
534 matrix_eval_CHOL (gsl_matrix *m)
535 {
536   if (!gsl_linalg_cholesky_decomp1 (m))
537     {
538       for (size_t y = 0; y < m->size1; y++)
539         for (size_t x = y + 1; x < m->size2; x++)
540           gsl_matrix_set (m, y, x, gsl_matrix_get (m, x, y));
541
542       for (size_t y = 0; y < m->size1; y++)
543         for (size_t x = 0; x < y; x++)
544           gsl_matrix_set (m, y, x, 0);
545       return m;
546     }
547   else
548     {
549       msg (SE, _("Input to CHOL function is not positive-definite."));
550       return NULL;
551     }
552 }
553
554 static gsl_matrix *
555 matrix_eval_col_extremum (gsl_matrix *m, bool min)
556 {
557   if (m->size1 <= 1)
558     return m;
559   else if (!m->size2)
560     return gsl_matrix_alloc (1, 0);
561
562   gsl_matrix *cext = gsl_matrix_alloc (1, m->size2);
563   for (size_t x = 0; x < m->size2; x++)
564     {
565       double ext = gsl_matrix_get (m, 0, x);
566       for (size_t y = 1; y < m->size1; y++)
567         {
568           double value = gsl_matrix_get (m, y, x);
569           if (min ? value < ext : value > ext)
570             ext = value;
571         }
572       gsl_matrix_set (cext, 0, x, ext);
573     }
574   return cext;
575 }
576
577 static gsl_matrix *
578 matrix_eval_CMAX (gsl_matrix *m)
579 {
580   return matrix_eval_col_extremum (m, false);
581 }
582
583 static gsl_matrix *
584 matrix_eval_CMIN (gsl_matrix *m)
585 {
586   return matrix_eval_col_extremum (m, true);
587 }
588
589 static gsl_matrix *
590 matrix_eval_COS (gsl_matrix *m)
591 {
592   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
593     *d = cos (*d);
594   return m;
595 }
596
597 static gsl_matrix *
598 matrix_eval_col_sum (gsl_matrix *m, bool square)
599 {
600   if (m->size1 == 0)
601     return m;
602   else if (!m->size2)
603     return gsl_matrix_alloc (1, 0);
604
605   gsl_matrix *result = gsl_matrix_alloc (1, m->size2);
606   for (size_t x = 0; x < m->size2; x++)
607     {
608       double sum = 0;
609       for (size_t y = 0; y < m->size1; y++)
610         {
611           double d = gsl_matrix_get (m, y, x);
612           sum += square ? pow2 (d) : d;
613         }
614       gsl_matrix_set (result, 0, x, sum);
615     }
616   return result;
617 }
618
619 static gsl_matrix *
620 matrix_eval_CSSQ (gsl_matrix *m)
621 {
622   return matrix_eval_col_sum (m, true);
623 }
624
625 static gsl_matrix *
626 matrix_eval_CSUM (gsl_matrix *m)
627 {
628   return matrix_eval_col_sum (m, false);
629 }
630
631 static int
632 compare_double_3way (const void *a_, const void *b_)
633 {
634   const double *a = a_;
635   const double *b = b_;
636   return *a < *b ? -1 : *a > *b;
637 }
638
639 static gsl_matrix *
640 matrix_eval_DESIGN (gsl_matrix *m)
641 {
642   double *tmp = xmalloc (m->size1 * m->size2 * sizeof *tmp);
643   gsl_matrix m2 = gsl_matrix_view_array (tmp, m->size2, m->size1).matrix;
644   gsl_matrix_transpose_memcpy (&m2, m);
645
646   for (size_t y = 0; y < m2.size1; y++)
647     qsort (tmp + y * m2.size2, m2.size2, sizeof *tmp, compare_double_3way);
648
649   size_t *n = xcalloc (m2.size1, sizeof *n);
650   size_t n_total = 0;
651   for (size_t i = 0; i < m2.size1; i++)
652     {
653       double *row = tmp + m2.size2 * i;
654       for (size_t j = 0; j < m2.size2; )
655         {
656           size_t k;
657           for (k = j + 1; k < m2.size2; k++)
658             if (row[j] != row[k])
659               break;
660           row[n[i]++] = row[j];
661           j = k;
662         }
663
664       if (n[i] <= 1)
665         msg (MW, _("Column %zu in DESIGN argument has constant value."), i + 1);
666       else
667         n_total += n[i];
668     }
669
670   gsl_matrix *result = gsl_matrix_alloc (m->size1, n_total);
671   size_t x = 0;
672   for (size_t i = 0; i < m->size2; i++)
673     {
674       if (n[i] <= 1)
675         continue;
676
677       const double *unique = tmp + m2.size2 * i;
678       for (size_t j = 0; j < n[i]; j++, x++)
679         {
680           double value = unique[j];
681           for (size_t y = 0; y < m->size1; y++)
682             gsl_matrix_set (result, y, x, gsl_matrix_get (m, y, i) == value);
683         }
684     }
685
686   free (n);
687   free (tmp);
688
689   return result;
690 }
691
692 static double
693 matrix_eval_DET (gsl_matrix *m)
694 {
695   gsl_permutation *p = gsl_permutation_alloc (m->size1);
696   int signum;
697   gsl_linalg_LU_decomp (m, p, &signum);
698   gsl_permutation_free (p);
699   return gsl_linalg_LU_det (m, signum);
700 }
701
702 static gsl_matrix *
703 matrix_eval_DIAG (gsl_matrix *m)
704 {
705   gsl_matrix *diag = gsl_matrix_alloc (MIN (m->size1, m->size2), 1);
706   for (size_t i = 0; i < diag->size1; i++)
707     gsl_matrix_set (diag, i, 0, gsl_matrix_get (m, i, i));
708   return diag;
709 }
710
711 static bool
712 is_symmetric (const gsl_matrix *m)
713 {
714   if (m->size1 != m->size2)
715     return false;
716
717   for (size_t y = 0; y < m->size1; y++)
718     for (size_t x = 0; x < y; x++)
719       if (gsl_matrix_get (m, y, x) != gsl_matrix_get (m, x, y))
720         return false;
721
722   return true;
723 }
724
725 static int
726 compare_double_desc (const void *a_, const void *b_)
727 {
728   const double *a = a_;
729   const double *b = b_;
730   return *a > *b ? -1 : *a < *b;
731 }
732
733 static gsl_matrix *
734 matrix_eval_EVAL (gsl_matrix *m)
735 {
736   if (!is_symmetric (m))
737     {
738       msg (SE, _("Argument of EVAL must be symmetric."));
739       return NULL;
740     }
741
742   gsl_eigen_symm_workspace *w = gsl_eigen_symm_alloc (m->size1);
743   gsl_matrix *eval = gsl_matrix_alloc (m->size1, 1);
744   gsl_vector v_eval = to_vector (eval);
745   gsl_eigen_symm (m, &v_eval, w);
746   gsl_eigen_symm_free (w);
747
748   assert (v_eval.stride == 1);
749   qsort (v_eval.data, v_eval.size, sizeof *v_eval.data, compare_double_desc);
750
751   return eval;
752 }
753
754 static gsl_matrix *
755 matrix_eval_EXP (gsl_matrix *m)
756 {
757   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
758     *d = exp (*d);
759   return m;
760 }
761
762 /* From https://gist.github.com/turingbirds/5e99656e08dbe1324c99, where it was
763    marked as:
764
765    Charl Linssen <charl@itfromb.it>
766    Feb 2016
767    PUBLIC DOMAIN */
768 static gsl_matrix *
769 matrix_eval_GINV (gsl_matrix *A)
770 {
771   size_t n = A->size1;
772   size_t m = A->size2;
773   bool swap = m > n;
774   gsl_matrix *tmp_mat = NULL;
775   if (swap)
776     {
777       /* libgsl SVD can only handle the case m <= n, so transpose matrix. */
778       tmp_mat = gsl_matrix_alloc (m, n);
779       gsl_matrix_transpose_memcpy (tmp_mat, A);
780       A = tmp_mat;
781       size_t i = m;
782       m = n;
783       n = i;
784     }
785
786   /* Do SVD. */
787   gsl_matrix *V = gsl_matrix_alloc (m, m);
788   gsl_vector *u = gsl_vector_alloc (m);
789
790   gsl_vector *tmp_vec = gsl_vector_alloc (m);
791   gsl_linalg_SV_decomp (A, V, u, tmp_vec);
792   gsl_vector_free (tmp_vec);
793
794   /* Compute Σ⁻¹. */
795   gsl_matrix *Sigma_pinv = gsl_matrix_alloc (m, n);
796   gsl_matrix_set_zero (Sigma_pinv);
797   double cutoff = 1e-15 * gsl_vector_max (u);
798
799   for (size_t i = 0; i < m; ++i)
800     {
801       double x = gsl_vector_get (u, i);
802       gsl_matrix_set (Sigma_pinv, i, i, x > cutoff ? 1.0 / x : 0);
803     }
804
805   /* libgsl SVD yields "thin" SVD - pad to full matrix by adding zeros */
806   gsl_matrix *U = gsl_matrix_calloc (n, n);
807   for (size_t i = 0; i < n; i++)
808     for (size_t j = 0; j < m; j++)
809       gsl_matrix_set (U, i, j, gsl_matrix_get (A, i, j));
810
811   /* two dot products to obtain pseudoinverse */
812   tmp_mat = gsl_matrix_alloc (m, n);
813   gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1., V, Sigma_pinv, 0., tmp_mat);
814
815   gsl_matrix *A_pinv;
816   if (swap)
817     {
818       A_pinv = gsl_matrix_alloc (n, m);
819       gsl_blas_dgemm (CblasNoTrans, CblasTrans, 1., U, tmp_mat, 0., A_pinv);
820     }
821   else
822     {
823       A_pinv = gsl_matrix_alloc (m, n);
824       gsl_blas_dgemm (CblasNoTrans, CblasTrans, 1., tmp_mat, U, 0., A_pinv);
825     }
826
827   gsl_matrix_free (tmp_mat);
828   gsl_matrix_free (U);
829   gsl_matrix_free (Sigma_pinv);
830   gsl_vector_free (u);
831   gsl_matrix_free (V);
832
833   return A_pinv;
834 }
835
836 struct grade
837   {
838     size_t y, x;
839     double value;
840   };
841
842 static int
843 grade_compare_3way (const void *a_, const void *b_)
844 {
845   const struct grade *a = a_;
846   const struct grade *b = b_;
847
848   return (a->value < b->value ? -1
849           : a->value > b->value ? 1
850           : a->y < b->y ? -1
851           : a->y > b->y ? 1
852           : a->x < b->x ? -1
853           : a->x > b->x);
854 }
855
856 static gsl_matrix *
857 matrix_eval_GRADE (gsl_matrix *m)
858 {
859   size_t n = m->size1 * m->size2;
860   struct grade *grades = xmalloc (n * sizeof *grades);
861
862   size_t i = 0;
863   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
864     grades[i++] = (struct grade) { .y = y, .x = x, .value = *d };
865   qsort (grades, n, sizeof *grades, grade_compare_3way);
866
867   for (size_t i = 0; i < n; i++)
868     gsl_matrix_set (m, grades[i].y, grades[i].x, i + 1);
869
870   free (grades);
871
872   return m;
873 }
874
875 static double
876 dot (gsl_vector *a, gsl_vector *b)
877 {
878   double result = 0.0;
879   for (size_t i = 0; i < a->size; i++)
880     result += gsl_vector_get (a, i) * gsl_vector_get (b, i);
881   return result;
882 }
883
884 static double
885 norm2 (gsl_vector *v)
886 {
887   double result = 0.0;
888   for (size_t i = 0; i < v->size; i++)
889     result += pow2 (gsl_vector_get (v, i));
890   return result;
891 }
892
893 static double
894 norm (gsl_vector *v)
895 {
896   return sqrt (norm2 (v));
897 }
898
899 static gsl_matrix *
900 matrix_eval_GSCH (gsl_matrix *v)
901 {
902   if (v->size2 < v->size1)
903     {
904       msg (SE, _("GSCH requires its argument to have at least as many columns "
905                  "as rows, but it has dimensions (%zu,%zu)."),
906            v->size1, v->size2);
907       return NULL;
908     }
909   if (!v->size1 || !v->size2)
910     return v;
911
912   gsl_matrix *u = gsl_matrix_calloc (v->size1, v->size2);
913   size_t ux = 0;
914   for (size_t vx = 0; vx < v->size2; vx++)
915     {
916       gsl_vector u_i = gsl_matrix_column (u, ux).vector;
917       gsl_vector v_i = gsl_matrix_column (v, vx).vector;
918
919       gsl_vector_memcpy (&u_i, &v_i);
920       for (size_t j = 0; j < ux; j++)
921         {
922           gsl_vector u_j = gsl_matrix_column (u, j).vector;
923           double scale = dot (&u_j, &u_i) / norm2 (&u_j);
924           for (size_t k = 0; k < u_i.size; k++)
925             gsl_vector_set (&u_i, k, (gsl_vector_get (&u_i, k)
926                                       - scale * gsl_vector_get (&u_j, k)));
927         }
928
929       double len = norm (&u_i);
930       if (len > 1e-15)
931         {
932           gsl_vector_scale (&u_i, 1.0 / len);
933           if (++ux >= v->size1)
934             break;
935         }
936     }
937
938   if (ux < v->size1)
939     {
940       msg (SE, _("Argument to GSCH with dimensions (%zu,%zu) contains only "
941                  "%zu linearly independent columns."),
942            v->size1, v->size2, ux);
943       return NULL;
944     }
945
946   u->size2 = v->size1;
947   return u;
948 }
949
950 static gsl_matrix *
951 matrix_eval_IDENT (double s1, double s2)
952 {
953   if (s1 < 0 || s1 > SIZE_MAX || s2 < 0 || s2 > SIZE_MAX)
954     {
955       msg (SE, _("Arguments to IDENT must be non-negative integers."));
956       return NULL;
957     }
958
959   gsl_matrix *m = gsl_matrix_alloc (s1, s2);
960   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
961     *d = x == y;
962   return m;
963 }
964
965 static void
966 invert_matrix (gsl_matrix *x)
967 {
968   gsl_permutation *p = gsl_permutation_alloc (x->size1);
969   int signum;
970   gsl_linalg_LU_decomp (x, p, &signum);
971   gsl_linalg_LU_invx (x, p);
972   gsl_permutation_free (p);
973 }
974
975 static gsl_matrix *
976 matrix_eval_INV (gsl_matrix *m)
977 {
978   invert_matrix (m);
979   return m;
980 }
981
982 static gsl_matrix *
983 matrix_eval_KRONEKER (gsl_matrix *a, gsl_matrix *b)
984 {
985   gsl_matrix *k = gsl_matrix_alloc (a->size1 * b->size1,
986                                     a->size2 * b->size2);
987   size_t y = 0;
988   for (size_t ar = 0; ar < a->size1; ar++)
989     for (size_t br = 0; br < b->size1; br++, y++)
990       {
991         size_t x = 0;
992         for (size_t ac = 0; ac < a->size2; ac++)
993           for (size_t bc = 0; bc < b->size2; bc++, x++)
994             {
995               double av = gsl_matrix_get (a, ar, ac);
996               double bv = gsl_matrix_get (b, br, bc);
997               gsl_matrix_set (k, y, x, av * bv);
998             }
999       }
1000   return k;
1001 }
1002
1003 static gsl_matrix *
1004 matrix_eval_LG10 (gsl_matrix *m)
1005 {
1006   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
1007     *d = log10 (*d);
1008   return m;
1009 }
1010
1011 static gsl_matrix *
1012 matrix_eval_LN (gsl_matrix *m)
1013 {
1014   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
1015     *d = log (*d);
1016   return m;
1017 }
1018
1019 static void
1020 matrix_eval_MAGIC_odd (gsl_matrix *m, size_t n)
1021 {
1022   /* Siamese method: https://en.wikipedia.org/wiki/Siamese_method. */
1023   size_t y = 0;
1024   size_t x = n / 2;
1025   for (size_t i = 1; i <= n * n; i++)
1026     {
1027       gsl_matrix_set (m, y, x, i);
1028
1029       size_t y1 = !y ? n - 1 : y - 1;
1030       size_t x1 = x + 1 >= n ? 0 : x + 1;
1031       if (gsl_matrix_get (m, y1, x1) == 0)
1032         {
1033           y = y1;
1034           x = x1;
1035         }
1036       else
1037         y = y + 1 >= n ? 0 : y + 1;
1038     }
1039 }
1040
1041 static void
1042 magic_exchange (gsl_matrix *m, size_t y1, size_t x1, size_t y2, size_t x2)
1043 {
1044   double a = gsl_matrix_get (m, y1, x1);
1045   double b = gsl_matrix_get (m, y2, x2);
1046   gsl_matrix_set (m, y1, x1, b);
1047   gsl_matrix_set (m, y2, x2, a);
1048 }
1049
1050 static void
1051 matrix_eval_MAGIC_doubly_even (gsl_matrix *m, size_t n)
1052 {
1053   size_t x, y;
1054
1055   /* A. Umar, "On the Construction of Even Order Magic Squares",
1056      https://arxiv.org/ftp/arxiv/papers/1202/1202.0948.pdf. */
1057   x = y = 0;
1058   for (size_t i = 1; i <= n * n / 2; i++)
1059     {
1060       gsl_matrix_set (m, y, x, i);
1061       if (++y >= n)
1062         {
1063           y = 0;
1064           x++;
1065         }
1066     }
1067
1068   x = n - 1;
1069   y = 0;
1070   for (size_t i = n * n; i > n * n / 2; i--)
1071     {
1072       gsl_matrix_set (m, y, x, i);
1073       if (++y >= n)
1074         {
1075           y = 0;
1076           x--;
1077         }
1078     }
1079
1080   for (size_t y = 0; y < n; y++)
1081     for (size_t x = 0; x < n / 2; x++)
1082       {
1083         unsigned int d = gsl_matrix_get (m, y, x);
1084         if (d % 2 != (y < n / 2))
1085           magic_exchange (m, y, x, y, n - x - 1);
1086       }
1087
1088   size_t y1 = n / 2;
1089   size_t y2 = n - 1;
1090   size_t x1 = n / 2 - 1;
1091   size_t x2 = n / 2;
1092   magic_exchange (m, y1, x1, y2, x1);
1093   magic_exchange (m, y1, x2, y2, x2);
1094 }
1095
1096 static void
1097 matrix_eval_MAGIC_singly_even (gsl_matrix *m, size_t n)
1098 {
1099   /* A. Umar, "On the Construction of Even Order Magic Squares",
1100      https://arxiv.org/ftp/arxiv/papers/1202/1202.0948.pdf. */
1101   size_t x, y;
1102
1103   x = y = 0;
1104   for (size_t i = 1; ; i++)
1105     {
1106       gsl_matrix_set (m, y, x, i);
1107       if (++y == n / 2 - 1)
1108         y += 2;
1109       else if (y >= n)
1110         {
1111           y = 0;
1112           if (++x >= n / 2)
1113             break;
1114         }
1115     }
1116
1117   x = n - 1;
1118   y = 0;
1119   for (size_t i = n * n; ; i--)
1120     {
1121       gsl_matrix_set (m, y, x, i);
1122       if (++y == n / 2 - 1)
1123         y += 2;
1124       else if (y >= n)
1125         {
1126           y = 0;
1127           if (--x < n / 2)
1128             break;
1129         }
1130     }
1131   for (size_t y = 0; y < n; y++)
1132     if (y != n / 2 - 1 && y != n / 2)
1133       for (size_t x = 0; x < n / 2; x++)
1134         {
1135           unsigned int d = gsl_matrix_get (m, y, x);
1136           if (d % 2 != (y < n / 2))
1137             magic_exchange (m, y, x, y, n - x - 1);
1138         }
1139
1140   size_t a0 = (n * n - 2 * n) / 2 + 1;
1141   for (size_t i = 0; i < n / 2; i++)
1142     {
1143       size_t a = a0 + i;
1144       gsl_matrix_set (m, n / 2, i, a);
1145       gsl_matrix_set (m, n / 2 - 1, i, (n * n + 1) - a);
1146     }
1147   for (size_t i = 0; i < n / 2; i++)
1148     {
1149       size_t a = a0 + i + n / 2;
1150       gsl_matrix_set (m, n / 2 - 1, n - i - 1, a);
1151       gsl_matrix_set (m, n / 2, n - i - 1, (n * n + 1) - a);
1152     }
1153   for (size_t x = 1; x < n / 2; x += 2)
1154     magic_exchange (m, n / 2, x, n / 2 - 1, x);
1155   for (size_t x = n / 2 + 2; x <= n - 3; x += 2)
1156     magic_exchange (m, n / 2, x, n / 2 - 1, x);
1157   size_t x1 = n / 2 - 2;
1158   size_t x2 = n / 2 + 1;
1159   size_t y1 = n / 2 - 2;
1160   size_t y2 = n / 2 + 1;
1161   magic_exchange (m, y1, x1, y2, x1);
1162   magic_exchange (m, y1, x2, y2, x2);
1163 }
1164
1165 static gsl_matrix *
1166 matrix_eval_MAGIC (double n_)
1167 {
1168   if (n_ < 3 || n_ >= sqrt (SIZE_MAX))
1169     {
1170       msg (SE, _("MAGIC argument must be an integer 3 or greater."));
1171       return NULL;
1172     }
1173   size_t n = n_;
1174
1175   gsl_matrix *m = gsl_matrix_calloc (n, n);
1176   if (n % 2)
1177     matrix_eval_MAGIC_odd (m, n);
1178   else if (n % 4)
1179     matrix_eval_MAGIC_singly_even (m, n);
1180   else
1181     matrix_eval_MAGIC_doubly_even (m, n);
1182   return m;
1183 }
1184
1185 static gsl_matrix *
1186 matrix_eval_MAKE (double r, double c, double value)
1187 {
1188   if (r < 0 || r >= SIZE_MAX || c < 0 || c >= SIZE_MAX)
1189     {
1190       msg (SE, _("Size arguments to MAKE must be integers."));
1191       return NULL;
1192     }
1193
1194   gsl_matrix *m = gsl_matrix_alloc (r, c);
1195   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
1196     *d = value;
1197   return m;
1198 }
1199
1200 static gsl_matrix *
1201 matrix_eval_MDIAG (gsl_vector *v)
1202 {
1203   gsl_matrix *m = gsl_matrix_alloc (v->size, v->size);
1204   gsl_vector diagonal = gsl_matrix_diagonal (m).vector;
1205   gsl_vector_memcpy (&diagonal, v);
1206   return m;
1207 }
1208
1209 static double
1210 matrix_eval_MMAX (gsl_matrix *m)
1211 {
1212   return gsl_matrix_max (m);
1213 }
1214
1215 static double
1216 matrix_eval_MMIN (gsl_matrix *m)
1217 {
1218   return gsl_matrix_min (m);
1219 }
1220
1221 static gsl_matrix *
1222 matrix_eval_MOD (gsl_matrix *m, double divisor)
1223 {
1224   if (divisor == 0.0)
1225     {
1226       msg (SE, _("Divisor argument to MOD function must be nonzero."));
1227       return NULL;
1228     }
1229
1230   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
1231     *d = fmod (*d, divisor);
1232   return m;
1233 }
1234
1235 static double
1236 matrix_eval_MSSQ (gsl_matrix *m)
1237 {
1238   double mssq = 0.0;
1239   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
1240     mssq += *d * *d;
1241   return mssq;
1242 }
1243
1244 static double
1245 matrix_eval_MSUM (gsl_matrix *m)
1246 {
1247   double msum = 0.0;
1248   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
1249     msum += *d;
1250   return msum;
1251 }
1252
1253 static double
1254 matrix_eval_NCOL (gsl_matrix *m)
1255 {
1256   return m->size2;
1257 }
1258
1259 static double
1260 matrix_eval_NROW (gsl_matrix *m)
1261 {
1262   return m->size1;
1263 }
1264
1265 static double
1266 matrix_eval_RANK (gsl_matrix *m)
1267 {
1268   gsl_vector *tau = gsl_vector_alloc (MIN (m->size1, m->size2));
1269   gsl_linalg_QR_decomp (m, tau);
1270   gsl_vector_free (tau);
1271
1272   return gsl_linalg_QRPT_rank (m, -1);
1273 }
1274
1275 static gsl_matrix *
1276 matrix_eval_RESHAPE (gsl_matrix *m, double r_, double c_)
1277 {
1278   if (r_ < 0 || r_ >= SIZE_MAX || c_ < 0 || c_ >= SIZE_MAX)
1279     {
1280       msg (SE, _("Arguments 2 and 3 to RESHAPE must be integers."));
1281       return NULL;
1282     }
1283   size_t r = r_;
1284   size_t c = c_;
1285   if (size_overflow_p (xtimes (r, xmax (c, 1))) || c * r != m->size1 * m->size2)
1286     {
1287       msg (SE, _("Product of RESHAPE arguments 2 and 3 differ from "
1288                  "product of matrix dimensions."));
1289       return NULL;
1290     }
1291
1292   gsl_matrix *dst = gsl_matrix_alloc (r, c);
1293   size_t y1 = 0;
1294   size_t x1 = 0;
1295   MATRIX_FOR_ALL_ELEMENTS (d, y2, x2, m)
1296     {
1297       gsl_matrix_set (dst, y1, x1, *d);
1298       if (++x1 >= c)
1299         {
1300           x1 = 0;
1301           y1++;
1302         }
1303     }
1304   return dst;
1305 }
1306
1307 static gsl_matrix *
1308 matrix_eval_row_extremum (gsl_matrix *m, bool min)
1309 {
1310   if (m->size2 <= 1)
1311     return m;
1312   else if (!m->size1)
1313     return gsl_matrix_alloc (0, 1);
1314
1315   gsl_matrix *rext = gsl_matrix_alloc (m->size1, 1);
1316   for (size_t y = 0; y < m->size1; y++)
1317     {
1318       double ext = gsl_matrix_get (m, y, 0);
1319       for (size_t x = 1; x < m->size2; x++)
1320         {
1321           double value = gsl_matrix_get (m, y, x);
1322           if (min ? value < ext : value > ext)
1323             ext = value;
1324         }
1325       gsl_matrix_set (rext, y, 0, ext);
1326     }
1327   return rext;
1328 }
1329
1330 static gsl_matrix *
1331 matrix_eval_RMAX (gsl_matrix *m)
1332 {
1333   return matrix_eval_row_extremum (m, false);
1334 }
1335
1336 static gsl_matrix *
1337 matrix_eval_RMIN (gsl_matrix *m)
1338 {
1339   return matrix_eval_row_extremum (m, true);
1340 }
1341
1342 static gsl_matrix *
1343 matrix_eval_RND (gsl_matrix *m)
1344 {
1345   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
1346     *d = rint (*d);
1347   return m;
1348 }
1349
1350 struct rank
1351   {
1352     size_t y, x;
1353     double value;
1354   };
1355
1356 static int
1357 rank_compare_3way (const void *a_, const void *b_)
1358 {
1359   const struct rank *a = a_;
1360   const struct rank *b = b_;
1361
1362   return a->value < b->value ? -1 : a->value > b->value;
1363 }
1364
1365 static gsl_matrix *
1366 matrix_eval_RNKORDER (gsl_matrix *m)
1367 {
1368   size_t n = m->size1 * m->size2;
1369   struct rank *ranks = xmalloc (n * sizeof *ranks);
1370   size_t i = 0;
1371   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
1372     ranks[i++] = (struct rank) { .y = y, .x = x, .value = *d };
1373   qsort (ranks, n, sizeof *ranks, rank_compare_3way);
1374
1375   for (size_t i = 0; i < n; )
1376     {
1377       size_t j;
1378       for (j = i + 1; j < n; j++)
1379         if (ranks[i].value != ranks[j].value)
1380           break;
1381
1382       double rank = (i + j + 1.0) / 2.0;
1383       for (size_t k = i; k < j; k++)
1384         gsl_matrix_set (m, ranks[k].y, ranks[k].x, rank);
1385
1386       i = j;
1387     }
1388
1389   free (ranks);
1390
1391   return m;
1392 }
1393
1394 static gsl_matrix *
1395 matrix_eval_row_sum (gsl_matrix *m, bool square)
1396 {
1397   if (m->size1 == 0)
1398     return m;
1399   else if (!m->size1)
1400     return gsl_matrix_alloc (0, 1);
1401
1402   gsl_matrix *result = gsl_matrix_alloc (m->size1, 1);
1403   for (size_t y = 0; y < m->size1; y++)
1404     {
1405       double sum = 0;
1406       for (size_t x = 0; x < m->size2; x++)
1407         {
1408           double d = gsl_matrix_get (m, y, x);
1409           sum += square ? pow2 (d) : d;
1410         }
1411       gsl_matrix_set (result, y, 0, sum);
1412     }
1413   return result;
1414 }
1415
1416 static gsl_matrix *
1417 matrix_eval_RSSQ (gsl_matrix *m)
1418 {
1419   return matrix_eval_row_sum (m, true);
1420 }
1421
1422 static gsl_matrix *
1423 matrix_eval_RSUM (gsl_matrix *m)
1424 {
1425   return matrix_eval_row_sum (m, false);
1426 }
1427
1428 static gsl_matrix *
1429 matrix_eval_SIN (gsl_matrix *m)
1430 {
1431   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
1432     *d = sin (*d);
1433   return m;
1434 }
1435
1436 static gsl_matrix *
1437 matrix_eval_SOLVE (gsl_matrix *m1, gsl_matrix *m2)
1438 {
1439   if (m1->size1 != m2->size1)
1440     {
1441       msg (SE, _("SOLVE requires its arguments to have the same number of "
1442                  "rows, but the first argument has dimensions (%zu,%zu) and "
1443                  "the second (%zu,%zu)."),
1444            m1->size1, m1->size2,
1445            m2->size1, m2->size2);
1446       return NULL;
1447     }
1448
1449   gsl_matrix *x = gsl_matrix_alloc (m2->size1, m2->size2);
1450   gsl_permutation *p = gsl_permutation_alloc (m1->size1);
1451   int signum;
1452   gsl_linalg_LU_decomp (m1, p, &signum);
1453   for (size_t i = 0; i < m2->size2; i++)
1454     {
1455       gsl_vector bi = gsl_matrix_column (m2, i).vector;
1456       gsl_vector xi = gsl_matrix_column (x, i).vector;
1457       gsl_linalg_LU_solve (m1, p, &bi, &xi);
1458     }
1459   gsl_permutation_free (p);
1460   return x;
1461 }
1462
1463 static gsl_matrix *
1464 matrix_eval_SQRT (gsl_matrix *m)
1465 {
1466   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
1467     {
1468       if (*d < 0)
1469         {
1470           msg (SE, _("Argument to SQRT must be nonnegative."));
1471           return NULL;
1472         }
1473       *d = sqrt (*d);
1474     }
1475   return m;
1476 }
1477
1478 static gsl_matrix *
1479 matrix_eval_SSCP (gsl_matrix *m)
1480 {
1481   gsl_matrix *sscp = gsl_matrix_alloc (m->size2, m->size2);
1482   gsl_blas_dgemm (CblasTrans, CblasNoTrans, 1.0, m, m, 0.0, sscp);
1483   return sscp;
1484 }
1485
1486 static gsl_matrix *
1487 matrix_eval_SVAL (gsl_matrix *m)
1488 {
1489   gsl_matrix *tmp_mat = NULL;
1490   if (m->size2 > m->size1)
1491     {
1492       tmp_mat = gsl_matrix_alloc (m->size2, m->size1);
1493       gsl_matrix_transpose_memcpy (tmp_mat, m);
1494       m = tmp_mat;
1495     }
1496
1497   /* Do SVD. */
1498   gsl_matrix *V = gsl_matrix_alloc (m->size2, m->size2);
1499   gsl_vector *S = gsl_vector_alloc (m->size2);
1500   gsl_vector *work = gsl_vector_alloc (m->size2);
1501   gsl_linalg_SV_decomp (m, V, S, work);
1502
1503   gsl_matrix *vals = gsl_matrix_alloc (m->size2, 1);
1504   for (size_t i = 0; i < m->size2; i++)
1505     gsl_matrix_set (vals, i, 0, gsl_vector_get (S, i));
1506
1507   gsl_matrix_free (V);
1508   gsl_vector_free (S);
1509   gsl_vector_free (work);
1510   gsl_matrix_free (tmp_mat);
1511
1512   return vals;
1513 }
1514
1515 static gsl_matrix *
1516 matrix_eval_SWEEP (gsl_matrix *m, double d)
1517 {
1518   if (d < 1 || d > SIZE_MAX)
1519     {
1520       msg (SE, _("Scalar argument to SWEEP must be integer."));
1521       return NULL;
1522     }
1523   size_t k = d - 1;
1524   if (k >= MIN (m->size1, m->size2))
1525     {
1526       msg (SE, _("Scalar argument to SWEEP must be integer less than or "
1527                  "equal to the smaller of the matrix argument's rows and "
1528                  "columns."));
1529       return NULL;
1530     }
1531
1532   double m_kk = gsl_matrix_get (m, k, k);
1533   if (fabs (m_kk) > 1e-19)
1534     {
1535       gsl_matrix *a = gsl_matrix_alloc (m->size1, m->size2);
1536       MATRIX_FOR_ALL_ELEMENTS (a_ij, i, j, a)
1537         {
1538           double m_ij = gsl_matrix_get (m, i, j);
1539           double m_ik = gsl_matrix_get (m, i, k);
1540           double m_kj = gsl_matrix_get (m, k, j);
1541           *a_ij = (i != k && j != k ? m_ij * m_kk - m_ik * m_kj
1542                    : i != k ? -m_ik
1543                    : j != k ? m_kj
1544                    : 1.0) / m_kk;
1545         }
1546       return a;
1547     }
1548   else
1549     {
1550       for (size_t i = 0; i < m->size1; i++)
1551         {
1552           gsl_matrix_set (m, i, k, 0);
1553           gsl_matrix_set (m, k, i, 0);
1554         }
1555       return m;
1556     }
1557 }
1558
1559 static double
1560 matrix_eval_TRACE (gsl_matrix *m)
1561 {
1562   double sum = 0;
1563   size_t n = MIN (m->size1, m->size2);
1564   for (size_t i = 0; i < n; i++)
1565     sum += gsl_matrix_get (m, i, i);
1566   return sum;
1567 }
1568
1569 static gsl_matrix *
1570 matrix_eval_T (gsl_matrix *m)
1571 {
1572   return matrix_eval_TRANSPOS (m);
1573 }
1574
1575 static gsl_matrix *
1576 matrix_eval_TRANSPOS (gsl_matrix *m)
1577 {
1578   if (m->size1 == m->size2)
1579     {
1580       gsl_matrix_transpose (m);
1581       return m;
1582     }
1583   else
1584     {
1585       gsl_matrix *t = gsl_matrix_alloc (m->size2, m->size1);
1586       gsl_matrix_transpose_memcpy (t, m);
1587       return t;
1588     }
1589 }
1590
1591 static gsl_matrix *
1592 matrix_eval_TRUNC (gsl_matrix *m)
1593 {
1594   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
1595     *d = trunc (*d);
1596   return m;
1597 }
1598
1599 static gsl_matrix *
1600 matrix_eval_UNIFORM (double r_, double c_)
1601 {
1602   if (r_ < 0 || r_ >= SIZE_MAX || c_ < 0 || c_ >= SIZE_MAX)
1603     {
1604       msg (SE, _("Arguments to UNIFORM must be integers."));
1605       return NULL;
1606     }
1607   size_t r = r_;
1608   size_t c = c_;
1609   if (size_overflow_p (xtimes (r, xmax (c, 1))))
1610     {
1611       msg (SE, _("Product of arguments to UNIFORM exceeds memory size."));
1612       return NULL;
1613     }
1614
1615   gsl_matrix *m = gsl_matrix_alloc (r, c);
1616   MATRIX_FOR_ALL_ELEMENTS (d, y, x, m)
1617     *d = gsl_ran_flat (get_rng (), 0, 1);
1618   return m;
1619 }
1620
1621 struct matrix_function
1622   {
1623     const char *name;
1624     enum matrix_op op;
1625     size_t min_args, max_args;
1626   };
1627
1628 static struct matrix_expr *matrix_parse_expr (struct matrix_state *);
1629
1630 static const struct matrix_function *
1631 matrix_parse_function_name (const char *token)
1632 {
1633   static const struct matrix_function functions[] =
1634     {
1635 #define F(NAME, PROTO) { #NAME, MOP_F_##NAME, PROTO##_MIN_ARGS, PROTO##_MAX_ARGS },
1636       MATRIX_FUNCTIONS
1637 #undef F
1638     };
1639   enum { N_FUNCTIONS = sizeof functions / sizeof *functions };
1640
1641   for (size_t i = 0; i < N_FUNCTIONS; i++)
1642     {
1643       if (lex_id_match_n (ss_cstr (functions[i].name), ss_cstr (token), 3))
1644         return &functions[i];
1645     }
1646   return NULL;
1647 }
1648
1649 static struct read_file *
1650 read_file_create (struct matrix_state *s, struct file_handle *fh)
1651 {
1652   for (size_t i = 0; i < s->n_read_files; i++)
1653     {
1654       struct read_file *rf = s->read_files[i];
1655       if (rf->file == fh)
1656         {
1657           fh_unref (fh);
1658           return rf;
1659         }
1660     }
1661
1662   struct read_file *rf = xmalloc (sizeof *rf);
1663   *rf = (struct read_file) { .file = fh };
1664
1665   s->read_files = xrealloc (s->read_files,
1666                             (s->n_read_files + 1) * sizeof *s->read_files);
1667   s->read_files[s->n_read_files++] = rf;
1668   return rf;
1669 }
1670
1671 static struct dfm_reader *
1672 read_file_open (struct read_file *rf)
1673 {
1674   if (!rf->reader)
1675     rf->reader = dfm_open_reader (rf->file, NULL, rf->encoding);
1676   return rf->reader;
1677 }
1678
1679 static bool
1680 matrix_parse_function (struct matrix_state *s, const char *token,
1681                        struct matrix_expr **exprp)
1682 {
1683   *exprp = NULL;
1684   if (lex_next_token (s->lexer, 1) != T_LPAREN)
1685     return false;
1686
1687   if (lex_match_id (s->lexer, "EOF"))
1688     {
1689       lex_get (s->lexer);
1690       struct file_handle *fh = fh_parse (s->lexer, FH_REF_FILE, s->session);
1691       if (!fh)
1692         return true;
1693
1694       if (!lex_force_match (s->lexer, T_RPAREN))
1695         {
1696           fh_unref (fh);
1697           return true;
1698         }
1699
1700       struct read_file *rf = read_file_create (s, fh);
1701
1702       struct matrix_expr *e = xmalloc (sizeof *e);
1703       *e = (struct matrix_expr) { .op = MOP_EOF, .eof = rf };
1704       *exprp = e;
1705       return true;
1706     }
1707
1708   const struct matrix_function *f = matrix_parse_function_name (token);
1709   if (!f)
1710     return false;
1711
1712   lex_get_n (s->lexer, 2);
1713
1714   struct matrix_expr *e = xmalloc (sizeof *e);
1715   *e = (struct matrix_expr) { .op = f->op, .subs = NULL };
1716
1717   size_t allocated_subs = 0;
1718   do
1719     {
1720       struct matrix_expr *sub = matrix_parse_expr (s);
1721       if (!sub)
1722         goto error;
1723
1724       if (e->n_subs >= allocated_subs)
1725         e->subs = x2nrealloc (e->subs, &allocated_subs, sizeof *e->subs);
1726       e->subs[e->n_subs++] = sub;
1727     }
1728   while (lex_match (s->lexer, T_COMMA));
1729   if (!lex_force_match (s->lexer, T_RPAREN))
1730     goto error;
1731
1732   *exprp = e;
1733   return true;
1734
1735 error:
1736   matrix_expr_destroy (e);
1737   return true;
1738 }
1739
1740 static struct matrix_expr *
1741 matrix_parse_primary (struct matrix_state *s)
1742 {
1743   if (lex_is_number (s->lexer))
1744     {
1745       double number = lex_number (s->lexer);
1746       lex_get (s->lexer);
1747       return matrix_expr_create_number (number);
1748     }
1749   else if (lex_is_string (s->lexer))
1750     {
1751       char string[sizeof (double)];
1752       buf_copy_str_rpad (string, sizeof string, lex_tokcstr (s->lexer), ' ');
1753       lex_get (s->lexer);
1754
1755       double number;
1756       memcpy (&number, string, sizeof number);
1757       return matrix_expr_create_number (number);
1758     }
1759   else if (lex_match (s->lexer, T_LPAREN))
1760     {
1761       struct matrix_expr *e = matrix_parse_or_xor (s);
1762       if (!e || !lex_force_match (s->lexer, T_RPAREN))
1763         {
1764           matrix_expr_destroy (e);
1765           return NULL;
1766         }
1767       return e;
1768     }
1769   else if (lex_match (s->lexer, T_LCURLY))
1770     {
1771       struct matrix_expr *e = matrix_parse_curly_semi (s);
1772       if (!e || !lex_force_match (s->lexer, T_RCURLY))
1773         {
1774           matrix_expr_destroy (e);
1775           return NULL;
1776         }
1777       return e;
1778     }
1779   else if (lex_token (s->lexer) == T_ID)
1780     {
1781       struct matrix_expr *retval;
1782       if (matrix_parse_function (s, lex_tokcstr (s->lexer), &retval))
1783         return retval;
1784
1785       struct matrix_var *var = matrix_var_lookup (s, lex_tokss (s->lexer));
1786       if (!var)
1787         {
1788           lex_error (s->lexer, _("Unknown variable %s."),
1789                      lex_tokcstr (s->lexer));
1790           return NULL;
1791         }
1792       lex_get (s->lexer);
1793
1794       struct matrix_expr *e = xmalloc (sizeof *e);
1795       *e = (struct matrix_expr) { .op = MOP_VARIABLE, .variable = var };
1796       return e;
1797     }
1798   else if (lex_token (s->lexer) == T_ALL)
1799     {
1800       struct matrix_expr *retval;
1801       if (matrix_parse_function (s, "ALL", &retval))
1802         return retval;
1803     }
1804
1805   lex_error (s->lexer, NULL);
1806   return NULL;
1807 }
1808
1809 static struct matrix_expr *matrix_parse_postfix (struct matrix_state *);
1810
1811 static bool
1812 matrix_parse_index_expr (struct matrix_state *s, struct matrix_expr **indexp)
1813 {
1814   if (lex_match (s->lexer, T_COLON))
1815     {
1816       *indexp = NULL;
1817       return true;
1818     }
1819   else
1820     {
1821       *indexp = matrix_parse_expr (s);
1822       return *indexp != NULL;
1823     }
1824 }
1825
1826 static struct matrix_expr *
1827 matrix_parse_postfix (struct matrix_state *s)
1828 {
1829   struct matrix_expr *lhs = matrix_parse_primary (s);
1830   if (!lhs || !lex_match (s->lexer, T_LPAREN))
1831     return lhs;
1832
1833   struct matrix_expr *i0;
1834   if (!matrix_parse_index_expr (s, &i0))
1835     {
1836       matrix_expr_destroy (lhs);
1837       return NULL;
1838     }
1839   if (lex_match (s->lexer, T_RPAREN))
1840     return (i0
1841             ? matrix_expr_create_2 (MOP_VEC_INDEX, lhs, i0)
1842             : matrix_expr_create_1 (MOP_VEC_ALL, lhs));
1843   else if (lex_match (s->lexer, T_COMMA))
1844     {
1845       struct matrix_expr *i1;
1846       if (!matrix_parse_index_expr (s, &i1)
1847           || !lex_force_match (s->lexer, T_RPAREN))
1848         {
1849           matrix_expr_destroy (lhs);
1850           matrix_expr_destroy (i0);
1851           matrix_expr_destroy (i1);
1852           return NULL;
1853         }
1854       return (i0 && i1 ? matrix_expr_create_3 (MOP_MAT_INDEX, lhs, i0, i1)
1855               : i0 ? matrix_expr_create_2 (MOP_ROW_INDEX, lhs, i0)
1856               : i1 ? matrix_expr_create_2 (MOP_COL_INDEX, lhs, i1)
1857               : lhs);
1858     }
1859   else
1860     {
1861       lex_error_expecting (s->lexer, "`)'", "`,'");
1862       return NULL;
1863     }
1864 }
1865
1866 static struct matrix_expr *
1867 matrix_parse_unary (struct matrix_state *s)
1868 {
1869   if (lex_match (s->lexer, T_DASH))
1870     {
1871       struct matrix_expr *lhs = matrix_parse_unary (s);
1872       return lhs ? matrix_expr_create_1 (MOP_NEGATE, lhs) : NULL;
1873     }
1874   else if (lex_match (s->lexer, T_PLUS))
1875     return matrix_parse_unary (s);
1876   else
1877     return matrix_parse_postfix (s);
1878 }
1879
1880 static struct matrix_expr *
1881 matrix_parse_seq (struct matrix_state *s)
1882 {
1883   struct matrix_expr *start = matrix_parse_unary (s);
1884   if (!start || !lex_match (s->lexer, T_COLON))
1885     return start;
1886
1887   struct matrix_expr *end = matrix_parse_unary (s);
1888   if (!end)
1889     {
1890       matrix_expr_destroy (start);
1891       return NULL;
1892     }
1893
1894   if (lex_match (s->lexer, T_COLON))
1895     {
1896       struct matrix_expr *increment = matrix_parse_unary (s);
1897       if (!increment)
1898         {
1899           matrix_expr_destroy (start);
1900           matrix_expr_destroy (end);
1901           return NULL;
1902         }
1903       return matrix_expr_create_3 (MOP_SEQ_BY, start, end, increment);
1904     }
1905   else
1906     return matrix_expr_create_2 (MOP_SEQ, start, end);
1907 }
1908
1909 static struct matrix_expr *
1910 matrix_parse_exp (struct matrix_state *s)
1911 {
1912   struct matrix_expr *lhs = matrix_parse_seq (s);
1913   if (!lhs)
1914     return NULL;
1915
1916   for (;;)
1917     {
1918       enum matrix_op op;
1919       if (lex_match (s->lexer, T_EXP))
1920         op = MOP_EXP_MAT;
1921       else if (lex_match_phrase (s->lexer, "&**"))
1922         op = MOP_EXP_ELEMS;
1923       else
1924         return lhs;
1925
1926       struct matrix_expr *rhs = matrix_parse_seq (s);
1927       if (!rhs)
1928         {
1929           matrix_expr_destroy (lhs);
1930           return NULL;
1931         }
1932       lhs = matrix_expr_create_2 (op, lhs, rhs);
1933     }
1934 }
1935
1936 static struct matrix_expr *
1937 matrix_parse_mul_div (struct matrix_state *s)
1938 {
1939   struct matrix_expr *lhs = matrix_parse_exp (s);
1940   if (!lhs)
1941     return NULL;
1942
1943   for (;;)
1944     {
1945       enum matrix_op op;
1946       if (lex_match (s->lexer, T_ASTERISK))
1947         op = MOP_MUL_MAT;
1948       else if (lex_match (s->lexer, T_SLASH))
1949         op = MOP_DIV_ELEMS;
1950       else if (lex_match_phrase (s->lexer, "&*"))
1951         op = MOP_MUL_ELEMS;
1952       else if (lex_match_phrase (s->lexer, "&/"))
1953         op = MOP_DIV_ELEMS;
1954       else
1955         return lhs;
1956
1957       struct matrix_expr *rhs = matrix_parse_exp (s);
1958       if (!rhs)
1959         {
1960           matrix_expr_destroy (lhs);
1961           return NULL;
1962         }
1963       lhs = matrix_expr_create_2 (op, lhs, rhs);
1964     }
1965 }
1966
1967 static struct matrix_expr *
1968 matrix_parse_add_sub (struct matrix_state *s)
1969 {
1970   struct matrix_expr *lhs = matrix_parse_mul_div (s);
1971   if (!lhs)
1972     return NULL;
1973
1974   for (;;)
1975     {
1976       enum matrix_op op;
1977       if (lex_match (s->lexer, T_PLUS))
1978         op = MOP_ADD_ELEMS;
1979       else if (lex_match (s->lexer, T_DASH))
1980         op = MOP_SUB_ELEMS;
1981       else if (lex_token (s->lexer) == T_NEG_NUM)
1982         op = MOP_ADD_ELEMS;
1983       else
1984         return lhs;
1985
1986       struct matrix_expr *rhs = matrix_parse_mul_div (s);
1987       if (!rhs)
1988         {
1989           matrix_expr_destroy (lhs);
1990           return NULL;
1991         }
1992       lhs = matrix_expr_create_2 (op, lhs, rhs);
1993     }
1994 }
1995
1996 static struct matrix_expr *
1997 matrix_parse_relational (struct matrix_state *s)
1998 {
1999   struct matrix_expr *lhs = matrix_parse_add_sub (s);
2000   if (!lhs)
2001     return NULL;
2002
2003   for (;;)
2004     {
2005       enum matrix_op op;
2006       if (lex_match (s->lexer, T_GT))
2007         op = MOP_GT;
2008       else if (lex_match (s->lexer, T_GE))
2009         op = MOP_GE;
2010       else if (lex_match (s->lexer, T_LT))
2011         op = MOP_LT;
2012       else if (lex_match (s->lexer, T_LE))
2013         op = MOP_LE;
2014       else if (lex_match (s->lexer, T_EQUALS) || lex_match (s->lexer, T_EQ))
2015         op = MOP_EQ;
2016       else if (lex_match (s->lexer, T_NE))
2017         op = MOP_NE;
2018       else
2019         return lhs;
2020
2021       struct matrix_expr *rhs = matrix_parse_add_sub (s);
2022       if (!rhs)
2023         {
2024           matrix_expr_destroy (lhs);
2025           return NULL;
2026         }
2027       lhs = matrix_expr_create_2 (op, lhs, rhs);
2028     }
2029 }
2030
2031 static struct matrix_expr *
2032 matrix_parse_not (struct matrix_state *s)
2033 {
2034   if (lex_match (s->lexer, T_NOT))
2035     {
2036       struct matrix_expr *lhs = matrix_parse_not (s);
2037       return lhs ? matrix_expr_create_1 (MOP_NOT, lhs) : NULL;
2038     }
2039   else
2040     return matrix_parse_relational (s);
2041 }
2042
2043 static struct matrix_expr *
2044 matrix_parse_and (struct matrix_state *s)
2045 {
2046   struct matrix_expr *lhs = matrix_parse_not (s);
2047   if (!lhs)
2048     return NULL;
2049
2050   while (lex_match (s->lexer, T_AND))
2051     {
2052       struct matrix_expr *rhs = matrix_parse_not (s);
2053       if (!rhs)
2054         {
2055           matrix_expr_destroy (lhs);
2056           return NULL;
2057         }
2058       lhs = matrix_expr_create_2 (MOP_AND, lhs, rhs);
2059     }
2060   return lhs;
2061 }
2062
2063 static struct matrix_expr *
2064 matrix_parse_or_xor (struct matrix_state *s)
2065 {
2066   struct matrix_expr *lhs = matrix_parse_and (s);
2067   if (!lhs)
2068     return NULL;
2069
2070   for (;;)
2071     {
2072       enum matrix_op op;
2073       if (lex_match (s->lexer, T_OR))
2074         op = MOP_OR;
2075       else if (lex_match_id (s->lexer, "XOR"))
2076         op = MOP_XOR;
2077       else
2078         return lhs;
2079
2080       struct matrix_expr *rhs = matrix_parse_and (s);
2081       if (!rhs)
2082         {
2083           matrix_expr_destroy (lhs);
2084           return NULL;
2085         }
2086       lhs = matrix_expr_create_2 (op, lhs, rhs);
2087     }
2088 }
2089
2090 static struct matrix_expr *
2091 matrix_parse_expr (struct matrix_state *s)
2092 {
2093   return matrix_parse_or_xor (s);
2094 }
2095 \f
2096 /* Expression evaluation. */
2097
2098 static double
2099 matrix_op_eval (enum matrix_op op, double a, double b)
2100 {
2101   switch (op)
2102     {
2103     case MOP_ADD_ELEMS: return a + b;
2104     case MOP_SUB_ELEMS: return a - b;
2105     case MOP_MUL_ELEMS: return a * b;
2106     case MOP_DIV_ELEMS: return a / b;
2107     case MOP_EXP_ELEMS: return pow (a, b);
2108     case MOP_GT: return a > b;
2109     case MOP_GE: return a >= b;
2110     case MOP_LT: return a < b;
2111     case MOP_LE: return a <= b;
2112     case MOP_EQ: return a == b;
2113     case MOP_NE: return a != b;
2114     case MOP_AND: return (a > 0) && (b > 0);
2115     case MOP_OR: return (a > 0) || (b > 0);
2116     case MOP_XOR: return (a > 0) != (b > 0);
2117
2118 #define F(NAME, PROTOTYPE) case MOP_F_##NAME:
2119       MATRIX_FUNCTIONS
2120 #undef F
2121     case MOP_NEGATE:
2122     case MOP_SEQ:
2123     case MOP_SEQ_BY:
2124     case MOP_MUL_MAT:
2125     case MOP_EXP_MAT:
2126     case MOP_NOT:
2127     case MOP_PASTE_HORZ:
2128     case MOP_PASTE_VERT:
2129     case MOP_EMPTY:
2130     case MOP_VEC_INDEX:
2131     case MOP_VEC_ALL:
2132     case MOP_MAT_INDEX:
2133     case MOP_ROW_INDEX:
2134     case MOP_COL_INDEX:
2135     case MOP_NUMBER:
2136     case MOP_VARIABLE:
2137     case MOP_EOF:
2138       NOT_REACHED ();
2139     }
2140   NOT_REACHED ();
2141 }
2142
2143 static const char *
2144 matrix_op_name (enum matrix_op op)
2145 {
2146   switch (op)
2147     {
2148     case MOP_ADD_ELEMS: return "+";
2149     case MOP_SUB_ELEMS: return "-";
2150     case MOP_MUL_ELEMS: return "&*";
2151     case MOP_DIV_ELEMS: return "&/";
2152     case MOP_EXP_ELEMS: return "&**";
2153     case MOP_GT: return ">";
2154     case MOP_GE: return ">=";
2155     case MOP_LT: return "<";
2156     case MOP_LE: return "<=";
2157     case MOP_EQ: return "=";
2158     case MOP_NE: return "<>";
2159     case MOP_AND: return "AND";
2160     case MOP_OR: return "OR";
2161     case MOP_XOR: return "XOR";
2162
2163 #define F(NAME, PROTOTYPE) case MOP_F_##NAME:
2164       MATRIX_FUNCTIONS
2165 #undef F
2166     case MOP_NEGATE:
2167     case MOP_SEQ:
2168     case MOP_SEQ_BY:
2169     case MOP_MUL_MAT:
2170     case MOP_EXP_MAT:
2171     case MOP_NOT:
2172     case MOP_PASTE_HORZ:
2173     case MOP_PASTE_VERT:
2174     case MOP_EMPTY:
2175     case MOP_VEC_INDEX:
2176     case MOP_VEC_ALL:
2177     case MOP_MAT_INDEX:
2178     case MOP_ROW_INDEX:
2179     case MOP_COL_INDEX:
2180     case MOP_NUMBER:
2181     case MOP_VARIABLE:
2182     case MOP_EOF:
2183       NOT_REACHED ();
2184     }
2185   NOT_REACHED ();
2186 }
2187
2188 static bool
2189 is_scalar (const gsl_matrix *m)
2190 {
2191   return m->size1 == 1 && m->size2 == 1;
2192 }
2193
2194 static double
2195 to_scalar (const gsl_matrix *m)
2196 {
2197   assert (is_scalar (m));
2198   return gsl_matrix_get (m, 0, 0);
2199 }
2200
2201 static gsl_matrix *
2202 matrix_expr_evaluate_elementwise (enum matrix_op op,
2203                                   gsl_matrix *a, gsl_matrix *b)
2204 {
2205   if (is_scalar (b))
2206     {
2207       double be = to_scalar (b);
2208       for (size_t r = 0; r < a->size1; r++)
2209         for (size_t c = 0; c < a->size2; c++)
2210           {
2211             double *ae = gsl_matrix_ptr (a, r, c);
2212             *ae = matrix_op_eval (op, *ae, be);
2213           }
2214       return a;
2215     }
2216   else if (is_scalar (a))
2217     {
2218       double ae = to_scalar (a);
2219       for (size_t r = 0; r < b->size1; r++)
2220         for (size_t c = 0; c < b->size2; c++)
2221           {
2222             double *be = gsl_matrix_ptr (b, r, c);
2223             *be = matrix_op_eval (op, ae, *be);
2224           }
2225       return b;
2226     }
2227   else if (a->size1 == b->size1 && a->size2 == b->size2)
2228     {
2229       for (size_t r = 0; r < a->size1; r++)
2230         for (size_t c = 0; c < a->size2; c++)
2231           {
2232             double *ae = gsl_matrix_ptr (a, r, c);
2233             double be = gsl_matrix_get (b, r, c);
2234             *ae = matrix_op_eval (op, *ae, be);
2235           }
2236       return a;
2237     }
2238   else
2239     {
2240       msg (SE, _("Operands to %s must have the same dimensions or one "
2241                  "must be a scalar, not matrices with dimensions (%zu,%zu) "
2242                  "and (%zu,%zu)."),
2243            matrix_op_name (op), a->size1, a->size2, b->size1, b->size2);
2244       return NULL;
2245     }
2246 }
2247
2248 static gsl_matrix *
2249 matrix_expr_evaluate_mul_mat (gsl_matrix *a, gsl_matrix *b)
2250 {
2251   if (is_scalar (a) || is_scalar (b))
2252     return matrix_expr_evaluate_elementwise (MOP_MUL_ELEMS, a, b);
2253
2254   if (a->size2 != b->size1)
2255     {
2256       msg (SE, _("Matrices with dimensions (%zu,%zu) and (%zu,%zu) are "
2257                  "not conformable for multiplication."),
2258            a->size1, a->size2, b->size1, b->size2);
2259       return NULL;
2260     }
2261
2262   gsl_matrix *c = gsl_matrix_alloc (a->size1, b->size2);
2263   gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0, a, b, 0.0, c);
2264   return c;
2265 }
2266
2267 static void
2268 swap_matrix (gsl_matrix **a, gsl_matrix **b)
2269 {
2270   gsl_matrix *tmp = *a;
2271   *a = *b;
2272   *b = tmp;
2273 }
2274
2275 static void
2276 mul_matrix (gsl_matrix **z, const gsl_matrix *x, const gsl_matrix *y,
2277             gsl_matrix **tmp)
2278 {
2279   gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0, x, y, 0.0, *tmp);
2280   swap_matrix (z, tmp);
2281 }
2282
2283 static void
2284 square_matrix (gsl_matrix **x, gsl_matrix **tmp)
2285 {
2286   mul_matrix (x, *x, *x, tmp);
2287 }
2288
2289 static gsl_matrix *
2290 matrix_expr_evaluate_exp_mat (gsl_matrix *x_, gsl_matrix *b)
2291 {
2292   gsl_matrix *x = x_;
2293   if (x->size1 != x->size2)
2294     {
2295       msg (SE, _("Matrix exponentation with ** requires a square matrix on "
2296                  "the left-hand size, not one with dimensions (%zu,%zu)."),
2297            x->size1, x->size2);
2298       return NULL;
2299     }
2300   if (!is_scalar (b))
2301     {
2302       msg (SE, _("Matrix exponentiation with ** requires a scalar on the "
2303                  "right-hand side, not a matrix with dimensions (%zu,%zu)."),
2304            b->size1, b->size2);
2305       return NULL;
2306     }
2307   double bf = to_scalar (b);
2308   if (bf != floor (bf) || bf <= LONG_MIN || bf > LONG_MAX)
2309     {
2310       msg (SE, _("Exponent %.1f in matrix multiplication is non-integer "
2311                  "or outside the valid range."), bf);
2312       return NULL;
2313     }
2314   long int bl = bf;
2315
2316   gsl_matrix *tmp = gsl_matrix_alloc (x->size1, x->size2);
2317   gsl_matrix *y = gsl_matrix_alloc (x->size1, x->size2);
2318   gsl_matrix_set_identity (y);
2319   if (bl == 0)
2320     return y;
2321
2322   for (unsigned long int n = labs (bl); n > 1; n /= 2)
2323     if (n & 1)
2324       {
2325         mul_matrix (&y, x, y, &tmp);
2326         square_matrix (&x, &tmp);
2327       }
2328     else
2329       square_matrix (&x, &tmp);
2330
2331   mul_matrix (&y, x, y, &tmp);
2332   if (bf < 0)
2333     invert_matrix (y);
2334
2335   if (tmp != x_)
2336     gsl_matrix_free (tmp);
2337   return y;
2338 }
2339
2340 static gsl_matrix *
2341 matrix_expr_evaluate_seq (gsl_matrix *start_, gsl_matrix *end_,
2342                           gsl_matrix *by_)
2343 {
2344   if (!is_scalar (start_) || !is_scalar (end_) || (by_ && !is_scalar (by_)))
2345     {
2346       msg (SE, _("All operands of : operator must be scalars."));
2347       return NULL;
2348     }
2349
2350   long int start = to_scalar (start_);
2351   long int end = to_scalar (end_);
2352   long int by = by_ ? to_scalar (by_) : 1;
2353
2354   if (!by)
2355     {
2356       msg (SE, _("The increment operand to : must be nonzero."));
2357       return NULL;
2358     }
2359
2360   long int n = (end > start && by > 0 ? (end - start + by) / by
2361                 : end < start && by < 0 ? (start - end - by) / -by
2362                 : 0);
2363   gsl_matrix *m = gsl_matrix_alloc (1, n);
2364   for (long int i = 0; i < n; i++)
2365     gsl_matrix_set (m, 0, i, start + i * by);
2366   return m;
2367 }
2368
2369 static gsl_matrix *
2370 matrix_expr_evaluate_not (gsl_matrix *a)
2371 {
2372   for (size_t r = 0; r < a->size1; r++)
2373     for (size_t c = 0; c < a->size2; c++)
2374       {
2375         double *ae = gsl_matrix_ptr (a, r, c);
2376         *ae = !(*ae > 0);
2377       }
2378   return a;
2379 }
2380
2381 static gsl_matrix *
2382 matrix_expr_evaluate_paste_horz (gsl_matrix *a, gsl_matrix *b)
2383 {
2384   if (a->size1 != b->size1)
2385     {
2386       if (!a->size1 || !a->size2)
2387         return b;
2388       else if (!b->size1 || !b->size2)
2389         return a;
2390
2391       msg (SE, _("All columns in a matrix must have the same number of rows, "
2392                  "but this tries to paste matrices with %zu and %zu rows."),
2393            a->size1, b->size1);
2394       return NULL;
2395     }
2396
2397   gsl_matrix *c = gsl_matrix_alloc (a->size1, a->size2 + b->size2);
2398   for (size_t y = 0; y < a->size1; y++)
2399     {
2400       for (size_t x = 0; x < a->size2; x++)
2401         gsl_matrix_set (c, y, x, gsl_matrix_get (a, y, x));
2402       for (size_t x = 0; x < b->size2; x++)
2403         gsl_matrix_set (c, y, x + a->size2, gsl_matrix_get (b, y, x));
2404     }
2405   return c;
2406 }
2407
2408 static gsl_matrix *
2409 matrix_expr_evaluate_paste_vert (gsl_matrix *a, gsl_matrix *b)
2410 {
2411   if (a->size2 != b->size2)
2412     {
2413       if (!a->size1 || !a->size2)
2414         return b;
2415       else if (!b->size1 || !b->size2)
2416         return a;
2417
2418       msg (SE, _("All rows in a matrix must have the same number of columns, "
2419                  "but this tries to stack matrices with %zu and %zu columns."),
2420            a->size2, b->size2);
2421       return NULL;
2422     }
2423
2424   gsl_matrix *c = gsl_matrix_alloc (a->size1 + b->size1, a->size2);
2425   for (size_t x = 0; x < a->size2; x++)
2426     {
2427       for (size_t y = 0; y < a->size1; y++)
2428         gsl_matrix_set (c, y, x, gsl_matrix_get (a, y, x));
2429       for (size_t y = 0; y < b->size1; y++)
2430         gsl_matrix_set (c, y + a->size1, x, gsl_matrix_get (b, y, x));
2431     }
2432   return c;
2433 }
2434
2435 static gsl_vector *
2436 matrix_to_vector (gsl_matrix *m)
2437 {
2438   assert (m->owner);
2439   gsl_vector v = to_vector (m);
2440   assert (v.block == m->block || !v.block);
2441   assert (!v.owner);
2442   v.owner = 1;
2443   m->owner = 0;
2444   return xmemdup (&v, sizeof v);
2445 }
2446
2447 enum index_type {
2448   IV_ROW,
2449   IV_COLUMN,
2450   IV_VECTOR
2451 };
2452
2453 struct index_vector
2454   {
2455     size_t *indexes;
2456     size_t n;
2457   };
2458 #define INDEX_VECTOR_INIT (struct index_vector) { .n = 0 }
2459
2460 static bool
2461 matrix_normalize_index_vector (gsl_matrix *m, size_t size,
2462                                enum index_type index_type, size_t other_size,
2463                                struct index_vector *iv)
2464 {
2465   if (m)
2466     {
2467       if (!is_vector (m))
2468         {
2469           switch (index_type)
2470             {
2471             case IV_VECTOR:
2472               msg (SE, _("Vector index must be scalar or vector, not a "
2473                          "matrix with dimensions (%zu,%zu)."),
2474                    m->size1, m->size2);
2475               break;
2476
2477             case IV_ROW:
2478               msg (SE, _("Matrix row index must be scalar or vector, not a "
2479                          "matrix with dimensions (%zu,%zu)."),
2480                    m->size1, m->size2);
2481               break;
2482
2483             case IV_COLUMN:
2484               msg (SE, _("Matrix column index must be scalar or vector, not a "
2485                          "matrix with dimensions (%zu,%zu)."),
2486                    m->size1, m->size2);
2487               break;
2488             }
2489           return false;
2490         }
2491
2492       gsl_vector v = to_vector (m);
2493       *iv = (struct index_vector) {
2494         .indexes = xnmalloc (v.size, sizeof *iv->indexes),
2495         .n = v.size,
2496       };
2497       for (size_t i = 0; i < v.size; i++)
2498         {
2499           double index = gsl_vector_get (&v, i);
2500           if (index < 1 || index >= size + 1)
2501             {
2502               switch (index_type)
2503                 {
2504                 case IV_VECTOR:
2505                   msg (SE, _("Index %g is out of range for vector "
2506                              "with %zu elements."), index, size);
2507                   break;
2508
2509                 case IV_ROW:
2510                   msg (SE, _("%g is not a valid row index for a matrix "
2511                              "with dimensions (%zu,%zu)."),
2512                        index, size, other_size);
2513                   break;
2514
2515                 case IV_COLUMN:
2516                   msg (SE, _("%g is not a valid column index for a matrix "
2517                              "with dimensions (%zu,%zu)."),
2518                        index, other_size, size);
2519                   break;
2520                 }
2521
2522               free (iv->indexes);
2523               return false;
2524             }
2525           iv->indexes[i] = index - 1;
2526         }
2527       return true;
2528     }
2529   else
2530     {
2531       *iv = (struct index_vector) {
2532         .indexes = xnmalloc (size, sizeof *iv->indexes),
2533         .n = size,
2534       };
2535       for (size_t i = 0; i < size; i++)
2536         iv->indexes[i] = i;
2537       return true;
2538     }
2539 }
2540
2541 static gsl_matrix *
2542 matrix_expr_evaluate_vec_all (gsl_matrix *sm)
2543 {
2544   if (!is_vector (sm))
2545     {
2546       msg (SE, _("Vector index operator must be applied to vector, "
2547                  "not a matrix with dimensions (%zu,%zu)."),
2548            sm->size1, sm->size2);
2549       return NULL;
2550     }
2551
2552   return sm;
2553 }
2554
2555 static gsl_matrix *
2556 matrix_expr_evaluate_vec_index (gsl_matrix *sm, gsl_matrix *im)
2557 {
2558   if (!matrix_expr_evaluate_vec_all (sm))
2559     return NULL;
2560
2561   gsl_vector sv = to_vector (sm);
2562   struct index_vector iv;
2563   if (!matrix_normalize_index_vector (im, sv.size, IV_VECTOR, 0, &iv))
2564     return NULL;
2565
2566   gsl_matrix *dm = gsl_matrix_alloc (sm->size1 == 1 ? 1 : iv.n,
2567                                      sm->size1 == 1 ? iv.n : 1);
2568   gsl_vector dv = to_vector (dm);
2569   for (size_t dx = 0; dx < iv.n; dx++)
2570     {
2571       size_t sx = iv.indexes[dx];
2572       gsl_vector_set (&dv, dx, gsl_vector_get (&sv, sx));
2573     }
2574   free (iv.indexes);
2575
2576   return dm;
2577 }
2578
2579 static gsl_matrix *
2580 matrix_expr_evaluate_mat_index (gsl_matrix *sm, gsl_matrix *im0,
2581                                 gsl_matrix *im1)
2582 {
2583   struct index_vector iv0;
2584   if (!matrix_normalize_index_vector (im0, sm->size1, IV_ROW, sm->size2, &iv0))
2585     return NULL;
2586
2587   struct index_vector iv1;
2588   if (!matrix_normalize_index_vector (im1, sm->size2, IV_COLUMN, sm->size1,
2589                                       &iv1))
2590     {
2591       free (iv0.indexes);
2592       return NULL;
2593     }
2594
2595   gsl_matrix *dm = gsl_matrix_alloc (iv0.n, iv1.n);
2596   for (size_t dy = 0; dy < iv0.n; dy++)
2597     {
2598       size_t sy = iv0.indexes[dy];
2599
2600       for (size_t dx = 0; dx < iv1.n; dx++)
2601         {
2602           size_t sx = iv1.indexes[dx];
2603           gsl_matrix_set (dm, dy, dx, gsl_matrix_get (sm, sy, sx));
2604         }
2605     }
2606   free (iv0.indexes);
2607   free (iv1.indexes);
2608   return dm;
2609 }
2610
2611 #define F(NAME, PROTOTYPE)                              \
2612   static gsl_matrix *matrix_expr_evaluate_##PROTOTYPE ( \
2613     const char *name, gsl_matrix *[], size_t,           \
2614     matrix_proto_##PROTOTYPE *);
2615 MATRIX_FUNCTIONS
2616 #undef F
2617
2618 static bool
2619 check_scalar_arg (const char *name, gsl_matrix *subs[], size_t index)
2620 {
2621   if (!is_scalar (subs[index]))
2622     {
2623       msg (SE, _("Function %s argument %zu must be a scalar, "
2624                  "but it has dimensions (%zu,%zu)."),
2625            name, index + 1, subs[index]->size1, subs[index]->size2);
2626       return false;
2627     }
2628   return true;
2629 }
2630
2631 static bool
2632 check_vector_arg (const char *name, gsl_matrix *subs[], size_t index)
2633 {
2634   if (!is_vector (subs[index]))
2635     {
2636       msg (SE, _("Function %s argument %zu must be a vector, "
2637                  "but it has dimensions (%zu,%zu)."),
2638            name, index + 1, subs[index]->size1, subs[index]->size2);
2639       return false;
2640     }
2641   return true;
2642 }
2643
2644 static bool
2645 to_scalar_args (const char *name, gsl_matrix *subs[], size_t n_subs, double d[])
2646 {
2647   for (size_t i = 0; i < n_subs; i++)
2648     {
2649       if (!check_scalar_arg (name, subs, i))
2650         return false;
2651       d[i] = to_scalar (subs[i]);
2652     }
2653   return true;
2654 }
2655
2656 static gsl_matrix *
2657 matrix_expr_evaluate_m_d (const char *name,
2658                           gsl_matrix *subs[], size_t n_subs,
2659                           matrix_proto_m_d *f)
2660 {
2661   assert (n_subs == 1);
2662
2663   double d;
2664   return to_scalar_args (name, subs, n_subs, &d) ? f(d) : NULL;
2665 }
2666
2667 static gsl_matrix *
2668 matrix_expr_evaluate_m_dd (const char *name,
2669                            gsl_matrix *subs[], size_t n_subs,
2670                            matrix_proto_m_dd *f)
2671 {
2672   assert (n_subs == 2);
2673
2674   double d[2];
2675   return to_scalar_args (name, subs, n_subs, d) ? f(d[0], d[1]) : NULL;
2676 }
2677
2678 static gsl_matrix *
2679 matrix_expr_evaluate_m_ddd (const char *name,
2680                            gsl_matrix *subs[], size_t n_subs,
2681                            matrix_proto_m_ddd *f)
2682 {
2683   assert (n_subs == 3);
2684
2685   double d[3];
2686   return to_scalar_args (name, subs, n_subs, d) ? f(d[0], d[1], d[2]) : NULL;
2687 }
2688
2689 static gsl_matrix *
2690 matrix_expr_evaluate_m_m (const char *name UNUSED,
2691                           gsl_matrix *subs[], size_t n_subs,
2692                           matrix_proto_m_m *f)
2693 {
2694   assert (n_subs == 1);
2695   return f (subs[0]);
2696 }
2697
2698 static gsl_matrix *
2699 matrix_expr_evaluate_m_md (const char *name UNUSED,
2700                            gsl_matrix *subs[], size_t n_subs,
2701                            matrix_proto_m_md *f)
2702 {
2703   assert (n_subs == 2);
2704   if (!check_scalar_arg (name, subs, 1))
2705     return NULL;
2706   return f (subs[0], to_scalar (subs[1]));
2707 }
2708
2709 static gsl_matrix *
2710 matrix_expr_evaluate_m_mdd (const char *name UNUSED,
2711                             gsl_matrix *subs[], size_t n_subs,
2712                             matrix_proto_m_mdd *f)
2713 {
2714   assert (n_subs == 3);
2715   if (!check_scalar_arg (name, subs, 1) || !check_scalar_arg (name, subs, 2))
2716     return NULL;
2717   return f (subs[0], to_scalar (subs[1]), to_scalar (subs[2]));
2718 }
2719
2720 static gsl_matrix *
2721 matrix_expr_evaluate_m_mm (const char *name UNUSED,
2722                            gsl_matrix *subs[], size_t n_subs,
2723                            matrix_proto_m_mm *f)
2724 {
2725   assert (n_subs == 2);
2726   return f (subs[0], subs[1]);
2727 }
2728
2729 static gsl_matrix *
2730 matrix_expr_evaluate_m_v (const char *name,
2731                           gsl_matrix *subs[], size_t n_subs,
2732                           matrix_proto_m_v *f)
2733 {
2734   assert (n_subs == 1);
2735   if (!check_vector_arg (name, subs, 0))
2736     return NULL;
2737   gsl_vector v = to_vector (subs[0]);
2738   return f (&v);
2739 }
2740
2741 static gsl_matrix *
2742 matrix_expr_evaluate_d_m (const char *name UNUSED,
2743                           gsl_matrix *subs[], size_t n_subs,
2744                           matrix_proto_d_m *f)
2745 {
2746   assert (n_subs == 1);
2747
2748   gsl_matrix *m = gsl_matrix_alloc (1, 1);
2749   gsl_matrix_set (m, 0, 0, f (subs[0]));
2750   return m;
2751 }
2752
2753 static gsl_matrix *
2754 matrix_expr_evaluate_m_any (const char *name UNUSED,
2755                           gsl_matrix *subs[], size_t n_subs,
2756                           matrix_proto_m_any *f)
2757 {
2758   return f (subs, n_subs);
2759 }
2760
2761 static gsl_matrix *
2762 matrix_expr_evaluate_IDENT (const char *name,
2763                             gsl_matrix *subs[], size_t n_subs,
2764                             matrix_proto_IDENT *f)
2765 {
2766   assert (n_subs <= 2);
2767
2768   double d[2];
2769   if (!to_scalar_args (name, subs, n_subs, d))
2770     return NULL;
2771
2772   return f (d[0], d[n_subs - 1]);
2773 }
2774
2775 static gsl_matrix *
2776 matrix_expr_evaluate (const struct matrix_expr *e)
2777 {
2778   if (e->op == MOP_NUMBER)
2779     {
2780       gsl_matrix *m = gsl_matrix_alloc (1, 1);
2781       gsl_matrix_set (m, 0, 0, e->number);
2782       return m;
2783     }
2784   else if (e->op == MOP_VARIABLE)
2785     {
2786       const gsl_matrix *src = e->variable->value;
2787       if (!src)
2788         {
2789           msg (SE, _("Uninitialized variable %s used in expression."),
2790                e->variable->name);
2791           return NULL;
2792         }
2793
2794       gsl_matrix *dst = gsl_matrix_alloc (src->size1, src->size2);
2795       gsl_matrix_memcpy (dst, src);
2796       return dst;
2797     }
2798   else if (e->op == MOP_EOF)
2799     {
2800       struct dfm_reader *reader = read_file_open (e->eof);
2801       gsl_matrix *m = gsl_matrix_alloc (1, 1);
2802       gsl_matrix_set (m, 0, 0, !reader || dfm_eof (reader));
2803       return m;
2804     }
2805
2806   enum { N_LOCAL = 3 };
2807   gsl_matrix *local_subs[N_LOCAL];
2808   gsl_matrix **subs = (e->n_subs < N_LOCAL
2809                        ? local_subs
2810                        : xmalloc (e->n_subs * sizeof *subs));
2811
2812   for (size_t i = 0; i < e->n_subs; i++)
2813     {
2814       subs[i] = matrix_expr_evaluate (e->subs[i]);
2815       if (!subs[i])
2816         {
2817           for (size_t j = 0; j < i; j++)
2818             gsl_matrix_free (subs[j]);
2819           if (subs != local_subs)
2820             free (subs);
2821           return NULL;
2822         }
2823     }
2824
2825   gsl_matrix *result = NULL;
2826   switch (e->op)
2827     {
2828 #define F(NAME, PROTOTYPE)                                              \
2829       case MOP_F_##NAME:                                                \
2830         result = matrix_expr_evaluate_##PROTOTYPE (#NAME,               \
2831                                                    subs, e->n_subs,     \
2832                                                    matrix_eval_##NAME); \
2833       break;
2834       MATRIX_FUNCTIONS
2835 #undef F
2836
2837     case MOP_NEGATE:
2838       gsl_matrix_scale (subs[0], -1.0);
2839       result = subs[0];
2840       break;
2841
2842     case MOP_ADD_ELEMS:
2843     case MOP_SUB_ELEMS:
2844     case MOP_MUL_ELEMS:
2845     case MOP_DIV_ELEMS:
2846     case MOP_EXP_ELEMS:
2847     case MOP_GT:
2848     case MOP_GE:
2849     case MOP_LT:
2850     case MOP_LE:
2851     case MOP_EQ:
2852     case MOP_NE:
2853     case MOP_AND:
2854     case MOP_OR:
2855     case MOP_XOR:
2856       result = matrix_expr_evaluate_elementwise (e->op, subs[0], subs[1]);
2857       break;
2858
2859     case MOP_NOT:
2860       result = matrix_expr_evaluate_not (subs[0]);
2861       break;
2862
2863     case MOP_SEQ:
2864       result = matrix_expr_evaluate_seq (subs[0], subs[1], NULL);
2865       break;
2866
2867     case MOP_SEQ_BY:
2868       result = matrix_expr_evaluate_seq (subs[0], subs[1], subs[2]);
2869       break;
2870
2871     case MOP_MUL_MAT:
2872       result = matrix_expr_evaluate_mul_mat (subs[0], subs[1]);
2873       break;
2874
2875     case MOP_EXP_MAT:
2876       result = matrix_expr_evaluate_exp_mat (subs[0], subs[1]);
2877       break;
2878
2879     case MOP_PASTE_HORZ:
2880       result = matrix_expr_evaluate_paste_horz (subs[0], subs[1]);
2881       break;
2882
2883     case MOP_PASTE_VERT:
2884       result = matrix_expr_evaluate_paste_vert (subs[0], subs[1]);
2885       break;
2886
2887     case MOP_EMPTY:
2888       result = gsl_matrix_alloc (0, 0);
2889       break;
2890
2891     case MOP_VEC_INDEX:
2892       result = matrix_expr_evaluate_vec_index (subs[0], subs[1]);
2893       break;
2894
2895     case MOP_VEC_ALL:
2896       result = matrix_expr_evaluate_vec_all (subs[0]);
2897       break;
2898
2899     case MOP_MAT_INDEX:
2900       result = matrix_expr_evaluate_mat_index (subs[0], subs[1], subs[2]);
2901       break;
2902
2903     case MOP_ROW_INDEX:
2904       result = matrix_expr_evaluate_mat_index (subs[0], subs[1], NULL);
2905       break;
2906
2907     case MOP_COL_INDEX:
2908       result = matrix_expr_evaluate_mat_index (subs[0], NULL, subs[1]);
2909       break;
2910
2911     case MOP_NUMBER:
2912     case MOP_VARIABLE:
2913     case MOP_EOF:
2914       NOT_REACHED ();
2915     }
2916
2917   for (size_t i = 0; i < e->n_subs; i++)
2918     if (subs[i] != result)
2919       gsl_matrix_free (subs[i]);
2920   if (subs != local_subs)
2921     free (subs);
2922   return result;
2923 }
2924
2925 static bool
2926 matrix_expr_evaluate_scalar (const struct matrix_expr *e, const char *context,
2927                              double *d)
2928 {
2929   gsl_matrix *m = matrix_expr_evaluate (e);
2930   if (!m)
2931     return false;
2932
2933   if (!is_scalar (m))
2934     {
2935       msg (SE, _("Expression for %s must evaluate to scalar, "
2936                  "not a matrix with dimensions (%zu,%zu)."),
2937            context, m->size1, m->size2);
2938       gsl_matrix_free (m);
2939       return false;
2940     }
2941
2942   *d = to_scalar (m);
2943   gsl_matrix_free (m);
2944   return true;
2945 }
2946
2947 static bool
2948 matrix_expr_evaluate_integer (const struct matrix_expr *e, const char *context,
2949                               long int *integer)
2950 {
2951   double d;
2952   if (!matrix_expr_evaluate_scalar (e, context, &d))
2953     return false;
2954
2955   d = trunc (d);
2956   if (d < LONG_MIN || d > LONG_MAX)
2957     {
2958       msg (SE, _("Expression for %s is outside the integer range."), context);
2959       return false;
2960     }
2961   *integer = d;
2962   return true;
2963 }
2964 \f
2965 struct matrix_lvalue
2966   {
2967     struct matrix_var *var;
2968     struct matrix_expr *indexes[2];
2969     size_t n_indexes;
2970   };
2971
2972 static void
2973 matrix_lvalue_destroy (struct matrix_lvalue *lvalue)
2974 {
2975   if (lvalue)
2976     for (size_t i = 0; i < lvalue->n_indexes; i++)
2977       matrix_expr_destroy (lvalue->indexes[i]);
2978 }
2979
2980 static struct matrix_lvalue *
2981 matrix_lvalue_parse (struct matrix_state *s)
2982 {
2983   struct matrix_lvalue *lvalue = xzalloc (sizeof *lvalue);
2984   if (!lex_force_id (s->lexer))
2985     goto error;
2986   lvalue->var = matrix_var_lookup (s, lex_tokss (s->lexer));
2987   if (lex_next_token (s->lexer, 1) == T_LPAREN)
2988     {
2989       if (!lvalue->var)
2990         {
2991           msg (SE, _("Undefined variable %s."), lex_tokcstr (s->lexer));
2992           return NULL;
2993         }
2994
2995       lex_get_n (s->lexer, 2);
2996
2997       if (!matrix_parse_index_expr (s, &lvalue->indexes[0]))
2998         goto error;
2999       lvalue->n_indexes++;
3000
3001       if (lex_match (s->lexer, T_COMMA))
3002         {
3003           if (!matrix_parse_index_expr (s, &lvalue->indexes[1]))
3004             goto error;
3005           lvalue->n_indexes++;
3006         }
3007       if (!lex_force_match (s->lexer, T_RPAREN))
3008         goto error;
3009     }
3010   else
3011     {
3012       if (!lvalue->var)
3013         lvalue->var = matrix_var_create (s, lex_tokss (s->lexer));
3014       lex_get (s->lexer);
3015     }
3016   return lvalue;
3017
3018 error:
3019   matrix_lvalue_destroy (lvalue);
3020   return NULL;
3021 }
3022
3023 static bool
3024 matrix_lvalue_evaluate_vector (struct matrix_expr *e, size_t size,
3025                                enum index_type index_type, size_t other_size,
3026                                struct index_vector *iv)
3027 {
3028   gsl_matrix *m;
3029   if (e)
3030     {
3031       m = matrix_expr_evaluate (e);
3032       if (!m)
3033         return false;
3034     }
3035   else
3036     m = NULL;
3037
3038   return matrix_normalize_index_vector (m, size, index_type, other_size, iv);
3039 }
3040
3041 static bool
3042 matrix_lvalue_assign_vector (struct matrix_lvalue *lvalue,
3043                              struct index_vector *iv, gsl_matrix *sm)
3044 {
3045   gsl_vector dv = to_vector (lvalue->var->value);
3046
3047   /* Convert source matrix 'sm' to source vector 'sv'. */
3048   if (!is_vector (sm))
3049     {
3050       msg (SE, _("Can't assign matrix with dimensions (%zu,%zu) to subvector."),
3051            sm->size1, sm->size2);
3052       return false;
3053     }
3054   gsl_vector sv = to_vector (sm);
3055   if (iv->n != sv.size)
3056     {
3057       msg (SE, _("Can't assign vector with %zu elements "
3058                  "to subvector with %zu."), sv.size, iv->n);
3059       return false;
3060     }
3061
3062   /* Assign elements. */
3063   for (size_t x = 0; x < iv->n; x++)
3064     gsl_vector_set (&dv, iv->indexes[x], gsl_vector_get (&sv, x));
3065   return true;
3066 }
3067
3068 static bool
3069 matrix_lvalue_assign_matrix (struct matrix_lvalue *lvalue,
3070                              struct index_vector *iv0,
3071                              struct index_vector *iv1, gsl_matrix *sm)
3072 {
3073   gsl_matrix *dm = lvalue->var->value;
3074
3075   /* Convert source matrix 'sm' to source vector 'sv'. */
3076   if (iv0->n != sm->size1)
3077     {
3078       msg (SE, _("Row index vector for assignment to %s has %zu elements "
3079                  "but source matrix has %zu rows."),
3080            lvalue->var->name, iv0->n, sm->size1);
3081       return false;
3082     }
3083   if (iv1->n != sm->size2)
3084     {
3085       msg (SE, _("Column index vector for assignment to %s has %zu elements "
3086                  "but source matrix has %zu columns."),
3087            lvalue->var->name, iv1->n, sm->size2);
3088       return false;
3089     }
3090
3091   /* Assign elements. */
3092   for (size_t y = 0; y < iv0->n; y++)
3093     {
3094       size_t f0 = iv0->indexes[y];
3095       for (size_t x = 0; x < iv1->n; x++)
3096         {
3097           size_t f1 = iv1->indexes[x];
3098           gsl_matrix_set (dm, f0, f1, gsl_matrix_get (sm, y, x));
3099         }
3100     }
3101   return true;
3102 }
3103
3104 /* Takes ownership of M. */
3105 static bool
3106 matrix_lvalue_assign (struct matrix_lvalue *lvalue,
3107                       struct index_vector *iv0, struct index_vector *iv1,
3108                       gsl_matrix *sm)
3109 {
3110   if (!lvalue->n_indexes)
3111     {
3112       gsl_matrix_free (lvalue->var->value);
3113       lvalue->var->value = sm;
3114       return true;
3115     }
3116   else
3117     {
3118       bool ok = (lvalue->n_indexes == 1
3119                  ? matrix_lvalue_assign_vector (lvalue, iv0, sm)
3120                  : matrix_lvalue_assign_matrix (lvalue, iv0, iv1, sm));
3121       free (iv0->indexes);
3122       free (iv1->indexes);
3123       gsl_matrix_free (sm);
3124       return ok;
3125     }
3126 }
3127
3128 static bool
3129 matrix_lvalue_evaluate (struct matrix_lvalue *lvalue,
3130                         struct index_vector *iv0,
3131                         struct index_vector *iv1)
3132 {
3133   *iv0 = INDEX_VECTOR_INIT;
3134   *iv1 = INDEX_VECTOR_INIT;
3135   if (!lvalue->n_indexes)
3136     return true;
3137
3138   /* Validate destination matrix exists and has the right shape. */
3139   gsl_matrix *dm = lvalue->var->value;
3140   if (!dm)
3141     {
3142       msg (SE, _("Undefined variable %s."), lvalue->var->name);
3143       return false;
3144     }
3145   else if (dm->size1 == 0 || dm->size2 == 0)
3146     {
3147       msg (SE, _("Cannot index matrix with dimensions (%zu,%zu)."),
3148            dm->size1, dm->size2);
3149       return false;
3150     }
3151   else if (lvalue->n_indexes == 1)
3152     {
3153       if (!is_vector (dm))
3154         {
3155           msg (SE, _("Can't use vector indexing on matrix %s with "
3156                      "dimensions (%zu,%zu)."),
3157                lvalue->var->name, dm->size1, dm->size2);
3158           return false;
3159         }
3160       return matrix_lvalue_evaluate_vector (lvalue->indexes[0],
3161                                             MAX (dm->size1, dm->size2),
3162                                             IV_VECTOR, 0, iv0);
3163     }
3164   else
3165     {
3166       assert (lvalue->n_indexes == 2);
3167       if (!matrix_lvalue_evaluate_vector (lvalue->indexes[0], dm->size1,
3168                                           IV_ROW, dm->size2, iv0))
3169         return false;
3170
3171       if (!matrix_lvalue_evaluate_vector (lvalue->indexes[1], dm->size2,
3172                                           IV_COLUMN, dm->size1, iv1))
3173         {
3174           free (iv0->indexes);
3175           return false;
3176         }
3177       return true;
3178     }
3179 }
3180
3181 /* Takes ownership of M. */
3182 static bool
3183 matrix_lvalue_evaluate_and_assign (struct matrix_lvalue *lvalue, gsl_matrix *sm)
3184 {
3185   struct index_vector iv0, iv1;
3186   return (matrix_lvalue_evaluate (lvalue, &iv0, &iv1)
3187           && matrix_lvalue_assign (lvalue, &iv0, &iv1, sm));
3188 }
3189
3190 \f
3191 /* Matrix command. */
3192
3193 struct matrix_cmds
3194   {
3195     struct matrix_cmd **commands;
3196     size_t n;
3197   };
3198
3199 struct matrix_cmd
3200   {
3201     enum matrix_cmd_type
3202       {
3203         MCMD_COMPUTE,
3204         MCMD_PRINT,
3205         MCMD_DO_IF,
3206         MCMD_LOOP,
3207         MCMD_BREAK,
3208         MCMD_DISPLAY,
3209         MCMD_RELEASE,
3210         MCMD_SAVE,
3211         MCMD_READ,
3212         MCMD_WRITE,
3213         MCMD_GET,
3214         MCMD_MSAVE,
3215         MCMD_MGET,
3216         MCMD_EIGEN,
3217         MCMD_SETDIAG,
3218         MCMD_SVD,
3219       }
3220     type;
3221
3222     union
3223       {
3224         struct compute_command
3225           {
3226             struct matrix_lvalue *lvalue;
3227             struct matrix_expr *rvalue;
3228           }
3229         compute;
3230
3231         struct print_command
3232           {
3233             struct matrix_expr *expression;
3234             bool use_default_format;
3235             struct fmt_spec format;
3236             char *title;
3237             int space;          /* -1 means NEWPAGE. */
3238
3239             struct print_labels
3240               {
3241                 struct string_array literals; /* CLABELS/RLABELS. */
3242                 struct matrix_expr *expr;     /* CNAMES/RNAMES. */
3243               }
3244             *rlabels, *clabels;
3245           }
3246         print;
3247
3248         struct do_if_command
3249           {
3250             struct do_if_clause
3251               {
3252                 struct matrix_expr *condition;
3253                 struct matrix_cmds commands;
3254               }
3255             *clauses;
3256             size_t n_clauses;
3257           }
3258         do_if;
3259
3260         struct loop_command
3261           {
3262             /* Index. */
3263             struct matrix_var *var;
3264             struct matrix_expr *start;
3265             struct matrix_expr *end;
3266             struct matrix_expr *increment;
3267
3268             /* Loop conditions. */
3269             struct matrix_expr *top_condition;
3270             struct matrix_expr *bottom_condition;
3271
3272             /* Commands. */
3273             struct matrix_cmds commands;
3274           }
3275         loop;
3276
3277         struct save_command
3278           {
3279             struct matrix_expr *expression;
3280             struct file_handle *outfile;
3281             struct string_array *variables;
3282             struct matrix_expr *names;
3283             struct stringi_set strings;
3284           }
3285         save;
3286
3287         struct read_command
3288           {
3289             struct read_file *rf;
3290             struct matrix_lvalue *dst;
3291             struct matrix_expr *size;
3292             int c1, c2;
3293             enum fmt_type format;
3294             int w;
3295             int d;
3296             bool symmetric;
3297             bool reread;
3298           }
3299         read;
3300
3301         struct write_command
3302           {
3303             struct matrix_expr *expression;
3304             struct file_handle *outfile;
3305             char *encoding;
3306             int c1, c2;
3307             enum fmt_type format;
3308             int w;
3309             int d;
3310             bool triangular;
3311             bool hold;
3312           }
3313         write;
3314
3315         struct display_command
3316           {
3317             struct matrix_state *state;
3318             bool dictionary;
3319             bool status;
3320           }
3321         display;
3322
3323         struct release_command
3324           {
3325             struct matrix_var **vars;
3326             size_t n_vars;
3327           }
3328         release;
3329
3330         struct get_command
3331           {
3332             struct matrix_lvalue *dst;
3333             struct file_handle *file;
3334             char *encoding;
3335             struct string_array variables;
3336             struct matrix_var *names;
3337
3338             /* Treatment of missing values. */
3339             struct
3340               {
3341                 enum
3342                   {
3343                     MGET_ERROR,  /* Flag error on command. */
3344                     MGET_ACCEPT, /* Accept without change, user-missing only. */
3345                     MGET_OMIT,   /* Drop this case. */
3346                     MGET_RECODE  /* Recode to 'substitute'. */
3347                   }
3348                 treatment;
3349                 double substitute; /* MGET_RECODE only. */
3350               }
3351             user, system;
3352           }
3353         get;
3354
3355         struct msave_command
3356           {
3357             struct msave_common *common;
3358             char *varname_;
3359             struct matrix_expr *expr;
3360             const char *rowtype;
3361             struct matrix_expr *factors;
3362             struct matrix_expr *splits;
3363           }
3364          msave;
3365
3366         struct mget_command
3367           {
3368             struct matrix_state *state;
3369             struct file_handle *file;
3370             struct stringi_set rowtypes;
3371           }
3372         mget;
3373
3374         struct eigen_command
3375           {
3376             struct matrix_expr *expr;
3377             struct matrix_var *evec;
3378             struct matrix_var *eval;
3379           }
3380         eigen;
3381
3382         struct setdiag_command
3383           {
3384             struct matrix_var *dst;
3385             struct matrix_expr *expr;
3386           }
3387         setdiag;
3388
3389         struct svd_command
3390           {
3391             struct matrix_expr *expr;
3392             struct matrix_var *u;
3393             struct matrix_var *s;
3394             struct matrix_var *v;
3395           }
3396         svd;
3397       };
3398   };
3399
3400 static struct matrix_cmd *matrix_parse_command (struct matrix_state *);
3401 static bool matrix_cmd_execute (struct matrix_cmd *);
3402
3403 static void
3404 matrix_cmd_destroy (struct matrix_cmd *cmd)
3405 {
3406   /* XXX */
3407   free (cmd);
3408 }
3409 \f
3410 static struct matrix_cmd *
3411 matrix_parse_compute (struct matrix_state *s)
3412 {
3413   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
3414   *cmd = (struct matrix_cmd) {
3415     .type = MCMD_COMPUTE,
3416     .compute = { .lvalue = NULL },
3417   };
3418
3419   struct compute_command *compute = &cmd->compute;
3420   compute->lvalue = matrix_lvalue_parse (s);
3421   if (!compute->lvalue)
3422     goto error;
3423
3424   if (!lex_force_match (s->lexer, T_EQUALS))
3425     goto error;
3426
3427   compute->rvalue = matrix_parse_expr (s);
3428   if (!compute->rvalue)
3429     goto error;
3430
3431   return cmd;
3432
3433 error:
3434   matrix_cmd_destroy (cmd);
3435   return NULL;
3436 }
3437
3438 static void
3439 matrix_cmd_execute_compute (struct compute_command *compute)
3440 {
3441   gsl_matrix *value = matrix_expr_evaluate (compute->rvalue);
3442   if (!value)
3443     return;
3444
3445   matrix_lvalue_evaluate_and_assign (compute->lvalue, value);
3446 }
3447 \f
3448 static void
3449 print_labels_destroy (struct print_labels *labels)
3450 {
3451   if (labels)
3452     {
3453       string_array_destroy (&labels->literals);
3454       matrix_expr_destroy (labels->expr);
3455       free (labels);
3456     }
3457 }
3458
3459 static void
3460 parse_literal_print_labels (struct matrix_state *s,
3461                             struct print_labels **labelsp)
3462 {
3463   lex_match (s->lexer, T_EQUALS);
3464   print_labels_destroy (*labelsp);
3465   *labelsp = xzalloc (sizeof **labelsp);
3466   while (lex_token (s->lexer) != T_SLASH
3467          && lex_token (s->lexer) != T_ENDCMD
3468          && lex_token (s->lexer) != T_STOP)
3469     {
3470       struct string label = DS_EMPTY_INITIALIZER;
3471       while (lex_token (s->lexer) != T_COMMA
3472              && lex_token (s->lexer) != T_SLASH
3473              && lex_token (s->lexer) != T_ENDCMD
3474              && lex_token (s->lexer) != T_STOP)
3475         {
3476           if (!ds_is_empty (&label))
3477             ds_put_byte (&label, ' ');
3478
3479           if (lex_token (s->lexer) == T_STRING)
3480             ds_put_cstr (&label, lex_tokcstr (s->lexer));
3481           else
3482             {
3483               char *rep = lex_next_representation (s->lexer, 0, 0);
3484               ds_put_cstr (&label, rep);
3485               free (rep);
3486             }
3487           lex_get (s->lexer);
3488         }
3489       string_array_append_nocopy (&(*labelsp)->literals,
3490                                   ds_steal_cstr (&label));
3491
3492       if (!lex_match (s->lexer, T_COMMA))
3493         break;
3494     }
3495 }
3496
3497 static bool
3498 parse_expr_print_labels (struct matrix_state *s, struct print_labels **labelsp)
3499 {
3500   lex_match (s->lexer, T_EQUALS);
3501   struct matrix_expr *e = matrix_parse_exp (s);
3502   if (!e)
3503     return false;
3504
3505   print_labels_destroy (*labelsp);
3506   *labelsp = xzalloc (sizeof **labelsp);
3507   (*labelsp)->expr = e;
3508   return true;
3509 }
3510
3511 static struct matrix_cmd *
3512 matrix_parse_print (struct matrix_state *s)
3513 {
3514   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
3515   *cmd = (struct matrix_cmd) {
3516     .type = MCMD_PRINT,
3517     .print = {
3518       .use_default_format = true,
3519     }
3520   };
3521
3522   if (lex_token (s->lexer) != T_SLASH && lex_token (s->lexer) != T_ENDCMD)
3523     {
3524       size_t depth = 0;
3525       for (size_t i = 0; ; i++)
3526         {
3527           enum token_type t = lex_next_token (s->lexer, i);
3528           if (t == T_LPAREN || t == T_LBRACK || t == T_LCURLY)
3529             depth++;
3530           else if ((t == T_RPAREN || t == T_RBRACK || t == T_RCURLY) && depth)
3531             depth--;
3532           else if ((t == T_SLASH && !depth) || t == T_ENDCMD || t == T_STOP)
3533             {
3534               if (i > 0)
3535                 cmd->print.title = lex_next_representation (s->lexer, 0, i - 1);
3536               break;
3537             }
3538         }
3539
3540       cmd->print.expression = matrix_parse_exp (s);
3541       if (!cmd->print.expression)
3542         goto error;
3543     }
3544
3545   while (lex_match (s->lexer, T_SLASH))
3546     {
3547       if (lex_match_id (s->lexer, "FORMAT"))
3548         {
3549           lex_match (s->lexer, T_EQUALS);
3550           if (!parse_format_specifier (s->lexer, &cmd->print.format))
3551             goto error;
3552           cmd->print.use_default_format = false;
3553         }
3554       else if (lex_match_id (s->lexer, "TITLE"))
3555         {
3556           lex_match (s->lexer, T_EQUALS);
3557           if (!lex_force_string (s->lexer))
3558             goto error;
3559           free (cmd->print.title);
3560           cmd->print.title = ss_xstrdup (lex_tokss (s->lexer));
3561           lex_get (s->lexer);
3562         }
3563       else if (lex_match_id (s->lexer, "SPACE"))
3564         {
3565           lex_match (s->lexer, T_EQUALS);
3566           if (lex_match_id (s->lexer, "NEWPAGE"))
3567             cmd->print.space = -1;
3568           else if (lex_force_int_range (s->lexer, "SPACE", 1, INT_MAX))
3569             {
3570               cmd->print.space = lex_integer (s->lexer);
3571               lex_get (s->lexer);
3572             }
3573           else
3574             goto error;
3575         }
3576       else if (lex_match_id (s->lexer, "RLABELS"))
3577         parse_literal_print_labels (s, &cmd->print.rlabels);
3578       else if (lex_match_id (s->lexer, "CLABELS"))
3579         parse_literal_print_labels (s, &cmd->print.clabels);
3580       else if (lex_match_id (s->lexer, "RNAMES"))
3581         {
3582           if (!parse_expr_print_labels (s, &cmd->print.rlabels))
3583             goto error;
3584         }
3585       else if (lex_match_id (s->lexer, "CNAMES"))
3586         {
3587           if (!parse_expr_print_labels (s, &cmd->print.clabels))
3588             goto error;
3589         }
3590       else
3591         {
3592           lex_error_expecting (s->lexer, "FORMAT", "TITLE", "SPACE",
3593                                "RLABELS", "CLABELS", "RNAMES", "CNAMES");
3594           goto error;
3595         }
3596
3597     }
3598   return cmd;
3599
3600 error:
3601   matrix_cmd_destroy (cmd);
3602   return NULL;
3603 }
3604
3605 static bool
3606 matrix_is_integer (const gsl_matrix *m)
3607 {
3608   for (size_t y = 0; y < m->size1; y++)
3609     for (size_t x = 0; x < m->size2; x++)
3610       {
3611         double d = gsl_matrix_get (m, y, x);
3612         if (d != floor (d))
3613           return false;
3614       }
3615   return true;
3616 }
3617
3618 static double
3619 matrix_max_magnitude (const gsl_matrix *m)
3620 {
3621   double max = 0.0;
3622   for (size_t y = 0; y < m->size1; y++)
3623     for (size_t x = 0; x < m->size2; x++)
3624       {
3625         double d = fabs (gsl_matrix_get (m, y, x));
3626         if (d > max)
3627           max = d;
3628       }
3629   return max;
3630 }
3631
3632 static bool
3633 format_fits (struct fmt_spec format, double x)
3634 {
3635   char *s = data_out (&(union value) { .f = x }, NULL,
3636                       &format, settings_get_fmt_settings ());
3637   bool fits = *s != '*' && !strchr (s, 'E');
3638   free (s);
3639   return fits;
3640 }
3641
3642 static struct fmt_spec
3643 default_format (const gsl_matrix *m, int *log_scale)
3644 {
3645   *log_scale = 0;
3646
3647   double max = matrix_max_magnitude (m);
3648
3649   if (matrix_is_integer (m))
3650     for (int w = 1; w <= 12; w++)
3651       {
3652         struct fmt_spec format = { .type = FMT_F, .w = w };
3653         if (format_fits (format, -max))
3654           return format;
3655       }
3656
3657   if (max >= 1e9 || max <= 1e-4)
3658     {
3659       char s[64];
3660       snprintf (s, sizeof s, "%.1e", max);
3661
3662       const char *e = strchr (s, 'e');
3663       if (e)
3664         *log_scale = atoi (e + 1);
3665     }
3666
3667   return (struct fmt_spec) { .type = FMT_F, .w = 13, .d = 10 };
3668 }
3669
3670 static char *
3671 trimmed_string (double d)
3672 {
3673   struct substring s = ss_buffer ((char *) &d, sizeof d);
3674   ss_rtrim (&s, ss_cstr (" "));
3675   return ss_xstrdup (s);
3676 }
3677
3678 static struct string_array *
3679 print_labels_get (const struct print_labels *labels, size_t n,
3680                   const char *prefix, bool truncate)
3681 {
3682   if (!labels)
3683     return NULL;
3684
3685   struct string_array *out = xzalloc (sizeof *out);
3686   if (labels->literals.n)
3687     string_array_clone (out, &labels->literals);
3688   else if (labels->expr)
3689     {
3690       gsl_matrix *m = matrix_expr_evaluate (labels->expr);
3691       if (m && is_vector (m))
3692         {
3693           gsl_vector v = to_vector (m);
3694           for (size_t i = 0; i < v.size; i++)
3695             string_array_append_nocopy (out, trimmed_string (
3696                                           gsl_vector_get (&v, i)));
3697         }
3698       gsl_matrix_free (m);
3699     }
3700
3701   while (out->n < n)
3702     {
3703       if (labels->expr)
3704         string_array_append_nocopy (out, xasprintf ("%s%zu", prefix,
3705                                                     out->n + 1));
3706       else
3707         string_array_append (out, "");
3708     }
3709   while (out->n > n)
3710     string_array_delete (out, out->n - 1);
3711
3712   if (truncate)
3713     for (size_t i = 0; i < out->n; i++)
3714       {
3715         char *s = out->strings[i];
3716         s[strnlen (s, 8)] = '\0';
3717       }
3718
3719   return out;
3720 }
3721
3722 static void
3723 matrix_cmd_print_space (int space)
3724 {
3725   if (space < 0)
3726     output_item_submit (page_break_item_create ());
3727   for (int i = 0; i < space; i++)
3728     output_log ("%s", "");
3729 }
3730
3731 static void
3732 matrix_cmd_print_text (const struct print_command *print, const gsl_matrix *m,
3733                        struct fmt_spec format, int log_scale)
3734 {
3735   matrix_cmd_print_space (print->space);
3736   if (print->title)
3737     output_log ("%s", print->title);
3738   if (log_scale != 0)
3739     output_log ("  10 ** %d   X", log_scale);
3740
3741   struct string_array *clabels = print_labels_get (print->clabels,
3742                                                    m->size2, "col", true);
3743   if (clabels && format.w < 8)
3744     format.w = 8;
3745   struct string_array *rlabels = print_labels_get (print->rlabels,
3746                                                    m->size1, "row", true);
3747
3748   if (clabels)
3749     {
3750       struct string line = DS_EMPTY_INITIALIZER;
3751       if (rlabels)
3752         ds_put_byte_multiple (&line, ' ', 8);
3753       for (size_t x = 0; x < m->size2; x++)
3754         ds_put_format (&line, " %*s", format.w, clabels->strings[x]);
3755       output_log_nocopy (ds_steal_cstr (&line));
3756     }
3757
3758   double scale = pow (10.0, log_scale);
3759   bool numeric = fmt_is_numeric (format.type);
3760   for (size_t y = 0; y < m->size1; y++)
3761     {
3762       struct string line = DS_EMPTY_INITIALIZER;
3763       if (rlabels)
3764         ds_put_format (&line, "%-8s", rlabels->strings[y]);
3765
3766       for (size_t x = 0; x < m->size2; x++)
3767         {
3768           double f = gsl_matrix_get (m, y, x);
3769           char *s = (numeric
3770                      ? data_out (&(union value) { .f = f / scale}, NULL,
3771                                  &format, settings_get_fmt_settings ())
3772                      : trimmed_string (f));
3773           ds_put_format (&line, " %s", s);
3774           free (s);
3775         }
3776       output_log_nocopy (ds_steal_cstr (&line));
3777     }
3778
3779   string_array_destroy (rlabels);
3780   string_array_destroy (clabels);
3781 }
3782
3783 static void
3784 create_print_dimension (struct pivot_table *table, enum pivot_axis_type axis,
3785                         const struct print_labels *print_labels, size_t n,
3786                         const char *name, const char *prefix)
3787 {
3788   struct string_array *labels = print_labels_get (print_labels, n, prefix,
3789                                                   false);
3790   struct pivot_dimension *d = pivot_dimension_create (table, axis, name);
3791   for (size_t i = 0; i < n; i++)
3792     pivot_category_create_leaf (
3793       d->root, (labels
3794                 ? pivot_value_new_user_text (labels->strings[i], SIZE_MAX)
3795                 : pivot_value_new_integer (i + 1)));
3796   if (!labels)
3797     d->hide_all_labels = true;
3798   string_array_destroy (labels);
3799 }
3800
3801 static void
3802 matrix_cmd_print_tables (const struct print_command *print, const gsl_matrix *m,
3803                          struct fmt_spec format, int log_scale)
3804 {
3805   struct pivot_table *table = pivot_table_create__ (
3806     pivot_value_new_user_text (print->title ? print->title : "", SIZE_MAX),
3807     "Matrix Print");
3808
3809   create_print_dimension (table, PIVOT_AXIS_ROW, print->rlabels, m->size1,
3810                           N_("Rows"), "row");
3811   create_print_dimension (table, PIVOT_AXIS_COLUMN, print->clabels, m->size2,
3812                           N_("Columns"), "col");
3813
3814   struct pivot_footnote *footnote = NULL;
3815   if (log_scale != 0)
3816     {
3817       char *s = xasprintf ("× 10**%d", log_scale);
3818       footnote = pivot_table_create_footnote (
3819         table, pivot_value_new_user_text_nocopy (s));
3820     }
3821
3822   double scale = pow (10.0, log_scale);
3823   bool numeric = fmt_is_numeric (format.type);
3824   for (size_t y = 0; y < m->size1; y++)
3825     for (size_t x = 0; x < m->size2; x++)
3826       {
3827         double f = gsl_matrix_get (m, y, x);
3828         struct pivot_value *v;
3829         if (numeric)
3830           {
3831             v = pivot_value_new_number (f / scale);
3832             v->numeric.format = format;
3833           }
3834         else
3835           v = pivot_value_new_user_text_nocopy (trimmed_string (f));
3836         if (footnote)
3837           pivot_value_add_footnote (v, footnote);
3838         pivot_table_put2 (table, y, x, v);
3839       }
3840
3841   pivot_table_submit (table);
3842 }
3843
3844 static void
3845 matrix_cmd_execute_print (const struct print_command *print)
3846 {
3847   if (print->expression)
3848     {
3849       gsl_matrix *m = matrix_expr_evaluate (print->expression);
3850       if (!m)
3851         return;
3852
3853       int log_scale = 0;
3854       struct fmt_spec format = (print->use_default_format
3855                                 ? default_format (m, &log_scale)
3856                                 : print->format);
3857
3858       if (settings_get_mdisplay () == SETTINGS_MDISPLAY_TEXT)
3859         matrix_cmd_print_text (print, m, format, log_scale);
3860       else
3861         matrix_cmd_print_tables (print, m, format, log_scale);
3862
3863       gsl_matrix_free (m);
3864     }
3865   else
3866     {
3867       matrix_cmd_print_space (print->space);
3868       if (print->title)
3869         output_log ("%s", print->title);
3870     }
3871 }
3872 \f
3873 /* DO IF. */
3874
3875 static bool
3876 matrix_parse_commands (struct matrix_state *s, struct matrix_cmds *c,
3877                        const char *command_name,
3878                        const char *stop1, const char *stop2)
3879 {
3880   lex_end_of_command (s->lexer);
3881   lex_discard_rest_of_command (s->lexer);
3882
3883   size_t allocated = 0;
3884   for (;;)
3885     {
3886       while (lex_token (s->lexer) == T_ENDCMD)
3887         lex_get (s->lexer);
3888
3889       if (lex_at_phrase (s->lexer, stop1)
3890           || (stop2 && lex_at_phrase (s->lexer, stop2)))
3891         return true;
3892
3893       if (lex_at_phrase (s->lexer, "END MATRIX"))
3894         {
3895           msg (SE, _("Premature END MATRIX within %s."), command_name);
3896           return false;
3897         }
3898
3899       struct matrix_cmd *cmd = matrix_parse_command (s);
3900       if (!cmd)
3901         return false;
3902
3903       if (c->n >= allocated)
3904         c->commands = x2nrealloc (c->commands, &allocated, sizeof *c->commands);
3905       c->commands[c->n++] = cmd;
3906     }
3907 }
3908
3909 static bool
3910 matrix_parse_do_if_clause (struct matrix_state *s,
3911                            struct do_if_command *ifc,
3912                            bool parse_condition,
3913                            size_t *allocated_clauses)
3914 {
3915   if (ifc->n_clauses >= *allocated_clauses)
3916     ifc->clauses = x2nrealloc (ifc->clauses, allocated_clauses,
3917                                sizeof *ifc->clauses);
3918   struct do_if_clause *c = &ifc->clauses[ifc->n_clauses++];
3919   *c = (struct do_if_clause) { .condition = NULL };
3920
3921   if (parse_condition)
3922     {
3923       c->condition = matrix_parse_expr (s);
3924       if (!c->condition)
3925         return false;
3926     }
3927
3928   return matrix_parse_commands (s, &c->commands, "DO IF", "ELSE", "END IF");
3929 }
3930
3931 static struct matrix_cmd *
3932 matrix_parse_do_if (struct matrix_state *s)
3933 {
3934   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
3935   *cmd = (struct matrix_cmd) {
3936     .type = MCMD_DO_IF,
3937     .do_if = { .n_clauses = 0 }
3938   };
3939
3940   size_t allocated_clauses = 0;
3941   do
3942     {
3943       if (!matrix_parse_do_if_clause (s, &cmd->do_if, true, &allocated_clauses))
3944         goto error;
3945     }
3946   while (lex_match_phrase (s->lexer, "ELSE IF"));
3947
3948   if (lex_match_id (s->lexer, "ELSE")
3949       && !matrix_parse_do_if_clause (s, &cmd->do_if, false, &allocated_clauses))
3950     goto error;
3951
3952   if (!lex_match_phrase (s->lexer, "END IF"))
3953     NOT_REACHED ();
3954   return cmd;
3955
3956 error:
3957   matrix_cmd_destroy (cmd);
3958   return NULL;
3959 }
3960
3961 static bool
3962 matrix_cmd_execute_do_if (struct do_if_command *cmd)
3963 {
3964   for (size_t i = 0; i < cmd->n_clauses; i++)
3965     {
3966       struct do_if_clause *c = &cmd->clauses[i];
3967       if (c->condition)
3968         {
3969           double d;
3970           if (!matrix_expr_evaluate_scalar (c->condition,
3971                                             i ? "ELSE IF" : "DO IF",
3972                                             &d) || d <= 0)
3973             continue;
3974         }
3975
3976       for (size_t j = 0; j < c->commands.n; j++)
3977         if (!matrix_cmd_execute (c->commands.commands[j]))
3978           return false;
3979       return true;
3980     }
3981   return true;
3982 }
3983 \f
3984 static struct matrix_cmd *
3985 matrix_parse_loop (struct matrix_state *s)
3986 {
3987   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
3988   *cmd = (struct matrix_cmd) { .type = MCMD_LOOP, .loop = { .var = NULL } };
3989
3990   struct loop_command *loop = &cmd->loop;
3991   if (lex_token (s->lexer) == T_ID && lex_next_token (s->lexer, 1) == T_EQUALS)
3992     {
3993       struct substring name = lex_tokss (s->lexer);
3994       loop->var = matrix_var_lookup (s, name);
3995       if (!loop->var)
3996         loop->var = matrix_var_create (s, name);
3997
3998       lex_get (s->lexer);
3999       lex_get (s->lexer);
4000
4001       loop->start = matrix_parse_expr (s);
4002       if (!loop->start || !lex_force_match (s->lexer, T_TO))
4003         goto error;
4004
4005       loop->end = matrix_parse_expr (s);
4006       if (!loop->end)
4007         goto error;
4008
4009       if (lex_match (s->lexer, T_BY))
4010         {
4011           loop->increment = matrix_parse_expr (s);
4012           if (!loop->increment)
4013             goto error;
4014         }
4015     }
4016
4017   if (lex_match_id (s->lexer, "IF"))
4018     {
4019       loop->top_condition = matrix_parse_expr (s);
4020       if (!loop->top_condition)
4021         goto error;
4022     }
4023
4024   bool was_in_loop = s->in_loop;
4025   s->in_loop = true;
4026   bool ok = matrix_parse_commands (s, &loop->commands, "LOOP",
4027                                    "END LOOP", NULL);
4028   s->in_loop = was_in_loop;
4029   if (!ok)
4030     goto error;
4031
4032   if (!lex_match_phrase (s->lexer, "END LOOP"))
4033     NOT_REACHED ();
4034
4035   if (lex_match_id (s->lexer, "IF"))
4036     {
4037       loop->bottom_condition = matrix_parse_expr (s);
4038       if (!loop->bottom_condition)
4039         goto error;
4040     }
4041
4042   return cmd;
4043
4044 error:
4045   matrix_cmd_destroy (cmd);
4046   return NULL;
4047 }
4048
4049 static void
4050 matrix_cmd_execute_loop (struct loop_command *cmd)
4051 {
4052   long int value = 0;
4053   long int end = 0;
4054   long int increment = 1;
4055   if (cmd->var)
4056     {
4057       if (!matrix_expr_evaluate_integer (cmd->start, "LOOP", &value)
4058           || !matrix_expr_evaluate_integer (cmd->end, "TO", &end)
4059           || (cmd->increment
4060               && !matrix_expr_evaluate_integer (cmd->increment, "BY",
4061                                                 &increment)))
4062         return;
4063
4064       if (increment > 0 ? value > end
4065           : increment < 0 ? value < end
4066           : true)
4067         return;
4068     }
4069
4070   int mxloops = settings_get_mxloops ();
4071   for (int i = 0; i < mxloops; i++)
4072     {
4073       if (cmd->var)
4074         {
4075           if (cmd->var->value
4076               && (cmd->var->value->size1 != 1 || cmd->var->value->size2 != 1))
4077             {
4078               gsl_matrix_free (cmd->var->value);
4079               cmd->var->value = NULL;
4080             }
4081           if (!cmd->var->value)
4082             cmd->var->value = gsl_matrix_alloc (1, 1);
4083
4084           gsl_matrix_set (cmd->var->value, 0, 0, value);
4085         }
4086
4087       if (cmd->top_condition)
4088         {
4089           double d;
4090           if (!matrix_expr_evaluate_scalar (cmd->top_condition, "LOOP IF",
4091                                             &d) || d <= 0)
4092             return;
4093         }
4094
4095       for (size_t j = 0; j < cmd->commands.n; j++)
4096         if (!matrix_cmd_execute (cmd->commands.commands[j]))
4097           return;
4098
4099       if (cmd->bottom_condition)
4100         {
4101           double d;
4102           if (!matrix_expr_evaluate_scalar (cmd->bottom_condition,
4103                                             "END LOOP IF", &d) || d > 0)
4104             return;
4105         }
4106
4107       if (cmd->var)
4108         {
4109           value += increment;
4110           if (increment > 0 ? value > end : value < end)
4111             return;
4112         }
4113     }
4114 }
4115 \f
4116 static struct matrix_cmd *
4117 matrix_parse_break (struct matrix_state *s)
4118 {
4119   if (!s->in_loop)
4120     {
4121       msg (SE, _("BREAK not inside LOOP."));
4122       return NULL;
4123     }
4124
4125   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
4126   *cmd = (struct matrix_cmd) { .type = MCMD_BREAK };
4127   return cmd;
4128 }
4129 \f
4130 static struct matrix_cmd *
4131 matrix_parse_display (struct matrix_state *s)
4132 {
4133   bool dictionary = false;
4134   bool status = false;
4135   while (lex_token (s->lexer) == T_ID)
4136     {
4137       if (lex_match_id (s->lexer, "DICTIONARY"))
4138         dictionary = true;
4139       else if (lex_match_id (s->lexer, "STATUS"))
4140         status = true;
4141       else
4142         {
4143           lex_error_expecting (s->lexer, "DICTIONARY", "STATUS");
4144           return NULL;
4145         }
4146     }
4147   if (!dictionary && !status)
4148     dictionary = status = true;
4149
4150   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
4151   *cmd = (struct matrix_cmd) {
4152     .type = MCMD_DISPLAY,
4153     .display = {
4154       .state = s,
4155       .dictionary = dictionary,
4156       .status = status,
4157     }
4158   };
4159   return cmd;
4160 }
4161
4162 static int
4163 compare_matrix_var_pointers (const void *a_, const void *b_)
4164 {
4165   const struct matrix_var *const *ap = a_;
4166   const struct matrix_var *const *bp = b_;
4167   const struct matrix_var *a = *ap;
4168   const struct matrix_var *b = *bp;
4169   return strcmp (a->name, b->name);
4170 }
4171
4172 static void
4173 matrix_cmd_execute_display (struct display_command *cmd)
4174 {
4175   const struct matrix_state *s = cmd->state;
4176
4177   struct pivot_table *table = pivot_table_create (N_("Matrix Variables"));
4178   pivot_dimension_create (
4179     table, PIVOT_AXIS_COLUMN, N_("Property"),
4180     N_("Rows"), N_("Columns"), N_("Size (kB)"));
4181
4182   const struct matrix_var **vars = xmalloc (hmap_count (&s->vars) * sizeof *vars);
4183   size_t n_vars = 0;
4184
4185   const struct matrix_var *var;
4186   HMAP_FOR_EACH (var, struct matrix_var, hmap_node, &s->vars)
4187     if (var->value)
4188       vars[n_vars++] = var;
4189   qsort (vars, n_vars, sizeof *vars, compare_matrix_var_pointers);
4190
4191   struct pivot_dimension *rows = pivot_dimension_create (
4192     table, PIVOT_AXIS_ROW, N_("Variable"));
4193   for (size_t i = 0; i < n_vars; i++)
4194     {
4195       const struct matrix_var *var = vars[i];
4196       pivot_category_create_leaf (
4197         rows->root, pivot_value_new_user_text (var->name, SIZE_MAX));
4198
4199       size_t r = var->value->size1;
4200       size_t c = var->value->size2;
4201       double values[] = { r, c, r * c * sizeof (double) / 1024 };
4202       for (size_t j = 0; j < sizeof values / sizeof *values; j++)
4203         pivot_table_put2 (table, j, i, pivot_value_new_integer (values[j]));
4204     }
4205   pivot_table_submit (table);
4206 }
4207 \f
4208 static struct matrix_cmd *
4209 matrix_parse_release (struct matrix_state *s)
4210 {
4211   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
4212   *cmd = (struct matrix_cmd) { .type = MCMD_RELEASE };
4213
4214   size_t allocated_vars = 0;
4215   while (lex_token (s->lexer) == T_ID)
4216     {
4217       struct matrix_var *var = matrix_var_lookup (s, lex_tokss (s->lexer));
4218       if (var)
4219         {
4220           if (cmd->release.n_vars >= allocated_vars)
4221             cmd->release.vars = x2nrealloc (cmd->release.vars, &allocated_vars,
4222                                             sizeof *cmd->release.vars);
4223           cmd->release.vars[cmd->release.n_vars++] = var;
4224         }
4225       else
4226         lex_error (s->lexer, _("Variable name expected."));
4227       lex_get (s->lexer);
4228
4229       if (!lex_match (s->lexer, T_COMMA))
4230         break;
4231     }
4232
4233   return cmd;
4234 }
4235
4236 static void
4237 matrix_cmd_execute_release (struct release_command *cmd)
4238 {
4239   for (size_t i = 0; i < cmd->n_vars; i++)
4240     {
4241       struct matrix_var *var = cmd->vars[i];
4242       gsl_matrix_free (var->value);
4243       var->value = NULL;
4244     }
4245 }
4246 \f
4247 static struct matrix_cmd *
4248 matrix_parse_save (struct matrix_state *s)
4249 {
4250   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
4251   *cmd = (struct matrix_cmd) {
4252     .type = MCMD_SAVE,
4253     .save = {
4254       .strings = STRINGI_SET_INITIALIZER (cmd->save.strings)
4255     }
4256   };
4257
4258   struct save_command *save = &cmd->save;
4259   save->expression = matrix_parse_exp (s);
4260   if (!save->expression)
4261     goto error;
4262
4263   while (lex_match (s->lexer, T_SLASH))
4264     {
4265       if (lex_match_id (s->lexer, "OUTFILE"))
4266         {
4267           lex_match (s->lexer, T_EQUALS);
4268
4269           fh_unref (save->outfile);
4270           save->outfile = (lex_match (s->lexer, T_ASTERISK)
4271                            ? fh_inline_file ()
4272                            : fh_parse (s->lexer, FH_REF_FILE, s->session));
4273           if (!save->outfile)
4274             goto error;
4275         }
4276       else if (lex_match_id (s->lexer, "VARIABLES"))
4277         {
4278           lex_match (s->lexer, T_EQUALS);
4279
4280           char **names;
4281           size_t n;
4282           struct dictionary *d = dict_create (get_default_encoding ());
4283           bool ok = parse_DATA_LIST_vars (s->lexer, d, &names, &n,
4284                                           PV_NO_SCRATCH | PV_NO_DUPLICATE);
4285           dict_unref (d);
4286           if (!ok)
4287             goto error;
4288
4289           string_array_destroy (save->variables);
4290           if (!save->variables)
4291             save->variables = xmalloc (sizeof *save->variables);
4292           *save->variables = (struct string_array) {
4293             .strings = names,
4294             .n = n,
4295             .allocated = n,
4296           };
4297         }
4298       else if (lex_match_id (s->lexer, "NAMES"))
4299         {
4300           lex_match (s->lexer, T_EQUALS);
4301           matrix_expr_destroy (save->names);
4302           save->names = matrix_parse_exp (s);
4303           if (!save->names)
4304             goto error;
4305         }
4306       else if (lex_match_id (s->lexer, "STRINGS"))
4307         {
4308           lex_match (s->lexer, T_EQUALS);
4309           while (lex_token (s->lexer) == T_ID)
4310             {
4311               stringi_set_insert (&save->strings, lex_tokcstr (s->lexer));
4312               lex_get (s->lexer);
4313               if (!lex_match (s->lexer, T_COMMA))
4314                 break;
4315             }
4316         }
4317       else
4318         {
4319           lex_error_expecting (s->lexer, "OUTFILE", "VARIABLES", "NAMES",
4320                                "STRINGS");
4321           goto error;
4322         }
4323     }
4324
4325   if (!save->outfile)
4326     {
4327       if (s->prev_save_outfile)
4328         save->outfile = fh_ref (s->prev_save_outfile);
4329       else
4330         {
4331           lex_sbc_missing ("OUTFILE");
4332           goto error;
4333         }
4334     }
4335   fh_unref (s->prev_save_outfile);
4336   s->prev_save_outfile = fh_ref (save->outfile);
4337
4338   if (save->variables && save->names)
4339     {
4340       msg (SW, _("VARIABLES and NAMES both specified; ignoring NAMES."));
4341       matrix_expr_destroy (save->names);
4342       save->names = NULL;
4343     }
4344
4345   return cmd;
4346
4347 error:
4348   matrix_cmd_destroy (cmd);
4349   return NULL;
4350 }
4351
4352 static void
4353 matrix_cmd_execute_save (const struct save_command *save)
4354 {
4355   assert (save->outfile != fh_inline_file ()); /* XXX not yet implemented */
4356
4357   gsl_matrix *m = matrix_expr_evaluate (save->expression);
4358   if (!m)
4359     return;
4360
4361   bool ok = true;
4362   struct dictionary *dict = dict_create (get_default_encoding ());
4363   struct string_array names = { .n = 0 };
4364   if (save->variables)
4365     string_array_clone (&names, save->variables);
4366   else if (save->names)
4367     {
4368       gsl_matrix *nm = matrix_expr_evaluate (save->names);
4369       if (nm && is_vector (nm))
4370         {
4371           gsl_vector nv = to_vector (nm);
4372           for (size_t i = 0; i < nv.size; i++)
4373             {
4374               char *name = trimmed_string (gsl_vector_get (&nv, i));
4375               if (dict_id_is_valid (dict, name, true))
4376                 string_array_append_nocopy (&names, name);
4377               else
4378                 ok = false;
4379             }
4380         }
4381     }
4382
4383   struct stringi_set strings;
4384   stringi_set_clone (&strings, &save->strings);
4385
4386   for (size_t i = 0; dict_get_var_cnt (dict) < m->size2; i++)
4387     {
4388       char tmp_name[64];
4389       const char *name;
4390       if (i < names.n)
4391         name = names.strings[i];
4392       else
4393         {
4394           snprintf (tmp_name, sizeof tmp_name, "COL%zu", i + 1);
4395           name = tmp_name;
4396         }
4397
4398       int width = stringi_set_delete (&strings, name) ? 8 : 0;
4399       struct variable *var = dict_create_var (dict, name, width);
4400       if (!var)
4401         {
4402           msg (SE, _("Duplicate variable name %s in SAVE statement."),
4403                name);
4404           ok = false;
4405         }
4406     }
4407
4408   if (!stringi_set_is_empty (&strings))
4409     {
4410       const char *example = stringi_set_node_get_string (
4411         stringi_set_first (&strings));
4412       msg (SE, ngettext ("STRINGS specified a variable %s, but no variable "
4413                          "with that name was found on SAVE.",
4414                          "STRINGS specified %2$zu variables, including %1$s, "
4415                          "whose names were not found on SAVE.",
4416                          stringi_set_count (&strings)),
4417            example, stringi_set_count (&strings));
4418       ok = false;
4419     }
4420   stringi_set_destroy (&strings);
4421   string_array_destroy (&names);
4422
4423   if (!ok)
4424     {
4425       gsl_matrix_free (m);
4426       dict_unref (dict);
4427       return;
4428     }
4429
4430   struct casewriter *writer = any_writer_open (save->outfile, dict);
4431   if (!writer)
4432     {
4433       gsl_matrix_free (m);
4434       dict_unref (dict);
4435       return;
4436     }
4437
4438   const struct caseproto *proto = dict_get_proto (dict);
4439   for (size_t y = 0; y < m->size1; y++)
4440     {
4441       struct ccase *c = case_create (proto);
4442       for (size_t x = 0; x < m->size2; x++)
4443         {
4444           double d = gsl_matrix_get (m, y, x);
4445           int width = caseproto_get_width (proto, x);
4446           union value *value = case_data_rw_idx (c, x);
4447           if (width == 0)
4448             value->f = d;
4449           else
4450             memcpy (value->s, &d, width);
4451         }
4452       casewriter_write (writer, c);
4453     }
4454   casewriter_destroy (writer);
4455
4456   gsl_matrix_free (m);
4457   dict_unref (dict);
4458 }
4459 \f
4460 static struct matrix_cmd *
4461 matrix_parse_read (struct matrix_state *s)
4462 {
4463   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
4464   *cmd = (struct matrix_cmd) {
4465     .type = MCMD_READ,
4466     .read = { .format = FMT_F },
4467   };
4468
4469   struct file_handle *fh = NULL;
4470   char *encoding = NULL;
4471   struct read_command *read = &cmd->read;
4472   read->dst = matrix_lvalue_parse (s);
4473   if (!read->dst)
4474     goto error;
4475
4476   int by = 0;
4477   int repetitions = 0;
4478   int record_width = 0;
4479   bool seen_format = false;
4480   while (lex_match (s->lexer, T_SLASH))
4481     {
4482       if (lex_match_id (s->lexer, "FILE"))
4483         {
4484           lex_match (s->lexer, T_EQUALS);
4485
4486           fh_unref (fh);
4487           fh = fh_parse (s->lexer, FH_REF_FILE, NULL);
4488           if (!fh)
4489             goto error;
4490         }
4491       else if (lex_match_id (s->lexer, "ENCODING"))
4492         {
4493           lex_match (s->lexer, T_EQUALS);
4494           if (!lex_force_string (s->lexer))
4495             goto error;
4496
4497           free (encoding);
4498           encoding = ss_xstrdup (lex_tokss (s->lexer));
4499
4500           lex_get (s->lexer);
4501         }
4502       else if (lex_match_id (s->lexer, "FIELD"))
4503         {
4504           lex_match (s->lexer, T_EQUALS);
4505
4506           if (!lex_force_int_range (s->lexer, "FIELD", 1, INT_MAX))
4507             goto error;
4508           read->c1 = lex_integer (s->lexer);
4509           lex_get (s->lexer);
4510           if (!lex_force_match (s->lexer, T_TO)
4511               || !lex_force_int_range (s->lexer, "TO", read->c1, INT_MAX))
4512             goto error;
4513           read->c2 = lex_integer (s->lexer) + 1;
4514           lex_get (s->lexer);
4515
4516           record_width = read->c2 - read->c1;
4517           if (lex_match (s->lexer, T_BY))
4518             {
4519               if (!lex_force_int_range (s->lexer, "BY", 1,
4520                                         read->c2 - read->c1))
4521                 goto error;
4522               by = lex_integer (s->lexer);
4523               lex_get (s->lexer);
4524
4525               if (record_width % by)
4526                 {
4527                   msg (SE, _("BY %d does not evenly divide record width %d."),
4528                        by, record_width);
4529                   goto error;
4530                 }
4531             }
4532           else
4533             by = 0;
4534         }
4535       else if (lex_match_id (s->lexer, "SIZE"))
4536         {
4537           lex_match (s->lexer, T_EQUALS);
4538           read->size = matrix_parse_exp (s);
4539           if (!read->size)
4540             goto error;
4541         }
4542       else if (lex_match_id (s->lexer, "MODE"))
4543         {
4544           lex_match (s->lexer, T_EQUALS);
4545           if (lex_match_id (s->lexer, "RECTANGULAR"))
4546             read->symmetric = false;
4547           else if (lex_match_id (s->lexer, "SYMMETRIC"))
4548             read->symmetric = true;
4549           else
4550             {
4551               lex_error_expecting (s->lexer, "RECTANGULAR", "SYMMETRIC");
4552               goto error;
4553             }
4554         }
4555       else if (lex_match_id (s->lexer, "REREAD"))
4556         read->reread = true;
4557       else if (lex_match_id (s->lexer, "FORMAT"))
4558         {
4559           if (seen_format)
4560             {
4561               lex_sbc_only_once ("FORMAT");
4562               goto error;
4563             }
4564           seen_format = true;
4565
4566           lex_match (s->lexer, T_EQUALS);
4567
4568           if (lex_token (s->lexer) != T_STRING && !lex_force_id (s->lexer))
4569             goto error;
4570
4571           const char *p = lex_tokcstr (s->lexer);
4572           if (c_isdigit (p[0]))
4573             {
4574               repetitions = atoi (p);
4575               p += strspn (p, "0123456789");
4576               if (!fmt_from_name (p, &read->format))
4577                 {
4578                   lex_error (s->lexer, _("Unknown format %s."), p);
4579                   goto error;
4580                 }
4581               lex_get (s->lexer);
4582             }
4583           else if (!fmt_from_name (p, &read->format))
4584             {
4585               struct fmt_spec format;
4586               if (!parse_format_specifier (s->lexer, &format))
4587                 goto error;
4588               read->format = format.type;
4589               read->w = format.w;
4590               read->d = format.d;
4591             }
4592         }
4593       else
4594         {
4595           lex_error_expecting (s->lexer, "FILE", "FIELD", "MODE",
4596                                "REREAD", "FORMAT");
4597           goto error;
4598         }
4599     }
4600
4601   if (!read->c1)
4602     {
4603       lex_sbc_missing ("FIELD");
4604       goto error;
4605     }
4606
4607   if (!read->dst->n_indexes && !read->size)
4608     {
4609       msg (SE, _("SIZE is required for reading data into a full matrix "
4610                  "(as opposed to a submatrix)."));
4611       goto error;
4612     }
4613
4614   if (!fh)
4615     {
4616       if (s->prev_read_file)
4617         fh = fh_ref (s->prev_read_file);
4618       else
4619         {
4620           lex_sbc_missing ("FILE");
4621           goto error;
4622         }
4623     }
4624   fh_unref (s->prev_read_file);
4625   s->prev_read_file = fh_ref (fh);
4626
4627   read->rf = read_file_create (s, fh);
4628   if (encoding)
4629     {
4630       free (read->rf->encoding);
4631       read->rf->encoding = encoding;
4632       encoding = NULL;
4633     }
4634
4635   /* Field width may be specified in multiple ways:
4636
4637      1. BY on FIELD.
4638      2. The format on FORMAT.
4639      3. The repetition factor on FORMAT.
4640
4641      (2) and (3) are mutually exclusive.
4642
4643      If more than one of these is present, they must agree.  If none of them is
4644      present, then free-field format is used.
4645    */
4646   if (repetitions > record_width)
4647     {
4648       msg (SE, _("%d repetitions cannot fit in record width %d."),
4649            repetitions, record_width);
4650       goto error;
4651     }
4652   int w = (repetitions ? record_width / repetitions
4653            : read->w ? read->w
4654            : by);
4655   if (by && w != by)
4656     {
4657       if (repetitions)
4658         msg (SE, _("FORMAT specifies %d repetitions with record width %d, "
4659                    "which implies field width %d, "
4660                    "but BY specifies field width %d."),
4661              repetitions, record_width, w, by);
4662       else
4663         msg (SE, _("FORMAT specifies field width %d but BY specifies %d."),
4664              w, by);
4665       goto error;
4666     }
4667   read->w = w;
4668   return cmd;
4669
4670 error:
4671   matrix_cmd_destroy (cmd);
4672   free (encoding);
4673   return NULL;
4674 }
4675
4676 static void
4677 matrix_read_set_field (struct read_command *read, struct dfm_reader *reader,
4678                        gsl_matrix *m, struct substring p, size_t y, size_t x)
4679 {
4680   const char *input_encoding = dfm_reader_get_encoding (reader);
4681   union value v;
4682   char *error = data_in (p, input_encoding, read->format,
4683                          settings_get_fmt_settings (), &v, 0, NULL);
4684   /* XXX report error if value is missing */
4685   if (error)
4686     msg (SW, _("GET parse error (%.*s): %s"), (int) p.length, p.string, error);
4687   else
4688     {
4689       gsl_matrix_set (m, y, x, v.f);
4690       if (read->symmetric && x != y)
4691         gsl_matrix_set (m, x, y, v.f);
4692     }
4693 }
4694
4695 static bool
4696 matrix_read_line (struct read_command *read, struct dfm_reader *reader,
4697                   struct substring *line)
4698 {
4699   if (dfm_eof (reader))
4700     {
4701       msg (SE, _("Unexpected end of file reading matrix data."));
4702       return false;
4703     }
4704   dfm_expand_tabs (reader);
4705   *line = ss_substr (dfm_get_record (reader),
4706                      read->c1 - 1, read->c2 - read->c1);
4707   return true;
4708 }
4709
4710 static void
4711 matrix_read (struct read_command *read, struct dfm_reader *reader,
4712              gsl_matrix *m)
4713 {
4714   for (size_t y = 0; y < m->size1; y++)
4715     {
4716       size_t nx = read->symmetric ? y + 1 : m->size2;
4717
4718       struct substring line = ss_empty ();
4719       for (size_t x = 0; x < nx; x++)
4720         {
4721           struct substring p;
4722           if (!read->w)
4723             {
4724               for (;;)
4725                 {
4726                   ss_ltrim (&line, ss_cstr (" ,"));
4727                   if (!ss_is_empty (line))
4728                     break;
4729                   if (!matrix_read_line (read, reader, &line))
4730                     return;
4731                   dfm_forward_record (reader);
4732                 }
4733
4734               ss_get_bytes (&line, ss_cspan (line, ss_cstr (" ,")), &p);
4735             }
4736           else
4737             {
4738               if (!matrix_read_line (read, reader, &line))
4739                 return;
4740               size_t fields_per_line = (read->c2 - read->c1) / read->w;
4741               int f = x % fields_per_line;
4742               if (f == fields_per_line - 1)
4743                 dfm_forward_record (reader);
4744
4745               p = ss_substr (line, read->w * f, read->w);
4746             }
4747
4748           matrix_read_set_field (read, reader, m, p, y, x);
4749         }
4750
4751       if (read->w)
4752         dfm_forward_record (reader);
4753       else
4754         {
4755           ss_ltrim (&line, ss_cstr (" ,"));
4756           if (!ss_is_empty (line))
4757             msg (SW, _("Trailing garbage on line \"%.*s\""),
4758                  (int) line.length, line.string);
4759         }
4760     }
4761 }
4762
4763 static void
4764 matrix_cmd_execute_read (struct read_command *read)
4765 {
4766   struct index_vector iv0, iv1;
4767   if (!matrix_lvalue_evaluate (read->dst, &iv0, &iv1))
4768     return;
4769
4770   size_t size[2] = { SIZE_MAX, SIZE_MAX };
4771   if (read->size)
4772     {
4773       gsl_matrix *m = matrix_expr_evaluate (read->size);
4774       if (!m)
4775         return;
4776
4777       if (!is_vector (m))
4778         {
4779           msg (SE, _("SIZE must evaluate to a scalar or a 2-element vector"));
4780           gsl_matrix_free (m);
4781           free (iv0.indexes);
4782           free (iv1.indexes);
4783           return;
4784         }
4785
4786       gsl_vector v = to_vector (m);
4787       double d[2];
4788       if (v.size == 1)
4789         {
4790           d[0] = gsl_vector_get (&v, 0);
4791           d[1] = 1;
4792         }
4793       else if (v.size == 2)
4794         {
4795           d[0] = gsl_vector_get (&v, 0);
4796           d[1] = gsl_vector_get (&v, 1);
4797         }
4798       else
4799         {
4800           msg (SE, _("SIZE must evaluate to a scalar or a 2-element vector"));
4801           gsl_matrix_free (m);
4802           free (iv0.indexes);
4803           free (iv1.indexes);
4804           return;
4805         }
4806       gsl_matrix_free (m);
4807
4808       if (d[0] < 0 || d[0] > SIZE_MAX || d[1] < 0 || d[1] > SIZE_MAX)
4809         {
4810           msg (SE, _("SIZE (%g,%g) is outside valid range."), d[0], d[1]);
4811           free (iv0.indexes);
4812           free (iv1.indexes);
4813           return;
4814         }
4815
4816       size[0] = d[0];
4817       size[1] = d[1];
4818     }
4819
4820   if (read->dst->n_indexes)
4821     {
4822       size_t submatrix_size[2];
4823       if (read->dst->n_indexes == 2)
4824         {
4825           submatrix_size[0] = iv0.n;
4826           submatrix_size[1] = iv1.n;
4827         }
4828       else if (read->dst->var->value->size1 == 1)
4829         {
4830           submatrix_size[0] = 1;
4831           submatrix_size[1] = iv0.n;
4832         }
4833       else
4834         {
4835           submatrix_size[0] = iv0.n;
4836           submatrix_size[1] = 1;
4837         }
4838
4839       if (read->size)
4840         {
4841           if (size[0] != submatrix_size[0] || size[1] != submatrix_size[1])
4842             {
4843               msg (SE, _("SIZE (%zu,%zu) differs from submatrix dimensions "
4844                          "(%zu,%zu)."),
4845                    size[0], size[1],
4846                    submatrix_size[0], submatrix_size[1]);
4847               free (iv0.indexes);
4848               free (iv1.indexes);
4849               return;
4850             }
4851         }
4852       else
4853         {
4854           size[0] = submatrix_size[0];
4855           size[1] = submatrix_size[1];
4856         }
4857     }
4858
4859   struct dfm_reader *reader = read_file_open (read->rf);
4860   if (read->reread)
4861     dfm_reread_record (reader, 1);
4862
4863   if (read->symmetric && size[0] != size[1])
4864     {
4865       msg (SE, _("Cannot read matrix with non-square dimensions (%zu,%zu) "
4866                  "using READ with MODE=SYMMETRIC."),
4867            size[0], size[1]);
4868       free (iv0.indexes);
4869       free (iv1.indexes);
4870       return;
4871     }
4872   gsl_matrix *tmp = gsl_matrix_calloc (size[0], size[1]);
4873   matrix_read (read, reader, tmp);
4874   matrix_lvalue_assign (read->dst, &iv0, &iv1, tmp);
4875 }
4876 \f
4877 static struct matrix_cmd *
4878 matrix_parse_write (struct matrix_state *s)
4879 {
4880   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
4881   *cmd = (struct matrix_cmd) {
4882     .type = MCMD_WRITE,
4883     .write = { .format = FMT_F },
4884   };
4885
4886   struct write_command *write = &cmd->write;
4887   write->expression = matrix_parse_exp (s);
4888   if (!write->expression)
4889     goto error;
4890
4891   int by = 0;
4892   int repetitions = 0;
4893   int record_width = 0;
4894   bool seen_format = false;
4895   while (lex_match (s->lexer, T_SLASH))
4896     {
4897       if (lex_match_id (s->lexer, "OUTFILE"))
4898         {
4899           lex_match (s->lexer, T_EQUALS);
4900
4901           fh_unref (write->outfile);
4902           write->outfile = fh_parse (s->lexer, FH_REF_FILE, NULL);
4903           if (!write->outfile)
4904             goto error;
4905         }
4906       else if (lex_match_id (s->lexer, "ENCODING"))
4907         {
4908           lex_match (s->lexer, T_EQUALS);
4909           if (!lex_force_string (s->lexer))
4910             goto error;
4911
4912           free (write->encoding);
4913           write->encoding = ss_xstrdup (lex_tokss (s->lexer));
4914
4915           lex_get (s->lexer);
4916         }
4917       else if (lex_match_id (s->lexer, "FIELD"))
4918         {
4919           lex_match (s->lexer, T_EQUALS);
4920
4921           if (!lex_force_int_range (s->lexer, "FIELD", 1, INT_MAX))
4922             goto error;
4923           write->c1 = lex_integer (s->lexer);
4924           lex_get (s->lexer);
4925           if (!lex_force_match (s->lexer, T_TO)
4926               || !lex_force_int_range (s->lexer, "TO", write->c1, INT_MAX))
4927             goto error;
4928           write->c2 = lex_integer (s->lexer) + 1;
4929           lex_get (s->lexer);
4930
4931           record_width = write->c2 - write->c1;
4932           if (lex_match (s->lexer, T_BY))
4933             {
4934               if (!lex_force_int_range (s->lexer, "BY", 1,
4935                                         write->c2 - write->c1))
4936                 goto error;
4937               by = lex_integer (s->lexer);
4938               lex_get (s->lexer);
4939
4940               if (record_width % by)
4941                 {
4942                   msg (SE, _("BY %d does not evenly divide record width %d."),
4943                        by, record_width);
4944                   goto error;
4945                 }
4946             }
4947           else
4948             by = 0;
4949         }
4950       else if (lex_match_id (s->lexer, "MODE"))
4951         {
4952           lex_match (s->lexer, T_EQUALS);
4953           if (lex_match_id (s->lexer, "RECTANGULAR"))
4954             write->triangular = false;
4955           else if (lex_match_id (s->lexer, "TRIANGULAR"))
4956             write->triangular = true;
4957           else
4958             {
4959               lex_error_expecting (s->lexer, "RECTANGULAR", "TRIANGULAR");
4960               goto error;
4961             }
4962         }
4963       else if (lex_match_id (s->lexer, "HOLD"))
4964         write->hold = true;
4965       else if (lex_match_id (s->lexer, "FORMAT"))
4966         {
4967           if (seen_format)
4968             {
4969               lex_sbc_only_once ("FORMAT");
4970               goto error;
4971             }
4972           seen_format = true;
4973
4974           lex_match (s->lexer, T_EQUALS);
4975
4976           if (lex_token (s->lexer) != T_STRING && !lex_force_id (s->lexer))
4977             goto error;
4978
4979           const char *p = lex_tokcstr (s->lexer);
4980           if (c_isdigit (p[0]))
4981             {
4982               repetitions = atoi (p);
4983               p += strspn (p, "0123456789");
4984               if (!fmt_from_name (p, &write->format))
4985                 {
4986                   lex_error (s->lexer, _("Unknown format %s."), p);
4987                   goto error;
4988                 }
4989               lex_get (s->lexer);
4990             }
4991           else if (!fmt_from_name (p, &write->format))
4992             {
4993               struct fmt_spec format;
4994               if (!parse_format_specifier (s->lexer, &format))
4995                 goto error;
4996               write->format = format.type;
4997               write->w = format.w;
4998               write->d = format.d;
4999             }
5000         }
5001       else
5002         {
5003           lex_error_expecting (s->lexer, "OUTFILE", "FIELD", "MODE",
5004                                "HOLD", "FORMAT");
5005           goto error;
5006         }
5007     }
5008
5009   if (!write->c1)
5010     {
5011       lex_sbc_missing ("FIELD");
5012       goto error;
5013     }
5014
5015   if (!write->outfile)
5016     {
5017       if (s->prev_write_outfile)
5018         write->outfile = fh_ref (s->prev_write_outfile);
5019       else
5020         {
5021           lex_sbc_missing ("OUTFILE");
5022           goto error;
5023         }
5024     }
5025   fh_unref (s->prev_write_outfile);
5026   s->prev_write_outfile = fh_ref (write->outfile);
5027
5028   /* Field width may be specified in multiple ways:
5029
5030      1. BY on FIELD.
5031      2. The format on FORMAT.
5032      3. The repetition factor on FORMAT.
5033
5034      (2) and (3) are mutually exclusive.
5035
5036      If more than one of these is present, they must agree.  If none of them is
5037      present, then free-field format is used.
5038    */
5039   if (repetitions > record_width)
5040     {
5041       msg (SE, _("%d repetitions cannot fit in record width %d."),
5042            repetitions, record_width);
5043       goto error;
5044     }
5045   int w = (repetitions ? record_width / repetitions
5046            : write->w ? write->w
5047            : by);
5048   if (by && w != by)
5049     {
5050       if (repetitions)
5051         msg (SE, _("FORMAT specifies %d repetitions with record width %d, "
5052                    "which implies field width %d, "
5053                    "but BY specifies field width %d."),
5054              repetitions, record_width, w, by);
5055       else
5056         msg (SE, _("FORMAT specifies field width %d but BY specifies %d."),
5057              w, by);
5058       goto error;
5059     }
5060   write->w = w;
5061   return cmd;
5062
5063 error:
5064   matrix_cmd_destroy (cmd);
5065   return NULL;
5066 }
5067
5068 static void
5069 matrix_cmd_execute_write (struct write_command *write)
5070 {
5071   gsl_matrix *m = matrix_expr_evaluate (write->expression);
5072   if (!m)
5073     return;
5074
5075   if (write->triangular && m->size1 != m->size2)
5076     {
5077       msg (SE, _("WRITE with MODE=TRIANGULAR requires a square matrix but "
5078                  "the matrix to be written has dimensions (%zu,%zu)."),
5079            m->size1, m->size2);
5080       gsl_matrix_free (m);
5081       return;
5082     }
5083
5084   struct dfm_writer *writer = dfm_open_writer (write->outfile, write->encoding);
5085   if (!writer)
5086     {
5087       gsl_matrix_free (m);
5088       return;
5089     }
5090
5091   const struct fmt_settings *settings = settings_get_fmt_settings ();
5092   struct fmt_spec format = {
5093     .type = write->format,
5094     .w = write->w ? write->w : 40,
5095     .d = write->d
5096   };
5097   struct u8_line line = U8_LINE_INITIALIZER;
5098   for (size_t y = 0; y < m->size1; y++)
5099     {
5100       size_t nx = write->triangular ? y + 1 : m->size2;
5101       int x0 = write->c1;
5102       for (size_t x = 0; x < nx; x++)
5103         {
5104           /* XXX string values */
5105           union value v = { .f = gsl_matrix_get (m, y, x) };
5106           char *s = (write->w
5107                      ? data_out (&v, NULL, &format, settings)
5108                      : data_out_stretchy (&v, NULL, &format, settings, NULL));
5109           size_t len = strlen (s);
5110           int width = u8_width (CHAR_CAST (const uint8_t *, s), len, UTF8);
5111           if (width + x0 > write->c2)
5112             {
5113               dfm_put_record_utf8 (writer, line.s.ss.string, line.s.ss.length);
5114               u8_line_clear (&line);
5115               x0 = write->c1;
5116             }
5117           u8_line_put (&line, x0, x0 + width, s, len);
5118           free (s);
5119
5120           x0 += write->w ? write->w : width + 1;
5121         }
5122
5123       dfm_put_record_utf8 (writer, line.s.ss.string, line.s.ss.length);
5124       u8_line_clear (&line);
5125     }
5126   u8_line_destroy (&line);
5127   dfm_close_writer (writer);
5128
5129   gsl_matrix_free (m);
5130 }
5131 \f
5132 static struct matrix_cmd *
5133 matrix_parse_get (struct matrix_state *s)
5134 {
5135   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
5136   *cmd = (struct matrix_cmd) {
5137     .type = MCMD_GET,
5138     .get = {
5139       .user = { .treatment = MGET_ERROR },
5140       .system = { .treatment = MGET_ERROR },
5141     }
5142   };
5143
5144   struct get_command *get = &cmd->get;
5145   get->dst = matrix_lvalue_parse (s);
5146   if (!get->dst)
5147     goto error;
5148
5149   while (lex_match (s->lexer, T_SLASH))
5150     {
5151       if (lex_match_id (s->lexer, "FILE"))
5152         {
5153           if (get->variables.n)
5154             {
5155               lex_error (s->lexer, _("FILE must precede VARIABLES"));
5156               goto error;
5157             }
5158           lex_match (s->lexer, T_EQUALS);
5159
5160           fh_unref (get->file);
5161           get->file = fh_parse (s->lexer, FH_REF_FILE, s->session);
5162           if (!get->file)
5163             goto error;
5164         }
5165       else if (lex_match_id (s->lexer, "ENCODING"))
5166         {
5167           if (get->variables.n)
5168             {
5169               lex_error (s->lexer, _("ENCODING must precede VARIABLES"));
5170               goto error;
5171             }
5172           lex_match (s->lexer, T_EQUALS);
5173           if (!lex_force_string (s->lexer))
5174             goto error;
5175
5176           free (get->encoding);
5177           get->encoding = ss_xstrdup (lex_tokss (s->lexer));
5178
5179           lex_get (s->lexer);
5180         }
5181       else if (lex_match_id (s->lexer, "VARIABLES"))
5182         {
5183           lex_match (s->lexer, T_EQUALS);
5184
5185           struct dictionary *dict = NULL;
5186           if (!get->file)
5187             {
5188               dict = dataset_dict (s->dataset);
5189               if (dict_get_var_cnt (dict) == 0)
5190                 {
5191                   lex_error (s->lexer, _("GET cannot read empty active file."));
5192                   goto error;
5193                 }
5194             }
5195           else
5196             {
5197               struct casereader *reader = any_reader_open_and_decode (
5198                 get->file, get->encoding, &dict, NULL);
5199               if (!reader)
5200                 goto error;
5201               casereader_destroy (reader);
5202             }
5203
5204           struct variable **vars;
5205           size_t n_vars;
5206           bool ok = parse_variables (s->lexer, dict, &vars, &n_vars,
5207                                      PV_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH);
5208           if (!ok)
5209             {
5210               dict_unref (dict);
5211               goto error;
5212             }
5213
5214           string_array_clear (&get->variables);
5215           for (size_t i = 0; i < n_vars; i++)
5216             string_array_append (&get->variables, var_get_name (vars[i]));
5217           free (vars);
5218           dict_unref (dict);
5219         }
5220       else if (lex_match_id (s->lexer, "NAMES"))
5221         {
5222           lex_match (s->lexer, T_EQUALS);
5223           if (!lex_force_id (s->lexer))
5224             goto error;
5225
5226           struct substring name = lex_tokss (s->lexer);
5227           get->names = matrix_var_lookup (s, name);
5228           if (!get->names)
5229             get->names = matrix_var_create (s, name);
5230           lex_get (s->lexer);
5231         }
5232       else if (lex_match_id (s->lexer, "MISSING"))
5233         {
5234           lex_match (s->lexer, T_EQUALS);
5235           if (lex_match_id (s->lexer, "ACCEPT"))
5236             get->user.treatment = MGET_ACCEPT;
5237           else if (lex_match_id (s->lexer, "OMIT"))
5238             get->user.treatment = MGET_OMIT;
5239           else if (lex_is_number (s->lexer))
5240             {
5241               get->user.treatment = MGET_RECODE;
5242               get->user.substitute = lex_number (s->lexer);
5243               lex_get (s->lexer);
5244             }
5245           else
5246             {
5247               lex_error (s->lexer, NULL);
5248               goto error;
5249             }
5250         }
5251       else if (lex_match_id (s->lexer, "SYSMIS"))
5252         {
5253           lex_match (s->lexer, T_EQUALS);
5254           if (lex_match_id (s->lexer, "OMIT"))
5255             get->user.treatment = MGET_OMIT;
5256           else if (lex_is_number (s->lexer))
5257             {
5258               get->user.treatment = MGET_RECODE;
5259               get->user.substitute = lex_number (s->lexer);
5260               lex_get (s->lexer);
5261             }
5262           else
5263             {
5264               lex_error (s->lexer, NULL);
5265               goto error;
5266             }
5267         }
5268       else
5269         {
5270           lex_error_expecting (s->lexer, "FILE", "VARIABLES", "NAMES",
5271                                "MISSING", "SYSMIS");
5272           goto error;
5273         }
5274     }
5275   return cmd;
5276
5277 error:
5278   matrix_cmd_destroy (cmd);
5279   return NULL;
5280 }
5281
5282 static void
5283 matrix_cmd_execute_get (struct get_command *get)
5284 {
5285   assert (get->file);           /* XXX */
5286
5287   struct dictionary *dict;
5288   struct casereader *reader = any_reader_open_and_decode (
5289     get->file, get->encoding, &dict, NULL);
5290   if (!reader)
5291     return;
5292
5293   const struct variable **vars = xnmalloc (
5294     get->variables.n ? get->variables.n : dict_get_var_cnt (dict),
5295     sizeof *vars);
5296   size_t n_vars = 0;
5297
5298   if (get->variables.n)
5299     {
5300       for (size_t i = 0; i < get->variables.n; i++)
5301         {
5302           const char *name = get->variables.strings[i];
5303           const struct variable *var = dict_lookup_var (dict, name);
5304           if (!var)
5305             {
5306               msg (SE, _("GET: Data file does not contain variable %s."),
5307                    name);
5308               dict_unref (dict);
5309               free (vars);
5310               return;
5311             }
5312           if (!var_is_numeric (var))
5313             {
5314               msg (SE, _("GET: Variable %s is not numeric."), name);
5315               dict_unref (dict);
5316               free (vars);
5317               return;
5318             }
5319           vars[n_vars++] = var;
5320         }
5321     }
5322   else
5323     {
5324       for (size_t i = 0; i < dict_get_var_cnt (dict); i++)
5325         {
5326           const struct variable *var = dict_get_var (dict, i);
5327           if (!var_is_numeric (var))
5328             {
5329               msg (SE, _("GET: Variable %s is not numeric."),
5330                    var_get_name (var));
5331               dict_unref (dict);
5332               free (vars);
5333               return;
5334             }
5335           vars[n_vars++] = var;
5336         }
5337     }
5338
5339   size_t n_rows = 0;
5340   gsl_matrix *m = gsl_matrix_alloc (4, n_vars);
5341   long long int casenum = 1;
5342   bool error = false;
5343   for (struct ccase *c = casereader_read (reader); c;
5344        c = casereader_read (reader), casenum++)
5345     {
5346       if (n_rows >= m->size1)
5347         {
5348           gsl_matrix *p = gsl_matrix_alloc (m->size1 * 2, n_vars);
5349           for (size_t y = 0; y < n_rows; y++)
5350             for (size_t x = 0; x < n_vars; x++)
5351               gsl_matrix_set (p, y, x, gsl_matrix_get (m, y, x));
5352           gsl_matrix_free (m);
5353           m = p;
5354         }
5355
5356       bool keep = true;
5357       for (size_t x = 0; x < n_vars; x++)
5358         {
5359           const struct variable *var = vars[x];
5360           double d = case_num (c, var);
5361           if (d == SYSMIS)
5362             {
5363               if (get->system.treatment == MGET_RECODE)
5364                 d = get->system.substitute;
5365               else if (get->system.treatment == MGET_OMIT)
5366                 keep = false;
5367               else
5368                 {
5369                   msg (SE, _("GET: Variable %s in case %lld "
5370                              "is system-missing."),
5371                        var_get_name (var), casenum);
5372                   error = true;
5373                 }
5374             }
5375           else if (var_is_num_missing (var, d, MV_USER))
5376             {
5377               if (get->user.treatment == MGET_RECODE)
5378                 d = get->user.substitute;
5379               else if (get->user.treatment == MGET_OMIT)
5380                 keep = false;
5381               else if (get->user.treatment != MGET_ACCEPT)
5382                 {
5383                   msg (SE, _("GET: Variable %s in case %lld has user-missing "
5384                              "value %g."),
5385                        var_get_name (var), casenum, d);
5386                   error = true;
5387                 }
5388             }
5389           gsl_matrix_set (m, n_rows, x, d);
5390         }
5391       case_unref (c);
5392       if (error)
5393         break;
5394       if (keep)
5395         n_rows++;
5396     }
5397   casereader_destroy (reader);
5398   if (!error)
5399     {
5400       m->size1 = n_rows;
5401       matrix_lvalue_evaluate_and_assign (get->dst, m);
5402     }
5403   else
5404     gsl_matrix_free (m);
5405   dict_unref (dict);
5406   free (vars);
5407 }
5408 \f
5409 static const char *
5410 match_rowtype (struct lexer *lexer)
5411 {
5412   static const char *rowtypes[] = {
5413     "COV", "CORR", "MEAN", "STDDEV", "N", "COUNT"
5414   };
5415   size_t n_rowtypes = sizeof rowtypes / sizeof *rowtypes;
5416
5417   for (size_t i = 0; i < n_rowtypes; i++)
5418     if (lex_match_id (lexer, rowtypes[i]))
5419       return rowtypes[i];
5420
5421   lex_error_expecting_array (lexer, rowtypes, n_rowtypes);
5422   return NULL;
5423 }
5424
5425 static bool
5426 parse_var_names (struct lexer *lexer, struct string_array *sa)
5427 {
5428   lex_match (lexer, T_EQUALS);
5429
5430   string_array_clear (sa);
5431
5432   struct dictionary *dict = dict_create (get_default_encoding ());
5433   dict_create_var_assert (dict, "ROWTYPE_", 8);
5434   dict_create_var_assert (dict, "VARNAME_", 8);
5435   char **names;
5436   size_t n_names;
5437   bool ok = parse_DATA_LIST_vars (lexer, dict, &names, &n_names,
5438                                   PV_NO_DUPLICATE | PV_NO_SCRATCH);
5439   dict_unref (dict);
5440
5441   if (ok)
5442     {
5443       string_array_clear (sa);
5444       sa->strings = names;
5445       sa->n = sa->allocated = n_names;
5446     }
5447   return ok;
5448 }
5449
5450 static void
5451 msave_common_uninit (struct msave_common *common)
5452 {
5453   if (common)
5454     {
5455       fh_unref (common->outfile);
5456       string_array_destroy (&common->variables);
5457       string_array_destroy (&common->fnames);
5458       string_array_destroy (&common->snames);
5459     }
5460 }
5461
5462 static bool
5463 compare_variables (const char *keyword,
5464                    const struct string_array *new,
5465                    const struct string_array *old)
5466 {
5467   if (new->n)
5468     {
5469       if (!old->n)
5470         {
5471           msg (SE, _("%s may only be specified on MSAVE if it was specified "
5472                      "on the first MSAVE within MATRIX."), keyword);
5473           return false;
5474         }
5475       else if (!string_array_equal_case (old, new))
5476         {
5477           msg (SE, _("%s must specify the same variables each time within "
5478                      "a given MATRIX."), keyword);
5479           return false;
5480         }
5481     }
5482   return true;
5483 }
5484
5485 static struct matrix_cmd *
5486 matrix_parse_msave (struct matrix_state *s)
5487 {
5488   struct msave_common common = { .outfile = NULL };
5489   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
5490   *cmd = (struct matrix_cmd) { .type = MCMD_MSAVE, .msave = { .expr = NULL } };
5491
5492   struct msave_command *msave = &cmd->msave;
5493   if (lex_token (s->lexer) == T_ID)
5494     msave->varname_ = ss_xstrdup (lex_tokss (s->lexer));
5495   msave->expr = matrix_parse_exp (s);
5496   if (!msave->expr)
5497     return NULL;
5498
5499   while (lex_match (s->lexer, T_SLASH))
5500     {
5501       if (lex_match_id (s->lexer, "TYPE"))
5502         {
5503           lex_match (s->lexer, T_EQUALS);
5504
5505           msave->rowtype = match_rowtype (s->lexer);
5506           if (!msave->rowtype)
5507             goto error;
5508         }
5509       else if (lex_match_id (s->lexer, "OUTFILE"))
5510         {
5511           lex_match (s->lexer, T_EQUALS);
5512
5513           fh_unref (common.outfile);
5514           common.outfile = fh_parse (s->lexer, FH_REF_FILE, NULL);
5515           if (!common.outfile)
5516             goto error;
5517         }
5518       else if (lex_match_id (s->lexer, "VARIABLES"))
5519         {
5520           if (!parse_var_names (s->lexer, &common.variables))
5521             goto error;
5522         }
5523       else if (lex_match_id (s->lexer, "FNAMES"))
5524         {
5525           if (!parse_var_names (s->lexer, &common.fnames))
5526             goto error;
5527         }
5528       else if (lex_match_id (s->lexer, "SNAMES"))
5529         {
5530           if (!parse_var_names (s->lexer, &common.snames))
5531             goto error;
5532         }
5533       else if (lex_match_id (s->lexer, "SPLIT"))
5534         {
5535           lex_match (s->lexer, T_EQUALS);
5536
5537           matrix_expr_destroy (msave->splits);
5538           msave->splits = matrix_parse_exp (s);
5539           if (!msave->splits)
5540             goto error;
5541         }
5542       else if (lex_match_id (s->lexer, "FACTOR"))
5543         {
5544           lex_match (s->lexer, T_EQUALS);
5545
5546           matrix_expr_destroy (msave->factors);
5547           msave->factors = matrix_parse_exp (s);
5548           if (!msave->factors)
5549             goto error;
5550         }
5551       else
5552         {
5553           lex_error_expecting (s->lexer, "TYPE", "OUTFILE", "VARIABLES",
5554                                "FNAMES", "SNAMES", "SPLIT", "FACTOR");
5555           goto error;
5556         }
5557     }
5558   if (!msave->rowtype)
5559     {
5560       lex_sbc_missing ("TYPE");
5561       goto error;
5562     }
5563   common.has_splits = msave->splits || common.snames.n;
5564   common.has_factors = msave->factors || common.fnames.n;
5565
5566   struct msave_common *c = s->common ? s->common : &common;
5567   if (c->fnames.n && !msave->factors)
5568     {
5569       msg (SE, _("FNAMES requires FACTOR."));
5570       goto error;
5571     }
5572   if (c->snames.n && !msave->splits)
5573     {
5574       msg (SE, _("SNAMES requires SPLIT."));
5575       goto error;
5576     }
5577   if (c->has_factors && !common.has_factors)
5578     {
5579       msg (SE, _("%s is required because it was present on the first "
5580                  "MSAVE in this MATRIX command."), "FACTOR");
5581       goto error;
5582     }
5583   if (c->has_splits && !common.has_splits)
5584     {
5585       msg (SE, _("%s is required because it was present on the first "
5586                  "MSAVE in this MATRIX command."), "SPLIT");
5587       goto error;
5588     }
5589
5590   if (!s->common)
5591     {
5592       if (!common.outfile)
5593         {
5594           lex_sbc_missing ("OUTFILE");
5595           goto error;
5596         }
5597       s->common = xmemdup (&common, sizeof common);
5598     }
5599   else
5600     {
5601       if (common.outfile)
5602         {
5603           bool same = common.outfile == s->common->outfile;
5604           fh_unref (common.outfile);
5605           if (!same)
5606             {
5607               msg (SE, _("OUTFILE must name the same file on each MSAVE "
5608                          "within a single MATRIX command."));
5609               goto error;
5610             }
5611         }
5612       if (!compare_variables ("VARIABLES",
5613                               &common.variables, &s->common->variables)
5614           || !compare_variables ("FNAMES", &common.fnames, &s->common->fnames)
5615           || !compare_variables ("SNAMES", &common.snames, &s->common->snames))
5616         goto error;
5617       msave_common_uninit (&common);
5618     }
5619   msave->common = s->common;
5620   if (!msave->varname_)
5621     msave->varname_ = xasprintf ("MAT%zu", ++s->common->n_varnames);
5622   return cmd;
5623
5624 error:
5625   msave_common_uninit (&common);
5626   matrix_cmd_destroy (cmd);
5627   return NULL;
5628 }
5629
5630 static gsl_vector *
5631 matrix_expr_evaluate_vector (struct matrix_expr *e, const char *name)
5632 {
5633   gsl_matrix *m = matrix_expr_evaluate (e);
5634   if (!m)
5635     return NULL;
5636
5637   if (!is_vector (m))
5638     {
5639       msg (SE, _("%s expression must evaluate to vector, not a matrix with "
5640                  "dimensions (%zu,%zu)."),
5641            name, m->size1, m->size2);
5642       gsl_matrix_free (m);
5643       return NULL;
5644     }
5645
5646   return matrix_to_vector (m);
5647 }
5648
5649 static const char *
5650 msave_add_vars (struct dictionary *d, const struct string_array *vars)
5651 {
5652   for (size_t i = 0; i < vars->n; i++)
5653     if (!dict_create_var (d, vars->strings[i], 0))
5654       return vars->strings[i];
5655   return NULL;
5656 }
5657
5658 static struct dictionary *
5659 msave_create_dict (const struct msave_common *common)
5660 {
5661   struct dictionary *dict = dict_create (get_default_encoding ());
5662
5663   const char *dup_split = msave_add_vars (dict, &common->snames);
5664   if (dup_split)
5665     {
5666       msg (SE, _("Duplicate SPLIT variable name %s."), dup_split);
5667       goto error;
5668     }
5669
5670   dict_create_var_assert (dict, "ROWTYPE_", 8);
5671
5672   const char *dup_factor = msave_add_vars (dict, &common->fnames);
5673   if (dup_factor)
5674     {
5675       msg (SE, _("Duplicate or invalid FACTOR variable name %s."), dup_factor);
5676       goto error;
5677     }
5678
5679   dict_create_var_assert (dict, "VARNAME_", 8);
5680
5681   const char *dup_var = msave_add_vars (dict, &common->variables);
5682   if (dup_var)
5683     {
5684       msg (SE, _("Duplicate or invalid variable name %s."), dup_var);
5685       goto error;
5686     }
5687
5688   return dict;
5689
5690 error:
5691   dict_unref (dict);
5692   return NULL;
5693 }
5694
5695 static void
5696 matrix_cmd_execute_msave (struct msave_command *msave)
5697 {
5698   struct msave_common *common = msave->common;
5699   gsl_matrix *m = NULL;
5700   gsl_vector *factors = NULL;
5701   gsl_vector *splits = NULL;
5702
5703   m = matrix_expr_evaluate (msave->expr);
5704   if (!m)
5705     goto error;
5706
5707   if (!common->variables.n)
5708     for (size_t i = 0; i < m->size2; i++)
5709       string_array_append_nocopy (&common->variables,
5710                                   xasprintf ("COL%zu", i + 1));
5711
5712   if (m->size2 != common->variables.n)
5713     {
5714       msg (SE, _("Matrix on MSAVE has %zu columns instead of required %zu."),
5715            m->size2, common->variables.n);
5716       goto error;
5717     }
5718
5719   if (msave->factors)
5720     {
5721       factors = matrix_expr_evaluate_vector (msave->factors, "FACTOR");
5722       if (!factors)
5723         goto error;
5724
5725       if (!common->fnames.n)
5726         for (size_t i = 0; i < factors->size; i++)
5727           string_array_append_nocopy (&common->fnames,
5728                                       xasprintf ("FAC%zu", i + 1));
5729
5730       if (factors->size != common->fnames.n)
5731         {
5732           msg (SE, _("There are %zu factor variables, "
5733                      "but %zu split values were supplied."),
5734                common->fnames.n, factors->size);
5735           goto error;
5736         }
5737     }
5738
5739   if (msave->splits)
5740     {
5741       splits = matrix_expr_evaluate_vector (msave->splits, "SPLIT");
5742       if (!splits)
5743         goto error;
5744
5745       if (!common->fnames.n)
5746         for (size_t i = 0; i < splits->size; i++)
5747           string_array_append_nocopy (&common->fnames,
5748                                       xasprintf ("SPL%zu", i + 1));
5749
5750       if (splits->size != common->fnames.n)
5751         {
5752           msg (SE, _("There are %zu split variables, "
5753                      "but %zu split values were supplied."),
5754                common->fnames.n, splits->size);
5755           goto error;
5756         }
5757     }
5758
5759   if (!common->writer)
5760     {
5761       struct dictionary *dict = msave_create_dict (common);
5762       if (!dict)
5763         goto error;
5764
5765       common->writer = any_writer_open (common->outfile, dict);
5766       if (!common->writer)
5767         {
5768           dict_unref (dict);
5769           goto error;
5770         }
5771
5772       common->dict = dict;
5773     }
5774
5775   for (size_t y = 0; y < m->size1; y++)
5776     {
5777       struct ccase *c = case_create (dict_get_proto (common->dict));
5778       size_t idx = 0;
5779
5780       /* Split variables */
5781       if (splits)
5782         for (size_t i = 0; i < splits->size; i++)
5783           case_data_rw_idx (c, idx++)->f = gsl_vector_get (splits, i);
5784
5785       /* ROWTYPE_. */
5786       buf_copy_str_rpad (CHAR_CAST (char *, case_data_rw_idx (c, idx++)->s), 8,
5787                          msave->rowtype, ' ');
5788
5789       /* Factors. */
5790       if (factors)
5791         for (size_t i = 0; i < factors->size; i++)
5792           *case_num_rw_idx (c, idx++) = gsl_vector_get (factors, i);
5793
5794       /* VARNAME_. */
5795       buf_copy_str_rpad (CHAR_CAST (char *, case_data_rw_idx (c, idx++)->s), 8,
5796                          msave->varname_, ' ');
5797
5798       /* Continuous variables. */
5799       for (size_t x = 0; x < m->size2; x++)
5800         case_data_rw_idx (c, idx++)->f = gsl_matrix_get (m, y, x);
5801       casewriter_write (common->writer, c);
5802     }
5803
5804 error:
5805   gsl_matrix_free (m);
5806   gsl_vector_free (factors);
5807   gsl_vector_free (splits);
5808 }
5809 \f
5810 static struct matrix_cmd *
5811 matrix_parse_mget (struct matrix_state *s)
5812 {
5813   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
5814   *cmd = (struct matrix_cmd) { .type = MCMD_MGET, .mget = { .state = s } };
5815
5816   struct mget_command *mget = &cmd->mget;
5817
5818   for (;;)
5819     {
5820       if (lex_match_id (s->lexer, "FILE"))
5821         {
5822           lex_match (s->lexer, T_EQUALS);
5823
5824           fh_unref (mget->file);
5825           mget->file = fh_parse (s->lexer, FH_REF_FILE, s->session);
5826           if (!mget->file)
5827             goto error;
5828         }
5829       else if (lex_match_id (s->lexer, "TYPE"))
5830         {
5831           lex_match (s->lexer, T_EQUALS);
5832           while (lex_token (s->lexer) != T_SLASH
5833                  && lex_token (s->lexer) != T_ENDCMD)
5834             {
5835               const char *rowtype = match_rowtype (s->lexer);
5836               if (!rowtype)
5837                 goto error;
5838
5839               stringi_set_insert (&mget->rowtypes, rowtype);
5840             }
5841         }
5842       else
5843         {
5844           lex_error_expecting (s->lexer, "FILE", "TYPE");
5845           goto error;
5846         }
5847       if (lex_token (s->lexer) == T_ENDCMD)
5848         break;
5849
5850       if (!lex_force_match (s->lexer, T_SLASH))
5851         goto error;
5852     }
5853   return cmd;
5854
5855 error:
5856   matrix_cmd_destroy (cmd);
5857   return NULL;
5858 }
5859
5860 static const struct variable *
5861 get_a8_var (const struct dictionary *d, const char *name)
5862 {
5863   const struct variable *v = dict_lookup_var (d, name);
5864   if (!v)
5865     {
5866       msg (SE, _("Matrix data file lacks %s variable."), name);
5867       return NULL;
5868     }
5869   if (var_get_width (v) != 8)
5870     {
5871       msg (SE, _("%s variable in matrix data file must be "
5872                  "8-byte string, but it has width %d."),
5873            name, var_get_width (v));
5874       return NULL;
5875     }
5876   return v;
5877 }
5878
5879 static bool
5880 is_rowtype (const union value *v, const char *rowtype)
5881 {
5882   struct substring vs = ss_buffer (CHAR_CAST (char *, v->s), 8);
5883   ss_rtrim (&vs, ss_cstr (" "));
5884   return ss_equals_case (vs, ss_cstr (rowtype));
5885 }
5886
5887 static void
5888 matrix_mget_commit_var (struct ccase **rows, size_t n_rows,
5889                         const struct dictionary *d,
5890                         const struct variable *rowtype_var,
5891                         struct matrix_state *s, size_t si, size_t fi,
5892                         size_t cs, size_t cn)
5893 {
5894   if (!n_rows)
5895     return;
5896
5897   const union value *rowtype_ = case_data (rows[0], rowtype_var);
5898   const char *name_prefix = (is_rowtype (rowtype_, "COV") ? "CV"
5899                              : is_rowtype (rowtype_, "CORR") ? "CR"
5900                              : is_rowtype (rowtype_, "MEAN") ? "MN"
5901                              : is_rowtype (rowtype_, "STDDEV") ? "SD"
5902                              : is_rowtype (rowtype_, "N") ? "NC"
5903                              : "CN");
5904
5905   struct string name = DS_EMPTY_INITIALIZER;
5906   ds_put_cstr (&name, name_prefix);
5907   if (fi > 0)
5908     ds_put_format (&name, "F%zu", fi);
5909   if (si > 0)
5910     ds_put_format (&name, "S%zu", si);
5911
5912   struct matrix_var *mv = matrix_var_lookup (s, ds_ss (&name));
5913   if (!mv)
5914     mv = matrix_var_create (s, ds_ss (&name));
5915   else if (mv->value)
5916     {
5917       msg (SW, _("Matrix data file contains variable with existing name %s."),
5918            ds_cstr (&name));
5919       goto exit;
5920     }
5921
5922   gsl_matrix *m = gsl_matrix_alloc (n_rows, cn);
5923   size_t n_missing = 0;
5924   for (size_t y = 0; y < n_rows; y++)
5925     {
5926       for (size_t x = 0; x < cn; x++)
5927         {
5928           struct variable *var = dict_get_var (d, cs + x);
5929           double value = case_num (rows[y], var);
5930           if (var_is_num_missing (var, value, MV_ANY))
5931             {
5932               n_missing++;
5933               value = 0.0;
5934             }
5935           gsl_matrix_set (m, y, x, value);
5936         }
5937     }
5938
5939   if (n_missing)
5940     msg (SE, ngettext ("Matrix data file variable %s contains a missing "
5941                        "value, which was treated as zero.",
5942                        "Matrix data file variable %s contains %zu missing "
5943                        "values, which were treated as zero.", n_missing),
5944          ds_cstr (&name), n_missing);
5945   mv->value = m;
5946
5947 exit:
5948   ds_destroy (&name);
5949   for (size_t y = 0; y < n_rows; y++)
5950     case_unref (rows[y]);
5951 }
5952
5953 static bool
5954 var_changed (const struct ccase *ca, const struct ccase *cb,
5955              const struct variable *var)
5956 {
5957   return !value_equal (case_data (ca, var), case_data (cb, var),
5958                        var_get_width (var));
5959 }
5960
5961 static bool
5962 vars_changed (const struct ccase *ca, const struct ccase *cb,
5963               const struct dictionary *d,
5964               size_t first_var, size_t n_vars)
5965 {
5966   for (size_t i = 0; i < n_vars; i++)
5967     {
5968       const struct variable *v = dict_get_var (d, first_var + i);
5969       if (var_changed (ca, cb, v))
5970         return true;
5971     }
5972   return false;
5973 }
5974
5975 static void
5976 matrix_cmd_execute_mget (struct mget_command *mget)
5977 {
5978   struct dictionary *d;
5979   struct casereader *r = any_reader_open_and_decode (mget->file, "UTF-8",
5980                                                      &d, NULL);
5981   if (!r)
5982     return;
5983
5984   const struct variable *rowtype_ = get_a8_var (d, "ROWTYPE_");
5985   const struct variable *varname_ = get_a8_var (d, "VARNAME_");
5986   if (!rowtype_ || !varname_)
5987     goto exit;
5988
5989   if (var_get_dict_index (rowtype_) >= var_get_dict_index (varname_))
5990     {
5991       msg (SE, _("ROWTYPE_ must precede VARNAME_ in matrix data file."));
5992       goto exit;
5993     }
5994   if (var_get_dict_index (varname_) + 1 >= dict_get_var_cnt (d))
5995     {
5996       msg (SE, _("Matrix data file contains no continuous variables."));
5997       goto exit;
5998     }
5999
6000   for (size_t i = 0; i < dict_get_var_cnt (d); i++)
6001     {
6002       const struct variable *v = dict_get_var (d, i);
6003       if (v != rowtype_ && v != varname_ && var_get_width (v) != 0)
6004         {
6005           msg (SE,
6006                _("Matrix data file contains unexpected string variable %s."),
6007                var_get_name (v));
6008           goto exit;
6009         }
6010     }
6011
6012   /* SPLIT variables. */
6013   size_t ss = 0;
6014   size_t sn = var_get_dict_index (rowtype_);
6015   struct ccase *sc = NULL;
6016   size_t si = 0;
6017
6018   /* FACTOR variables. */
6019   size_t fs = var_get_dict_index (rowtype_) + 1;
6020   size_t fn = var_get_dict_index (varname_) - var_get_dict_index (rowtype_) - 1;
6021   struct ccase *fc = NULL;
6022   size_t fi = 0;
6023
6024   /* Continuous variables. */
6025   size_t cs = var_get_dict_index (varname_) + 1;
6026   size_t cn = dict_get_var_cnt (d) - cs;
6027   struct ccase *cc = NULL;
6028
6029   /* Matrix. */
6030   struct ccase **rows = NULL;
6031   size_t allocated_rows = 0;
6032   size_t n_rows = 0;
6033
6034   struct ccase *c;
6035   while ((c = casereader_read (r)) != NULL)
6036     {
6037       bool sd = vars_changed (sc, c, d, ss, sn);
6038       bool fd = sd || vars_changed (fc, c, d, fs, fn);
6039       bool md = fd || !cc || var_changed (cc, c, rowtype_) || var_changed (cc, c, varname_);
6040       if (sd)
6041         {
6042           si++;
6043           case_unref (sc);
6044           sc = case_ref (c);
6045         }
6046       if (fd)
6047         {
6048           fi++;
6049           case_unref (fc);
6050           fc = case_ref (c);
6051         }
6052       if (md)
6053         {
6054           matrix_mget_commit_var (rows, n_rows, d, rowtype_,
6055                                   mget->state, si, fi, cs, cn);
6056           n_rows = 0;
6057           case_unref (cc);
6058           cc = case_ref (c);
6059         }
6060
6061       if (n_rows >= allocated_rows)
6062         rows = x2nrealloc (rows, &allocated_rows, sizeof *rows);
6063       rows[n_rows++] = c;
6064     }
6065   matrix_mget_commit_var (rows, n_rows, d, rowtype_,
6066                           mget->state, si, fi, cs, cn);
6067   free (rows);
6068
6069 exit:
6070   casereader_destroy (r);
6071 }
6072 \f
6073 static bool
6074 matrix_parse_dst_var (struct matrix_state *s, struct matrix_var **varp)
6075 {
6076   if (!lex_force_id (s->lexer))
6077     return false;
6078
6079   *varp = matrix_var_lookup (s, lex_tokss (s->lexer));
6080   if (!*varp)
6081     *varp = matrix_var_create (s, lex_tokss (s->lexer));
6082   lex_get (s->lexer);
6083   return true;
6084 }
6085
6086 static struct matrix_cmd *
6087 matrix_parse_eigen (struct matrix_state *s)
6088 {
6089   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
6090   *cmd = (struct matrix_cmd) {
6091     .type = MCMD_EIGEN,
6092     .eigen = { .expr = NULL }
6093   };
6094
6095   struct eigen_command *eigen = &cmd->eigen;
6096   if (!lex_force_match (s->lexer, T_LPAREN))
6097     goto error;
6098   eigen->expr = matrix_parse_expr (s);
6099   if (!eigen->expr
6100       || !lex_force_match (s->lexer, T_COMMA)
6101       || !matrix_parse_dst_var (s, &eigen->evec)
6102       || !lex_force_match (s->lexer, T_COMMA)
6103       || !matrix_parse_dst_var (s, &eigen->eval)
6104       || !lex_force_match (s->lexer, T_RPAREN))
6105     goto error;
6106
6107   return cmd;
6108
6109 error:
6110   matrix_cmd_destroy (cmd);
6111   return NULL;
6112 }
6113
6114 static void
6115 matrix_cmd_execute_eigen (struct eigen_command *eigen)
6116 {
6117   gsl_matrix *A = matrix_expr_evaluate (eigen->expr);
6118   if (!A)
6119     return;
6120   if (!is_symmetric (A))
6121     {
6122       msg (SE, _("Argument of EIGEN must be symmetric."));
6123       gsl_matrix_free (A);
6124       return;
6125     }
6126
6127   gsl_eigen_symmv_workspace *w = gsl_eigen_symmv_alloc (A->size1);
6128   gsl_matrix *eval = gsl_matrix_alloc (A->size1, 1);
6129   gsl_vector v_eval = to_vector (eval);
6130   gsl_matrix *evec = gsl_matrix_alloc (A->size1, A->size2);
6131   gsl_eigen_symmv (A, &v_eval, evec, w);
6132   gsl_eigen_symmv_free (w);
6133
6134   gsl_eigen_symmv_sort (&v_eval, evec, GSL_EIGEN_SORT_VAL_DESC);
6135
6136   gsl_matrix_free (A);
6137
6138   gsl_matrix_free (eigen->eval->value);
6139   eigen->eval->value = eval;
6140
6141   gsl_matrix_free (eigen->evec->value);
6142   eigen->evec->value = evec;
6143 }
6144 \f
6145 static struct matrix_cmd *
6146 matrix_parse_setdiag (struct matrix_state *s)
6147 {
6148   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
6149   *cmd = (struct matrix_cmd) {
6150     .type = MCMD_SETDIAG,
6151     .setdiag = { .dst = NULL }
6152   };
6153
6154   struct setdiag_command *setdiag = &cmd->setdiag;
6155   if (!lex_force_match (s->lexer, T_LPAREN) || !lex_force_id (s->lexer))
6156     goto error;
6157
6158   setdiag->dst = matrix_var_lookup (s, lex_tokss (s->lexer));
6159   if (!setdiag->dst)
6160     {
6161       lex_error (s->lexer, _("Unknown variable %s."), lex_tokcstr (s->lexer));
6162       goto error;
6163     }
6164   lex_get (s->lexer);
6165
6166   if (!lex_force_match (s->lexer, T_COMMA))
6167     goto error;
6168
6169   setdiag->expr = matrix_parse_expr (s);
6170   if (!setdiag->expr)
6171     goto error;
6172
6173   if (!lex_force_match (s->lexer, T_RPAREN))
6174     goto error;
6175
6176   return cmd;
6177
6178 error:
6179   matrix_cmd_destroy (cmd);
6180   return NULL;
6181 }
6182
6183 static void
6184 matrix_cmd_execute_setdiag (struct setdiag_command *setdiag)
6185 {
6186   gsl_matrix *dst = setdiag->dst->value;
6187   if (!dst)
6188     {
6189       msg (SE, _("SETDIAG destination matrix %s is uninitialized."),
6190            setdiag->dst->name);
6191       return;
6192     }
6193
6194   gsl_matrix *src = matrix_expr_evaluate (setdiag->expr);
6195   if (!src)
6196     return;
6197
6198   size_t n = MIN (dst->size1, dst->size2);
6199   if (is_scalar (src))
6200     {
6201       double d = to_scalar (src);
6202       for (size_t i = 0; i < n; i++)
6203         gsl_matrix_set (dst, i, i, d);
6204     }
6205   else if (is_vector (src))
6206     {
6207       gsl_vector v = to_vector (src);
6208       for (size_t i = 0; i < n && i < v.size; i++)
6209         gsl_matrix_set (dst, i, i, gsl_vector_get (&v, i));
6210     }
6211   else
6212     msg (SE, _("SETDIAG argument 2 must be a scalar or a vector but it "
6213                "has dimensions (%zu,%zu)."),
6214          src->size1, src->size2);
6215   gsl_matrix_free (src);
6216 }
6217 \f
6218 static struct matrix_cmd *
6219 matrix_parse_svd (struct matrix_state *s)
6220 {
6221   struct matrix_cmd *cmd = xmalloc (sizeof *cmd);
6222   *cmd = (struct matrix_cmd) {
6223     .type = MCMD_SVD,
6224     .svd = { .expr = NULL }
6225   };
6226
6227   struct svd_command *svd = &cmd->svd;
6228   if (!lex_force_match (s->lexer, T_LPAREN))
6229     goto error;
6230   svd->expr = matrix_parse_expr (s);
6231   if (!svd->expr
6232       || !lex_force_match (s->lexer, T_COMMA)
6233       || !matrix_parse_dst_var (s, &svd->u)
6234       || !lex_force_match (s->lexer, T_COMMA)
6235       || !matrix_parse_dst_var (s, &svd->s)
6236       || !lex_force_match (s->lexer, T_COMMA)
6237       || !matrix_parse_dst_var (s, &svd->v)
6238       || !lex_force_match (s->lexer, T_RPAREN))
6239     goto error;
6240
6241   return cmd;
6242
6243 error:
6244   matrix_cmd_destroy (cmd);
6245   return NULL;
6246 }
6247
6248 static void
6249 matrix_cmd_execute_svd (struct svd_command *svd)
6250 {
6251   gsl_matrix *m = matrix_expr_evaluate (svd->expr);
6252   if (!m)
6253     return;
6254
6255   if (m->size1 >= m->size2)
6256     {
6257       gsl_matrix *A = m;
6258       gsl_matrix *V = gsl_matrix_alloc (A->size2, A->size2);
6259       gsl_matrix *S = gsl_matrix_calloc (A->size2, A->size2);
6260       gsl_vector Sv = gsl_matrix_diagonal (S).vector;
6261       gsl_vector *work = gsl_vector_alloc (A->size2);
6262       gsl_linalg_SV_decomp (A, V, &Sv, work);
6263       gsl_vector_free (work);
6264
6265       matrix_var_set (svd->u, A);
6266       matrix_var_set (svd->s, S);
6267       matrix_var_set (svd->v, V);
6268     }
6269   else
6270     {
6271       gsl_matrix *At = gsl_matrix_alloc (m->size2, m->size1);
6272       gsl_matrix_transpose_memcpy (At, m);
6273       gsl_matrix *Vt = gsl_matrix_alloc (At->size2, At->size2);
6274       gsl_matrix *St = gsl_matrix_calloc (At->size2, At->size2);
6275       gsl_vector Stv = gsl_matrix_diagonal (St).vector;
6276       gsl_vector *work = gsl_vector_alloc (At->size2);
6277       gsl_linalg_SV_decomp (At, Vt, &Stv, work);
6278       gsl_vector_free (work);
6279
6280       matrix_var_set (svd->v, At);
6281       matrix_var_set (svd->s, St);
6282       matrix_var_set (svd->u, Vt);
6283     }
6284 }
6285 \f
6286 static bool
6287 matrix_cmd_execute (struct matrix_cmd *cmd)
6288 {
6289   switch (cmd->type)
6290     {
6291     case MCMD_COMPUTE:
6292       matrix_cmd_execute_compute (&cmd->compute);
6293       break;
6294
6295     case MCMD_PRINT:
6296       matrix_cmd_execute_print (&cmd->print);
6297       break;
6298
6299     case MCMD_DO_IF:
6300       return matrix_cmd_execute_do_if (&cmd->do_if);
6301
6302     case MCMD_LOOP:
6303       matrix_cmd_execute_loop (&cmd->loop);
6304       break;
6305
6306     case MCMD_BREAK:
6307       return false;
6308
6309     case MCMD_DISPLAY:
6310       matrix_cmd_execute_display (&cmd->display);
6311       break;
6312
6313     case MCMD_RELEASE:
6314       matrix_cmd_execute_release (&cmd->release);
6315       break;
6316
6317     case MCMD_SAVE:
6318       matrix_cmd_execute_save (&cmd->save);
6319       break;
6320
6321     case MCMD_READ:
6322       matrix_cmd_execute_read (&cmd->read);
6323       break;
6324
6325     case MCMD_WRITE:
6326       matrix_cmd_execute_write (&cmd->write);
6327       break;
6328
6329     case MCMD_GET:
6330       matrix_cmd_execute_get (&cmd->get);
6331       break;
6332
6333     case MCMD_MSAVE:
6334       matrix_cmd_execute_msave (&cmd->msave);
6335       break;
6336
6337     case MCMD_MGET:
6338       matrix_cmd_execute_mget (&cmd->mget);
6339       break;
6340
6341     case MCMD_EIGEN:
6342       matrix_cmd_execute_eigen (&cmd->eigen);
6343       break;
6344
6345     case MCMD_SETDIAG:
6346       matrix_cmd_execute_setdiag (&cmd->setdiag);
6347       break;
6348
6349     case MCMD_SVD:
6350       matrix_cmd_execute_svd (&cmd->svd);
6351       break;
6352     }
6353
6354   return true;
6355 }
6356
6357 struct matrix_command_name
6358   {
6359     const char *name;
6360     struct matrix_cmd *(*parse) (struct matrix_state *);
6361   };
6362
6363 static const struct matrix_command_name *
6364 matrix_parse_command_name (struct lexer *lexer)
6365 {
6366   static const struct matrix_command_name commands[] = {
6367     { "COMPUTE", matrix_parse_compute },
6368     { "CALL EIGEN", matrix_parse_eigen },
6369     { "CALL SETDIAG", matrix_parse_setdiag },
6370     { "CALL SVD", matrix_parse_svd },
6371     { "PRINT", matrix_parse_print },
6372     { "DO IF", matrix_parse_do_if },
6373     { "LOOP", matrix_parse_loop },
6374     { "BREAK", matrix_parse_break },
6375     { "READ", matrix_parse_read },
6376     { "WRITE", matrix_parse_write },
6377     { "GET", matrix_parse_get },
6378     { "SAVE", matrix_parse_save },
6379     { "MGET", matrix_parse_mget },
6380     { "MSAVE", matrix_parse_msave },
6381     { "DISPLAY", matrix_parse_display },
6382     { "RELEASE", matrix_parse_release },
6383   };
6384   static size_t n = sizeof commands / sizeof *commands;
6385
6386   for (const struct matrix_command_name *c = commands; c < &commands[n]; c++)
6387     if (lex_match_phrase (lexer, c->name))
6388       return c;
6389   return NULL;
6390 }
6391
6392 static struct matrix_cmd *
6393 matrix_parse_command (struct matrix_state *s)
6394 {
6395   size_t nesting_level = SIZE_MAX;
6396
6397   struct matrix_cmd *c = NULL;
6398   const struct matrix_command_name *cmd = matrix_parse_command_name (s->lexer);
6399   if (!cmd)
6400     lex_error (s->lexer, _("Unknown matrix command."));
6401   else if (!cmd->parse)
6402     lex_error (s->lexer, _("Matrix command %s is not yet implemented."),
6403                cmd->name);
6404   else
6405     {
6406       nesting_level = output_open_group (
6407         group_item_create_nocopy (utf8_to_title (cmd->name),
6408                                   utf8_to_title (cmd->name)));
6409       c = cmd->parse (s);
6410     }
6411
6412   if (c)
6413     lex_end_of_command (s->lexer);
6414   lex_discard_rest_of_command (s->lexer);
6415   if (nesting_level != SIZE_MAX)
6416     output_close_groups (nesting_level);
6417
6418   return c;
6419 }
6420
6421 int
6422 cmd_matrix (struct lexer *lexer, struct dataset *ds)
6423 {
6424   if (!lex_force_match (lexer, T_ENDCMD))
6425     return CMD_FAILURE;
6426
6427   struct matrix_state state = {
6428     .session = dataset_session (ds),
6429     .lexer = lexer,
6430     .vars = HMAP_INITIALIZER (state.vars),
6431   };
6432
6433   for (;;)
6434     {
6435       while (lex_match (lexer, T_ENDCMD))
6436         continue;
6437       if (lex_token (lexer) == T_STOP)
6438         {
6439           msg (SE, _("Unexpected end of input expecting matrix command."));
6440           break;
6441         }
6442
6443       if (lex_match_phrase (lexer, "END MATRIX"))
6444         break;
6445
6446       struct matrix_cmd *c = matrix_parse_command (&state);
6447       if (c)
6448         {
6449           matrix_cmd_execute (c);
6450           matrix_cmd_destroy (c);
6451         }
6452     }
6453
6454   if (state.common)
6455     {
6456       dict_unref (state.common->dict);
6457       casewriter_destroy (state.common->writer);
6458       free (state.common);
6459     }
6460
6461   return CMD_SUCCESS;
6462 }