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