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