add isl_mat_swap_cols
[platform/upstream/isl.git] / isl_mat.c
index 3fde011..e2566d5 100644 (file)
--- a/isl_mat.c
+++ b/isl_mat.c
@@ -358,6 +358,35 @@ error:
        return NULL;
 }
 
+struct isl_mat *isl_mat_right_kernel(struct isl_ctx *ctx, struct isl_mat *mat)
+{
+       int i, rank;
+       struct isl_mat *U = NULL;
+       struct isl_mat *K;
+
+       mat = isl_mat_left_hermite(ctx, mat, 0, &U, NULL);
+       if (!mat || !U)
+               goto error;
+
+       for (i = 0, rank = 0; rank < mat->n_col; ++rank) {
+               while (i < mat->n_row && isl_int_is_zero(mat->row[i][rank]))
+                       ++i;
+               if (i >= mat->n_row)
+                       break;
+       }
+       K = isl_mat_alloc(ctx, U->n_row, U->n_col - rank);
+       if (!K)
+               goto error;
+       isl_mat_sub_copy(ctx, K->row, U->row, U->n_row, 0, rank, U->n_col-rank);
+       isl_mat_free(ctx, mat);
+       isl_mat_free(ctx, U);
+       return K;
+error:
+       isl_mat_free(ctx, mat);
+       isl_mat_free(ctx, U);
+       return NULL;
+}
+
 struct isl_mat *isl_mat_lin_to_aff(struct isl_ctx *ctx, struct isl_mat *mat)
 {
        int i;
@@ -624,6 +653,42 @@ error:
        return NULL;
 }
 
+struct isl_mat *isl_mat_transpose(struct isl_ctx *ctx, struct isl_mat *mat)
+{
+       int i, j;
+
+       mat = isl_mat_cow(ctx, mat);
+       if (!mat)
+               return NULL;
+       isl_assert(ctx, mat->n_col == mat->n_row, goto error);
+       for (i = 0; i < mat->n_row; ++i)
+               for (j = i + 1; j < mat->n_col; ++j)
+                       isl_int_swap(mat->row[i][j], mat->row[j][i]);
+       return mat;
+error:
+       isl_mat_free(ctx, mat);
+       return NULL;
+}
+
+struct isl_mat *isl_mat_swap_cols(struct isl_ctx *ctx,
+       struct isl_mat *mat, unsigned i, unsigned j)
+{
+       int r;
+
+       mat = isl_mat_cow(ctx, mat);
+       if (!mat)
+               return NULL;
+       isl_assert(ctx, i < mat->n_col, goto error);
+       isl_assert(ctx, j < mat->n_col, goto error);
+
+       for (r = 0; r < mat->n_row; ++r)
+               isl_int_swap(mat->row[r][i], mat->row[r][j]);
+       return mat;
+error:
+       isl_mat_free(ctx, mat);
+       return NULL;
+}
+
 struct isl_mat *isl_mat_swap_rows(struct isl_ctx *ctx,
        struct isl_mat *mat, unsigned i, unsigned j)
 {
@@ -767,6 +832,7 @@ struct isl_set *isl_set_preimage(struct isl_ctx *ctx,
                set->dim->n_out -= mat->n_row;
        }
        isl_mat_free(ctx, mat);
+       F_CLR(set, ISL_SET_NORMALIZED);
        return set;
 error:
        isl_set_free(set);
@@ -780,7 +846,7 @@ void isl_mat_dump(struct isl_ctx *ctx, struct isl_mat *mat,
        int i, j;
 
        if (!mat) {
-               fprintf(out, "null mat\n");
+               fprintf(out, "%*snull mat\n", indent, "");
                return;
        }
 
@@ -809,6 +875,7 @@ struct isl_mat *isl_mat_drop_cols(struct isl_ctx *ctx, struct isl_mat *mat,
 {
        int r;
 
+       mat = isl_mat_cow(ctx, mat);
        if (!mat)
                return NULL;
 
@@ -826,6 +893,7 @@ struct isl_mat *isl_mat_drop_rows(struct isl_ctx *ctx, struct isl_mat *mat,
 {
        int r;
 
+       mat = isl_mat_cow(ctx, mat);
        if (!mat)
                return NULL;
 
@@ -835,3 +903,20 @@ struct isl_mat *isl_mat_drop_rows(struct isl_ctx *ctx, struct isl_mat *mat,
        mat->n_row -= n;
        return mat;
 }
+
+void isl_mat_col_submul(struct isl_mat *mat,
+                       int dst_col, isl_int f, int src_col)
+{
+       int i;
+
+       for (i = 0; i < mat->n_row; ++i)
+               isl_int_submul(mat->row[i][dst_col], f, mat->row[i][src_col]);
+}
+
+void isl_mat_col_mul(struct isl_mat *mat, int dst_col, isl_int f, int src_col)
+{
+       int i;
+
+       for (i = 0; i < mat->n_row; ++i)
+               isl_int_mul(mat->row[i][dst_col], f, mat->row[i][src_col]);
+}