4 #include "isl_map_private.h"
6 struct isl_mat
*isl_mat_alloc(struct isl_ctx
*ctx
,
7 unsigned n_row
, unsigned n_col
)
12 mat
= isl_alloc_type(ctx
, struct isl_mat
);
17 mat
->block
= isl_blk_alloc(ctx
, n_row
* n_col
);
18 if (isl_blk_is_error(mat
->block
))
20 mat
->row
= isl_alloc_array(ctx
, isl_int
*, n_row
);
24 for (i
= 0; i
< n_row
; ++i
)
25 mat
->row
[i
] = mat
->block
.data
+ i
* n_col
;
34 isl_blk_free(ctx
, mat
->block
);
39 struct isl_mat
*isl_mat_sub_alloc(struct isl_ctx
*ctx
, isl_int
**row
,
40 unsigned first_row
, unsigned n_row
, unsigned first_col
, unsigned n_col
)
45 mat
= isl_alloc_type(ctx
, struct isl_mat
);
48 mat
->row
= isl_alloc_array(ctx
, isl_int
*, n_row
);
51 for (i
= 0; i
< n_row
; ++i
)
52 mat
->row
[i
] = row
[first_row
+i
] + first_col
;
56 mat
->block
= isl_blk_empty();
57 mat
->flags
= ISL_MAT_BORROWED
;
64 void isl_mat_sub_copy(struct isl_ctx
*ctx
, isl_int
**dst
, isl_int
**src
,
65 unsigned n_row
, unsigned dst_col
, unsigned src_col
, unsigned n_col
)
69 for (i
= 0; i
< n_row
; ++i
)
70 isl_seq_cpy(dst
[i
]+dst_col
, src
[i
]+src_col
, n_col
);
73 void isl_mat_sub_neg(struct isl_ctx
*ctx
, isl_int
**dst
, isl_int
**src
,
74 unsigned n_row
, unsigned dst_col
, unsigned src_col
, unsigned n_col
)
78 for (i
= 0; i
< n_row
; ++i
)
79 isl_seq_neg(dst
[i
]+dst_col
, src
[i
]+src_col
, n_col
);
82 struct isl_mat
*isl_mat_copy(struct isl_ctx
*ctx
, struct isl_mat
*mat
)
91 struct isl_mat
*isl_mat_dup(struct isl_ctx
*ctx
, struct isl_mat
*mat
)
98 mat2
= isl_mat_alloc(ctx
, mat
->n_row
, mat
->n_col
);
101 for (i
= 0; i
< mat
->n_row
; ++i
)
102 isl_seq_cpy(mat2
->row
[i
], mat
->row
[i
], mat
->n_col
);
106 struct isl_mat
*isl_mat_cow(struct isl_ctx
*ctx
, struct isl_mat
*mat
)
108 struct isl_mat
*mat2
;
112 if (mat
->ref
== 1 && !ISL_F_ISSET(mat
, ISL_MAT_BORROWED
))
115 mat2
= isl_mat_dup(ctx
, mat
);
116 isl_mat_free(ctx
, mat
);
120 void isl_mat_free(struct isl_ctx
*ctx
, struct isl_mat
*mat
)
128 if (!ISL_F_ISSET(mat
, ISL_MAT_BORROWED
))
129 isl_blk_free(ctx
, mat
->block
);
134 struct isl_mat
*isl_mat_identity(struct isl_ctx
*ctx
, unsigned n_row
)
139 mat
= isl_mat_alloc(ctx
, n_row
, n_row
);
142 for (i
= 0; i
< n_row
; ++i
) {
143 isl_seq_clr(mat
->row
[i
], i
);
144 isl_int_set_si(mat
->row
[i
][i
], 1);
145 isl_seq_clr(mat
->row
[i
]+i
+1, n_row
-(i
+1));
151 struct isl_vec
*isl_mat_vec_product(struct isl_ctx
*ctx
,
152 struct isl_mat
*mat
, struct isl_vec
*vec
)
155 struct isl_vec
*prod
;
160 isl_assert(ctx
, mat
->n_col
== vec
->size
, goto error
);
162 prod
= isl_vec_alloc(ctx
, mat
->n_row
);
166 for (i
= 0; i
< prod
->size
; ++i
)
167 isl_seq_inner_product(mat
->row
[i
], vec
->block
.data
, vec
->size
,
168 &prod
->block
.data
[i
]);
169 isl_mat_free(ctx
, mat
);
170 isl_vec_free(ctx
, vec
);
173 isl_mat_free(ctx
, mat
);
174 isl_vec_free(ctx
, vec
);
178 struct isl_mat
*isl_mat_aff_direct_sum(struct isl_ctx
*ctx
,
179 struct isl_mat
*left
, struct isl_mat
*right
)
187 isl_assert(ctx
, left
->n_row
== right
->n_row
, goto error
);
188 isl_assert(ctx
, left
->n_row
>= 1, goto error
);
189 isl_assert(ctx
, left
->n_col
>= 1, goto error
);
190 isl_assert(ctx
, right
->n_col
>= 1, goto error
);
192 isl_seq_first_non_zero(left
->row
[0]+1, left
->n_col
-1) == -1,
195 isl_seq_first_non_zero(right
->row
[0]+1, right
->n_col
-1) == -1,
198 sum
= isl_mat_alloc(ctx
, left
->n_row
, left
->n_col
+ right
->n_col
- 1);
201 isl_int_lcm(sum
->row
[0][0], left
->row
[0][0], right
->row
[0][0]);
202 isl_int_divexact(left
->row
[0][0], sum
->row
[0][0], left
->row
[0][0]);
203 isl_int_divexact(right
->row
[0][0], sum
->row
[0][0], right
->row
[0][0]);
205 isl_seq_clr(sum
->row
[0]+1, sum
->n_col
-1);
206 for (i
= 1; i
< sum
->n_row
; ++i
) {
207 isl_int_mul(sum
->row
[i
][0], left
->row
[0][0], left
->row
[i
][0]);
208 isl_int_addmul(sum
->row
[i
][0],
209 right
->row
[0][0], right
->row
[i
][0]);
210 isl_seq_scale(sum
->row
[i
]+1, left
->row
[i
]+1, left
->row
[0][0],
212 isl_seq_scale(sum
->row
[i
]+left
->n_col
,
213 right
->row
[i
]+1, right
->row
[0][0],
217 isl_int_divexact(left
->row
[0][0], sum
->row
[0][0], left
->row
[0][0]);
218 isl_int_divexact(right
->row
[0][0], sum
->row
[0][0], right
->row
[0][0]);
219 isl_mat_free(ctx
, left
);
220 isl_mat_free(ctx
, right
);
223 isl_mat_free(ctx
, left
);
224 isl_mat_free(ctx
, right
);
228 static void exchange(struct isl_ctx
*ctx
, struct isl_mat
*M
, struct isl_mat
**U
,
229 struct isl_mat
**Q
, unsigned row
, unsigned i
, unsigned j
)
232 for (r
= row
; r
< M
->n_row
; ++r
)
233 isl_int_swap(M
->row
[r
][i
], M
->row
[r
][j
]);
235 for (r
= 0; r
< (*U
)->n_row
; ++r
)
236 isl_int_swap((*U
)->row
[r
][i
], (*U
)->row
[r
][j
]);
239 isl_mat_swap_rows(ctx
, *Q
, i
, j
);
242 static void subtract(struct isl_mat
*M
, struct isl_mat
**U
,
243 struct isl_mat
**Q
, unsigned row
, unsigned i
, unsigned j
, isl_int m
)
246 for (r
= row
; r
< M
->n_row
; ++r
)
247 isl_int_submul(M
->row
[r
][j
], m
, M
->row
[r
][i
]);
249 for (r
= 0; r
< (*U
)->n_row
; ++r
)
250 isl_int_submul((*U
)->row
[r
][j
], m
, (*U
)->row
[r
][i
]);
253 for (r
= 0; r
< (*Q
)->n_col
; ++r
)
254 isl_int_addmul((*Q
)->row
[i
][r
], m
, (*Q
)->row
[j
][r
]);
258 static void oppose(struct isl_ctx
*ctx
, struct isl_mat
*M
, struct isl_mat
**U
,
259 struct isl_mat
**Q
, unsigned row
, unsigned col
)
262 for (r
= row
; r
< M
->n_row
; ++r
)
263 isl_int_neg(M
->row
[r
][col
], M
->row
[r
][col
]);
265 for (r
= 0; r
< (*U
)->n_row
; ++r
)
266 isl_int_neg((*U
)->row
[r
][col
], (*U
)->row
[r
][col
]);
269 isl_seq_neg((*Q
)->row
[col
], (*Q
)->row
[col
], (*Q
)->n_col
);
272 /* Given matrix M, compute
277 * with U and Q unimodular matrices and H a matrix in column echelon form
278 * such that on each echelon row the entries in the non-echelon column
279 * are non-negative (if neg == 0) or non-positive (if neg == 1)
280 * and stricly smaller (in absolute value) than the entries in the echelon
282 * If U or Q are NULL, then these matrices are not computed.
284 struct isl_mat
*isl_mat_left_hermite(struct isl_ctx
*ctx
,
285 struct isl_mat
*M
, int neg
, struct isl_mat
**U
, struct isl_mat
**Q
)
296 M
= isl_mat_cow(ctx
, M
);
300 *U
= isl_mat_identity(ctx
, M
->n_col
);
305 *Q
= isl_mat_identity(ctx
, M
->n_col
);
312 for (row
= 0; row
< M
->n_row
; ++row
) {
314 first
= isl_seq_abs_min_non_zero(M
->row
[row
]+col
, M
->n_col
-col
);
319 exchange(ctx
, M
, U
, Q
, row
, first
, col
);
320 if (isl_int_is_neg(M
->row
[row
][col
]))
321 oppose(ctx
, M
, U
, Q
, row
, col
);
323 while ((off
= isl_seq_first_non_zero(M
->row
[row
]+first
,
324 M
->n_col
-first
)) != -1) {
326 isl_int_fdiv_q(c
, M
->row
[row
][first
], M
->row
[row
][col
]);
327 subtract(M
, U
, Q
, row
, col
, first
, c
);
328 if (!isl_int_is_zero(M
->row
[row
][first
]))
329 exchange(ctx
, M
, U
, Q
, row
, first
, col
);
333 for (i
= 0; i
< col
; ++i
) {
334 if (isl_int_is_zero(M
->row
[row
][i
]))
337 isl_int_cdiv_q(c
, M
->row
[row
][i
], M
->row
[row
][col
]);
339 isl_int_fdiv_q(c
, M
->row
[row
][i
], M
->row
[row
][col
]);
340 if (isl_int_is_zero(c
))
342 subtract(M
, U
, Q
, row
, col
, i
, c
);
351 isl_mat_free(ctx
, *Q
);
355 isl_mat_free(ctx
, *U
);
361 struct isl_mat
*isl_mat_right_kernel(struct isl_ctx
*ctx
, struct isl_mat
*mat
)
364 struct isl_mat
*U
= NULL
;
367 mat
= isl_mat_left_hermite(ctx
, mat
, 0, &U
, NULL
);
371 for (i
= 0, rank
= 0; rank
< mat
->n_col
; ++rank
) {
372 while (i
< mat
->n_row
&& isl_int_is_zero(mat
->row
[i
][rank
]))
377 K
= isl_mat_alloc(ctx
, U
->n_row
, U
->n_col
- rank
);
380 isl_mat_sub_copy(ctx
, K
->row
, U
->row
, U
->n_row
, 0, rank
, U
->n_col
-rank
);
381 isl_mat_free(ctx
, mat
);
382 isl_mat_free(ctx
, U
);
385 isl_mat_free(ctx
, mat
);
386 isl_mat_free(ctx
, U
);
390 struct isl_mat
*isl_mat_lin_to_aff(struct isl_ctx
*ctx
, struct isl_mat
*mat
)
393 struct isl_mat
*mat2
;
397 mat2
= isl_mat_alloc(ctx
, 1+mat
->n_row
, 1+mat
->n_col
);
400 isl_int_set_si(mat2
->row
[0][0], 1);
401 isl_seq_clr(mat2
->row
[0]+1, mat
->n_col
);
402 for (i
= 0; i
< mat
->n_row
; ++i
) {
403 isl_int_set_si(mat2
->row
[1+i
][0], 0);
404 isl_seq_cpy(mat2
->row
[1+i
]+1, mat
->row
[i
], mat
->n_col
);
406 isl_mat_free(ctx
, mat
);
410 static int row_first_non_zero(isl_int
**row
, unsigned n_row
, unsigned col
)
414 for (i
= 0; i
< n_row
; ++i
)
415 if (!isl_int_is_zero(row
[i
][col
]))
420 static int row_abs_min_non_zero(isl_int
**row
, unsigned n_row
, unsigned col
)
422 int i
, min
= row_first_non_zero(row
, n_row
, col
);
425 for (i
= min
+ 1; i
< n_row
; ++i
) {
426 if (isl_int_is_zero(row
[i
][col
]))
428 if (isl_int_abs_lt(row
[i
][col
], row
[min
][col
]))
434 static void inv_exchange(struct isl_ctx
*ctx
,
435 struct isl_mat
*left
, struct isl_mat
*right
,
436 unsigned i
, unsigned j
)
438 left
= isl_mat_swap_rows(ctx
, left
, i
, j
);
439 right
= isl_mat_swap_rows(ctx
, right
, i
, j
);
442 static void inv_oppose(struct isl_ctx
*ctx
,
443 struct isl_mat
*left
, struct isl_mat
*right
, unsigned row
)
445 isl_seq_neg(left
->row
[row
]+row
, left
->row
[row
]+row
, left
->n_col
-row
);
446 isl_seq_neg(right
->row
[row
], right
->row
[row
], right
->n_col
);
449 static void inv_subtract(struct isl_ctx
*ctx
,
450 struct isl_mat
*left
, struct isl_mat
*right
,
451 unsigned row
, unsigned i
, isl_int m
)
454 isl_seq_combine(left
->row
[i
]+row
,
455 ctx
->one
, left
->row
[i
]+row
,
456 m
, left
->row
[row
]+row
,
458 isl_seq_combine(right
->row
[i
], ctx
->one
, right
->row
[i
],
459 m
, right
->row
[row
], right
->n_col
);
462 /* Compute inv(left)*right
464 struct isl_mat
*isl_mat_inverse_product(struct isl_ctx
*ctx
,
465 struct isl_mat
*left
, struct isl_mat
*right
)
473 isl_assert(ctx
, left
->n_row
== left
->n_col
, goto error
);
474 isl_assert(ctx
, left
->n_row
== right
->n_row
, goto error
);
476 if (left
->n_row
== 0) {
477 isl_mat_free(ctx
, left
);
481 left
= isl_mat_cow(ctx
, left
);
482 right
= isl_mat_cow(ctx
, right
);
488 for (row
= 0; row
< left
->n_row
; ++row
) {
489 int pivot
, first
, i
, off
;
490 pivot
= row_abs_min_non_zero(left
->row
+row
, left
->n_row
-row
, row
);
494 isl_assert(ctx
, pivot
>= 0, goto error
);
498 inv_exchange(ctx
, left
, right
, pivot
, row
);
499 if (isl_int_is_neg(left
->row
[row
][row
]))
500 inv_oppose(ctx
, left
, right
, row
);
502 while ((off
= row_first_non_zero(left
->row
+first
,
503 left
->n_row
-first
, row
)) != -1) {
505 isl_int_fdiv_q(a
, left
->row
[first
][row
],
506 left
->row
[row
][row
]);
507 inv_subtract(ctx
, left
, right
, row
, first
, a
);
508 if (!isl_int_is_zero(left
->row
[first
][row
]))
509 inv_exchange(ctx
, left
, right
, row
, first
);
513 for (i
= 0; i
< row
; ++i
) {
514 if (isl_int_is_zero(left
->row
[i
][row
]))
516 isl_int_gcd(a
, left
->row
[row
][row
], left
->row
[i
][row
]);
517 isl_int_divexact(b
, left
->row
[i
][row
], a
);
518 isl_int_divexact(a
, left
->row
[row
][row
], a
);
520 isl_seq_combine(left
->row
[i
]+row
,
522 b
, left
->row
[row
]+row
,
524 isl_seq_combine(right
->row
[i
], a
, right
->row
[i
],
525 b
, right
->row
[row
], right
->n_col
);
530 isl_int_set(a
, left
->row
[0][0]);
531 for (row
= 1; row
< left
->n_row
; ++row
)
532 isl_int_lcm(a
, a
, left
->row
[row
][row
]);
533 if (isl_int_is_zero(a
)){
535 isl_assert(ctx
, 0, goto error
);
537 for (row
= 0; row
< left
->n_row
; ++row
) {
538 isl_int_divexact(left
->row
[row
][row
], a
, left
->row
[row
][row
]);
539 if (isl_int_is_one(left
->row
[row
][row
]))
541 isl_seq_scale(right
->row
[row
], right
->row
[row
],
542 left
->row
[row
][row
], right
->n_col
);
546 isl_mat_free(ctx
, left
);
549 isl_mat_free(ctx
, left
);
550 isl_mat_free(ctx
, right
);
554 void isl_mat_col_scale(struct isl_mat
*mat
, unsigned col
, isl_int m
)
558 for (i
= 0; i
< mat
->n_row
; ++i
)
559 isl_int_mul(mat
->row
[i
][col
], mat
->row
[i
][col
], m
);
562 void isl_mat_col_combine(struct isl_mat
*mat
, unsigned dst
,
563 isl_int m1
, unsigned src1
, isl_int m2
, unsigned src2
)
569 for (i
= 0; i
< mat
->n_row
; ++i
) {
570 isl_int_mul(tmp
, m1
, mat
->row
[i
][src1
]);
571 isl_int_addmul(tmp
, m2
, mat
->row
[i
][src2
]);
572 isl_int_set(mat
->row
[i
][dst
], tmp
);
577 struct isl_mat
*isl_mat_right_inverse(struct isl_ctx
*ctx
,
584 mat
= isl_mat_cow(ctx
, mat
);
588 inv
= isl_mat_identity(ctx
, mat
->n_col
);
589 inv
= isl_mat_cow(ctx
, inv
);
595 for (row
= 0; row
< mat
->n_row
; ++row
) {
596 int pivot
, first
, i
, off
;
597 pivot
= isl_seq_abs_min_non_zero(mat
->row
[row
]+row
, mat
->n_col
-row
);
605 exchange(ctx
, mat
, &inv
, NULL
, row
, pivot
, row
);
606 if (isl_int_is_neg(mat
->row
[row
][row
]))
607 oppose(ctx
, mat
, &inv
, NULL
, row
, row
);
609 while ((off
= isl_seq_first_non_zero(mat
->row
[row
]+first
,
610 mat
->n_col
-first
)) != -1) {
612 isl_int_fdiv_q(a
, mat
->row
[row
][first
],
614 subtract(mat
, &inv
, NULL
, row
, row
, first
, a
);
615 if (!isl_int_is_zero(mat
->row
[row
][first
]))
616 exchange(ctx
, mat
, &inv
, NULL
, row
, row
, first
);
620 for (i
= 0; i
< row
; ++i
) {
621 if (isl_int_is_zero(mat
->row
[row
][i
]))
623 isl_int_gcd(a
, mat
->row
[row
][row
], mat
->row
[row
][i
]);
624 isl_int_divexact(b
, mat
->row
[row
][i
], a
);
625 isl_int_divexact(a
, mat
->row
[row
][row
], a
);
627 isl_mat_col_combine(mat
, i
, a
, i
, b
, row
);
628 isl_mat_col_combine(inv
, i
, a
, i
, b
, row
);
633 isl_int_set(a
, mat
->row
[0][0]);
634 for (row
= 1; row
< mat
->n_row
; ++row
)
635 isl_int_lcm(a
, a
, mat
->row
[row
][row
]);
636 if (isl_int_is_zero(a
)){
640 for (row
= 0; row
< mat
->n_row
; ++row
) {
641 isl_int_divexact(mat
->row
[row
][row
], a
, mat
->row
[row
][row
]);
642 if (isl_int_is_one(mat
->row
[row
][row
]))
644 isl_mat_col_scale(inv
, row
, mat
->row
[row
][row
]);
648 isl_mat_free(ctx
, mat
);
652 isl_mat_free(ctx
, mat
);
656 struct isl_mat
*isl_mat_transpose(struct isl_ctx
*ctx
, struct isl_mat
*mat
)
660 mat
= isl_mat_cow(ctx
, mat
);
663 isl_assert(ctx
, mat
->n_col
== mat
->n_row
, goto error
);
664 for (i
= 0; i
< mat
->n_row
; ++i
)
665 for (j
= i
+ 1; j
< mat
->n_col
; ++j
)
666 isl_int_swap(mat
->row
[i
][j
], mat
->row
[j
][i
]);
669 isl_mat_free(ctx
, mat
);
673 struct isl_mat
*isl_mat_swap_cols(struct isl_ctx
*ctx
,
674 struct isl_mat
*mat
, unsigned i
, unsigned j
)
678 mat
= isl_mat_cow(ctx
, mat
);
681 isl_assert(ctx
, i
< mat
->n_col
, goto error
);
682 isl_assert(ctx
, j
< mat
->n_col
, goto error
);
684 for (r
= 0; r
< mat
->n_row
; ++r
)
685 isl_int_swap(mat
->row
[r
][i
], mat
->row
[r
][j
]);
688 isl_mat_free(ctx
, mat
);
692 struct isl_mat
*isl_mat_swap_rows(struct isl_ctx
*ctx
,
693 struct isl_mat
*mat
, unsigned i
, unsigned j
)
699 mat
= isl_mat_cow(ctx
, mat
);
703 mat
->row
[i
] = mat
->row
[j
];
708 struct isl_mat
*isl_mat_product(struct isl_ctx
*ctx
,
709 struct isl_mat
*left
, struct isl_mat
*right
)
712 struct isl_mat
*prod
;
716 isl_assert(ctx
, left
->n_col
== right
->n_row
, goto error
);
717 prod
= isl_mat_alloc(ctx
, left
->n_row
, right
->n_col
);
720 if (left
->n_col
== 0) {
721 for (i
= 0; i
< prod
->n_row
; ++i
)
722 isl_seq_clr(prod
->row
[i
], prod
->n_col
);
725 for (i
= 0; i
< prod
->n_row
; ++i
) {
726 for (j
= 0; j
< prod
->n_col
; ++j
) {
727 isl_int_mul(prod
->row
[i
][j
],
728 left
->row
[i
][0], right
->row
[0][j
]);
729 for (k
= 1; k
< left
->n_col
; ++k
)
730 isl_int_addmul(prod
->row
[i
][j
],
731 left
->row
[i
][k
], right
->row
[k
][j
]);
734 isl_mat_free(ctx
, left
);
735 isl_mat_free(ctx
, right
);
738 isl_mat_free(ctx
, left
);
739 isl_mat_free(ctx
, right
);
743 /* Replace the variables x in bset by x' given by x = M x', with
746 * If there are fewer variables x' then there are x, then we perform
747 * the transformation in place, which that, in principle,
748 * this frees up some extra variables as the number
749 * of columns remains constant, but we would have to extend
750 * the div array too as the number of rows in this array is assumed
751 * to be equal to extra.
753 struct isl_basic_set
*isl_basic_set_preimage(struct isl_basic_set
*bset
,
764 bset
= isl_basic_set_cow(bset
);
768 isl_assert(ctx
, bset
->dim
->nparam
== 0, goto error
);
769 isl_assert(ctx
, bset
->n_div
== 0, goto error
);
770 isl_assert(ctx
, 1+bset
->dim
->n_out
== mat
->n_row
, goto error
);
772 if (mat
->n_col
> mat
->n_row
)
773 bset
= isl_basic_set_extend(bset
, 0, mat
->n_col
-1, 0,
775 else if (mat
->n_col
< mat
->n_row
) {
776 bset
->dim
= isl_dim_cow(bset
->dim
);
779 bset
->dim
->n_out
-= mat
->n_row
- mat
->n_col
;
782 t
= isl_mat_sub_alloc(ctx
, bset
->eq
, 0, bset
->n_eq
, 0, mat
->n_row
);
783 t
= isl_mat_product(ctx
, t
, isl_mat_copy(ctx
, mat
));
786 for (i
= 0; i
< bset
->n_eq
; ++i
) {
787 isl_seq_swp_or_cpy(bset
->eq
[i
], t
->row
[i
], t
->n_col
);
788 isl_seq_clr(bset
->eq
[i
]+t
->n_col
, bset
->extra
);
790 isl_mat_free(ctx
, t
);
792 t
= isl_mat_sub_alloc(ctx
, bset
->ineq
, 0, bset
->n_ineq
, 0, mat
->n_row
);
793 t
= isl_mat_product(ctx
, t
, mat
);
796 for (i
= 0; i
< bset
->n_ineq
; ++i
) {
797 isl_seq_swp_or_cpy(bset
->ineq
[i
], t
->row
[i
], t
->n_col
);
798 isl_seq_clr(bset
->ineq
[i
]+t
->n_col
, bset
->extra
);
800 isl_mat_free(ctx
, t
);
802 bset
= isl_basic_set_simplify(bset
);
803 bset
= isl_basic_set_finalize(bset
);
807 isl_mat_free(ctx
, mat
);
809 isl_basic_set_free(bset
);
813 struct isl_set
*isl_set_preimage(struct isl_set
*set
, struct isl_mat
*mat
)
818 set
= isl_set_cow(set
);
823 for (i
= 0; i
< set
->n
; ++i
) {
824 set
->p
[i
] = isl_basic_set_preimage(set
->p
[i
],
825 isl_mat_copy(ctx
, mat
));
829 if (mat
->n_col
!= mat
->n_row
) {
830 set
->dim
= isl_dim_cow(set
->dim
);
833 set
->dim
->n_out
+= mat
->n_col
;
834 set
->dim
->n_out
-= mat
->n_row
;
836 isl_mat_free(ctx
, mat
);
837 ISL_F_CLR(set
, ISL_SET_NORMALIZED
);
841 isl_mat_free(ctx
, mat
);
845 void isl_mat_dump(struct isl_ctx
*ctx
, struct isl_mat
*mat
,
846 FILE *out
, int indent
)
851 fprintf(out
, "%*snull mat\n", indent
, "");
856 fprintf(out
, "%*s[]\n", indent
, "");
858 for (i
= 0; i
< mat
->n_row
; ++i
) {
860 fprintf(out
, "%*s[[", indent
, "");
862 fprintf(out
, "%*s[", indent
+1, "");
863 for (j
= 0; j
< mat
->n_col
; ++j
) {
866 isl_int_print(out
, mat
->row
[i
][j
], 0);
868 if (i
== mat
->n_row
-1)
869 fprintf(out
, "]]\n");
875 struct isl_mat
*isl_mat_drop_cols(struct isl_ctx
*ctx
, struct isl_mat
*mat
,
876 unsigned col
, unsigned n
)
880 mat
= isl_mat_cow(ctx
, mat
);
884 if (col
!= mat
->n_col
-n
) {
885 for (r
= 0; r
< mat
->n_row
; ++r
)
886 isl_seq_cpy(mat
->row
[r
]+col
, mat
->row
[r
]+col
+n
,
887 mat
->n_col
- col
- n
);
893 struct isl_mat
*isl_mat_drop_rows(struct isl_ctx
*ctx
, struct isl_mat
*mat
,
894 unsigned row
, unsigned n
)
898 mat
= isl_mat_cow(ctx
, mat
);
902 for (r
= row
; r
+n
< mat
->n_row
; ++r
)
903 mat
->row
[r
] = mat
->row
[r
+n
];
909 void isl_mat_col_submul(struct isl_mat
*mat
,
910 int dst_col
, isl_int f
, int src_col
)
914 for (i
= 0; i
< mat
->n_row
; ++i
)
915 isl_int_submul(mat
->row
[i
][dst_col
], f
, mat
->row
[i
][src_col
]);
918 void isl_mat_col_mul(struct isl_mat
*mat
, int dst_col
, isl_int f
, int src_col
)
922 for (i
= 0; i
< mat
->n_row
; ++i
)
923 isl_int_mul(mat
->row
[i
][dst_col
], f
, mat
->row
[i
][src_col
]);