Lines Matching defs:mat
25 isl_ctx *isl_mat_get_ctx(__isl_keep isl_mat *mat)
27 return mat ? mat->ctx : NULL;
30 /* Return a hash value that digests "mat".
32 uint32_t isl_mat_get_hash(__isl_keep isl_mat *mat)
37 if (!mat)
41 isl_hash_byte(hash, mat->n_row & 0xFF);
42 isl_hash_byte(hash, mat->n_col & 0xFF);
43 for (i = 0; i < mat->n_row; ++i) {
46 row_hash = isl_seq_get_hash(mat->row[i], mat->n_col);
57 struct isl_mat *mat;
59 mat = isl_alloc_type(ctx, struct isl_mat);
60 if (!mat)
63 mat->row = NULL;
64 mat->block = isl_blk_alloc(ctx, n_row * n_col);
65 if (isl_blk_is_error(mat->block))
67 mat->row = isl_calloc_array(ctx, isl_int *, n_row);
68 if (n_row && !mat->row)
73 mat->row[i] = mat->block.data + i * n_col;
76 mat->ctx = ctx;
78 mat->ref = 1;
79 mat->n_row = n_row;
80 mat->n_col = n_col;
81 mat->max_col = n_col;
82 mat->flags = 0;
84 return mat;
86 isl_blk_free(ctx, mat->block);
87 free(mat);
91 __isl_give isl_mat *isl_mat_extend(__isl_take isl_mat *mat,
98 if (!mat)
101 if (mat->max_col >= n_col && mat->n_row >= n_row) {
102 if (mat->n_col < n_col)
103 mat->n_col = n_col;
104 return mat;
107 if (mat->max_col < n_col) {
110 if (n_row < mat->n_row)
111 n_row = mat->n_row;
112 new_mat = isl_mat_alloc(mat->ctx, n_row, n_col);
115 for (i = 0; i < mat->n_row; ++i)
116 isl_seq_cpy(new_mat->row[i], mat->row[i], mat->n_col);
117 isl_mat_free(mat);
121 mat = isl_mat_cow(mat);
122 if (!mat)
125 old = mat->block.data;
126 mat->block = isl_blk_extend(mat->ctx, mat->block, n_row * mat->max_col);
127 if (isl_blk_is_error(mat->block))
129 row = isl_realloc_array(mat->ctx, mat->row, isl_int *, n_row);
132 mat->row = row;
134 for (i = 0; i < mat->n_row; ++i)
135 mat->row[i] = mat->block.data + (mat->row[i] - old);
136 for (i = mat->n_row; i < n_row; ++i)
137 mat->row[i] = mat->block.data + i * mat->max_col;
138 mat->n_row = n_row;
139 if (mat->n_col < n_col)
140 mat->n_col = n_col;
142 return mat;
144 isl_mat_free(mat);
152 struct isl_mat *mat;
154 mat = isl_alloc_type(ctx, struct isl_mat);
155 if (!mat)
157 mat->row = isl_alloc_array(ctx, isl_int *, n_row);
158 if (n_row && !mat->row)
161 mat->row[i] = row[first_row+i] + first_col;
162 mat->ctx = ctx;
164 mat->ref = 1;
165 mat->n_row = n_row;
166 mat->n_col = n_col;
167 mat->block = isl_blk_empty();
168 mat->flags = ISL_MAT_BORROWED;
169 return mat;
171 free(mat);
175 __isl_give isl_mat *isl_mat_sub_alloc(__isl_keep isl_mat *mat,
178 if (!mat)
180 return isl_mat_sub_alloc6(mat->ctx, mat->row, first_row, n_row,
202 __isl_give isl_mat *isl_mat_copy(__isl_keep isl_mat *mat)
204 if (!mat)
207 mat->ref++;
208 return mat;
211 __isl_give isl_mat *isl_mat_dup(__isl_keep isl_mat *mat)
216 if (!mat)
218 mat2 = isl_mat_alloc(mat->ctx, mat->n_row, mat->n_col);
221 for (i = 0; i < mat->n_row; ++i)
222 isl_seq_cpy(mat2->row[i], mat->row[i], mat->n_col);
226 __isl_give isl_mat *isl_mat_cow(__isl_take isl_mat *mat)
229 if (!mat)
232 if (mat->ref == 1 && !ISL_F_ISSET(mat, ISL_MAT_BORROWED))
233 return mat;
235 mat2 = isl_mat_dup(mat);
236 isl_mat_free(mat);
240 __isl_null isl_mat *isl_mat_free(__isl_take isl_mat *mat)
242 if (!mat)
245 if (--mat->ref > 0)
248 if (!ISL_F_ISSET(mat, ISL_MAT_BORROWED))
249 isl_blk_free(mat->ctx, mat->block);
250 isl_ctx_deref(mat->ctx);
251 free(mat->row);
252 free(mat);
257 isl_size isl_mat_rows(__isl_keep isl_mat *mat)
259 return mat ? mat->n_row : isl_size_error;
262 isl_size isl_mat_cols(__isl_keep isl_mat *mat)
264 return mat ? mat->n_col : isl_size_error;
267 /* Check that "col" is a valid column position for "mat".
269 static isl_stat check_col(__isl_keep isl_mat *mat, int col)
271 if (!mat)
273 if (col < 0 || col >= mat->n_col)
274 isl_die(isl_mat_get_ctx(mat), isl_error_invalid,
279 /* Check that "row" is a valid row position for "mat".
281 static isl_stat check_row(__isl_keep isl_mat *mat, int row)
283 if (!mat)
285 if (row < 0 || row >= mat->n_row)
286 isl_die(isl_mat_get_ctx(mat), isl_error_invalid,
291 /* Check that there are "n" columns starting at position "first" in "mat".
293 static isl_stat check_col_range(__isl_keep isl_mat *mat, unsigned first,
296 if (!mat)
298 if (first + n > mat->n_col || first + n < first)
299 isl_die(isl_mat_get_ctx(mat), isl_error_invalid,
305 /* Check that there are "n" rows starting at position "first" in "mat".
307 static isl_stat check_row_range(__isl_keep isl_mat *mat, unsigned first,
310 if (!mat)
312 if (first + n > mat->n_row || first + n < first)
313 isl_die(isl_mat_get_ctx(mat), isl_error_invalid,
319 int isl_mat_get_element(__isl_keep isl_mat *mat, int row, int col, isl_int *v)
321 if (check_row(mat, row) < 0)
323 if (check_col(mat, col) < 0)
325 isl_int_set(*v, mat->row[row][col]);
329 /* Extract the element at row "row", oolumn "col" of "mat".
331 __isl_give isl_val *isl_mat_get_element_val(__isl_keep isl_mat *mat,
336 if (check_row(mat, row) < 0)
338 if (check_col(mat, col) < 0)
340 ctx = isl_mat_get_ctx(mat);
341 return isl_val_int_from_isl_int(ctx, mat->row[row][col]);
344 __isl_give isl_mat *isl_mat_set_element(__isl_take isl_mat *mat,
347 mat = isl_mat_cow(mat);
348 if (check_row(mat, row) < 0)
349 return isl_mat_free(mat);
350 if (check_col(mat, col) < 0)
351 return isl_mat_free(mat);
352 isl_int_set(mat->row[row][col], v);
353 return mat;
356 __isl_give isl_mat *isl_mat_set_element_si(__isl_take isl_mat *mat,
359 mat = isl_mat_cow(mat);
360 if (check_row(mat, row) < 0)
361 return isl_mat_free(mat);
362 if (check_col(mat, col) < 0)
363 return isl_mat_free(mat);
364 isl_int_set_si(mat->row[row][col], v);
365 return mat;
368 /* Replace the element at row "row", column "col" of "mat" by "v".
370 __isl_give isl_mat *isl_mat_set_element_val(__isl_take isl_mat *mat,
374 return isl_mat_free(mat);
378 mat = isl_mat_set_element(mat, row, col, v->n);
380 return mat;
383 return isl_mat_free(mat);
389 struct isl_mat *mat;
391 mat = isl_mat_alloc(ctx, n_row, n_row);
392 if (!mat)
395 isl_seq_clr(mat->row[i], i);
396 isl_int_set(mat->row[i][i], d);
397 isl_seq_clr(mat->row[i]+i+1, n_row-(i+1));
400 return mat;
408 isl_mat *mat;
410 mat = isl_mat_alloc(ctx, n_row, n_col);
411 if (!mat)
414 isl_seq_clr(mat->row[i], n_col);
416 return mat;
426 /* Is "mat" a (possibly scaled) identity matrix?
428 isl_bool isl_mat_is_scaled_identity(__isl_keep isl_mat *mat)
432 if (!mat)
434 if (mat->n_row != mat->n_col)
437 for (i = 0; i < mat->n_row; ++i) {
438 if (isl_seq_first_non_zero(mat->row[i], i) != -1)
440 if (isl_int_ne(mat->row[0][0], mat->row[i][i]))
442 if (isl_seq_first_non_zero(mat->row[i] + i + 1,
443 mat->n_col - (i + 1)) != -1)
450 __isl_give isl_vec *isl_mat_vec_product(__isl_take isl_mat *mat,
456 if (!mat || !vec)
459 isl_assert(mat->ctx, mat->n_col == vec->size, goto error);
461 prod = isl_vec_alloc(mat->ctx, mat->n_row);
466 isl_seq_inner_product(mat->row[i], vec->el, vec->size,
468 isl_mat_free(mat);
472 isl_mat_free(mat);
477 __isl_give isl_vec *isl_mat_vec_inverse_product(__isl_take isl_mat *mat,
483 if (!mat || !vec)
490 vec_mat = isl_mat_inverse_product(mat, vec_mat);
501 isl_mat_free(mat);
507 __isl_take isl_mat *mat)
512 if (!mat || !vec)
515 isl_assert(mat->ctx, mat->n_row == vec->size, goto error);
517 prod = isl_vec_alloc(mat->ctx, mat->n_col);
524 isl_int_addmul(prod->el[i], vec->el[j], mat->row[j][i]);
526 isl_mat_free(mat);
530 isl_mat_free(mat);
723 /* Use row "row" of "mat" to eliminate column "col" from all other rows.
725 static __isl_give isl_mat *eliminate(__isl_take isl_mat *mat, int row, int col)
731 nr = isl_mat_rows(mat);
732 nc = isl_mat_cols(mat);
734 return isl_mat_free(mat);
736 ctx = isl_mat_get_ctx(mat);
741 if (isl_int_is_zero(mat->row[k][col]))
743 mat = isl_mat_cow(mat);
744 if (!mat)
746 isl_seq_elim(mat->row[k], mat->row[row], col, nc, NULL);
747 isl_seq_normalize(ctx, mat->row[k], nc);
750 return mat;
753 /* Perform Gaussian elimination on the rows of "mat", but start
762 __isl_give isl_mat *isl_mat_reverse_gauss(__isl_take isl_mat *mat)
767 nr = isl_mat_rows(mat);
768 nc = isl_mat_cols(mat);
770 return isl_mat_free(mat);
776 if (!isl_int_is_zero(mat->row[k][last]))
784 mat = isl_mat_swap_rows(mat, k, row);
785 if (!mat)
787 if (isl_int_is_neg(mat->row[row][last]))
788 mat = isl_mat_row_neg(mat, row);
789 mat = eliminate(mat, row, last);
790 if (!mat)
793 mat = isl_mat_drop_rows(mat, 0, row + 1);
795 return mat;
798 /* Negate the lexicographically negative rows of "mat" such that
801 __isl_give isl_mat *isl_mat_lexnonneg_rows(__isl_take isl_mat *mat)
806 nr = isl_mat_rows(mat);
807 nc = isl_mat_cols(mat);
809 return isl_mat_free(mat);
814 pos = isl_seq_first_non_zero(mat->row[i], nc);
817 if (isl_int_is_nonneg(mat->row[i][pos]))
819 mat = isl_mat_row_neg(mat, i);
820 if (!mat)
824 return mat;
852 /* Return the rank of "mat", or isl_size_error in case of error.
854 isl_size isl_mat_rank(__isl_keep isl_mat *mat)
859 H = isl_mat_left_hermite(isl_mat_copy(mat), 0, NULL, NULL);
869 __isl_give isl_mat *isl_mat_right_kernel(__isl_take isl_mat *mat)
875 mat = isl_mat_left_hermite(mat, 0, &U, NULL);
876 if (!mat || !U)
879 rank = hermite_first_zero_col(mat, 0, mat->n_row);
884 isl_mat_free(mat);
888 isl_mat_free(mat);
893 __isl_give isl_mat *isl_mat_lin_to_aff(__isl_take isl_mat *mat)
898 if (!mat)
900 mat2 = isl_mat_alloc(mat->ctx, 1+mat->n_row, 1+mat->n_col);
904 isl_seq_clr(mat2->row[0]+1, mat->n_col);
905 for (i = 0; i < mat->n_row; ++i) {
907 isl_seq_cpy(mat2->row[1+i]+1, mat->row[i], mat->n_col);
909 isl_mat_free(mat);
912 isl_mat_free(mat);
925 isl_mat *mat;
930 mat = isl_mat_alloc(mat1->ctx, mat1->n_row + mat2->n_row,
932 if (!mat)
935 isl_seq_cpy(mat->row[i], mat1->row[i], mat1->n_col);
936 isl_seq_clr(mat->row[i] + mat1->n_col, mat2->n_col);
939 isl_seq_clr(mat->row[mat1->n_row + i], mat1->n_col);
940 isl_seq_cpy(mat->row[mat1->n_row + i] + mat1->n_col,
945 return mat;
1101 void isl_mat_col_scale(__isl_keep isl_mat *mat, unsigned col, isl_int m)
1105 for (i = 0; i < mat->n_row; ++i)
1106 isl_int_mul(mat->row[i][col], mat->row[i][col], m);
1109 void isl_mat_col_combine(__isl_keep isl_mat *mat, unsigned dst,
1116 for (i = 0; i < mat->n_row; ++i) {
1117 isl_int_mul(tmp, m1, mat->row[i][src1]);
1118 isl_int_addmul(tmp, m2, mat->row[i][src2]);
1119 isl_int_set(mat->row[i][dst], tmp);
1124 __isl_give isl_mat *isl_mat_right_inverse(__isl_take isl_mat *mat)
1130 mat = isl_mat_cow(mat);
1131 if (!mat)
1134 inv = isl_mat_identity(mat->ctx, mat->n_col);
1141 for (row = 0; row < mat->n_row; ++row) {
1143 pivot = isl_seq_abs_min_non_zero(mat->row[row]+row, mat->n_col-row);
1147 isl_assert(mat->ctx, pivot >= 0, goto error);
1151 exchange(mat, &inv, NULL, row, pivot, row);
1152 if (isl_int_is_neg(mat->row[row][row]))
1153 oppose(mat, &inv, NULL, row, row);
1155 while ((off = isl_seq_first_non_zero(mat->row[row]+first,
1156 mat->n_col-first)) != -1) {
1158 isl_int_fdiv_q(a, mat->row[row][first],
1159 mat->row[row][row]);
1160 subtract(mat, &inv, NULL, row, row, first, a);
1161 if (!isl_int_is_zero(mat->row[row][first]))
1162 exchange(mat, &inv, NULL, row, row, first);
1167 if (isl_int_is_zero(mat->row[row][i]))
1169 isl_int_gcd(a, mat->row[row][row], mat->row[row][i]);
1170 isl_int_divexact(b, mat->row[row][i], a);
1171 isl_int_divexact(a, mat->row[row][row], a);
1173 isl_mat_col_combine(mat, i, a, i, b, row);
1179 isl_int_set(a, mat->row[0][0]);
1180 for (row = 1; row < mat->n_row; ++row)
1181 isl_int_lcm(a, a, mat->row[row][row]);
1186 for (row = 0; row < mat->n_row; ++row) {
1187 isl_int_divexact(mat->row[row][row], a, mat->row[row][row]);
1188 if (isl_int_is_one(mat->row[row][row]))
1190 isl_mat_col_scale(inv, row, mat->row[row][row]);
1194 isl_mat_free(mat);
1198 isl_mat_free(mat);
1203 __isl_give isl_mat *isl_mat_transpose(__isl_take isl_mat *mat)
1208 if (!mat)
1211 if (mat->n_col == mat->n_row) {
1212 mat = isl_mat_cow(mat);
1213 if (!mat)
1215 for (i = 0; i < mat->n_row; ++i)
1216 for (j = i + 1; j < mat->n_col; ++j)
1217 isl_int_swap(mat->row[i][j], mat->row[j][i]);
1218 return mat;
1220 transpose = isl_mat_alloc(mat->ctx, mat->n_col, mat->n_row);
1223 for (i = 0; i < mat->n_row; ++i)
1224 for (j = 0; j < mat->n_col; ++j)
1225 isl_int_set(transpose->row[j][i], mat->row[i][j]);
1226 isl_mat_free(mat);
1229 isl_mat_free(mat);
1233 __isl_give isl_mat *isl_mat_swap_cols(__isl_take isl_mat *mat,
1238 mat = isl_mat_cow(mat);
1239 if (check_col_range(mat, i, 1) < 0 ||
1240 check_col_range(mat, j, 1) < 0)
1241 return isl_mat_free(mat);
1243 for (r = 0; r < mat->n_row; ++r)
1244 isl_int_swap(mat->row[r][i], mat->row[r][j]);
1245 return mat;
1248 __isl_give isl_mat *isl_mat_swap_rows(__isl_take isl_mat *mat,
1253 if (!mat)
1255 mat = isl_mat_cow(mat);
1256 if (check_row_range(mat, i, 1) < 0 ||
1257 check_row_range(mat, j, 1) < 0)
1258 return isl_mat_free(mat);
1260 t = mat->row[i];
1261 mat->row[i] = mat->row[j];
1262 mat->row[j] = t;
1263 return mat;
1312 * with M the matrix mat.
1323 unsigned n_div, int has_div, struct isl_mat *mat)
1329 if (mat->n_col >= mat->n_row)
1332 e = mat->n_row - mat->n_col;
1335 isl_int_mul(q[i][0], q[i][0], mat->row[0][0]);
1336 t = isl_mat_sub_alloc6(mat->ctx, q, 0, n, has_div, mat->n_row);
1337 t = isl_mat_product(t, mat);
1351 * M the matrix mat.
1361 __isl_take isl_basic_set *bset, __isl_take isl_mat *mat)
1365 if (!bset || !mat)
1373 isl_assert(ctx, 1+bset->dim->n_out == mat
1374 isl_assert(ctx, mat->n_col > 0, goto error);
1376 if (mat->n_col > mat->n_row) {
1378 mat->n_col - mat->n_row);
1381 } else if (mat->n_col < mat->n_row) {
1385 bset->dim->n_out -= mat->n_row - mat->n_col;
1389 isl_mat_copy(mat)) < 0)
1393 isl_mat_copy(mat)) < 0)
1396 if (preimage(ctx, bset->div, bset->n_div, bset->n_div, 1, mat) < 0)
1410 isl_mat_free(mat);
1417 __isl_take isl_set *set, __isl_take isl_mat *mat)
1427 isl_mat_copy(mat));
1431 if (mat->n_col != mat->n_row) {
1435 set->dim->n_out += mat->n_col;
1436 set->dim->n_out -= mat->n_row;
1438 isl_mat_free(mat);
1443 isl_mat_free(mat);
1448 * of some coefficient matrix by x' with x = M x' with M the matrix mat.
1452 unsigned first_col, __isl_take isl_mat *mat)
1458 if (!mat)
1460 ctx = isl_mat_get_ctx(mat);
1461 t = isl_mat_sub_alloc6(ctx, row, 0, n_row, first_col, mat->n_row);
1462 t = isl_mat_product(t, mat);
1471 void isl_mat_print_internal(__isl_keep isl_mat *mat, FILE *out, int indent)
1475 if (!mat) {
1476 fprintf(out, "%*snull mat\n", indent, "");
1480 if (mat->n_row == 0)
1483 for (i = 0; i < mat->n_row; ++i) {
1488 for (j = 0; j < mat->n_col; ++j) {
1491 isl_int_print(out, mat->row[i][j], 0);
1493 if (i == mat->n_row-1)
1500 void isl_mat_dump(__isl_keep isl_mat *mat)
1502 isl_mat_print_internal(mat, stderr, 0);
1505 __isl_give isl_mat *isl_mat_drop_cols(__isl_take isl_mat *mat,
1511 return mat;
1513 mat = isl_mat_cow(mat);
1514 if (check_col_range(mat, col, n) < 0)
1515 return isl_mat_free(mat);
1517 if (col != mat->n_col-n) {
1518 for (r = 0; r < mat->n_row; ++r)
1519 isl_seq_cpy(mat->row[r]+col, mat->row[r]+col+n,
1520 mat->n_col - col - n);
1522 mat->n_col -= n;
1523 return mat;
1526 __isl_give isl_mat *isl_mat_drop_rows(__isl_take isl_mat *mat,
1531 mat = isl_mat_cow(mat);
1532 if (check_row_range(mat, row, n) < 0)
1533 return isl_mat_free(mat);
1535 for (r = row; r+n < mat->n_row; ++r)
1536 mat->row[r] = mat->row[r+n];
1538 mat->n_row -= n;
1539 return mat;
1542 __isl_give isl_mat *isl_mat_insert_cols(__isl_take isl_mat *mat,
1547 if (check_col_range(mat, col, 0) < 0)
1548 return isl_mat_free(mat);
1550 return mat;
1552 ext = isl_mat_alloc(mat->ctx, mat->n_row, mat->n_col + n);
1556 isl_mat_sub_copy(mat->ctx, ext->row, mat->row, mat->n_row, 0, 0, col);
1557 isl_mat_sub_copy(mat->ctx, ext->row, mat->row, mat->n_row,
1558 col + n, col, mat->n_col - col);
1560 isl_mat_free(mat);
1563 isl_mat_free(mat);
1567 __isl_give isl_mat *isl_mat_insert_zero_cols(__isl_take isl_mat *mat,
1572 if (!mat)
1574 mat = isl_mat_insert_cols(mat, first, n);
1575 if (!mat)
1578 for (i = 0; i < mat->n_row; ++i)
1579 isl_seq_clr(mat->row[i] + first, n);
1581 return mat;
1584 __isl_give isl_mat *isl_mat_add_zero_cols(__isl_take isl_mat *mat, unsigned n)
1586 if (!mat)
1589 return isl_mat_insert_zero_cols(mat, mat->n_col, n);
1592 __isl_give isl_mat *isl_mat_insert_rows(__isl_take isl_mat *mat,
1597 if (check_row_range(mat, row, 0) < 0)
1598 return isl_mat_free(mat);
1600 return mat;
1602 ext = isl_mat_alloc(mat->ctx, mat->n_row + n, mat->n_col);
1606 isl_mat_sub_copy(mat->ctx, ext->row, mat->row, row, 0, 0, mat->n_col);
1607 isl_mat_sub_copy(mat->ctx, ext->row + row + n, mat->row + row,
1608 mat->n_row - row, 0, 0, mat->n_col);
1610 isl_mat_free(mat);
1613 isl_mat_free(mat);
1617 __isl_give isl_mat *isl_mat_add_rows(__isl_take isl_mat *mat, unsigned n)
1619 if (!mat)
1622 return isl_mat_insert_rows(mat, mat->n_row, n);
1625 __isl_give isl_mat *isl_mat_insert_zero_rows(__isl_take isl_mat *mat,
1630 mat = isl_mat_insert_rows(mat, row, n);
1631 if (!mat)
1635 isl_seq_clr(mat->row[row + i], mat->n_col);
1637 return mat;
1640 __isl_give isl_mat *isl_mat_add_zero_rows(__isl_take isl_mat *mat, unsigned n)
1642 if (!mat)
1645 return isl_mat_insert_zero_rows(mat, mat->n_row, n);
1648 void isl_mat_col_submul(__isl_keep isl_mat *mat,
1653 for (i = 0; i < mat->n_row; ++i)
1654 isl_int_submul(mat->row[i][dst_col], f, mat->row[i][src_col]);
1657 void isl_mat_col_add(__isl_keep isl_mat *mat, int dst_col, int src_col)
1661 if (!mat)
1664 for (i = 0; i < mat->n_row; ++i)
1665 isl_int_add(mat->row[i][dst_col],
1666 mat->row[i][dst_col], mat->row[i][src_col]);
1669 void isl_mat_col_mul(__isl_keep isl_mat *mat, int dst_col, isl_int f,
1674 for (i = 0; i < mat->n_row; ++i)
1675 isl_int_mul(mat->row[i][dst_col], f, mat->row[i][src_col]);
1678 /* Add "f" times column "src_col" to column "dst_col" of "mat" and
1681 __isl_give isl_mat *isl_mat_col_addmul(__isl_take isl_mat *mat, int dst_col,
1686 if (check_col(mat, dst_col) < 0 || check_col(mat, src_col) < 0)
1687 return isl_mat_free(mat);
1689 for (i = 0; i < mat->n_row; ++i) {
1690 if (isl_int_is_zero(mat->row[i][src_col]))
1692 mat = isl_mat_cow(mat);
1693 if (!mat)
1695 isl_int_addmul(mat->row[i][dst_col], f, mat->row[i][src_col]);
1698 return mat;
1701 /* Negate column "col" of "mat" and return the result.
1703 __isl_give isl_mat *isl_mat_col_neg(__isl_take isl_mat *mat, int col)
1707 if (check_col(mat, col) < 0)
1708 return isl_mat_free(mat);
1710 for (i = 0; i < mat->n_row; ++i) {
1711 if (isl_int_is_zero(mat->row[i][col]))
1713 mat = isl_mat_cow(mat);
1714 if (!mat)
1716 isl_int_neg(mat->row[i][col], mat->row[i][col]);
1719 return mat;
1722 /* Negate row "row" of "mat" and return the result.
1724 __isl_give isl_mat *isl_mat_row_neg(__isl_take isl_mat *mat, int row)
1726 if (check_row(mat, row) < 0)
1727 return isl_mat_free(mat);
1728 if (isl_seq_first_non_zero(mat->row[row], mat->n_col) == -1)
1729 return mat;
1730 mat = isl_mat_cow(mat);
1731 if (!mat)
1733 isl_seq_neg(mat->row[row], mat->row[row], mat->n_col);
1734 return mat;
1768 struct isl_mat *mat;
1783 mat = isl_mat_alloc(top->ctx, top->n_row + bot->n_row, top->n_col);
1784 if (!mat)
1786 isl_mat_sub_copy(mat->ctx, mat->row, top->row, top->n_row,
1787 0, 0, mat->n_col);
1788 isl_mat_sub_copy(mat->ctx, mat->row + top->n_row, bot->row, bot->n_row,
1789 0, 0, mat->n_col);
1792 return mat;
1821 struct isl_mat *mat;
1825 mat = isl_mat_alloc(vec->ctx, 1, vec->size);
1826 if (!mat)
1829 isl_seq_cpy(mat->row[0], vec->el, vec->size);
1832 return mat;
1838 /* Return a copy of row "row" of "mat" as an isl_vec.
1840 __isl_give isl_vec *isl_mat_get_row(__isl_keep isl_mat *mat, unsigned row)
1844 if (!mat)
1846 if (row >= mat->n_row)
1847 isl_die(mat->ctx, isl_error_invalid, "row out of range",
1850 v = isl_vec_alloc(isl_mat_get_ctx(mat), mat->n_col);
1853 isl_seq_cpy(v->el, mat->row[row], mat->n_col);
1864 __isl_give isl_mat *isl_mat_move_cols(__isl_take isl_mat *mat,
1869 if (!mat)
1872 return mat;
1874 res = isl_mat_alloc(mat->ctx, mat->n_row, mat->n_col);
1879 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1881 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1883 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1885 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1889 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1891 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1893 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1895 isl_mat_sub_copy(res->ctx, res->row, mat->row, mat->n_row,
1899 isl_mat_free(mat);
1903 isl_mat_free(mat);
1907 /* Return the gcd of the elements in row "row" of "mat" in *gcd.
1910 isl_stat isl_mat_row_gcd(__isl_keep isl_mat *mat, int row, isl_int *gcd)
1912 if (check_row(mat, row) < 0)
1915 isl_seq_gcd(mat->row[row], mat->n_col, gcd);
1920 void isl_mat_gcd(__isl_keep isl_mat *mat, isl_int *gcd)
1926 if (!mat)
1930 for (i = 0; i < mat->n_row; ++i) {
1931 isl_seq_gcd(mat->row[i], mat->n_col, &g);
1937 /* Return the result of scaling "mat" by a factor of "m".
1939 __isl_give isl_mat *isl_mat_scale(__isl_take isl_mat *mat, isl_int m)
1944 return mat;
1946 mat = isl_mat_cow(mat);
1947 if (!mat)
1950 for (i = 0; i < mat->n_row; ++i)
1951 isl_seq_scale(mat->row[i], mat->row[i], m, mat->n_col);
1953 return mat;
1956 __isl_give isl_mat *isl_mat_scale_down(__isl_take isl_mat *mat, isl_int m)
1961 return mat;
1963 mat = isl_mat_cow(mat);
1964 if (!mat)
1967 for (i = 0; i < mat->n_row; ++i)
1968 isl_seq_scale_down(mat->row[i], mat->row[i], m, mat->n_col);
1970 return mat;
1973 __isl_give isl_mat *isl_mat_scale_down_row(__isl_take isl_mat *mat, int row,
1977 return mat;
1979 mat = isl_mat_cow(mat);
1980 if (!mat)
1983 isl_seq_scale_down(mat->row[row], mat->row[row], m, mat->n_col);
1985 return mat;
1988 __isl_give isl_mat *isl_mat_normalize(__isl_take isl_mat *mat)
1992 if (!mat)
1996 isl_mat_gcd(mat, &gcd);
1997 mat = isl_mat_scale_down(mat, gcd);
2000 return mat;
2003 __isl_give isl_mat *isl_mat_normalize_row(__isl_take isl_mat *mat, int row)
2005 mat = isl_mat_cow(mat);
2006 if (!mat)
2009 isl_seq_normalize(mat->ctx, mat->row[row], mat->n_col);
2011 return mat;
2016 int isl_mat_initial_non_zero_cols(__isl_keep isl_mat *mat)
2020 if (!mat)
2023 for (i = 0; i < mat->n_col; ++i)
2024 if (row_first_non_zero(mat->row, mat->n_row, i) < 0)
2030 /* Return a basis for the space spanned by the rows of "mat".
2034 __isl_give isl_mat *isl_mat_row_basis(__isl_take isl_mat *mat)
2036 return isl_mat_reverse_gauss(mat);
2091 isl_mat *mat;
2104 mat = isl_mat_concat(isl_mat_copy(mat1), isl_mat_copy(mat2));
2105 r = isl_mat_rank(mat);
2106 isl_mat_free(mat);