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
;
37 isl_blk_free(ctx
, mat
->block
);
42 struct isl_mat
*isl_mat_extend(struct isl_mat
*mat
,
43 unsigned n_row
, unsigned n_col
)
51 if (mat
->max_col
>= n_col
&& mat
->n_row
>= n_row
) {
52 if (mat
->n_col
< n_col
)
57 if (mat
->max_col
< n_col
) {
58 struct isl_mat
*new_mat
;
60 if (n_row
< mat
->n_row
)
62 new_mat
= isl_mat_alloc(mat
->ctx
, n_row
, n_col
);
65 for (i
= 0; i
< mat
->n_row
; ++i
)
66 isl_seq_cpy(new_mat
->row
[i
], mat
->row
[i
], mat
->n_col
);
71 mat
= isl_mat_cow(mat
);
75 assert(mat
->ref
== 1);
76 old
= mat
->block
.data
;
77 mat
->block
= isl_blk_extend(mat
->ctx
, mat
->block
, n_row
* mat
->max_col
);
78 if (isl_blk_is_error(mat
->block
))
80 mat
->row
= isl_realloc_array(mat
->ctx
, mat
->row
, isl_int
*, n_row
);
84 for (i
= 0; i
< mat
->n_row
; ++i
)
85 mat
->row
[i
] = mat
->block
.data
+ (mat
->row
[i
] - old
);
86 for (i
= mat
->n_row
; i
< n_row
; ++i
)
87 mat
->row
[i
] = mat
->block
.data
+ i
* mat
->max_col
;
89 if (mat
->n_col
< n_col
)
98 struct isl_mat
*isl_mat_sub_alloc(struct isl_ctx
*ctx
, isl_int
**row
,
99 unsigned first_row
, unsigned n_row
, unsigned first_col
, unsigned n_col
)
104 mat
= isl_alloc_type(ctx
, struct isl_mat
);
107 mat
->row
= isl_alloc_array(ctx
, isl_int
*, n_row
);
110 for (i
= 0; i
< n_row
; ++i
)
111 mat
->row
[i
] = row
[first_row
+i
] + first_col
;
117 mat
->block
= isl_blk_empty();
118 mat
->flags
= ISL_MAT_BORROWED
;
125 void isl_mat_sub_copy(struct isl_ctx
*ctx
, isl_int
**dst
, isl_int
**src
,
126 unsigned n_row
, unsigned dst_col
, unsigned src_col
, unsigned n_col
)
130 for (i
= 0; i
< n_row
; ++i
)
131 isl_seq_cpy(dst
[i
]+dst_col
, src
[i
]+src_col
, n_col
);
134 void isl_mat_sub_neg(struct isl_ctx
*ctx
, isl_int
**dst
, isl_int
**src
,
135 unsigned n_row
, unsigned dst_col
, unsigned src_col
, unsigned n_col
)
139 for (i
= 0; i
< n_row
; ++i
)
140 isl_seq_neg(dst
[i
]+dst_col
, src
[i
]+src_col
, n_col
);
143 struct isl_mat
*isl_mat_copy(struct isl_mat
*mat
)
152 struct isl_mat
*isl_mat_dup(struct isl_mat
*mat
)
155 struct isl_mat
*mat2
;
159 mat2
= isl_mat_alloc(mat
->ctx
, mat
->n_row
, mat
->n_col
);
162 for (i
= 0; i
< mat
->n_row
; ++i
)
163 isl_seq_cpy(mat2
->row
[i
], mat
->row
[i
], mat
->n_col
);
167 struct isl_mat
*isl_mat_cow(struct isl_mat
*mat
)
169 struct isl_mat
*mat2
;
173 if (mat
->ref
== 1 && !ISL_F_ISSET(mat
, ISL_MAT_BORROWED
))
176 mat2
= isl_mat_dup(mat
);
181 void isl_mat_free(struct isl_mat
*mat
)
189 if (!ISL_F_ISSET(mat
, ISL_MAT_BORROWED
))
190 isl_blk_free(mat
->ctx
, mat
->block
);
191 isl_ctx_deref(mat
->ctx
);
196 struct isl_mat
*isl_mat_identity(struct isl_ctx
*ctx
, unsigned n_row
)
201 mat
= isl_mat_alloc(ctx
, n_row
, n_row
);
204 for (i
= 0; i
< n_row
; ++i
) {
205 isl_seq_clr(mat
->row
[i
], i
);
206 isl_int_set_si(mat
->row
[i
][i
], 1);
207 isl_seq_clr(mat
->row
[i
]+i
+1, n_row
-(i
+1));
213 struct isl_vec
*isl_mat_vec_product(struct isl_mat
*mat
, struct isl_vec
*vec
)
216 struct isl_vec
*prod
;
221 isl_assert(mat
->ctx
, mat
->n_col
== vec
->size
, goto error
);
223 prod
= isl_vec_alloc(mat
->ctx
, mat
->n_row
);
227 for (i
= 0; i
< prod
->size
; ++i
)
228 isl_seq_inner_product(mat
->row
[i
], vec
->el
, vec
->size
,
229 &prod
->block
.data
[i
]);
239 struct isl_vec
*isl_vec_mat_product(struct isl_vec
*vec
, struct isl_mat
*mat
)
242 struct isl_vec
*prod
;
247 isl_assert(mat
->ctx
, mat
->n_row
== vec
->size
, goto error
);
249 prod
= isl_vec_alloc(mat
->ctx
, mat
->n_col
);
253 for (i
= 0; i
< prod
->size
; ++i
) {
254 isl_int_set_si(prod
->el
[i
], 0);
255 for (j
= 0; j
< vec
->size
; ++j
)
256 isl_int_addmul(prod
->el
[i
], vec
->el
[j
], mat
->row
[j
][i
]);
267 struct isl_mat
*isl_mat_aff_direct_sum(struct isl_mat
*left
,
268 struct isl_mat
*right
)
276 isl_assert(left
->ctx
, left
->n_row
== right
->n_row
, goto error
);
277 isl_assert(left
->ctx
, left
->n_row
>= 1, goto error
);
278 isl_assert(left
->ctx
, left
->n_col
>= 1, goto error
);
279 isl_assert(left
->ctx
, right
->n_col
>= 1, goto error
);
280 isl_assert(left
->ctx
,
281 isl_seq_first_non_zero(left
->row
[0]+1, left
->n_col
-1) == -1,
283 isl_assert(left
->ctx
,
284 isl_seq_first_non_zero(right
->row
[0]+1, right
->n_col
-1) == -1,
287 sum
= isl_mat_alloc(left
->ctx
, left
->n_row
, left
->n_col
+ right
->n_col
- 1);
290 isl_int_lcm(sum
->row
[0][0], left
->row
[0][0], right
->row
[0][0]);
291 isl_int_divexact(left
->row
[0][0], sum
->row
[0][0], left
->row
[0][0]);
292 isl_int_divexact(right
->row
[0][0], sum
->row
[0][0], right
->row
[0][0]);
294 isl_seq_clr(sum
->row
[0]+1, sum
->n_col
-1);
295 for (i
= 1; i
< sum
->n_row
; ++i
) {
296 isl_int_mul(sum
->row
[i
][0], left
->row
[0][0], left
->row
[i
][0]);
297 isl_int_addmul(sum
->row
[i
][0],
298 right
->row
[0][0], right
->row
[i
][0]);
299 isl_seq_scale(sum
->row
[i
]+1, left
->row
[i
]+1, left
->row
[0][0],
301 isl_seq_scale(sum
->row
[i
]+left
->n_col
,
302 right
->row
[i
]+1, right
->row
[0][0],
306 isl_int_divexact(left
->row
[0][0], sum
->row
[0][0], left
->row
[0][0]);
307 isl_int_divexact(right
->row
[0][0], sum
->row
[0][0], right
->row
[0][0]);
317 static void exchange(struct isl_mat
*M
, struct isl_mat
**U
,
318 struct isl_mat
**Q
, unsigned row
, unsigned i
, unsigned j
)
321 for (r
= row
; r
< M
->n_row
; ++r
)
322 isl_int_swap(M
->row
[r
][i
], M
->row
[r
][j
]);
324 for (r
= 0; r
< (*U
)->n_row
; ++r
)
325 isl_int_swap((*U
)->row
[r
][i
], (*U
)->row
[r
][j
]);
328 isl_mat_swap_rows(*Q
, i
, j
);
331 static void subtract(struct isl_mat
*M
, struct isl_mat
**U
,
332 struct isl_mat
**Q
, unsigned row
, unsigned i
, unsigned j
, isl_int m
)
335 for (r
= row
; r
< M
->n_row
; ++r
)
336 isl_int_submul(M
->row
[r
][j
], m
, M
->row
[r
][i
]);
338 for (r
= 0; r
< (*U
)->n_row
; ++r
)
339 isl_int_submul((*U
)->row
[r
][j
], m
, (*U
)->row
[r
][i
]);
342 for (r
= 0; r
< (*Q
)->n_col
; ++r
)
343 isl_int_addmul((*Q
)->row
[i
][r
], m
, (*Q
)->row
[j
][r
]);
347 static void oppose(struct isl_mat
*M
, struct isl_mat
**U
,
348 struct isl_mat
**Q
, unsigned row
, unsigned col
)
351 for (r
= row
; r
< M
->n_row
; ++r
)
352 isl_int_neg(M
->row
[r
][col
], M
->row
[r
][col
]);
354 for (r
= 0; r
< (*U
)->n_row
; ++r
)
355 isl_int_neg((*U
)->row
[r
][col
], (*U
)->row
[r
][col
]);
358 isl_seq_neg((*Q
)->row
[col
], (*Q
)->row
[col
], (*Q
)->n_col
);
361 /* Given matrix M, compute
366 * with U and Q unimodular matrices and H a matrix in column echelon form
367 * such that on each echelon row the entries in the non-echelon column
368 * are non-negative (if neg == 0) or non-positive (if neg == 1)
369 * and stricly smaller (in absolute value) than the entries in the echelon
371 * If U or Q are NULL, then these matrices are not computed.
373 struct isl_mat
*isl_mat_left_hermite(struct isl_mat
*M
, int neg
,
374 struct isl_mat
**U
, struct isl_mat
**Q
)
389 *U
= isl_mat_identity(M
->ctx
, M
->n_col
);
394 *Q
= isl_mat_identity(M
->ctx
, M
->n_col
);
401 for (row
= 0; row
< M
->n_row
; ++row
) {
403 first
= isl_seq_abs_min_non_zero(M
->row
[row
]+col
, M
->n_col
-col
);
408 exchange(M
, U
, Q
, row
, first
, col
);
409 if (isl_int_is_neg(M
->row
[row
][col
]))
410 oppose(M
, U
, Q
, row
, col
);
412 while ((off
= isl_seq_first_non_zero(M
->row
[row
]+first
,
413 M
->n_col
-first
)) != -1) {
415 isl_int_fdiv_q(c
, M
->row
[row
][first
], M
->row
[row
][col
]);
416 subtract(M
, U
, Q
, row
, col
, first
, c
);
417 if (!isl_int_is_zero(M
->row
[row
][first
]))
418 exchange(M
, U
, Q
, row
, first
, col
);
422 for (i
= 0; i
< col
; ++i
) {
423 if (isl_int_is_zero(M
->row
[row
][i
]))
426 isl_int_cdiv_q(c
, M
->row
[row
][i
], M
->row
[row
][col
]);
428 isl_int_fdiv_q(c
, M
->row
[row
][i
], M
->row
[row
][col
]);
429 if (isl_int_is_zero(c
))
431 subtract(M
, U
, Q
, row
, col
, i
, c
);
450 struct isl_mat
*isl_mat_right_kernel(struct isl_mat
*mat
)
453 struct isl_mat
*U
= NULL
;
456 mat
= isl_mat_left_hermite(mat
, 0, &U
, NULL
);
460 for (i
= 0, rank
= 0; rank
< mat
->n_col
; ++rank
) {
461 while (i
< mat
->n_row
&& isl_int_is_zero(mat
->row
[i
][rank
]))
466 K
= isl_mat_alloc(U
->ctx
, U
->n_row
, U
->n_col
- rank
);
469 isl_mat_sub_copy(K
->ctx
, K
->row
, U
->row
, U
->n_row
, 0, rank
, U
->n_col
-rank
);
479 struct isl_mat
*isl_mat_lin_to_aff(struct isl_mat
*mat
)
482 struct isl_mat
*mat2
;
486 mat2
= isl_mat_alloc(mat
->ctx
, 1+mat
->n_row
, 1+mat
->n_col
);
489 isl_int_set_si(mat2
->row
[0][0], 1);
490 isl_seq_clr(mat2
->row
[0]+1, mat
->n_col
);
491 for (i
= 0; i
< mat
->n_row
; ++i
) {
492 isl_int_set_si(mat2
->row
[1+i
][0], 0);
493 isl_seq_cpy(mat2
->row
[1+i
]+1, mat
->row
[i
], mat
->n_col
);
499 static int row_first_non_zero(isl_int
**row
, unsigned n_row
, unsigned col
)
503 for (i
= 0; i
< n_row
; ++i
)
504 if (!isl_int_is_zero(row
[i
][col
]))
509 static int row_abs_min_non_zero(isl_int
**row
, unsigned n_row
, unsigned col
)
511 int i
, min
= row_first_non_zero(row
, n_row
, col
);
514 for (i
= min
+ 1; i
< n_row
; ++i
) {
515 if (isl_int_is_zero(row
[i
][col
]))
517 if (isl_int_abs_lt(row
[i
][col
], row
[min
][col
]))
523 static void inv_exchange(struct isl_mat
*left
, struct isl_mat
*right
,
524 unsigned i
, unsigned j
)
526 left
= isl_mat_swap_rows(left
, i
, j
);
527 right
= isl_mat_swap_rows(right
, i
, j
);
530 static void inv_oppose(
531 struct isl_mat
*left
, struct isl_mat
*right
, unsigned row
)
533 isl_seq_neg(left
->row
[row
]+row
, left
->row
[row
]+row
, left
->n_col
-row
);
534 isl_seq_neg(right
->row
[row
], right
->row
[row
], right
->n_col
);
537 static void inv_subtract(struct isl_mat
*left
, struct isl_mat
*right
,
538 unsigned row
, unsigned i
, isl_int m
)
541 isl_seq_combine(left
->row
[i
]+row
,
542 left
->ctx
->one
, left
->row
[i
]+row
,
543 m
, left
->row
[row
]+row
,
545 isl_seq_combine(right
->row
[i
], right
->ctx
->one
, right
->row
[i
],
546 m
, right
->row
[row
], right
->n_col
);
549 /* Compute inv(left)*right
551 struct isl_mat
*isl_mat_inverse_product(struct isl_mat
*left
,
552 struct isl_mat
*right
)
560 isl_assert(left
->ctx
, left
->n_row
== left
->n_col
, goto error
);
561 isl_assert(left
->ctx
, left
->n_row
== right
->n_row
, goto error
);
563 if (left
->n_row
== 0) {
568 left
= isl_mat_cow(left
);
569 right
= isl_mat_cow(right
);
575 for (row
= 0; row
< left
->n_row
; ++row
) {
576 int pivot
, first
, i
, off
;
577 pivot
= row_abs_min_non_zero(left
->row
+row
, left
->n_row
-row
, row
);
581 isl_assert(left
->ctx
, pivot
>= 0, goto error
);
585 inv_exchange(left
, right
, pivot
, row
);
586 if (isl_int_is_neg(left
->row
[row
][row
]))
587 inv_oppose(left
, right
, row
);
589 while ((off
= row_first_non_zero(left
->row
+first
,
590 left
->n_row
-first
, row
)) != -1) {
592 isl_int_fdiv_q(a
, left
->row
[first
][row
],
593 left
->row
[row
][row
]);
594 inv_subtract(left
, right
, row
, first
, a
);
595 if (!isl_int_is_zero(left
->row
[first
][row
]))
596 inv_exchange(left
, right
, row
, first
);
600 for (i
= 0; i
< row
; ++i
) {
601 if (isl_int_is_zero(left
->row
[i
][row
]))
603 isl_int_gcd(a
, left
->row
[row
][row
], left
->row
[i
][row
]);
604 isl_int_divexact(b
, left
->row
[i
][row
], a
);
605 isl_int_divexact(a
, left
->row
[row
][row
], a
);
607 isl_seq_combine(left
->row
[i
]+row
,
609 b
, left
->row
[row
]+row
,
611 isl_seq_combine(right
->row
[i
], a
, right
->row
[i
],
612 b
, right
->row
[row
], right
->n_col
);
617 isl_int_set(a
, left
->row
[0][0]);
618 for (row
= 1; row
< left
->n_row
; ++row
)
619 isl_int_lcm(a
, a
, left
->row
[row
][row
]);
620 if (isl_int_is_zero(a
)){
622 isl_assert(left
->ctx
, 0, goto error
);
624 for (row
= 0; row
< left
->n_row
; ++row
) {
625 isl_int_divexact(left
->row
[row
][row
], a
, left
->row
[row
][row
]);
626 if (isl_int_is_one(left
->row
[row
][row
]))
628 isl_seq_scale(right
->row
[row
], right
->row
[row
],
629 left
->row
[row
][row
], right
->n_col
);
641 void isl_mat_col_scale(struct isl_mat
*mat
, unsigned col
, isl_int m
)
645 for (i
= 0; i
< mat
->n_row
; ++i
)
646 isl_int_mul(mat
->row
[i
][col
], mat
->row
[i
][col
], m
);
649 void isl_mat_col_combine(struct isl_mat
*mat
, unsigned dst
,
650 isl_int m1
, unsigned src1
, isl_int m2
, unsigned src2
)
656 for (i
= 0; i
< mat
->n_row
; ++i
) {
657 isl_int_mul(tmp
, m1
, mat
->row
[i
][src1
]);
658 isl_int_addmul(tmp
, m2
, mat
->row
[i
][src2
]);
659 isl_int_set(mat
->row
[i
][dst
], tmp
);
664 struct isl_mat
*isl_mat_right_inverse(struct isl_mat
*mat
)
670 mat
= isl_mat_cow(mat
);
674 inv
= isl_mat_identity(mat
->ctx
, mat
->n_col
);
675 inv
= isl_mat_cow(inv
);
681 for (row
= 0; row
< mat
->n_row
; ++row
) {
682 int pivot
, first
, i
, off
;
683 pivot
= isl_seq_abs_min_non_zero(mat
->row
[row
]+row
, mat
->n_col
-row
);
691 exchange(mat
, &inv
, NULL
, row
, pivot
, row
);
692 if (isl_int_is_neg(mat
->row
[row
][row
]))
693 oppose(mat
, &inv
, NULL
, row
, row
);
695 while ((off
= isl_seq_first_non_zero(mat
->row
[row
]+first
,
696 mat
->n_col
-first
)) != -1) {
698 isl_int_fdiv_q(a
, mat
->row
[row
][first
],
700 subtract(mat
, &inv
, NULL
, row
, row
, first
, a
);
701 if (!isl_int_is_zero(mat
->row
[row
][first
]))
702 exchange(mat
, &inv
, NULL
, row
, row
, first
);
706 for (i
= 0; i
< row
; ++i
) {
707 if (isl_int_is_zero(mat
->row
[row
][i
]))
709 isl_int_gcd(a
, mat
->row
[row
][row
], mat
->row
[row
][i
]);
710 isl_int_divexact(b
, mat
->row
[row
][i
], a
);
711 isl_int_divexact(a
, mat
->row
[row
][row
], a
);
713 isl_mat_col_combine(mat
, i
, a
, i
, b
, row
);
714 isl_mat_col_combine(inv
, i
, a
, i
, b
, row
);
719 isl_int_set(a
, mat
->row
[0][0]);
720 for (row
= 1; row
< mat
->n_row
; ++row
)
721 isl_int_lcm(a
, a
, mat
->row
[row
][row
]);
722 if (isl_int_is_zero(a
)){
726 for (row
= 0; row
< mat
->n_row
; ++row
) {
727 isl_int_divexact(mat
->row
[row
][row
], a
, mat
->row
[row
][row
]);
728 if (isl_int_is_one(mat
->row
[row
][row
]))
730 isl_mat_col_scale(inv
, row
, mat
->row
[row
][row
]);
742 struct isl_mat
*isl_mat_transpose(struct isl_mat
*mat
)
744 struct isl_mat
*transpose
= NULL
;
747 if (mat
->n_col
== mat
->n_row
) {
748 mat
= isl_mat_cow(mat
);
751 for (i
= 0; i
< mat
->n_row
; ++i
)
752 for (j
= i
+ 1; j
< mat
->n_col
; ++j
)
753 isl_int_swap(mat
->row
[i
][j
], mat
->row
[j
][i
]);
756 transpose
= isl_mat_alloc(mat
->ctx
, mat
->n_col
, mat
->n_row
);
759 for (i
= 0; i
< mat
->n_row
; ++i
)
760 for (j
= 0; j
< mat
->n_col
; ++j
)
761 isl_int_set(transpose
->row
[j
][i
], mat
->row
[i
][j
]);
769 struct isl_mat
*isl_mat_swap_cols(struct isl_mat
*mat
, unsigned i
, unsigned j
)
773 mat
= isl_mat_cow(mat
);
776 isl_assert(mat
->ctx
, i
< mat
->n_col
, goto error
);
777 isl_assert(mat
->ctx
, j
< mat
->n_col
, goto error
);
779 for (r
= 0; r
< mat
->n_row
; ++r
)
780 isl_int_swap(mat
->row
[r
][i
], mat
->row
[r
][j
]);
787 struct isl_mat
*isl_mat_swap_rows(struct isl_mat
*mat
, unsigned i
, unsigned j
)
793 mat
= isl_mat_cow(mat
);
797 mat
->row
[i
] = mat
->row
[j
];
802 struct isl_mat
*isl_mat_product(struct isl_mat
*left
, struct isl_mat
*right
)
805 struct isl_mat
*prod
;
809 isl_assert(left
->ctx
, left
->n_col
== right
->n_row
, goto error
);
810 prod
= isl_mat_alloc(left
->ctx
, left
->n_row
, right
->n_col
);
813 if (left
->n_col
== 0) {
814 for (i
= 0; i
< prod
->n_row
; ++i
)
815 isl_seq_clr(prod
->row
[i
], prod
->n_col
);
818 for (i
= 0; i
< prod
->n_row
; ++i
) {
819 for (j
= 0; j
< prod
->n_col
; ++j
) {
820 isl_int_mul(prod
->row
[i
][j
],
821 left
->row
[i
][0], right
->row
[0][j
]);
822 for (k
= 1; k
< left
->n_col
; ++k
)
823 isl_int_addmul(prod
->row
[i
][j
],
824 left
->row
[i
][k
], right
->row
[k
][j
]);
836 /* Replace the variables x in the rows q by x' given by x = M x',
837 * with M the matrix mat.
839 * If the number of new variables is greater than the original
840 * number of variables, then the rows q have already been
841 * preextended. If the new number is smaller, then the coefficients
842 * of the divs, which are not changed, need to be shifted down.
843 * The row q may be the equalities, the inequalities or the
844 * div expressions. In the latter case, has_div is true and
845 * we need to take into account the extra denominator column.
847 static int preimage(struct isl_ctx
*ctx
, isl_int
**q
, unsigned n
,
848 unsigned n_div
, int has_div
, struct isl_mat
*mat
)
854 if (mat
->n_col
>= mat
->n_row
)
857 e
= mat
->n_row
- mat
->n_col
;
859 for (i
= 0; i
< n
; ++i
)
860 isl_int_mul(q
[i
][0], q
[i
][0], mat
->row
[0][0]);
861 t
= isl_mat_sub_alloc(mat
->ctx
, q
, 0, n
, has_div
, mat
->n_row
);
862 t
= isl_mat_product(t
, mat
);
865 for (i
= 0; i
< n
; ++i
) {
866 isl_seq_swp_or_cpy(q
[i
] + has_div
, t
->row
[i
], t
->n_col
);
867 isl_seq_cpy(q
[i
] + has_div
+ t
->n_col
,
868 q
[i
] + has_div
+ t
->n_col
+ e
, n_div
);
869 isl_seq_clr(q
[i
] + has_div
+ t
->n_col
+ n_div
, e
);
875 /* Replace the variables x in bset by x' given by x = M x', with
878 * If there are fewer variables x' then there are x, then we perform
879 * the transformation in place, which that, in principle,
880 * this frees up some extra variables as the number
881 * of columns remains constant, but we would have to extend
882 * the div array too as the number of rows in this array is assumed
883 * to be equal to extra.
885 struct isl_basic_set
*isl_basic_set_preimage(struct isl_basic_set
*bset
,
894 bset
= isl_basic_set_cow(bset
);
898 isl_assert(ctx
, bset
->dim
->nparam
== 0, goto error
);
899 isl_assert(ctx
, 1+bset
->dim
->n_out
== mat
->n_row
, goto error
);
901 if (mat
->n_col
> mat
->n_row
)
902 bset
= isl_basic_set_extend(bset
, 0, mat
->n_col
-1, 0,
904 else if (mat
->n_col
< mat
->n_row
) {
905 bset
->dim
= isl_dim_cow(bset
->dim
);
908 bset
->dim
->n_out
-= mat
->n_row
- mat
->n_col
;
911 if (preimage(ctx
, bset
->eq
, bset
->n_eq
, bset
->n_div
, 0,
912 isl_mat_copy(mat
)) < 0)
915 if (preimage(ctx
, bset
->ineq
, bset
->n_ineq
, bset
->n_div
, 0,
916 isl_mat_copy(mat
)) < 0)
919 if (preimage(ctx
, bset
->div
, bset
->n_div
, bset
->n_div
, 1, mat
) < 0)
922 ISL_F_CLR(bset
, ISL_BASIC_SET_NO_IMPLICIT
);
923 ISL_F_CLR(bset
, ISL_BASIC_SET_NO_REDUNDANT
);
924 ISL_F_CLR(bset
, ISL_BASIC_SET_NORMALIZED
);
925 ISL_F_CLR(bset
, ISL_BASIC_SET_NORMALIZED_DIVS
);
926 ISL_F_CLR(bset
, ISL_BASIC_SET_ALL_EQUALITIES
);
928 bset
= isl_basic_set_simplify(bset
);
929 bset
= isl_basic_set_finalize(bset
);
935 isl_basic_set_free(bset
);
939 struct isl_set
*isl_set_preimage(struct isl_set
*set
, struct isl_mat
*mat
)
944 set
= isl_set_cow(set
);
949 for (i
= 0; i
< set
->n
; ++i
) {
950 set
->p
[i
] = isl_basic_set_preimage(set
->p
[i
],
955 if (mat
->n_col
!= mat
->n_row
) {
956 set
->dim
= isl_dim_cow(set
->dim
);
959 set
->dim
->n_out
+= mat
->n_col
;
960 set
->dim
->n_out
-= mat
->n_row
;
963 ISL_F_CLR(set
, ISL_SET_NORMALIZED
);
971 void isl_mat_dump(struct isl_mat
*mat
, FILE *out
, int indent
)
976 fprintf(out
, "%*snull mat\n", indent
, "");
981 fprintf(out
, "%*s[]\n", indent
, "");
983 for (i
= 0; i
< mat
->n_row
; ++i
) {
985 fprintf(out
, "%*s[[", indent
, "");
987 fprintf(out
, "%*s[", indent
+1, "");
988 for (j
= 0; j
< mat
->n_col
; ++j
) {
991 isl_int_print(out
, mat
->row
[i
][j
], 0);
993 if (i
== mat
->n_row
-1)
994 fprintf(out
, "]]\n");
1000 struct isl_mat
*isl_mat_drop_cols(struct isl_mat
*mat
, unsigned col
, unsigned n
)
1004 mat
= isl_mat_cow(mat
);
1008 if (col
!= mat
->n_col
-n
) {
1009 for (r
= 0; r
< mat
->n_row
; ++r
)
1010 isl_seq_cpy(mat
->row
[r
]+col
, mat
->row
[r
]+col
+n
,
1011 mat
->n_col
- col
- n
);
1017 struct isl_mat
*isl_mat_drop_rows(struct isl_mat
*mat
, unsigned row
, unsigned n
)
1021 mat
= isl_mat_cow(mat
);
1025 for (r
= row
; r
+n
< mat
->n_row
; ++r
)
1026 mat
->row
[r
] = mat
->row
[r
+n
];
1032 void isl_mat_col_submul(struct isl_mat
*mat
,
1033 int dst_col
, isl_int f
, int src_col
)
1037 for (i
= 0; i
< mat
->n_row
; ++i
)
1038 isl_int_submul(mat
->row
[i
][dst_col
], f
, mat
->row
[i
][src_col
]);
1041 void isl_mat_col_mul(struct isl_mat
*mat
, int dst_col
, isl_int f
, int src_col
)
1045 for (i
= 0; i
< mat
->n_row
; ++i
)
1046 isl_int_mul(mat
->row
[i
][dst_col
], f
, mat
->row
[i
][src_col
]);
1049 struct isl_mat
*isl_mat_unimodular_complete(struct isl_mat
*M
, int row
)
1052 struct isl_mat
*H
= NULL
, *Q
= NULL
;
1057 isl_assert(M
->ctx
, M
->n_row
== M
->n_col
, goto error
);
1059 H
= isl_mat_left_hermite(isl_mat_copy(M
), 0, NULL
, &Q
);
1060 M
->n_row
= M
->n_col
;
1063 for (r
= 0; r
< row
; ++r
)
1064 isl_assert(M
->ctx
, isl_int_is_one(H
->row
[r
][r
]), goto error
);
1065 for (r
= row
; r
< M
->n_row
; ++r
)
1066 isl_seq_cpy(M
->row
[r
], Q
->row
[r
], M
->n_col
);