isl_equalities.c File Reference

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

Go to the source code of this file.

Functions

static struct isl_matparticular_solution (struct isl_ctx *ctx, struct isl_mat *B, struct isl_vec *d)
static struct isl_matparameter_compression_1 (struct isl_ctx *ctx, struct isl_mat *B, struct isl_vec *d)
static struct isl_matparameter_compression_multi (struct isl_ctx *ctx, struct isl_mat *B, struct isl_vec *d)
struct isl_matisl_mat_parameter_compression (struct isl_ctx *ctx, struct isl_mat *B, struct isl_vec *d)
struct isl_matisl_mat_variable_compression (struct isl_ctx *ctx, struct isl_mat *B, struct isl_mat **T2)
static struct isl_basic_setcompress_variables (struct isl_ctx *ctx, struct isl_basic_set *bset, struct isl_mat **T, struct isl_mat **T2)
struct isl_basic_setisl_basic_set_remove_equalities (struct isl_basic_set *bset, struct isl_mat **T, struct isl_mat **T2)
int isl_basic_set_dim_residue_class (struct isl_basic_set *bset, int pos, isl_int *modulo, isl_int *residue)


Function Documentation

static struct isl_mat* particular_solution ( struct isl_ctx *  ctx,
struct isl_mat B,
struct isl_vec d 
) [static, read]

Definition at line 52 of file isl_equalities.c.

00054 {
00055         int i, j;
00056         struct isl_mat *M = NULL;
00057         struct isl_mat *C = NULL;
00058         struct isl_mat *U = NULL;
00059         struct isl_mat *H = NULL;
00060         struct isl_mat *cst = NULL;
00061         struct isl_mat *T = NULL;
00062 
00063         M = isl_mat_alloc(ctx, B->n_row, B->n_row + B->n_col - 1);
00064         C = isl_mat_alloc(ctx, 1 + B->n_row, 1);
00065         if (!M || !C)
00066                 goto error;
00067         isl_int_set_si(C->row[0][0], 1);
00068         for (i = 0; i < B->n_row; ++i) {
00069                 isl_seq_clr(M->row[i], B->n_row);
00070                 isl_int_set(M->row[i][i], d->block.data[i]);
00071                 isl_int_neg(C->row[1 + i][0], B->row[i][0]);
00072                 isl_int_fdiv_r(C->row[1+i][0], C->row[1+i][0], M->row[i][i]);
00073                 for (j = 0; j < B->n_col - 1; ++j)
00074                         isl_int_fdiv_r(M->row[i][B->n_row + j],
00075                                         B->row[i][1 + j], M->row[i][i]);
00076         }
00077         M = isl_mat_left_hermite(ctx, M, 0, &U, NULL);
00078         if (!M || !U)
00079                 goto error;
00080         H = isl_mat_sub_alloc(ctx, M->row, 0, B->n_row, 0, B->n_row);
00081         H = isl_mat_lin_to_aff(ctx, H);
00082         C = isl_mat_inverse_product(ctx, H, C);
00083         if (!C)
00084                 goto error;
00085         for (i = 0; i < B->n_row; ++i) {
00086                 if (!isl_int_is_divisible_by(C->row[1+i][0], C->row[0][0]))
00087                         break;
00088                 isl_int_divexact(C->row[1+i][0], C->row[1+i][0], C->row[0][0]);
00089         }
00090         if (i < B->n_row)
00091                 cst = isl_mat_alloc(ctx, B->n_row, 0);
00092         else
00093                 cst = isl_mat_sub_alloc(ctx, C->row, 1, B->n_row, 0, 1);
00094         T = isl_mat_sub_alloc(ctx, U->row, B->n_row, B->n_col - 1, 0, B->n_row);
00095         cst = isl_mat_product(ctx, T, cst);
00096         isl_mat_free(ctx, M);
00097         isl_mat_free(ctx, C);
00098         isl_mat_free(ctx, U);
00099         return cst;
00100 error:
00101         isl_mat_free(ctx, M);
00102         isl_mat_free(ctx, C);
00103         isl_mat_free(ctx, U);
00104         return NULL;
00105 }

static struct isl_mat* parameter_compression_1 ( struct isl_ctx *  ctx,
struct isl_mat B,
struct isl_vec d 
) [static, read]

Definition at line 115 of file isl_equalities.c.

00117 {
00118         struct isl_mat *U;
00119 
00120         U = isl_mat_alloc(ctx, B->n_col - 1, B->n_col - 1);
00121         if (!U)
00122                 return NULL;
00123         isl_seq_cpy(U->row[0], B->row[0] + 1, B->n_col - 1);
00124         U = isl_mat_unimodular_complete(ctx, U, 1);
00125         U = isl_mat_right_inverse(ctx, U);
00126         if (!U)
00127                 return NULL;
00128         isl_mat_col_mul(U, 0, d->block.data[0], 0);
00129         U = isl_mat_lin_to_aff(ctx, U);
00130         return U;
00131 error:
00132         isl_mat_free(ctx, U);
00133         return NULL;
00134 }

static struct isl_mat* parameter_compression_multi ( struct isl_ctx *  ctx,
struct isl_mat B,
struct isl_vec d 
) [static, read]

Definition at line 149 of file isl_equalities.c.

00151 {
00152         int i, j, k;
00153         int ok;
00154         isl_int D;
00155         struct isl_mat *A = NULL, *U = NULL;
00156         struct isl_mat *T;
00157         unsigned size;
00158 
00159         isl_int_init(D);
00160 
00161         isl_vec_lcm(ctx, d, &D);
00162 
00163         size = B->n_col - 1;
00164         A = isl_mat_alloc(ctx, size, B->n_row * size);
00165         U = isl_mat_alloc(ctx, size, size);
00166         if (!U || !A)
00167                 goto error;
00168         for (i = 0; i < B->n_row; ++i) {
00169                 isl_seq_cpy(U->row[0], B->row[i] + 1, size);
00170                 U = isl_mat_unimodular_complete(ctx, U, 1);
00171                 if (!U)
00172                         goto error;
00173                 isl_int_divexact(D, D, d->block.data[i]);
00174                 for (k = 0; k < U->n_col; ++k)
00175                         isl_int_mul(A->row[k][i*size+0], D, U->row[0][k]);
00176                 isl_int_mul(D, D, d->block.data[i]);
00177                 for (j = 1; j < U->n_row; ++j)
00178                         for (k = 0; k < U->n_col; ++k)
00179                                 isl_int_mul(A->row[k][i*size+j],
00180                                                 D, U->row[j][k]);
00181         }
00182         A = isl_mat_left_hermite(ctx, A, 0, NULL, NULL);
00183         T = isl_mat_sub_alloc(ctx, A->row, 0, A->n_row, 0, A->n_row);
00184         T = isl_mat_lin_to_aff(ctx, T);
00185         isl_int_set(T->row[0][0], D);
00186         T = isl_mat_right_inverse(ctx, T);
00187         isl_assert(ctx, isl_int_is_one(T->row[0][0]), goto error);
00188         T = isl_mat_transpose(ctx, T);
00189         isl_mat_free(ctx, A);
00190         isl_mat_free(ctx, U);
00191 
00192         isl_int_clear(D);
00193         return T;
00194 error:
00195         isl_mat_free(ctx, A);
00196         isl_mat_free(ctx, U);
00197         isl_int_clear(D);
00198         return NULL;
00199 }

struct isl_mat* isl_mat_parameter_compression ( struct isl_ctx *  ctx,
struct isl_mat B,
struct isl_vec d 
) [read]

Definition at line 295 of file isl_equalities.c.

00297 {
00298         int i;
00299         struct isl_mat *cst = NULL;
00300         struct isl_mat *T = NULL;
00301         isl_int D;
00302 
00303         if (!B || !d)
00304                 goto error;
00305         isl_assert(ctx, B->n_row == d->size, goto error);
00306         cst = particular_solution(ctx, B, d);
00307         if (!cst)
00308                 goto error;
00309         if (cst->n_col == 0) {
00310                 T = isl_mat_alloc(ctx, B->n_col, 0);
00311                 isl_mat_free(ctx, cst);
00312                 isl_mat_free(ctx, B);
00313                 isl_vec_free(ctx, d);
00314                 return T;
00315         }
00316         isl_int_init(D);
00317         /* Replace a*g*row = 0 mod g*m by row = 0 mod m */
00318         for (i = 0; i < B->n_row; ++i) {
00319                 isl_seq_gcd(B->row[i] + 1, B->n_col - 1, &D);
00320                 if (isl_int_is_one(D))
00321                         continue;
00322                 if (isl_int_is_zero(D)) {
00323                         B = isl_mat_drop_rows(ctx, B, i, 1);
00324                         d = isl_vec_cow(ctx, d);
00325                         if (!B || !d)
00326                                 goto error2;
00327                         isl_seq_cpy(d->block.data+i, d->block.data+i+1,
00328                                                         d->size - (i+1));
00329                         d->size--;
00330                         i--;
00331                         continue;
00332                 }
00333                 B = isl_mat_cow(ctx, B);
00334                 if (!B)
00335                         goto error2;
00336                 isl_seq_scale_down(B->row[i] + 1, B->row[i] + 1, D, B->n_col-1);
00337                 isl_int_gcd(D, D, d->block.data[i]);
00338                 d = isl_vec_cow(ctx, d);
00339                 if (!d)
00340                         goto error2;
00341                 isl_int_divexact(d->block.data[i], d->block.data[i], D);
00342         }
00343         isl_int_clear(D);
00344         if (B->n_row == 0)
00345                 T = isl_mat_identity(ctx, B->n_col);
00346         else if (B->n_row == 1)
00347                 T = parameter_compression_1(ctx, B, d);
00348         else
00349                 T = parameter_compression_multi(ctx, B, d);
00350         T = isl_mat_left_hermite(ctx, T, 0, NULL, NULL);
00351         if (!T)
00352                 goto error;
00353         isl_mat_sub_copy(ctx, T->row + 1, cst->row, cst->n_row, 0, 0, 1);
00354         isl_mat_free(ctx, cst);
00355         isl_mat_free(ctx, B);
00356         isl_vec_free(ctx, d);
00357         return T;
00358 error2:
00359         isl_int_clear(D);
00360 error:
00361         isl_mat_free(ctx, cst);
00362         isl_mat_free(ctx, B);
00363         isl_vec_free(ctx, d);
00364         return NULL;
00365 }

struct isl_mat* isl_mat_variable_compression ( struct isl_ctx *  ctx,
struct isl_mat B,
struct isl_mat **  T2 
) [read]

Definition at line 408 of file isl_equalities.c.

00410 {
00411         int i;
00412         struct isl_mat *H = NULL, *C = NULL, *H1, *U = NULL, *U1, *U2, *TC;
00413         unsigned dim;
00414 
00415         if (T2)
00416                 *T2 = NULL;
00417         if (!B)
00418                 goto error;
00419 
00420         dim = B->n_col - 1;
00421         H = isl_mat_sub_alloc(ctx, B->row, 0, B->n_row, 1, dim);
00422         H = isl_mat_left_hermite(ctx, H, 0, &U, T2);
00423         if (!H || !U || (T2 && !*T2))
00424                 goto error;
00425         if (T2) {
00426                 *T2 = isl_mat_drop_rows(ctx, *T2, 0, B->n_row);
00427                 *T2 = isl_mat_lin_to_aff(ctx, *T2);
00428                 if (!*T2)
00429                         goto error;
00430         }
00431         C = isl_mat_alloc(ctx, 1+B->n_row, 1);
00432         if (!C)
00433                 goto error;
00434         isl_int_set_si(C->row[0][0], 1);
00435         isl_mat_sub_neg(ctx, C->row+1, B->row, B->n_row, 0, 0, 1);
00436         H1 = isl_mat_sub_alloc(ctx, H->row, 0, H->n_row, 0, H->n_row);
00437         H1 = isl_mat_lin_to_aff(ctx, H1);
00438         TC = isl_mat_inverse_product(ctx, H1, C);
00439         if (!TC)
00440                 goto error;
00441         isl_mat_free(ctx, H);
00442         if (!isl_int_is_one(TC->row[0][0])) {
00443                 for (i = 0; i < B->n_row; ++i) {
00444                         if (!isl_int_is_divisible_by(TC->row[1+i][0], TC->row[0][0])) {
00445                                 isl_mat_free(ctx, B);
00446                                 isl_mat_free(ctx, TC);
00447                                 isl_mat_free(ctx, U);
00448                                 if (T2) {
00449                                         isl_mat_free(ctx, *T2);
00450                                         *T2 = NULL;
00451                                 }
00452                                 return isl_mat_alloc(ctx, 1 + dim, 0);
00453                         }
00454                         isl_seq_scale_down(TC->row[1+i], TC->row[1+i], TC->row[0][0], 1);
00455                 }
00456                 isl_int_set_si(TC->row[0][0], 1);
00457         }
00458         U1 = isl_mat_sub_alloc(ctx, U->row, 0, U->n_row, 0, B->n_row);
00459         U1 = isl_mat_lin_to_aff(ctx, U1);
00460         U2 = isl_mat_sub_alloc(ctx, U->row, 0, U->n_row,
00461                                 B->n_row, U->n_row - B->n_row);
00462         U2 = isl_mat_lin_to_aff(ctx, U2);
00463         isl_mat_free(ctx, U);
00464         TC = isl_mat_product(ctx, U1, TC);
00465         TC = isl_mat_aff_direct_sum(ctx, TC, U2);
00466 
00467         isl_mat_free(ctx, B);
00468 
00469         return TC;
00470 error:
00471         isl_mat_free(ctx, B);
00472         isl_mat_free(ctx, H);
00473         isl_mat_free(ctx, U);
00474         if (T2) {
00475                 isl_mat_free(ctx, *T2);
00476                 *T2 = NULL;
00477         }
00478         return NULL;
00479 }

static struct isl_basic_set* compress_variables ( struct isl_ctx *  ctx,
struct isl_basic_set bset,
struct isl_mat **  T,
struct isl_mat **  T2 
) [static, read]

Definition at line 488 of file isl_equalities.c.

00490 {
00491         struct isl_mat *B, *TC;
00492         unsigned dim;
00493 
00494         if (T)
00495                 *T = NULL;
00496         if (T2)
00497                 *T2 = NULL;
00498         if (!bset)
00499                 goto error;
00500         isl_assert(ctx, isl_basic_set_n_param(bset) == 0, goto error);
00501         isl_assert(ctx, bset->n_div == 0, goto error);
00502         dim = isl_basic_set_n_dim(bset);
00503         isl_assert(ctx, bset->n_eq <= dim, goto error);
00504         if (bset->n_eq == 0)
00505                 return bset;
00506 
00507         B = isl_mat_sub_alloc(ctx, bset->eq, 0, bset->n_eq, 0, 1 + dim);
00508         TC = isl_mat_variable_compression(ctx, B, T2);
00509         if (!TC)
00510                 goto error;
00511         if (TC->n_col == 0) {
00512                 isl_mat_free(ctx, TC);
00513                 if (T2) {
00514                         isl_mat_free(ctx, *T2);
00515                         *T2 = NULL;
00516                 }
00517                 return isl_basic_set_set_to_empty(bset);
00518         }
00519 
00520         bset = isl_basic_set_preimage(bset, T ? isl_mat_copy(ctx, TC) : TC);
00521         if (T)
00522                 *T = TC;
00523         return bset;
00524 error:
00525         isl_basic_set_free(bset);
00526         return NULL;
00527 }

struct isl_basic_set* isl_basic_set_remove_equalities ( struct isl_basic_set bset,
struct isl_mat **  T,
struct isl_mat **  T2 
) [read]

Definition at line 529 of file isl_equalities.c.

00531 {
00532         if (T)
00533                 *T = NULL;
00534         if (T2)
00535                 *T2 = NULL;
00536         if (!bset)
00537                 return NULL;
00538         isl_assert(bset->ctx, isl_basic_set_n_param(bset) == 0, goto error);
00539         bset = isl_basic_set_gauss(bset, NULL);
00540         if (ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY))
00541                 return bset;
00542         bset = compress_variables(bset->ctx, bset, T, T2);
00543         return bset;
00544 error:
00545         isl_basic_set_free(bset);
00546         *T = NULL;
00547         return NULL;
00548 }

int isl_basic_set_dim_residue_class ( struct isl_basic_set bset,
int  pos,
isl_int modulo,
isl_int residue 
)

Definition at line 554 of file isl_equalities.c.

00556 {
00557         struct isl_ctx *ctx;
00558         struct isl_mat *H = NULL, *U = NULL, *C, *H1, *U1;
00559         unsigned total;
00560         unsigned nparam;
00561 
00562         if (!bset || !modulo || !residue)
00563                 return -1;
00564 
00565         ctx = bset->ctx;
00566         total = isl_basic_set_total_dim(bset);
00567         nparam = isl_basic_set_n_param(bset);
00568         H = isl_mat_sub_alloc(ctx, bset->eq, 0, bset->n_eq, 1, total);
00569         H = isl_mat_left_hermite(ctx, H, 0, &U, NULL);
00570         if (!H)
00571                 return -1;
00572 
00573         isl_seq_gcd(U->row[nparam + pos]+bset->n_eq,
00574                         total-bset->n_eq, modulo);
00575         if (isl_int_is_zero(*modulo) || isl_int_is_one(*modulo)) {
00576                 isl_int_set_si(*residue, 0);
00577                 isl_mat_free(ctx, H);
00578                 isl_mat_free(ctx, U);
00579                 return 0;
00580         }
00581 
00582         C = isl_mat_alloc(ctx, 1+bset->n_eq, 1);
00583         if (!C)
00584                 goto error;
00585         isl_int_set_si(C->row[0][0], 1);
00586         isl_mat_sub_neg(ctx, C->row+1, bset->eq, bset->n_eq, 0, 0, 1);
00587         H1 = isl_mat_sub_alloc(ctx, H->row, 0, H->n_row, 0, H->n_row);
00588         H1 = isl_mat_lin_to_aff(ctx, H1);
00589         C = isl_mat_inverse_product(ctx, H1, C);
00590         isl_mat_free(ctx, H);
00591         U1 = isl_mat_sub_alloc(ctx, U->row, nparam+pos, 1, 0, bset->n_eq);
00592         U1 = isl_mat_lin_to_aff(ctx, U1);
00593         isl_mat_free(ctx, U);
00594         C = isl_mat_product(ctx, U1, C);
00595         if (!C)
00596                 goto error;
00597         if (!isl_int_is_divisible_by(C->row[1][0], C->row[0][0])) {
00598                 bset = isl_basic_set_copy(bset);
00599                 bset = isl_basic_set_set_to_empty(bset);
00600                 isl_basic_set_free(bset);
00601                 isl_int_set_si(*modulo, 0);
00602                 isl_int_set_si(*residue, 0);
00603                 return 0;
00604         }
00605         isl_int_divexact(*residue, C->row[1][0], C->row[0][0]);
00606         isl_int_fdiv_r(*residue, *residue, *modulo);
00607         isl_mat_free(ctx, C);
00608         return 0;
00609 error:
00610         isl_mat_free(ctx, H);
00611         isl_mat_free(ctx, U);
00612         return -1;
00613 }


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