isl_mat.c File Reference

#include "isl_dim.h"
#include "isl_seq.h"
#include "isl_mat.h"
#include "isl_map_private.h"

Go to the source code of this file.

Functions

struct isl_matisl_mat_alloc (struct isl_ctx *ctx, unsigned n_row, unsigned n_col)
struct isl_matisl_mat_extend (struct isl_ctx *ctx, struct isl_mat *mat, unsigned n_row, unsigned n_col)
struct isl_matisl_mat_sub_alloc (struct isl_ctx *ctx, isl_int **row, unsigned first_row, unsigned n_row, unsigned first_col, unsigned n_col)
void isl_mat_sub_copy (struct isl_ctx *ctx, isl_int **dst, isl_int **src, unsigned n_row, unsigned dst_col, unsigned src_col, unsigned n_col)
void isl_mat_sub_neg (struct isl_ctx *ctx, isl_int **dst, isl_int **src, unsigned n_row, unsigned dst_col, unsigned src_col, unsigned n_col)
struct isl_matisl_mat_copy (struct isl_ctx *ctx, struct isl_mat *mat)
struct isl_matisl_mat_dup (struct isl_ctx *ctx, struct isl_mat *mat)
struct isl_matisl_mat_cow (struct isl_ctx *ctx, struct isl_mat *mat)
void isl_mat_free (struct isl_ctx *ctx, struct isl_mat *mat)
struct isl_matisl_mat_identity (struct isl_ctx *ctx, unsigned n_row)
struct isl_vecisl_mat_vec_product (struct isl_ctx *ctx, struct isl_mat *mat, struct isl_vec *vec)
struct isl_matisl_mat_aff_direct_sum (struct isl_ctx *ctx, struct isl_mat *left, struct isl_mat *right)
static void exchange (struct isl_ctx *ctx, struct isl_mat *M, struct isl_mat **U, struct isl_mat **Q, unsigned row, unsigned i, unsigned 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 oppose (struct isl_ctx *ctx, struct isl_mat *M, struct isl_mat **U, struct isl_mat **Q, unsigned row, unsigned col)
struct isl_matisl_mat_left_hermite (struct isl_ctx *ctx, struct isl_mat *M, int neg, struct isl_mat **U, struct isl_mat **Q)
struct isl_matisl_mat_right_kernel (struct isl_ctx *ctx, struct isl_mat *mat)
struct isl_matisl_mat_lin_to_aff (struct isl_ctx *ctx, struct isl_mat *mat)
static int row_first_non_zero (isl_int **row, unsigned n_row, unsigned col)
static int row_abs_min_non_zero (isl_int **row, unsigned n_row, unsigned col)
static void inv_exchange (struct isl_ctx *ctx, struct isl_mat *left, struct isl_mat *right, unsigned i, unsigned j)
static void inv_oppose (struct isl_ctx *ctx, struct isl_mat *left, struct isl_mat *right, unsigned row)
static void inv_subtract (struct isl_ctx *ctx, struct isl_mat *left, struct isl_mat *right, unsigned row, unsigned i, isl_int m)
struct isl_matisl_mat_inverse_product (struct isl_ctx *ctx, struct isl_mat *left, struct isl_mat *right)
void isl_mat_col_scale (struct isl_mat *mat, unsigned col, isl_int m)
void isl_mat_col_combine (struct isl_mat *mat, unsigned dst, isl_int m1, unsigned src1, isl_int m2, unsigned src2)
struct isl_matisl_mat_right_inverse (struct isl_ctx *ctx, struct isl_mat *mat)
struct isl_matisl_mat_transpose (struct isl_ctx *ctx, struct isl_mat *mat)
struct isl_matisl_mat_swap_cols (struct isl_ctx *ctx, struct isl_mat *mat, unsigned i, unsigned j)
struct isl_matisl_mat_swap_rows (struct isl_ctx *ctx, struct isl_mat *mat, unsigned i, unsigned j)
struct isl_matisl_mat_product (struct isl_ctx *ctx, struct isl_mat *left, struct isl_mat *right)
static int preimage (struct isl_ctx *ctx, isl_int **q, unsigned n, unsigned n_div, int has_div, struct isl_mat *mat)
struct isl_basic_setisl_basic_set_preimage (struct isl_basic_set *bset, struct isl_mat *mat)
struct isl_setisl_set_preimage (struct isl_set *set, struct isl_mat *mat)
void isl_mat_dump (struct isl_ctx *ctx, struct isl_mat *mat, FILE *out, int indent)
struct isl_matisl_mat_drop_cols (struct isl_ctx *ctx, struct isl_mat *mat, unsigned col, unsigned n)
struct isl_matisl_mat_drop_rows (struct isl_ctx *ctx, struct isl_mat *mat, unsigned row, unsigned n)
void isl_mat_col_submul (struct isl_mat *mat, int dst_col, isl_int f, int src_col)
void isl_mat_col_mul (struct isl_mat *mat, int dst_col, isl_int f, int src_col)
struct isl_matisl_mat_unimodular_complete (struct isl_ctx *ctx, struct isl_mat *M, int row)


Function Documentation

struct isl_mat* isl_mat_alloc ( struct isl_ctx *  ctx,
unsigned  n_row,
unsigned  n_col 
) [read]

Definition at line 6 of file isl_mat.c.

00008 {
00009         int i;
00010         struct isl_mat *mat;
00011 
00012         mat = isl_alloc_type(ctx, struct isl_mat);
00013         if (!mat)
00014                 return NULL;
00015 
00016         mat->row = NULL;
00017         mat->block = isl_blk_alloc(ctx, n_row * n_col);
00018         if (isl_blk_is_error(mat->block))
00019                 goto error;
00020         mat->row = isl_alloc_array(ctx, isl_int *, n_row);
00021         if (!mat->row)
00022                 goto error;
00023 
00024         for (i = 0; i < n_row; ++i)
00025                 mat->row[i] = mat->block.data + i * n_col;
00026 
00027         mat->ref = 1;
00028         mat->n_row = n_row;
00029         mat->n_col = n_col;
00030         mat->flags = 0;
00031 
00032         return mat;
00033 error:
00034         isl_blk_free(ctx, mat->block);
00035         free(mat);
00036         return NULL;
00037 }

struct isl_mat* isl_mat_extend ( struct isl_ctx *  ctx,
struct isl_mat mat,
unsigned  n_row,
unsigned  n_col 
) [read]

Definition at line 39 of file isl_mat.c.

00041 {
00042         int i;
00043         isl_int *old;
00044 
00045         if (!mat)
00046                 return NULL;
00047 
00048         if (mat->n_col >= n_col && mat->n_row >= n_row)
00049                 return mat;
00050 
00051         if (mat->n_col < n_col) {
00052                 struct isl_mat *new_mat;
00053 
00054                 new_mat = isl_mat_alloc(ctx, n_row, n_col);
00055                 if (!new_mat)
00056                         goto error;
00057                 for (i = 0; i < mat->n_row; ++i)
00058                         isl_seq_cpy(new_mat->row[i], mat->row[i], mat->n_col);
00059                 isl_mat_free(ctx, mat);
00060                 return new_mat;
00061         }
00062 
00063         mat = isl_mat_cow(ctx, mat);
00064         if (!mat)
00065                 goto error;
00066 
00067         assert(mat->ref == 1);
00068         old = mat->block.data;
00069         mat->block = isl_blk_extend(ctx, mat->block, n_row * mat->n_col);
00070         if (isl_blk_is_error(mat->block))
00071                 goto error;
00072         mat->row = isl_realloc_array(ctx, mat->row, isl_int *, n_row);
00073         if (!mat->row)
00074                 goto error;
00075 
00076         for (i = 0; i < mat->n_row; ++i)
00077                 mat->row[i] = mat->block.data + (mat->row[i] - old);
00078         for (i = mat->n_row; i < n_row; ++i)
00079                 mat->row[i] = mat->block.data + i * mat->n_col;
00080         mat->n_row = n_row;
00081 
00082         return mat;
00083 error:
00084         isl_mat_free(ctx, mat);
00085         return NULL;
00086 }

struct isl_mat* isl_mat_sub_alloc ( struct isl_ctx *  ctx,
isl_int **  row,
unsigned  first_row,
unsigned  n_row,
unsigned  first_col,
unsigned  n_col 
) [read]

Definition at line 88 of file isl_mat.c.

00090 {
00091         int i;
00092         struct isl_mat *mat;
00093 
00094         mat = isl_alloc_type(ctx, struct isl_mat);
00095         if (!mat)
00096                 return NULL;
00097         mat->row = isl_alloc_array(ctx, isl_int *, n_row);
00098         if (!mat->row)
00099                 goto error;
00100         for (i = 0; i < n_row; ++i)
00101                 mat->row[i] = row[first_row+i] + first_col;
00102         mat->ref = 1;
00103         mat->n_row = n_row;
00104         mat->n_col = n_col;
00105         mat->block = isl_blk_empty();
00106         mat->flags = ISL_MAT_BORROWED;
00107         return mat;
00108 error:
00109         free(mat);
00110         return NULL;
00111 }

void isl_mat_sub_copy ( struct isl_ctx *  ctx,
isl_int **  dst,
isl_int **  src,
unsigned  n_row,
unsigned  dst_col,
unsigned  src_col,
unsigned  n_col 
)

Definition at line 113 of file isl_mat.c.

00115 {
00116         int i;
00117 
00118         for (i = 0; i < n_row; ++i)
00119                 isl_seq_cpy(dst[i]+dst_col, src[i]+src_col, n_col);
00120 }

void isl_mat_sub_neg ( struct isl_ctx *  ctx,
isl_int **  dst,
isl_int **  src,
unsigned  n_row,
unsigned  dst_col,
unsigned  src_col,
unsigned  n_col 
)

Definition at line 122 of file isl_mat.c.

00124 {
00125         int i;
00126 
00127         for (i = 0; i < n_row; ++i)
00128                 isl_seq_neg(dst[i]+dst_col, src[i]+src_col, n_col);
00129 }

struct isl_mat* isl_mat_copy ( struct isl_ctx *  ctx,
struct isl_mat mat 
) [read]

Definition at line 131 of file isl_mat.c.

00132 {
00133         if (!mat)
00134                 return NULL;
00135 
00136         mat->ref++;
00137         return mat;
00138 }

struct isl_mat* isl_mat_dup ( struct isl_ctx *  ctx,
struct isl_mat mat 
) [read]

Definition at line 140 of file isl_mat.c.

00141 {
00142         int i;
00143         struct isl_mat *mat2;
00144 
00145         if (!mat)
00146                 return NULL;
00147         mat2 = isl_mat_alloc(ctx, mat->n_row, mat->n_col);
00148         if (!mat2)
00149                 return NULL;
00150         for (i = 0; i < mat->n_row; ++i)
00151                 isl_seq_cpy(mat2->row[i], mat->row[i], mat->n_col);
00152         return mat2;
00153 }

struct isl_mat* isl_mat_cow ( struct isl_ctx *  ctx,
struct isl_mat mat 
) [read]

Definition at line 155 of file isl_mat.c.

00156 {
00157         struct isl_mat *mat2;
00158         if (!mat)
00159                 return NULL;
00160 
00161         if (mat->ref == 1 && !ISL_F_ISSET(mat, ISL_MAT_BORROWED))
00162                 return mat;
00163 
00164         mat2 = isl_mat_dup(ctx, mat);
00165         isl_mat_free(ctx, mat);
00166         return mat2;
00167 }

void isl_mat_free ( struct isl_ctx *  ctx,
struct isl_mat mat 
)

Definition at line 169 of file isl_mat.c.

00170 {
00171         if (!mat)
00172                 return;
00173 
00174         if (--mat->ref > 0)
00175                 return;
00176 
00177         if (!ISL_F_ISSET(mat, ISL_MAT_BORROWED))
00178                 isl_blk_free(ctx, mat->block);
00179         free(mat->row);
00180         free(mat);
00181 }

struct isl_mat* isl_mat_identity ( struct isl_ctx *  ctx,
unsigned  n_row 
) [read]

Definition at line 183 of file isl_mat.c.

00184 {
00185         int i;
00186         struct isl_mat *mat;
00187 
00188         mat = isl_mat_alloc(ctx, n_row, n_row);
00189         if (!mat)
00190                 return NULL;
00191         for (i = 0; i < n_row; ++i) {
00192                 isl_seq_clr(mat->row[i], i);
00193                 isl_int_set_si(mat->row[i][i], 1);
00194                 isl_seq_clr(mat->row[i]+i+1, n_row-(i+1));
00195         }
00196 
00197         return mat;
00198 }

struct isl_vec* isl_mat_vec_product ( struct isl_ctx *  ctx,
struct isl_mat mat,
struct isl_vec vec 
) [read]

Definition at line 200 of file isl_mat.c.

00202 {
00203         int i;
00204         struct isl_vec *prod;
00205 
00206         if (!mat || !vec)
00207                 goto error;
00208 
00209         isl_assert(ctx, mat->n_col == vec->size, goto error);
00210 
00211         prod = isl_vec_alloc(ctx, mat->n_row);
00212         if (!prod)
00213                 goto error;
00214 
00215         for (i = 0; i < prod->size; ++i)
00216                 isl_seq_inner_product(mat->row[i], vec->block.data, vec->size,
00217                                         &prod->block.data[i]);
00218         isl_mat_free(ctx, mat);
00219         isl_vec_free(ctx, vec);
00220         return prod;
00221 error:
00222         isl_mat_free(ctx, mat);
00223         isl_vec_free(ctx, vec);
00224         return NULL;
00225 }

struct isl_mat* isl_mat_aff_direct_sum ( struct isl_ctx *  ctx,
struct isl_mat left,
struct isl_mat right 
) [read]

Definition at line 227 of file isl_mat.c.

00229 {
00230         int i;
00231         struct isl_mat *sum;
00232 
00233         if (!left || !right)
00234                 goto error;
00235 
00236         isl_assert(ctx, left->n_row == right->n_row, goto error);
00237         isl_assert(ctx, left->n_row >= 1, goto error);
00238         isl_assert(ctx, left->n_col >= 1, goto error);
00239         isl_assert(ctx, right->n_col >= 1, goto error);
00240         isl_assert(ctx,
00241             isl_seq_first_non_zero(left->row[0]+1, left->n_col-1) == -1,
00242             goto error);
00243         isl_assert(ctx,
00244             isl_seq_first_non_zero(right->row[0]+1, right->n_col-1) == -1,
00245             goto error);
00246 
00247         sum = isl_mat_alloc(ctx, left->n_row, left->n_col + right->n_col - 1);
00248         if (!sum)
00249                 goto error;
00250         isl_int_lcm(sum->row[0][0], left->row[0][0], right->row[0][0]);
00251         isl_int_divexact(left->row[0][0], sum->row[0][0], left->row[0][0]);
00252         isl_int_divexact(right->row[0][0], sum->row[0][0], right->row[0][0]);
00253 
00254         isl_seq_clr(sum->row[0]+1, sum->n_col-1);
00255         for (i = 1; i < sum->n_row; ++i) {
00256                 isl_int_mul(sum->row[i][0], left->row[0][0], left->row[i][0]);
00257                 isl_int_addmul(sum->row[i][0],
00258                                 right->row[0][0], right->row[i][0]);
00259                 isl_seq_scale(sum->row[i]+1, left->row[i]+1, left->row[0][0],
00260                                 left->n_col-1);
00261                 isl_seq_scale(sum->row[i]+left->n_col,
00262                                 right->row[i]+1, right->row[0][0],
00263                                 right->n_col-1);
00264         }
00265 
00266         isl_int_divexact(left->row[0][0], sum->row[0][0], left->row[0][0]);
00267         isl_int_divexact(right->row[0][0], sum->row[0][0], right->row[0][0]);
00268         isl_mat_free(ctx, left);
00269         isl_mat_free(ctx, right);
00270         return sum;
00271 error:
00272         isl_mat_free(ctx, left);
00273         isl_mat_free(ctx, right);
00274         return NULL;
00275 }

static void exchange ( struct isl_ctx *  ctx,
struct isl_mat M,
struct isl_mat **  U,
struct isl_mat **  Q,
unsigned  row,
unsigned  i,
unsigned  j 
) [static]

Definition at line 277 of file isl_mat.c.

00279 {
00280         int r;
00281         for (r = row; r < M->n_row; ++r)
00282                 isl_int_swap(M->row[r][i], M->row[r][j]);
00283         if (U) {
00284                 for (r = 0; r < (*U)->n_row; ++r)
00285                         isl_int_swap((*U)->row[r][i], (*U)->row[r][j]);
00286         }
00287         if (Q)
00288                 isl_mat_swap_rows(ctx, *Q, i, j);
00289 }

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]

Definition at line 291 of file isl_mat.c.

00293 {
00294         int r;
00295         for (r = row; r < M->n_row; ++r)
00296                 isl_int_submul(M->row[r][j], m, M->row[r][i]);
00297         if (U) {
00298                 for (r = 0; r < (*U)->n_row; ++r)
00299                         isl_int_submul((*U)->row[r][j], m, (*U)->row[r][i]);
00300         }
00301         if (Q) {
00302                 for (r = 0; r < (*Q)->n_col; ++r)
00303                         isl_int_addmul((*Q)->row[i][r], m, (*Q)->row[j][r]);
00304         }
00305 }

static void oppose ( struct isl_ctx *  ctx,
struct isl_mat M,
struct isl_mat **  U,
struct isl_mat **  Q,
unsigned  row,
unsigned  col 
) [static]

Definition at line 307 of file isl_mat.c.

00309 {
00310         int r;
00311         for (r = row; r < M->n_row; ++r)
00312                 isl_int_neg(M->row[r][col], M->row[r][col]);
00313         if (U) {
00314                 for (r = 0; r < (*U)->n_row; ++r)
00315                         isl_int_neg((*U)->row[r][col], (*U)->row[r][col]);
00316         }
00317         if (Q)
00318                 isl_seq_neg((*Q)->row[col], (*Q)->row[col], (*Q)->n_col);
00319 }

struct isl_mat* isl_mat_left_hermite ( struct isl_ctx *  ctx,
struct isl_mat M,
int  neg,
struct isl_mat **  U,
struct isl_mat **  Q 
) [read]

Definition at line 333 of file isl_mat.c.

00335 {
00336         isl_int c;
00337         int row, col;
00338 
00339         if (U)
00340                 *U = NULL;
00341         if (Q)
00342                 *Q = NULL;
00343         if (!M)
00344                 goto error;
00345         M = isl_mat_cow(ctx, M);
00346         if (!M)
00347                 goto error;
00348         if (U) {
00349                 *U = isl_mat_identity(ctx, M->n_col);
00350                 if (!*U)
00351                         goto error;
00352         }
00353         if (Q) {
00354                 *Q = isl_mat_identity(ctx, M->n_col);
00355                 if (!*Q)
00356                         goto error;
00357         }
00358 
00359         col = 0;
00360         isl_int_init(c);
00361         for (row = 0; row < M->n_row; ++row) {
00362                 int first, i, off;
00363                 first = isl_seq_abs_min_non_zero(M->row[row]+col, M->n_col-col);
00364                 if (first == -1)
00365                         continue;
00366                 first += col;
00367                 if (first != col)
00368                         exchange(ctx, M, U, Q, row, first, col);
00369                 if (isl_int_is_neg(M->row[row][col]))
00370                         oppose(ctx, M, U, Q, row, col);
00371                 first = col+1;
00372                 while ((off = isl_seq_first_non_zero(M->row[row]+first,
00373                                                        M->n_col-first)) != -1) {
00374                         first += off;
00375                         isl_int_fdiv_q(c, M->row[row][first], M->row[row][col]);
00376                         subtract(M, U, Q, row, col, first, c);
00377                         if (!isl_int_is_zero(M->row[row][first]))
00378                                 exchange(ctx, M, U, Q, row, first, col);
00379                         else
00380                                 ++first;
00381                 }
00382                 for (i = 0; i < col; ++i) {
00383                         if (isl_int_is_zero(M->row[row][i]))
00384                                 continue;
00385                         if (neg)
00386                                 isl_int_cdiv_q(c, M->row[row][i], M->row[row][col]);
00387                         else
00388                                 isl_int_fdiv_q(c, M->row[row][i], M->row[row][col]);
00389                         if (isl_int_is_zero(c))
00390                                 continue;
00391                         subtract(M, U, Q, row, col, i, c);
00392                 }
00393                 ++col;
00394         }
00395         isl_int_clear(c);
00396 
00397         return M;
00398 error:
00399         if (Q) {
00400                 isl_mat_free(ctx, *Q);
00401                 *Q = NULL;
00402         }
00403         if (U) {
00404                 isl_mat_free(ctx, *U);
00405                 *U = NULL;
00406         }
00407         return NULL;
00408 }

struct isl_mat* isl_mat_right_kernel ( struct isl_ctx *  ctx,
struct isl_mat mat 
) [read]

Definition at line 410 of file isl_mat.c.

00411 {
00412         int i, rank;
00413         struct isl_mat *U = NULL;
00414         struct isl_mat *K;
00415 
00416         mat = isl_mat_left_hermite(ctx, mat, 0, &U, NULL);
00417         if (!mat || !U)
00418                 goto error;
00419 
00420         for (i = 0, rank = 0; rank < mat->n_col; ++rank) {
00421                 while (i < mat->n_row && isl_int_is_zero(mat->row[i][rank]))
00422                         ++i;
00423                 if (i >= mat->n_row)
00424                         break;
00425         }
00426         K = isl_mat_alloc(ctx, U->n_row, U->n_col - rank);
00427         if (!K)
00428                 goto error;
00429         isl_mat_sub_copy(ctx, K->row, U->row, U->n_row, 0, rank, U->n_col-rank);
00430         isl_mat_free(ctx, mat);
00431         isl_mat_free(ctx, U);
00432         return K;
00433 error:
00434         isl_mat_free(ctx, mat);
00435         isl_mat_free(ctx, U);
00436         return NULL;
00437 }

struct isl_mat* isl_mat_lin_to_aff ( struct isl_ctx *  ctx,
struct isl_mat mat 
) [read]

Definition at line 439 of file isl_mat.c.

00440 {
00441         int i;
00442         struct isl_mat *mat2;
00443 
00444         if (!mat)
00445                 return NULL;
00446         mat2 = isl_mat_alloc(ctx, 1+mat->n_row, 1+mat->n_col);
00447         if (!mat2)
00448                 return NULL;
00449         isl_int_set_si(mat2->row[0][0], 1);
00450         isl_seq_clr(mat2->row[0]+1, mat->n_col);
00451         for (i = 0; i < mat->n_row; ++i) {
00452                 isl_int_set_si(mat2->row[1+i][0], 0);
00453                 isl_seq_cpy(mat2->row[1+i]+1, mat->row[i], mat->n_col);
00454         }
00455         isl_mat_free(ctx, mat);
00456         return mat2;
00457 }

static int row_first_non_zero ( isl_int **  row,
unsigned  n_row,
unsigned  col 
) [static]

Definition at line 459 of file isl_mat.c.

00460 {
00461         int i;
00462 
00463         for (i = 0; i < n_row; ++i)
00464                 if (!isl_int_is_zero(row[i][col]))
00465                         return i;
00466         return -1;
00467 }

static int row_abs_min_non_zero ( isl_int **  row,
unsigned  n_row,
unsigned  col 
) [static]

Definition at line 469 of file isl_mat.c.

00470 {
00471         int i, min = row_first_non_zero(row, n_row, col);
00472         if (min < 0)
00473                 return -1;
00474         for (i = min + 1; i < n_row; ++i) {
00475                 if (isl_int_is_zero(row[i][col]))
00476                         continue;
00477                 if (isl_int_abs_lt(row[i][col], row[min][col]))
00478                         min = i;
00479         }
00480         return min;
00481 }

static void inv_exchange ( struct isl_ctx *  ctx,
struct isl_mat left,
struct isl_mat right,
unsigned  i,
unsigned  j 
) [static]

Definition at line 483 of file isl_mat.c.

00486 {
00487         left = isl_mat_swap_rows(ctx, left, i, j);
00488         right = isl_mat_swap_rows(ctx, right, i, j);
00489 }

static void inv_oppose ( struct isl_ctx *  ctx,
struct isl_mat left,
struct isl_mat right,
unsigned  row 
) [static]

Definition at line 491 of file isl_mat.c.

00493 {
00494         isl_seq_neg(left->row[row]+row, left->row[row]+row, left->n_col-row);
00495         isl_seq_neg(right->row[row], right->row[row], right->n_col);
00496 }

static void inv_subtract ( struct isl_ctx *  ctx,
struct isl_mat left,
struct isl_mat right,
unsigned  row,
unsigned  i,
isl_int  m 
) [static]

Definition at line 498 of file isl_mat.c.

00501 {
00502         isl_int_neg(m, m);
00503         isl_seq_combine(left->row[i]+row,
00504                         ctx->one, left->row[i]+row,
00505                         m, left->row[row]+row,
00506                         left->n_col-row);
00507         isl_seq_combine(right->row[i], ctx->one, right->row[i],
00508                         m, right->row[row], right->n_col);
00509 }

struct isl_mat* isl_mat_inverse_product ( struct isl_ctx *  ctx,
struct isl_mat left,
struct isl_mat right 
) [read]

Definition at line 513 of file isl_mat.c.

00515 {
00516         int row;
00517         isl_int a, b;
00518 
00519         if (!left || !right)
00520                 goto error;
00521 
00522         isl_assert(ctx, left->n_row == left->n_col, goto error);
00523         isl_assert(ctx, left->n_row == right->n_row, goto error);
00524 
00525         if (left->n_row == 0) {
00526                 isl_mat_free(ctx, left);
00527                 return right;
00528         }
00529 
00530         left = isl_mat_cow(ctx, left);
00531         right = isl_mat_cow(ctx, right);
00532         if (!left || !right)
00533                 goto error;
00534 
00535         isl_int_init(a);
00536         isl_int_init(b);
00537         for (row = 0; row < left->n_row; ++row) {
00538                 int pivot, first, i, off;
00539                 pivot = row_abs_min_non_zero(left->row+row, left->n_row-row, row);
00540                 if (pivot < 0) {
00541                         isl_int_clear(a);
00542                         isl_int_clear(b);
00543                         isl_assert(ctx, pivot >= 0, goto error);
00544                 }
00545                 pivot += row;
00546                 if (pivot != row)
00547                         inv_exchange(ctx, left, right, pivot, row);
00548                 if (isl_int_is_neg(left->row[row][row]))
00549                         inv_oppose(ctx, left, right, row);
00550                 first = row+1;
00551                 while ((off = row_first_non_zero(left->row+first,
00552                                         left->n_row-first, row)) != -1) {
00553                         first += off;
00554                         isl_int_fdiv_q(a, left->row[first][row],
00555                                         left->row[row][row]);
00556                         inv_subtract(ctx, left, right, row, first, a);
00557                         if (!isl_int_is_zero(left->row[first][row]))
00558                                 inv_exchange(ctx, left, right, row, first);
00559                         else
00560                                 ++first;
00561                 }
00562                 for (i = 0; i < row; ++i) {
00563                         if (isl_int_is_zero(left->row[i][row]))
00564                                 continue;
00565                         isl_int_gcd(a, left->row[row][row], left->row[i][row]);
00566                         isl_int_divexact(b, left->row[i][row], a);
00567                         isl_int_divexact(a, left->row[row][row], a);
00568                         isl_int_neg(a, a);
00569                         isl_seq_combine(left->row[i]+row,
00570                                         a, left->row[i]+row,
00571                                         b, left->row[row]+row,
00572                                         left->n_col-row);
00573                         isl_seq_combine(right->row[i], a, right->row[i],
00574                                         b, right->row[row], right->n_col);
00575                 }
00576         }
00577         isl_int_clear(b);
00578 
00579         isl_int_set(a, left->row[0][0]);
00580         for (row = 1; row < left->n_row; ++row)
00581                 isl_int_lcm(a, a, left->row[row][row]);
00582         if (isl_int_is_zero(a)){
00583                 isl_int_clear(a);
00584                 isl_assert(ctx, 0, goto error);
00585         }
00586         for (row = 0; row < left->n_row; ++row) {
00587                 isl_int_divexact(left->row[row][row], a, left->row[row][row]);
00588                 if (isl_int_is_one(left->row[row][row]))
00589                         continue;
00590                 isl_seq_scale(right->row[row], right->row[row],
00591                                 left->row[row][row], right->n_col);
00592         }
00593         isl_int_clear(a);
00594 
00595         isl_mat_free(ctx, left);
00596         return right;
00597 error:
00598         isl_mat_free(ctx, left);
00599         isl_mat_free(ctx, right);
00600         return NULL;
00601 }

void isl_mat_col_scale ( struct isl_mat mat,
unsigned  col,
isl_int  m 
)

Definition at line 603 of file isl_mat.c.

00604 {
00605         int i;
00606 
00607         for (i = 0; i < mat->n_row; ++i)
00608                 isl_int_mul(mat->row[i][col], mat->row[i][col], m);
00609 }

void isl_mat_col_combine ( struct isl_mat mat,
unsigned  dst,
isl_int  m1,
unsigned  src1,
isl_int  m2,
unsigned  src2 
)

Definition at line 611 of file isl_mat.c.

00613 {
00614         int i;
00615         isl_int tmp;
00616 
00617         isl_int_init(tmp);
00618         for (i = 0; i < mat->n_row; ++i) {
00619                 isl_int_mul(tmp, m1, mat->row[i][src1]);
00620                 isl_int_addmul(tmp, m2, mat->row[i][src2]);
00621                 isl_int_set(mat->row[i][dst], tmp);
00622         }
00623         isl_int_clear(tmp);
00624 }

struct isl_mat* isl_mat_right_inverse ( struct isl_ctx *  ctx,
struct isl_mat mat 
) [read]

Definition at line 626 of file isl_mat.c.

00628 {
00629         struct isl_mat *inv;
00630         int row;
00631         isl_int a, b;
00632 
00633         mat = isl_mat_cow(ctx, mat);
00634         if (!mat)
00635                 return NULL;
00636 
00637         inv = isl_mat_identity(ctx, mat->n_col);
00638         inv = isl_mat_cow(ctx, inv);
00639         if (!inv)
00640                 goto error;
00641 
00642         isl_int_init(a);
00643         isl_int_init(b);
00644         for (row = 0; row < mat->n_row; ++row) {
00645                 int pivot, first, i, off;
00646                 pivot = isl_seq_abs_min_non_zero(mat->row[row]+row, mat->n_col-row);
00647                 if (pivot < 0) {
00648                         isl_int_clear(a);
00649                         isl_int_clear(b);
00650                         goto error;
00651                 }
00652                 pivot += row;
00653                 if (pivot != row)
00654                         exchange(ctx, mat, &inv, NULL, row, pivot, row);
00655                 if (isl_int_is_neg(mat->row[row][row]))
00656                         oppose(ctx, mat, &inv, NULL, row, row);
00657                 first = row+1;
00658                 while ((off = isl_seq_first_non_zero(mat->row[row]+first,
00659                                                     mat->n_col-first)) != -1) {
00660                         first += off;
00661                         isl_int_fdiv_q(a, mat->row[row][first],
00662                                                     mat->row[row][row]);
00663                         subtract(mat, &inv, NULL, row, row, first, a);
00664                         if (!isl_int_is_zero(mat->row[row][first]))
00665                                 exchange(ctx, mat, &inv, NULL, row, row, first);
00666                         else
00667                                 ++first;
00668                 }
00669                 for (i = 0; i < row; ++i) {
00670                         if (isl_int_is_zero(mat->row[row][i]))
00671                                 continue;
00672                         isl_int_gcd(a, mat->row[row][row], mat->row[row][i]);
00673                         isl_int_divexact(b, mat->row[row][i], a);
00674                         isl_int_divexact(a, mat->row[row][row], a);
00675                         isl_int_neg(a, a);
00676                         isl_mat_col_combine(mat, i, a, i, b, row);
00677                         isl_mat_col_combine(inv, i, a, i, b, row);
00678                 }
00679         }
00680         isl_int_clear(b);
00681 
00682         isl_int_set(a, mat->row[0][0]);
00683         for (row = 1; row < mat->n_row; ++row)
00684                 isl_int_lcm(a, a, mat->row[row][row]);
00685         if (isl_int_is_zero(a)){
00686                 isl_int_clear(a);
00687                 goto error;
00688         }
00689         for (row = 0; row < mat->n_row; ++row) {
00690                 isl_int_divexact(mat->row[row][row], a, mat->row[row][row]);
00691                 if (isl_int_is_one(mat->row[row][row]))
00692                         continue;
00693                 isl_mat_col_scale(inv, row, mat->row[row][row]);
00694         }
00695         isl_int_clear(a);
00696 
00697         isl_mat_free(ctx, mat);
00698 
00699         return inv;
00700 error:
00701         isl_mat_free(ctx, mat);
00702         return NULL;
00703 }

struct isl_mat* isl_mat_transpose ( struct isl_ctx *  ctx,
struct isl_mat mat 
) [read]

Definition at line 705 of file isl_mat.c.

00706 {
00707         struct isl_mat *transpose = NULL;
00708         int i, j;
00709 
00710         if (mat->n_col == mat->n_row) {
00711                 mat = isl_mat_cow(ctx, mat);
00712                 if (!mat)
00713                         return NULL;
00714                 for (i = 0; i < mat->n_row; ++i)
00715                         for (j = i + 1; j < mat->n_col; ++j)
00716                                 isl_int_swap(mat->row[i][j], mat->row[j][i]);
00717                 return mat;
00718         }
00719         transpose = isl_mat_alloc(ctx, mat->n_col, mat->n_row);
00720         if (!transpose)
00721                 goto error;
00722         for (i = 0; i < mat->n_row; ++i)
00723                 for (j = 0; j < mat->n_col; ++j)
00724                         isl_int_set(transpose->row[j][i], mat->row[i][j]);
00725         isl_mat_free(ctx, mat);
00726         return transpose;
00727 error:
00728         isl_mat_free(ctx, mat);
00729         return NULL;
00730 }

struct isl_mat* isl_mat_swap_cols ( struct isl_ctx *  ctx,
struct isl_mat mat,
unsigned  i,
unsigned  j 
) [read]

Definition at line 732 of file isl_mat.c.

00734 {
00735         int r;
00736 
00737         mat = isl_mat_cow(ctx, mat);
00738         if (!mat)
00739                 return NULL;
00740         isl_assert(ctx, i < mat->n_col, goto error);
00741         isl_assert(ctx, j < mat->n_col, goto error);
00742 
00743         for (r = 0; r < mat->n_row; ++r)
00744                 isl_int_swap(mat->row[r][i], mat->row[r][j]);
00745         return mat;
00746 error:
00747         isl_mat_free(ctx, mat);
00748         return NULL;
00749 }

struct isl_mat* isl_mat_swap_rows ( struct isl_ctx *  ctx,
struct isl_mat mat,
unsigned  i,
unsigned  j 
) [read]

Definition at line 751 of file isl_mat.c.

00753 {
00754         isl_int *t;
00755 
00756         if (!mat)
00757                 return NULL;
00758         mat = isl_mat_cow(ctx, mat);
00759         if (!mat)
00760                 return NULL;
00761         t = mat->row[i];
00762         mat->row[i] = mat->row[j];
00763         mat->row[j] = t;
00764         return mat;
00765 }

struct isl_mat* isl_mat_product ( struct isl_ctx *  ctx,
struct isl_mat left,
struct isl_mat right 
) [read]

Definition at line 767 of file isl_mat.c.

00769 {
00770         int i, j, k;
00771         struct isl_mat *prod;
00772 
00773         if (!left || !right)
00774                 goto error;
00775         isl_assert(ctx, left->n_col == right->n_row, goto error);
00776         prod = isl_mat_alloc(ctx, left->n_row, right->n_col);
00777         if (!prod)
00778                 goto error;
00779         if (left->n_col == 0) {
00780                 for (i = 0; i < prod->n_row; ++i)
00781                         isl_seq_clr(prod->row[i], prod->n_col);
00782                 return prod;
00783         }
00784         for (i = 0; i < prod->n_row; ++i) {
00785                 for (j = 0; j < prod->n_col; ++j) {
00786                         isl_int_mul(prod->row[i][j],
00787                                     left->row[i][0], right->row[0][j]);
00788                         for (k = 1; k < left->n_col; ++k)
00789                                 isl_int_addmul(prod->row[i][j],
00790                                             left->row[i][k], right->row[k][j]);
00791                 }
00792         }
00793         isl_mat_free(ctx, left);
00794         isl_mat_free(ctx, right);
00795         return prod;
00796 error:
00797         isl_mat_free(ctx, left);
00798         isl_mat_free(ctx, right);
00799         return NULL;
00800 }

static int preimage ( struct isl_ctx *  ctx,
isl_int **  q,
unsigned  n,
unsigned  n_div,
int  has_div,
struct isl_mat mat 
) [static]

Definition at line 813 of file isl_mat.c.

00815 {
00816         int i;
00817         struct isl_mat *t;
00818         int e;
00819 
00820         if (mat->n_col >= mat->n_row)
00821                 e = 0;
00822         else
00823                 e = mat->n_row - mat->n_col;
00824         if (has_div)
00825                 for (i = 0; i < n; ++i)
00826                         isl_int_mul(q[i][0], q[i][0], mat->row[0][0]);
00827         t = isl_mat_sub_alloc(ctx, q, 0, n, has_div, mat->n_row);
00828         t = isl_mat_product(ctx, t, mat);
00829         if (!t)
00830                 return -1;
00831         for (i = 0; i < n; ++i) {
00832                 isl_seq_swp_or_cpy(q[i] + has_div, t->row[i], t->n_col);
00833                 isl_seq_cpy(q[i] + has_div + t->n_col,
00834                             q[i] + has_div + t->n_col + e, n_div);
00835                 isl_seq_clr(q[i] + has_div + t->n_col + n_div, e);
00836         }
00837         isl_mat_free(ctx, t);
00838         return 0;
00839 }

struct isl_basic_set* isl_basic_set_preimage ( struct isl_basic_set bset,
struct isl_mat mat 
) [read]

Definition at line 851 of file isl_mat.c.

00853 {
00854         struct isl_ctx *ctx;
00855 
00856         if (!bset || !mat)
00857                 goto error;
00858 
00859         ctx = bset->ctx;
00860         bset = isl_basic_set_cow(bset);
00861         if (!bset)
00862                 goto error;
00863 
00864         isl_assert(ctx, bset->dim->nparam == 0, goto error);
00865         isl_assert(ctx, 1+bset->dim->n_out == mat->n_row, goto error);
00866 
00867         if (mat->n_col > mat->n_row)
00868                 bset = isl_basic_set_extend(bset, 0, mat->n_col-1, 0,
00869                                                 0, 0);
00870         else if (mat->n_col < mat->n_row) {
00871                 bset->dim = isl_dim_cow(bset->dim);
00872                 if (!bset->dim)
00873                         goto error;
00874                 bset->dim->n_out -= mat->n_row - mat->n_col;
00875         }
00876 
00877         if (preimage(ctx, bset->eq, bset->n_eq, bset->n_div, 0,
00878                         isl_mat_copy(ctx, mat)) < 0)
00879                 goto error;
00880 
00881         if (preimage(ctx, bset->ineq, bset->n_ineq, bset->n_div, 0,
00882                         isl_mat_copy(ctx, mat)) < 0)
00883                 goto error;
00884 
00885         if (preimage(ctx, bset->div, bset->n_div, bset->n_div, 1, mat) < 0)
00886                 goto error2;
00887 
00888         ISL_F_CLR(bset, ISL_BASIC_SET_NO_IMPLICIT);
00889         ISL_F_CLR(bset, ISL_BASIC_SET_NO_REDUNDANT);
00890         ISL_F_CLR(bset, ISL_BASIC_SET_NORMALIZED);
00891         ISL_F_CLR(bset, ISL_BASIC_SET_NORMALIZED_DIVS);
00892         ISL_F_CLR(bset, ISL_BASIC_SET_ALL_EQUALITIES);
00893 
00894         bset = isl_basic_set_simplify(bset);
00895         bset = isl_basic_set_finalize(bset);
00896 
00897         return bset;
00898 error:
00899         isl_mat_free(ctx, mat);
00900 error2:
00901         isl_basic_set_free(bset);
00902         return NULL;
00903 }

struct isl_set* isl_set_preimage ( struct isl_set set,
struct isl_mat mat 
) [read]

Definition at line 905 of file isl_mat.c.

00906 {
00907         struct isl_ctx *ctx;
00908         int i;
00909 
00910         set = isl_set_cow(set);
00911         if (!set)
00912                 return NULL;
00913 
00914         ctx = set->ctx;
00915         for (i = 0; i < set->n; ++i) {
00916                 set->p[i] = isl_basic_set_preimage(set->p[i],
00917                                                     isl_mat_copy(ctx, mat));
00918                 if (!set->p[i])
00919                         goto error;
00920         }
00921         if (mat->n_col != mat->n_row) {
00922                 set->dim = isl_dim_cow(set->dim);
00923                 if (!set->dim)
00924                         goto error;
00925                 set->dim->n_out += mat->n_col;
00926                 set->dim->n_out -= mat->n_row;
00927         }
00928         isl_mat_free(ctx, mat);
00929         ISL_F_CLR(set, ISL_SET_NORMALIZED);
00930         return set;
00931 error:
00932         isl_set_free(set);
00933         isl_mat_free(ctx, mat);
00934         return NULL;
00935 }

void isl_mat_dump ( struct isl_ctx *  ctx,
struct isl_mat mat,
FILE *  out,
int  indent 
)

Definition at line 937 of file isl_mat.c.

00939 {
00940         int i, j;
00941 
00942         if (!mat) {
00943                 fprintf(out, "%*snull mat\n", indent, "");
00944                 return;
00945         }
00946 
00947         if (mat->n_row == 0)
00948                 fprintf(out, "%*s[]\n", indent, "");
00949 
00950         for (i = 0; i < mat->n_row; ++i) {
00951                 if (!i)
00952                         fprintf(out, "%*s[[", indent, "");
00953                 else
00954                         fprintf(out, "%*s[", indent+1, "");
00955                 for (j = 0; j < mat->n_col; ++j) {
00956                         if (j)
00957                             fprintf(out, ",");
00958                         isl_int_print(out, mat->row[i][j], 0);
00959                 }
00960                 if (i == mat->n_row-1)
00961                         fprintf(out, "]]\n");
00962                 else
00963                         fprintf(out, "]\n");
00964         }
00965 }

struct isl_mat* isl_mat_drop_cols ( struct isl_ctx *  ctx,
struct isl_mat mat,
unsigned  col,
unsigned  n 
) [read]

Definition at line 967 of file isl_mat.c.

00969 {
00970         int r;
00971 
00972         mat = isl_mat_cow(ctx, mat);
00973         if (!mat)
00974                 return NULL;
00975 
00976         if (col != mat->n_col-n) {
00977                 for (r = 0; r < mat->n_row; ++r)
00978                         isl_seq_cpy(mat->row[r]+col, mat->row[r]+col+n,
00979                                         mat->n_col - col - n);
00980         }
00981         mat->n_col -= n;
00982         return mat;
00983 }

struct isl_mat* isl_mat_drop_rows ( struct isl_ctx *  ctx,
struct isl_mat mat,
unsigned  row,
unsigned  n 
) [read]

Definition at line 985 of file isl_mat.c.

00987 {
00988         int r;
00989 
00990         mat = isl_mat_cow(ctx, mat);
00991         if (!mat)
00992                 return NULL;
00993 
00994         for (r = row; r+n < mat->n_row; ++r)
00995                 mat->row[r] = mat->row[r+n];
00996 
00997         mat->n_row -= n;
00998         return mat;
00999 }

void isl_mat_col_submul ( struct isl_mat mat,
int  dst_col,
isl_int  f,
int  src_col 
)

Definition at line 1001 of file isl_mat.c.

01003 {
01004         int i;
01005 
01006         for (i = 0; i < mat->n_row; ++i)
01007                 isl_int_submul(mat->row[i][dst_col], f, mat->row[i][src_col]);
01008 }

void isl_mat_col_mul ( struct isl_mat mat,
int  dst_col,
isl_int  f,
int  src_col 
)

Definition at line 1010 of file isl_mat.c.

01011 {
01012         int i;
01013 
01014         for (i = 0; i < mat->n_row; ++i)
01015                 isl_int_mul(mat->row[i][dst_col], f, mat->row[i][src_col]);
01016 }

struct isl_mat* isl_mat_unimodular_complete ( struct isl_ctx *  ctx,
struct isl_mat M,
int  row 
) [read]

Definition at line 1018 of file isl_mat.c.

01020 {
01021         int r;
01022         struct isl_mat *H = NULL, *Q = NULL;
01023 
01024         isl_assert(ctx, M->n_row == M->n_col, goto error);
01025         M->n_row = row;
01026         H = isl_mat_left_hermite(ctx, isl_mat_copy(ctx, M), 0, NULL, &Q);
01027         M->n_row = M->n_col;
01028         if (!H)
01029                 goto error;
01030         for (r = 0; r < row; ++r)
01031                 isl_assert(ctx, isl_int_is_one(H->row[r][r]), goto error);
01032         for (r = row; r < M->n_row; ++r)
01033                 isl_seq_cpy(M->row[r], Q->row[r], M->n_col);
01034         isl_mat_free(ctx, H);
01035         isl_mat_free(ctx, Q);
01036         return M;
01037 error:
01038         isl_mat_free(ctx, H);
01039         isl_mat_free(ctx, Q);
01040         isl_mat_free(ctx, M);
01041         return NULL;
01042 }


Generated on Fri Jul 17 16:32:58 2009 for CLooG / ISL by  doxygen 1.5.9