+ else if (mf->triangle == LOWER)
+ {
+ if (mf->diagonal == DIAGONAL)
+ {
+ /* 1 . . .
+ 2 1 . .
+ 3 5 1 .
+ 4 6 7 1 */
+ static const struct read_matrix_params rmp = { 0, 0, 0, 0, 0, 1 };
+ return &rmp;
+ }
+ else
+ {
+ /* . . . .
+ 2 . . .
+ 3 5 . .
+ 4 6 7 . */
+ static const struct read_matrix_params rmp = { 1, 0, 0, 0, 0, 1 };
+ return &rmp;
+ }
+ }
+ else if (mf->triangle == UPPER)
+ {
+ if (mf->diagonal == DIAGONAL)
+ {
+ /* 1 2 3 4
+ . 1 5 6
+ . . 1 7
+ . . . 1 */
+ static const struct read_matrix_params rmp = { 0, 0, 0, INT_MAX, 1, 0 };
+ return &rmp;
+ }
+ else
+ {
+ /* . 2 3 4
+ . . 5 6
+ . . . 7
+ . . . . */
+ static const struct read_matrix_params rmp = { 0, -1, 1, INT_MAX, 1, 0 };
+ return &rmp;
+ }
+ }
+ else
+ NOT_REACHED ();
+}
+
+static void
+schedule_matrices (struct matrix_format *mf)
+{
+ struct matrix_sched *ms0 = &mf->ms[0];
+ ms0->nr = 1;
+ ms0->nc = 1;
+ ms0->rp = xmalloc (sizeof *ms0->rp);
+ ms0->rp[0] = (struct row_sched) { .y = 0, .x0 = 0, .x1 = 1 };
+ ms0->n_rp = 1;
+
+ struct matrix_sched *ms1 = &mf->ms[1];
+ ms1->nr = 1;
+ ms1->nc = mf->n_cvars;
+ ms1->rp = xmalloc (sizeof *ms1->rp);
+ ms1->rp[0] = (struct row_sched) { .y = 0, .x0 = 0, .x1 = mf->n_cvars };
+ ms1->n_rp = 1;
+
+ struct matrix_sched *ms2 = &mf->ms[2];
+ ms2->nr = mf->n_cvars;
+ ms2->nc = mf->n_cvars;
+ ms2->rp = xmalloc (mf->n_cvars * sizeof *ms2->rp);
+ ms2->n_rp = 0;
+
+ const struct read_matrix_params *rmp = get_read_matrix_params (mf);
+ int x0 = rmp->x0;
+ int x1 = rmp->x1 < mf->n_cvars ? rmp->x1 : mf->n_cvars - 1;
+ int y0 = rmp->dy0;
+ int y1 = (int) mf->n_cvars + rmp->dy1;
+ for (int y = y0; y < y1; y++)
+ {
+ assert (x0 >= 0 && x0 < mf->n_cvars);
+ assert (x1 >= 0 && x1 < mf->n_cvars);
+ assert (x1 >= x0);