X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=isl_mat.c;h=271c64948b36cdc45e0dcb841c2595f78c3a3020;hb=305cd3d3c297f1a4a9ce1245a0c1a1d0ce9f8a1f;hp=fb09d2302e6d2f03540f19be3b864811c40da507;hpb=b4b6def475768cd6f364246473b7125b8b4afd8a;p=platform%2Fupstream%2Fisl.git diff --git a/isl_mat.c b/isl_mat.c index fb09d23..271c649 100644 --- a/isl_mat.c +++ b/isl_mat.c @@ -7,10 +7,12 @@ * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium */ -#include "isl_dim.h" -#include "isl_seq.h" -#include "isl_mat.h" +#include +#include +#include +#include #include "isl_map_private.h" +#include struct isl_mat *isl_mat_alloc(struct isl_ctx *ctx, unsigned n_row, unsigned n_col) @@ -53,6 +55,7 @@ struct isl_mat *isl_mat_extend(struct isl_mat *mat, { int i; isl_int *old; + isl_int **row; if (!mat) return NULL; @@ -81,14 +84,14 @@ struct isl_mat *isl_mat_extend(struct isl_mat *mat, if (!mat) goto error; - assert(mat->ref == 1); old = mat->block.data; mat->block = isl_blk_extend(mat->ctx, mat->block, n_row * mat->max_col); if (isl_blk_is_error(mat->block)) goto error; - mat->row = isl_realloc_array(mat->ctx, mat->row, isl_int *, n_row); - if (!mat->row) + row = isl_realloc_array(mat->ctx, mat->row, isl_int *, n_row); + if (!row) goto error; + mat->row = row; for (i = 0; i < mat->n_row; ++i) mat->row[i] = mat->block.data + (mat->row[i] - old); @@ -202,6 +205,49 @@ void isl_mat_free(struct isl_mat *mat) free(mat); } +int isl_mat_rows(__isl_keep isl_mat *mat) +{ + return mat ? mat->n_row : -1; +} + +int isl_mat_cols(__isl_keep isl_mat *mat) +{ + return mat ? mat->n_col : -1; +} + +int isl_mat_get_element(__isl_keep isl_mat *mat, int row, int col, isl_int *v) +{ + if (!mat) + return -1; + if (row < 0 || row >= mat->n_row) + isl_die(mat->ctx, isl_error_invalid, "row out of range", + return -1); + if (col < 0 || col >= mat->n_col) + isl_die(mat->ctx, isl_error_invalid, "column out of range", + return -1); + isl_int_set(*v, mat->row[row][col]); + return 0; +} + +__isl_give isl_mat *isl_mat_set_element(__isl_take isl_mat *mat, + int row, int col, isl_int v) +{ + mat = isl_mat_cow(mat); + if (!mat) + return NULL; + if (row < 0 || row >= mat->n_row) + isl_die(mat->ctx, isl_error_invalid, "row out of range", + goto error); + if (col < 0 || col >= mat->n_col) + isl_die(mat->ctx, isl_error_invalid, "column out of range", + goto error); + isl_int_set(mat->row[row][col], v); + return mat; +error: + isl_mat_free(mat); + return NULL; +} + struct isl_mat *isl_mat_identity(struct isl_ctx *ctx, unsigned n_row) { int i; @@ -813,6 +859,7 @@ struct isl_mat *isl_mat_right_inverse(struct isl_mat *mat) return inv; error: isl_mat_free(mat); + isl_mat_free(inv); return NULL; } @@ -976,10 +1023,11 @@ struct isl_basic_set *isl_basic_set_preimage(struct isl_basic_set *bset, 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); - else if (mat->n_col < mat->n_row) { + if (mat->n_col > mat->n_row) { + bset = isl_basic_set_extend(bset, 0, mat->n_col-1, 0, 0, 0); + if (!bset) + goto error; + } else if (mat->n_col < mat->n_row) { bset->dim = isl_dim_cow(bset->dim); if (!bset->dim) goto error; @@ -1132,6 +1180,64 @@ error: return NULL; } +__isl_give isl_mat *isl_mat_insert_zero_cols(__isl_take isl_mat *mat, + unsigned first, unsigned n) +{ + int i; + + if (!mat) + return NULL; + mat = isl_mat_insert_cols(mat, first, n); + if (!mat) + return NULL; + + for (i = 0; i < mat->n_row; ++i) + isl_seq_clr(mat->row[i] + first, n); + + return mat; +} + +__isl_give isl_mat *isl_mat_add_zero_cols(__isl_take isl_mat *mat, unsigned n) +{ + if (!mat) + return NULL; + + return isl_mat_insert_zero_cols(mat, mat->n_col, n); +} + +__isl_give isl_mat *isl_mat_insert_rows(__isl_take isl_mat *mat, + unsigned row, unsigned n) +{ + isl_mat *ext; + + if (!mat) + return NULL; + if (n == 0) + return mat; + + ext = isl_mat_alloc(mat->ctx, mat->n_row + n, mat->n_col); + if (!ext) + goto error; + + isl_mat_sub_copy(mat->ctx, ext->row, mat->row, row, 0, 0, mat->n_col); + isl_mat_sub_copy(mat->ctx, ext->row + row + n, mat->row + row, + mat->n_row - row, 0, 0, mat->n_col); + + isl_mat_free(mat); + return ext; +error: + isl_mat_free(mat); + return NULL; +} + +__isl_give isl_mat *isl_mat_add_rows(__isl_take isl_mat *mat, unsigned n) +{ + if (!mat) + return NULL; + + return isl_mat_insert_rows(mat, mat->n_row, n); +} + void isl_mat_col_submul(struct isl_mat *mat, int dst_col, isl_int f, int src_col) { @@ -1141,6 +1247,18 @@ void isl_mat_col_submul(struct isl_mat *mat, isl_int_submul(mat->row[i][dst_col], f, mat->row[i][src_col]); } +void isl_mat_col_add(__isl_keep isl_mat *mat, int dst_col, int src_col) +{ + int i; + + if (!mat) + return; + + for (i = 0; i < mat->n_row; ++i) + isl_int_add(mat->row[i][dst_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) { int i; @@ -1298,3 +1416,48 @@ error: isl_mat_free(mat); return NULL; } + +void isl_mat_gcd(__isl_keep isl_mat *mat, isl_int *gcd) +{ + int i; + isl_int g; + + isl_int_set_si(*gcd, 0); + if (!mat) + return; + + isl_int_init(g); + for (i = 0; i < mat->n_row; ++i) { + isl_seq_gcd(mat->row[i], mat->n_col, &g); + isl_int_gcd(*gcd, *gcd, g); + } + isl_int_clear(g); +} + +__isl_give isl_mat *isl_mat_scale_down(__isl_take isl_mat *mat, isl_int m) +{ + int i; + + if (!mat) + return NULL; + + for (i = 0; i < mat->n_row; ++i) + isl_seq_scale_down(mat->row[i], mat->row[i], m, mat->n_col); + + return mat; +} + +__isl_give isl_mat *isl_mat_normalize(__isl_take isl_mat *mat) +{ + isl_int gcd; + + if (!mat) + return NULL; + + isl_int_init(gcd); + isl_mat_gcd(mat, &gcd); + mat = isl_mat_scale_down(mat, gcd); + isl_int_clear(gcd); + + return mat; +}