* Copyright 2008-2009 Katholieke Universiteit Leuven
* Copyright 2010 INRIA Saclay
* Copyright 2014 Ecole Normale Superieure
- * Copyright 2017 Sven Verdoolaege
+ * Copyright 2016-2017 Sven Verdoolaege
*
* Use of this software is governed by the MIT license
*
#include <isl_vec_private.h>
#include <isl_space_private.h>
#include <isl_val_private.h>
-#include <isl/deprecated/mat_int.h>
isl_ctx *isl_mat_get_ctx(__isl_keep isl_mat *mat)
{
@@ -51,7 +50,7 @@ uint32_t isl_mat_get_hash(__isl_keep isl_mat *mat)
return hash;
}
-struct isl_mat *isl_mat_alloc(struct isl_ctx *ctx,
+__isl_give isl_mat *isl_mat_alloc(isl_ctx *ctx,
unsigned n_row, unsigned n_col)
{
int i;
@@ -65,12 +64,14 @@ struct isl_mat *isl_mat_alloc(struct isl_ctx *ctx,
mat->block = isl_blk_alloc(ctx, n_row * n_col);
if (isl_blk_is_error(mat->block))
goto error;
- mat->row = isl_alloc_array(ctx, isl_int *, n_row);
+ mat->row = isl_calloc_array(ctx, isl_int *, n_row);
if (n_row && !mat->row)
goto error;
- for (i = 0; i < n_row; ++i)
- mat->row[i] = mat->block.data + i * n_col;
+ if (n_col != 0) {
+ for (i = 0; i < n_row; ++i)
+ mat->row[i] = mat->block.data + i * n_col;
+ }
mat->ctx = ctx;
isl_ctx_ref(ctx);
return NULL;
}
-struct isl_mat *isl_mat_extend(struct isl_mat *mat,
+__isl_give isl_mat *isl_mat_extend(__isl_take isl_mat *mat,
unsigned n_row, unsigned n_col)
{
int i;
@@ -253,14 +254,14 @@ __isl_null isl_mat *isl_mat_free(__isl_take isl_mat *mat)
return NULL;
}
-int isl_mat_rows(__isl_keep isl_mat *mat)
+isl_size isl_mat_rows(__isl_keep isl_mat *mat)
{
- return mat ? mat->n_row : -1;
+ return mat ? mat->n_row : isl_size_error;
}
-int isl_mat_cols(__isl_keep isl_mat *mat)
+isl_size isl_mat_cols(__isl_keep isl_mat *mat)
{
- return mat ? mat->n_col : -1;
+ return mat ? mat->n_col : isl_size_error;
}
/* Check that "col" is a valid column position for "mat".
@@ -424,26 +425,26 @@ __isl_give isl_mat *isl_mat_identity(isl_ctx *ctx, unsigned n_row)
/* Is "mat" a (possibly scaled) identity matrix?
*/
-int isl_mat_is_scaled_identity(__isl_keep isl_mat *mat)
+isl_bool isl_mat_is_scaled_identity(__isl_keep isl_mat *mat)
{
int i;
if (!mat)
- return -1;
+ return isl_bool_error;
if (mat->n_row != mat->n_col)
- return 0;
+ return isl_bool_false;
for (i = 0; i < mat->n_row; ++i) {
if (isl_seq_first_non_zero(mat->row[i], i) != -1)
- return 0;
+ return isl_bool_false;
if (isl_int_ne(mat->row[0][0], mat->row[i][i]))
- return 0;
+ return isl_bool_false;
if (isl_seq_first_non_zero(mat->row[i] + i + 1,
mat->n_col - (i + 1)) != -1)
- return 0;
+ return isl_bool_false;
}
- return 1;
+ return isl_bool_true;
}
__isl_give isl_vec *isl_mat_vec_product(__isl_take isl_mat *mat,
@@ -581,8 +582,8 @@ error:
return NULL;
}
-static void exchange(struct isl_mat *M, struct isl_mat **U,
- struct isl_mat **Q, unsigned row, unsigned i, unsigned j)
+static void exchange(__isl_keep isl_mat *M, __isl_keep isl_mat **U,
+ __isl_keep isl_mat **Q, unsigned row, unsigned i, unsigned j)
{
int r;
for (r = row; r < M->n_row; ++r)
@@ -595,8 +596,8 @@ static void exchange(struct isl_mat *M, struct isl_mat **U,
isl_mat_swap_rows(*Q, i, j);
}
-static void subtract(struct isl_mat *M, struct isl_mat **U,
- struct isl_mat **Q, unsigned row, unsigned i, unsigned j, isl_int m)
+static void subtract(__isl_keep isl_mat *M, __isl_keep isl_mat **U,
+ __isl_keep isl_mat **Q, unsigned row, unsigned i, unsigned j, isl_int m)
{
int r;
for (r = row; r < M->n_row; ++r)
@@ -611,8 +612,8 @@ static void subtract(struct isl_mat *M, struct isl_mat **U,
}
}
-static void oppose(struct isl_mat *M, struct isl_mat **U,
- struct isl_mat **Q, unsigned row, unsigned col)
+static void oppose(__isl_keep isl_mat *M, __isl_keep isl_mat **U,
+ __isl_keep isl_mat **Q, unsigned row, unsigned col)
{
int r;
for (r = row; r < M->n_row; ++r)
@@ -649,9 +650,6 @@ __isl_give isl_mat *isl_mat_left_hermite(__isl_take isl_mat *M, int neg,
*Q = NULL;
if (!M)
goto error;
- M = isl_mat_cow(M);
- if (!M)
- goto error;
if (U) {
*U = isl_mat_identity(M->ctx, M->n_col);
if (!*U)
@@ -663,6 +661,13 @@ __isl_give isl_mat *isl_mat_left_hermite(__isl_take isl_mat *M, int neg,
goto error;
}
+ if (M->n_col == 0)
+ return M;
+
+ M = isl_mat_cow(M);
+ if (!M)
+ goto error;
+
col = 0;
isl_int_init(c);
for (row = 0; row < M->n_row; ++row) {
@@ -719,15 +724,16 @@ error:
*/
static __isl_give isl_mat *eliminate(__isl_take isl_mat *mat, int row, int col)
{
- int k, nr, nc;
+ int k;
+ isl_size nr, nc;
isl_ctx *ctx;
- if (!mat)
- return NULL;
-
- ctx = isl_mat_get_ctx(mat);
nr = isl_mat_rows(mat);
nc = isl_mat_cols(mat);
+ if (nr < 0 || nc < 0)
+ return isl_mat_free(mat);
+
+ ctx = isl_mat_get_ctx(mat);
for (k = 0; k < nr; ++k) {
if (k == row)
@@ -755,13 +761,13 @@ static __isl_give isl_mat *eliminate(__isl_take isl_mat *mat, int row, int col)
*/
__isl_give isl_mat *isl_mat_reverse_gauss(__isl_take isl_mat *mat)
{
- int k, row, last, nr, nc;
-
- if (!mat)
- return NULL;
+ int k, row, last;
+ isl_size nr, nc;
nr = isl_mat_rows(mat);
nc = isl_mat_cols(mat);
+ if (nr < 0 || nc < 0)
+ return isl_mat_free(mat);
last = nc - 1;
for (row = nr - 1; row >= 0; --row) {
@@ -794,13 +800,13 @@ __isl_give isl_mat *isl_mat_reverse_gauss(__isl_take isl_mat *mat)
*/
__isl_give isl_mat *isl_mat_lexnonneg_rows(__isl_take isl_mat *mat)
{
- int i, nr, nc;
-
- if (!mat)
- return NULL;
+ int i;
+ isl_size nr, nc;
nr = isl_mat_rows(mat);
nc = isl_mat_cols(mat);
+ if (nr < 0 || nc < 0)
+ return isl_mat_free(mat);
for (i = 0; i < nr; ++i) {
int pos;
@@ -843,16 +849,16 @@ static int hermite_first_zero_col(__isl_keep isl_mat *H, int first_col,
return H->n_col;
}
-/* Return the rank of "mat", or -1 in case of error.
+/* Return the rank of "mat", or isl_size_error in case of error.
*/
-int isl_mat_rank(__isl_keep isl_mat *mat)
+isl_size isl_mat_rank(__isl_keep isl_mat *mat)
{
int rank;
isl_mat *H;
H = isl_mat_left_hermite(isl_mat_copy(mat), 0, NULL, NULL);
if (!H)
- return -1;
+ return isl_size_error;
rank = hermite_first_zero_col(H, 0, H->n_row);
isl_mat_free(H);
@@ -884,6 +890,18 @@ error:
return NULL;
}
+/* Return a basis for the orthogonal complement of the space spanned
+ * by the rows of "M".
+ * That is, each of the rows of the result is orthogonal to each
+ * of the rows of "M".
+ *
+ * The complement is derived as the transpose of the right kernel.
+ */
+__isl_give isl_mat *isl_mat_row_complement(__isl_take isl_mat *mat)
+{
+ return isl_mat_transpose(isl_mat_right_kernel(mat));
+}
+
__isl_give isl_mat *isl_mat_lin_to_aff(__isl_take isl_mat *mat)
{
int i;
@@ -979,13 +997,13 @@ static isl_stat inv_exchange(__isl_keep isl_mat **left,
}
static void inv_oppose(
- struct isl_mat *left, struct isl_mat *right, unsigned row)
+ __isl_keep isl_mat *left, __isl_keep isl_mat *right, unsigned row)
{
isl_seq_neg(left->row[row]+row, left->row[row]+row, left->n_col-row);
isl_seq_neg(right->row[row], right->row[row], right->n_col);
}
-static void inv_subtract(struct isl_mat *left, struct isl_mat *right,
+static void inv_subtract(__isl_keep isl_mat *left, __isl_keep isl_mat *right,
unsigned row, unsigned i, isl_int m)
{
isl_int_neg(m, m);
@@ -1092,7 +1110,7 @@ error:
return NULL;
}
-void isl_mat_col_scale(struct isl_mat *mat, unsigned col, isl_int m)
+void isl_mat_col_scale(__isl_keep isl_mat *mat, unsigned col, isl_int m)
{
int i;
@@ -1100,7 +1118,7 @@ void isl_mat_col_scale(struct isl_mat *mat, unsigned col, isl_int m)
isl_int_mul(mat->row[i][col], mat->row[i][col], m);
}
-void isl_mat_col_combine(struct isl_mat *mat, unsigned dst,
+void isl_mat_col_combine(__isl_keep isl_mat *mat, unsigned dst,
isl_int m1, unsigned src1, isl_int m2, unsigned src2)
{
int i;
@@ -1361,15 +1379,15 @@ __isl_give isl_basic_set *isl_basic_set_preimage(
ctx = bset->ctx;
bset = isl_basic_set_cow(bset);
- if (!bset)
+ if (isl_basic_set_check_no_params(bset) < 0)
goto error;
- isl_assert(ctx, bset->dim->nparam == 0, goto error);
isl_assert(ctx, 1+bset->dim->n_out == mat->n_row, goto error);
isl_assert(ctx, mat->n_col > 0, goto error);
if (mat->n_col > mat->n_row) {
- bset = isl_basic_set_extend(bset, 0, mat->n_col-1, 0, 0, 0);
+ bset = isl_basic_set_add_dims(bset, isl_dim_set,
+ mat->n_col - mat->n_row);
if (!bset)
goto error;
} else if (mat->n_col < mat->n_row) {
@@ -1392,7 +1410,7 @@ __isl_give isl_basic_set *isl_basic_set_preimage(
ISL_F_CLR(bset, ISL_BASIC_SET_NO_IMPLICIT);
ISL_F_CLR(bset, ISL_BASIC_SET_NO_REDUNDANT);
- ISL_F_CLR(bset, ISL_BASIC_SET_NORMALIZED);
+ ISL_F_CLR(bset, ISL_BASIC_SET_SORTED);
ISL_F_CLR(bset, ISL_BASIC_SET_NORMALIZED_DIVS);
ISL_F_CLR(bset, ISL_BASIC_SET_ALL_EQUALITIES);
@@ -1639,7 +1657,7 @@ __isl_give isl_mat *isl_mat_add_zero_rows(__isl_take isl_mat *mat, unsigned n)
return isl_mat_insert_zero_rows(mat, mat->n_row, n);
}
-void isl_mat_col_submul(struct isl_mat *mat,
+void isl_mat_col_submul(__isl_keep isl_mat *mat,
int dst_col, isl_int f, int src_col)
{
int i;
@@ -1660,7 +1678,8 @@ void isl_mat_col_add(__isl_keep isl_mat *mat, int dst_col, int src_col)
mat->row[i][dst_col], mat->row[i][src_col]);
}
-void isl_mat_col_mul(struct isl_mat *mat, int dst_col, isl_int f, int src_col)
+void isl_mat_col_mul(__isl_keep isl_mat *mat, int dst_col, isl_int f,
+ int src_col)
{
int i;
@@ -1848,6 +1867,25 @@ __isl_give isl_vec *isl_mat_get_row(__isl_keep isl_mat *mat, unsigned row)
return v;
}
+/* Return a copy of column "col" of "mat" as an isl_vec.
+ */
+__isl_give isl_vec *isl_mat_get_col(__isl_keep isl_mat *mat, unsigned col)
+{
+ int i;
+ isl_vec *v;
+
+ if (check_col_range(mat, col, 1) < 0)
+ return NULL;
+
+ v = isl_vec_alloc(isl_mat_get_ctx(mat), mat->n_row);
+ if (!v)
+ return NULL;
+ for (i = 0; i < mat->n_row; ++i)
+ isl_int_set(v->el[i], mat->row[i][col]);
+
+ return v;
+}
+
__isl_give isl_mat *isl_mat_vec_concat(__isl_take isl_mat *top,
__isl_take isl_vec *bot)
{
@@ -2044,19 +2082,22 @@ __isl_give isl_mat *isl_mat_row_basis(__isl_take isl_mat *mat)
__isl_give isl_mat *isl_mat_row_basis_extension(
__isl_take isl_mat *mat1, __isl_take isl_mat *mat2)
{
- int n_row;
- int r1, r, n1;
+ isl_size n_row;
+ int r1, r;
+ isl_size n1;
isl_mat *H, *Q;
n1 = isl_mat_rows(mat1);
H = isl_mat_concat(mat1, mat2);
H = isl_mat_left_hermite(H, 0, NULL, &Q);
- if (!H || !Q)
+ if (n1 < 0 || !H || !Q)
goto error;
r1 = hermite_first_zero_col(H, 0, n1);
r = hermite_first_zero_col(H, r1, H->n_row);
n_row = isl_mat_rows(Q);
+ if (n_row < 0)
+ goto error;
Q = isl_mat_drop_rows(Q, r, n_row - r);
Q = isl_mat_drop_rows(Q, 0, r1);
@@ -2077,7 +2118,7 @@ error:
isl_bool isl_mat_has_linearly_independent_rows(__isl_keep isl_mat *mat1,
__isl_keep isl_mat *mat2)
{
- int r1, r2, r;
+ isl_size r1, r2, r;
isl_mat *mat;
r1 = isl_mat_rank(mat1);
@@ -2096,5 +2137,5 @@ isl_bool isl_mat_has_linearly_independent_rows(__isl_keep isl_mat *mat1,
isl_mat_free(mat);
if (r < 0)
return isl_bool_error;
- return r == r1 + r2;
+ return isl_bool_ok(r == r1 + r2);
}