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