00001
00002
00003
00004 #include<polylib/polylib.h>
00005 #include <polylib/matrix_addon.h>
00006
00007
00008
00009 void split_constraints(Matrix const * M, Matrix ** Eqs, Matrix **Ineqs) {
00010 unsigned int i, j, k_eq, k_ineq, nb_eqs=0;
00011
00012
00013 for (i=0; i< M->NbRows; i++)
00014 if (value_zero_p(M->p[i][0])) nb_eqs++;
00015
00016
00017 (*Eqs) = Matrix_Alloc(nb_eqs, M->NbColumns);
00018 (*Ineqs) = Matrix_Alloc(M->NbRows-nb_eqs, M->NbColumns);
00019
00020 k_eq = k_ineq = 0;
00021 for(i=0; i< M->NbRows; i++) {
00022 if (value_zero_p(M->p[i][0]))
00023 {
00024 for(j=0; j< M->NbColumns; j++)
00025 value_assign((*Eqs)->p[k_eq][j], M->p[i][j]);
00026 k_eq++;
00027 }
00028 else
00029 {
00030 for(j=0; j< M->NbColumns; j++)
00031 value_assign((*Ineqs)->p[k_ineq][j], M->p[i][j]);
00032 k_ineq++;
00033 }
00034 }
00035 }
00036
00037
00038 Matrix * Identity_Matrix(unsigned int dim) {
00039 Matrix * ret = Matrix_Alloc(dim, dim);
00040 unsigned int i,j;
00041 for (i=0; i< dim; i++) {
00042 for (j=0; j< dim; j++) {
00043 if (i==j)
00044 { value_set_si(ret->p[i][j], 1); }
00045 else value_set_si(ret->p[i][j], 0);
00046 }
00047 }
00048 return ret;
00049 }
00050
00051
00052
00053 void mtransformation_inverse(Matrix * transf, Matrix ** inverse, Value * g) {
00054 Value factor;
00055 unsigned int i,j;
00056
00057 value_init(*g);
00058 value_set_si(*g,1);
00059
00060
00061 Matrix * tmp = Matrix_Copy(transf);
00062 Matrix * inv = Matrix_Alloc(transf->NbRows, transf->NbColumns+1);
00063 MatInverse(tmp, inv);
00064 Matrix_Free(tmp);
00065
00066
00067 (*inverse) = Matrix_Alloc(transf->NbRows, transf->NbRows);
00068 for (i=0; i< inv->NbRows; i++)
00069 Lcm3(*g, inv->p[i][inv->NbColumns-1],g);
00070 for (i=0; i< inv->NbRows; i++) {
00071 value_division(factor, *g, inv->p[i][inv->NbColumns-1]);
00072 for (j=0; j< (*inverse)->NbColumns; j++) value_multiply((*inverse)->p[i][j], inv->p[i][j], factor);
00073 }
00074
00075
00076 value_clear(factor);
00077 Matrix_Free(inv);
00078 }
00079
00080
00081
00082
00083 Matrix * mtransformation_expand_left_to_dim(Matrix * M, int new_dim) {
00084 assert(new_dim>=M->NbColumns);
00085 assert(M->NbRows==M->NbColumns);
00086 Matrix * ret = Identity_Matrix(new_dim);
00087 int offset = new_dim-M->NbRows;
00088 unsigned int i,j;
00089 for (i=0; i< M->NbRows; i++)
00090 for (j=0; j< M->NbRows; j++)
00091 value_assign(ret->p[offset+i][offset+j], M->p[i][j]);
00092 return ret;
00093 }
00094
00095
00096
00097 void mpolyhedron_simplify(Matrix * polyh) {
00098 int i, j;
00099 Value cur_gcd;
00100 value_init(cur_gcd);
00101 for (i=0; i< polyh->NbRows; i++) {
00102 value_set_si(cur_gcd, 0);
00103 for (j=1; j< polyh->NbColumns; j++) Gcd(cur_gcd, polyh->p[i][j], &cur_gcd);
00104 printf(" gcd[%d] = ", i); value_print(stdout, VALUE_FMT, cur_gcd);printf("\n");
00105 for (j=1; j< polyh->NbColumns; j++) value_division(polyh->p[i][j], polyh->p[i][j], cur_gcd);
00106 }
00107 value_clear(cur_gcd);
00108 }
00109
00110
00111
00112
00113 void mpolyhedron_inflate(Matrix * polyh, unsigned int nb_parms) {
00114 unsigned int i,j;
00115 unsigned nb_vars = polyh->NbColumns-nb_parms-2;
00116 Value infl;
00117 value_init(infl);
00118
00119 for (i=0; i< polyh->NbRows; i++) {
00120 value_set_si(infl, 0);
00121 for (j=0; j< nb_vars; j++) {
00122 if (value_sign(polyh->p[i][j])<0)
00123 value_addto(infl, infl, polyh->p[i][j]);
00124 }
00125
00126 value_subtract(polyh->p[i][polyh->NbColumns-1], polyh->p[i][polyh->NbColumns-1], infl);
00127 }
00128 value_clear(infl);
00129 }
00130
00131
00132
00133
00134 void mpolyhedron_deflate(Matrix * polyh, unsigned int nb_parms) {
00135 unsigned int i,j;
00136 unsigned nb_vars = polyh->NbColumns-nb_parms-2;
00137 Value defl;
00138 value_init(defl);
00139
00140 for (i=0; i< polyh->NbRows; i++) {
00141 value_set_si(defl, 0);
00142 for (j=0; j< nb_vars; j++) {
00143 if (value_sign(polyh->p[i][j])>0)
00144 value_addto(defl, defl, polyh->p[i][j]);
00145 }
00146
00147 value_subtract(polyh->p[i][polyh->NbColumns-1], polyh->p[i][polyh->NbColumns-1], defl);
00148 }
00149 value_clear(defl);
00150 }
00151
00152
00153
00154 void eliminate_var_with_constr(Matrix * Eliminator, unsigned int eliminator_row, Matrix * Victim, unsigned int victim_row, unsigned int var_to_elim) {
00155 Value cur_lcm, mul_a, mul_b, a, b, sb;
00156 Value tmp, tmp2;
00157 int k;
00158 value_init(cur_lcm); value_init(mul_a); value_init(mul_b); value_init(a); value_init(b); value_init(sb);
00159 value_init(tmp); value_init(tmp2);
00160
00161 if (value_notzero_p(Victim->p[victim_row][var_to_elim+1])) {
00162 value_assign(a, Eliminator->p[eliminator_row][var_to_elim+1]);
00163 value_assign(b, Victim->p[victim_row][var_to_elim+1]);
00164 Lcm3(a, b, &cur_lcm);
00165
00166 value_division(tmp, cur_lcm, b);
00167 value_absolute(mul_a, tmp);
00168 value_absolute(tmp, b);
00169 value_division(sb, tmp, b);
00170
00171 #ifdef GNUMP
00172 mpz_divexact(tmp, cur_lcm, a);
00173 value_multiply(mul_b, tmp, sb);
00174 #else
00175 mul_b = cur_lcm / a * sb;
00176 #endif
00177
00178 value_assign(Victim->p[victim_row][0], Victim->p[victim_row][0]);
00179 for (k=1; k<Victim->NbColumns; k++) {
00180 value_multiply(tmp, Victim->p[victim_row][k], mul_a);
00181 value_multiply(tmp2, Eliminator->p[eliminator_row][k], mul_b);
00182 value_subtract(Victim->p[victim_row][k], tmp, tmp2);
00183
00184 }
00185 }
00186 value_clear(cur_lcm); value_clear(mul_a); value_clear(mul_b); value_clear(a); value_clear(b); value_clear(sb);
00187 value_clear(tmp); value_clear(tmp2);
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197 void mpolyhedron_compress_last_vars(Matrix * M, Matrix * compression) {
00198 unsigned int i, j, k;
00199 unsigned int offset = M->NbColumns - compression->NbRows;
00200 Matrix * M_tmp = Matrix_Alloc(1, M->NbColumns);
00201 assert(compression->NbRows==compression->NbColumns);
00202
00203 for(i=0; i< M->NbRows; i++) {
00204 for (j=0; j< compression->NbRows; j++) {
00205 value_set_si(M_tmp->p[0][j], 0);
00206 for (k=0; k< compression->NbRows; k++) {
00207 value_addmul(M_tmp->p[0][j], M->p[i][k+offset],compression->p[k][j] );
00208 }
00209 }
00210 for (j=0; j< compression->NbRows; j++)
00211 value_assign(M->p[i][j+offset], M_tmp->p[0][j]);
00212 }
00213 Matrix_Free(M_tmp);
00214 }
00215
00216
00217
00218
00219
00220
00221 unsigned int mpolyhedron_eliminate_first_variables(Matrix * Eqs, Matrix * Ineqs) {
00222 unsigned int i, j, k;
00223
00224 for (i=0; i< Eqs->NbRows; i++) {
00225
00226 for (j=0; j<Eqs->NbRows && (Eqs->p[j][i+1]==0 || ( !value_cmp_si(Eqs->p[j][0],2) )); j++);
00227
00228 if (j==Eqs->NbRows) return 0;
00229
00230 for (k=j+1; k<Eqs->NbRows; k++)
00231 eliminate_var_with_constr(Eqs, j, Eqs, k, i);
00232 for (k=0; k< Ineqs->NbRows; k++)
00233 eliminate_var_with_constr(Eqs, j, Ineqs, k, i);
00234
00235 value_set_si(Eqs->p[j][0],2);
00236 }
00237
00238 for (i=0; i< Eqs->NbRows; i++) value_set_si(Eqs->p[i][0],0);
00239 return 1;
00240 }
00241