00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <stdlib.h>
00033 #include <polylib/matrix_permutations.h>
00034
00035
00036 unsigned int nb_bits(unsigned long long int x) {
00037 unsigned int i,n=0;
00038 unsigned long long int y=x;
00039 for (i=0; i< 64; i++) {
00040 n+=y%2;
00041 y>>=1;
00042 }
00043 return n;
00044 }
00045
00046
00047
00048
00049
00050
00051 unsigned int * permutation_inverse(unsigned int * perm, unsigned int nb_elems) {
00052 int i;
00053 unsigned int * inv_perm = (unsigned int *)malloc(sizeof(unsigned int) * nb_elems);
00054 for (i=0; i< nb_elems; i++) inv_perm[perm[i]] = i;
00055 return inv_perm;
00056 }
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 Matrix * mtransformation_permute(Matrix * transf, unsigned int * permutation) {
00067 Matrix * permuted;
00068 unsigned int i,j;
00069
00070 assert(transf->NbRows==transf->NbColumns);
00071 permuted = Matrix_Alloc(transf->NbRows, transf->NbRows);
00072 for (i= 0; i< transf->NbRows; i++) {
00073 for (j= 0; j< transf->NbRows; j++) {
00074 value_assign(permuted->p[permutation[i]][permutation[j]], transf->p[i][j]);
00075 }
00076 }
00077 return permuted;
00078 }
00079
00080
00081
00082
00083
00084
00085 Matrix * mpolyhedron_permute(Matrix * polyh, unsigned int * permutation) {
00086 unsigned int i,j;
00087 Matrix * permuted = Matrix_Alloc(polyh->NbRows, polyh->NbColumns);
00088 for (i= 0; i< polyh->NbRows; i++) {
00089 value_assign(permuted->p[i][0], polyh->p[i][0]);
00090 for (j= 1; j< polyh->NbColumns; j++) {
00091 value_assign(permuted->p[i][permutation[j-1]+1], polyh->p[i][j]);
00092 }
00093 }
00094 return permuted;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104 void Constraints_permute(Matrix * C, unsigned int * perm, Matrix ** Cp) {
00105 unsigned int i,j;
00106 if ((*Cp)==NULL) {
00107 (*Cp) = Matrix_Alloc(C->NbRows, C->NbColumns);
00108 }
00109 else {
00110 assert((*Cp)->NbRows == C->NbRows && (*Cp)->NbColumns==C->NbColumns);
00111 }
00112 for (i= 0; i< C->NbRows; i++) {
00113 value_assign((*Cp)->p[i][0], C->p[i][0]);
00114 for (j= 1; j< C->NbColumns; j++) {
00115 value_assign((*Cp)->p[i][perm[j-1]+1], C->p[i][j]);
00116 }
00117 }
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 unsigned long long int eliminable_vars(Matrix * Eqs, unsigned start,
00135 unsigned end) {
00136 unsigned long long int combination;
00137 unsigned int i,j,k;
00138 Matrix * M, * H, * Q, *U;
00139 Matrix * Square_Mat, *Eqs2;
00140 unsigned nb_vars = end - start + 1 ;
00141 Polyhedron * OverConstrained;
00142
00143 assert (start>0 && end < Eqs->NbColumns-1);
00144
00145
00146 if (Eqs->NbRows >nb_vars) {
00147
00148 Eqs2 = Matrix_Copy(Eqs);
00149 OverConstrained = Constraints2Polyhedron(Eqs2,
00150 Eqs->NbColumns*Eqs->NbColumns);
00151 Matrix_Free(Eqs2);
00152 if (emptyQ(OverConstrained)) {
00153 Polyhedron_Free(OverConstrained);
00154 return 0;
00155 }
00156 Polyhedron_Free(OverConstrained);
00157 }
00158
00159
00160 for (i=0; i< Eqs->NbRows; i++) {
00161 assert (!Vector_IsZero(Eqs->p[i], Eqs->NbColumns));
00162 }
00163
00164 Square_Mat= Matrix_Alloc(Eqs->NbRows, Eqs->NbRows);
00165
00166
00167
00168
00169
00170
00171
00172 for (combination = ((unsigned long long int) 1<<(Eqs->NbRows))-1;
00173 (combination < ((unsigned long long int) 1 << nb_vars)) ;
00174 combination++) {
00175 if (nb_bits(combination) == Eqs->NbRows) {
00176 k=0;
00177
00178 for (j=0; j< nb_vars; j++) {
00179 if ((combination>>j)%2) {
00180 for (i=0; i< Eqs->NbRows; i++) {
00181 value_assign(Square_Mat->p[i][k], Eqs->p[i][j+start]);
00182 }
00183 k++;
00184 }
00185 }
00186
00187 right_hermite(Square_Mat, &H, &Q, &U);
00188 Matrix_Free(Q);
00189 Matrix_Free(U);
00190
00191
00192
00193 if ( value_notzero_p((H->p[Eqs->NbRows-1][Eqs->NbRows-1])) ) {
00194 Matrix_Free(Square_Mat);
00195 Matrix_Free(H);
00196 return combination;
00197 }
00198 Matrix_Free(H);
00199 }
00200 }
00201 Matrix_Free(Square_Mat);
00202 return (unsigned long long int) 0;
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 unsigned int * find_a_permutation(Matrix * Eqs, unsigned int nb_parms) {
00214 unsigned int i, j, k;
00215 int nb_vars = Eqs->NbColumns-nb_parms-2;
00216 unsigned long long int combination;
00217 unsigned int * permutation = (unsigned int *)malloc(sizeof(unsigned int) *
00218 Eqs->NbColumns-1);
00219
00220
00221 if ((combination = eliminable_vars(Eqs, 1, nb_vars)) == 0) {
00222
00223 return NULL;
00224 }
00225
00226
00227
00228 k=0;
00229 for (i=0; i< nb_vars; i++) {
00230
00231 if (combination%2) {
00232 permutation[i] = k;
00233 k++;
00234 }
00235
00236 else permutation[i] = Eqs->NbRows+nb_parms+ i-k;
00237 combination>>=1;
00238 }
00239
00240 for (i=0; i< nb_parms; i++) {
00241 permutation[nb_vars+i] = Eqs->NbRows+i;
00242 }
00243
00244 permutation[Eqs->NbColumns-2] = Eqs->NbColumns-2;
00245
00246 return permutation;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256 unsigned int * permutation_for_full_dim2(unsigned int * vars_to_keep,
00257 unsigned int nb_keep,
00258 unsigned int nb_vars_parms,
00259 unsigned int nb_parms) {
00260 unsigned int * permutation =
00261 (unsigned int*)malloc(sizeof(unsigned int) * nb_vars_parms+1);
00262 unsigned int i;
00263 int cur_keep =0, cur_go = 0;
00264 for (i=0; i< nb_vars_parms - nb_parms; i++) {
00265 if (i==vars_to_keep[cur_keep]) {
00266 permutation[i] = nb_vars_parms-nb_keep+cur_keep;
00267 cur_keep++;
00268 }
00269 else {
00270 permutation[i] = cur_go;
00271 cur_go++;
00272 }
00273 }
00274
00275 for (i=0; i< nb_parms; i++)
00276 permutation[i+nb_vars_parms-nb_parms] = i+nb_vars_parms-nb_parms-nb_keep;
00277
00278
00279 permutation[nb_vars_parms] = nb_vars_parms;
00280 return permutation;
00281 }