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