00001 #include <stdlib.h>
00002 #include <polylib/polylib.h>
00003
00004
00005
00006
00007 Value *Lcm (Value i, Value j) {
00008
00009 Value *tmp;
00010 Value aux;
00011
00012 tmp = (Value *) malloc (sizeof(Value));
00013 value_init(aux); value_init(*tmp);
00014 Gcd(i,j,tmp);
00015 value_multiply(aux,i,j);
00016 value_division(*tmp,aux,*tmp);
00017 value_clear(aux);
00018 return tmp;
00019 }
00020
00021
00022
00023
00024 Matrix *Identity (unsigned size) {
00025
00026 unsigned i, j;
00027 Matrix *A;
00028
00029 A = Matrix_Alloc(size, size);
00030 for (i = 0;i < size; i ++)
00031 for (j = 0; j < size; j ++)
00032 value_set_si(A->p[i][j],0);
00033 for (i =0; i < size; i ++)
00034 value_set_si(A->p[i][i],1);
00035 return A;
00036 }
00037
00038
00039
00040
00041 void ExchangeRows(Matrix *M, int Row1, int Row2) {
00042
00043 int i;
00044 Value *temp;
00045
00046 temp = (Value *) malloc (sizeof(Value) * M->NbColumns);
00047
00048 for (i = 0 ;i < (int)M->NbColumns; i++) {
00049 value_init(temp[i]);
00050 value_assign(temp[i],M->p[Row1][i]);
00051 }
00052 for (i = 0; i < (int)M->NbColumns; i++) {
00053 value_assign(M->p[Row1][i],M->p[Row2][i]);
00054 value_assign(M->p[Row2][i],temp[i]);
00055 value_clear(temp[i]);
00056 }
00057 free (temp);
00058 return ;
00059 }
00060
00061
00062
00063
00064 void ExchangeColumns(Matrix *M, int Column1, int Column2) {
00065
00066 int i;
00067 Value *temp;
00068
00069 temp = (Value *) malloc(sizeof(Value) * M->NbRows);
00070 for (i = 0 ;i < (int) M->NbRows; i++) {
00071 value_init(temp[i]);
00072 value_assign(temp[i],M->p[i][Column1]);
00073 }
00074 for (i = 0; i < (int)M->NbRows; i++) {
00075 value_assign(M->p[i][Column1],M->p[i][Column2]);
00076 value_assign(M->p[i][Column2],temp[i]);
00077 value_clear(temp[i]);
00078 }
00079 free (temp);
00080 return ;
00081 }
00082
00083
00084
00085
00086 Matrix *Transpose (Matrix *A) {
00087
00088 int i,j;
00089 Matrix *transpose;
00090
00091 transpose = Matrix_Alloc (A->NbColumns, A->NbRows);
00092 for (i = 0; i < (int)A->NbRows; i++)
00093 for (j = 0; j < (int)A->NbColumns; j++)
00094 value_assign(transpose->p[j][i],A->p[i][j]);
00095 return transpose;
00096 }
00097
00098
00099
00100
00101 Matrix *Matrix_Copy(Matrix *Src ) {
00102
00103 Matrix *Dst;
00104 unsigned i, j;
00105
00106 Dst = Matrix_Alloc(Src->NbRows, Src->NbColumns);
00107
00108 for (i = 0; i < Src->NbRows; i++)
00109 for (j = 0; j < Src->NbColumns; j++)
00110 value_assign(Dst->p[i][j],Src->p[i][j]);
00111 return Dst;
00112 }
00113
00114
00115
00116
00117 Bool isIntegral (Matrix *A) {
00118
00119 unsigned i, j;
00120 Value divisor, tmp;
00121
00122 value_init(divisor); value_init(tmp);
00123 value_assign(divisor,A->p[A->NbRows-1][A->NbColumns-1]);
00124
00125 for (i = 0; i < A->NbRows ; i++)
00126 for (j = 0; j < A->NbColumns ; j++) {
00127 value_modulus(tmp,A->p[i][j],divisor);
00128 if (value_notzero_p(tmp)) {
00129 value_clear(divisor); value_clear(tmp);
00130 return False;
00131 }
00132 }
00133 value_clear(divisor); value_clear(tmp);
00134 return True ;
00135 }
00136
00137
00138
00139
00140 Bool isinHnf(Matrix *A) {
00141
00142 Matrix *temp ;
00143 unsigned i, j ;
00144 Value rem;
00145
00146 value_init(rem);
00147 temp = Homogenise(A,True) ;
00148 for (i = 0; i < temp->NbRows; i++) {
00149 value_assign(rem,temp->p[i][i]);
00150 for (j = 0; j < i ; j++)
00151 if (value_ge(temp->p[i][j],rem)) {
00152 Matrix_Free(temp);
00153 value_clear(rem);
00154 return False ;
00155 }
00156 for (j = i+1; j < temp->NbColumns ; j++)
00157 if (value_notzero_p(temp->p[i][j])) {
00158 Matrix_Free(temp);
00159 value_clear(rem);
00160 return False ;
00161 }
00162 }
00163 value_clear(rem);
00164 return True ;
00165 }
00166
00167
00168
00169
00170 void PutRowLast (Matrix *X, int Rownumber) {
00171
00172 int i, j ;
00173 Value *vector;
00174
00175 if (Rownumber == X->NbRows-1)
00176 return;
00177 vector = (Value *) malloc (sizeof(Value) * X->NbColumns);
00178
00179 for (i = 0; i < X->NbColumns; i++) {
00180 value_init(vector[i]);
00181 value_assign(vector[i],X->p[Rownumber][i]);
00182 }
00183 for (i = Rownumber; i < X->NbRows-1; i++)
00184 for (j = 0; j < X->NbColumns; j++)
00185 value_assign(X->p[i][j],X->p[i+1][j]);
00186
00187 for (j = 0; j < X->NbColumns ; j++) {
00188 value_assign(X->p[i][j],vector[j]);
00189 value_clear(vector[j]);
00190 }
00191 free (vector);
00192 return;
00193 }
00194
00195
00196
00197
00198 void PutRowFirst(Matrix *X, int Rownumber) {
00199
00200 int i, j ;
00201 Value *vector;
00202
00203 vector = (Value *) malloc (sizeof(Value) * X->NbColumns);
00204
00205 for (i = 0; i < X->NbColumns; i++) {
00206 value_init(vector[i]);
00207 value_assign(vector[i],X->p[Rownumber][i]);
00208 }
00209 for (i = Rownumber; i > 0; i--)
00210 for (j = 0; j < X->NbColumns; j++)
00211 value_assign(X->p[i][j],X->p[i-1][j]);
00212
00213 for (j = 0; j < X->NbColumns ; j++) {
00214 value_assign(X->p[i][j],vector[j]);
00215 value_clear(vector[j]);
00216 }
00217 free(vector);
00218 return;
00219 }
00220
00221
00222
00223
00224
00225 void PutColumnFirst (Matrix *X, int Columnnumber) {
00226
00227 int i, j ;
00228 Value *vector;
00229
00230 vector = (Value *)malloc(sizeof (Value) * X->NbRows);
00231
00232 for (i = 0; i < X->NbRows; i++) {
00233 value_init(vector[i]);
00234 value_assign(vector[i],X->p[i][Columnnumber]);
00235 }
00236
00237 for (i = 0; i < X->NbRows; i ++)
00238 for (j = Columnnumber; j > 0; j --)
00239 value_assign(X->p[i][j],X->p[i][j-1]);
00240
00241 for (i = 0; i < X->NbRows ; i ++) {
00242 value_assign(X->p[i][0],vector[i]);
00243 value_clear(vector[i]);
00244 }
00245 free (vector);
00246 return ;
00247 }
00248
00249
00250
00251
00252 void PutColumnLast (Matrix *X, int Columnnumber) {
00253
00254 int i, j ;
00255 Value *vector;
00256
00257 vector = (Value *) malloc (sizeof (Value) * X->NbRows);
00258
00259 for (i = 0; i < X->NbRows; i++) {
00260 value_init(vector[i]);
00261 value_assign(vector[i],X->p[i][Columnnumber]);
00262 }
00263
00264 for (i = 0; i < X->NbRows; i++)
00265 for (j = Columnnumber; j < X->NbColumns-1; j++)
00266 value_assign(X->p[i][j],X->p[i][j+1]);
00267
00268 for (i = 0; i < X->NbRows ; i++) {
00269 value_assign(X->p[i][X->NbColumns-1],vector[i]);
00270 value_clear(vector[i]);
00271 }
00272 free (vector);
00273 return ;
00274 }
00275
00276
00277
00278
00279 Matrix *AddANullRow (Matrix *M) {
00280
00281 int i,j;
00282 Matrix *Result;
00283
00284 Result = Matrix_Alloc(M->NbRows+1,M->NbColumns);
00285 for (i = 0;i < M->NbRows; i++)
00286 for (j = 0; j < M->NbColumns ; j++)
00287 value_assign(Result->p[i][j],M->p[i][j]);
00288 for (j = 0; j < M->NbColumns; j++)
00289 value_set_si(Result->p[i][j],0);
00290 return Result;
00291 }
00292
00293
00294
00295
00296
00297 Matrix *AddANullColumn(Matrix *M) {
00298
00299 int i,j;
00300 Matrix *Result;
00301
00302 Result = Matrix_Alloc(M->NbRows, M->NbColumns+1);
00303 for (i = 0;i < M->NbRows; i++)
00304 for (j = 0; j < M->NbColumns ; j++)
00305 value_assign(Result->p[i][j],M->p[i][j]);
00306 for (i = 0; i < M->NbRows; i++)
00307 value_set_si(Result->p[i][M->NbColumns],0);
00308 return Result;
00309 }
00310
00311
00312
00313
00314 Matrix *RemoveRow(Matrix *M, int Rownumber) {
00315
00316 Matrix *temp, *Result;
00317 int i,j;
00318
00319 temp = Matrix_Copy (M);
00320 PutRowLast(temp, Rownumber);
00321 Result = Matrix_Alloc(temp->NbRows-1, temp->NbColumns);
00322
00323 for (i = 0; i < Result->NbRows; i ++)
00324 for (j = 0; j < Result->NbColumns; j ++)
00325 value_assign(Result->p[i][j],temp->p[i][j]);
00326 return Result;
00327 }
00328
00329
00330
00331
00332 Matrix *RemoveColumn (Matrix *M, int Columnnumber) {
00333
00334 Matrix *temp, *Result;
00335 int i,j;
00336
00337 temp = Matrix_Copy(M);
00338 PutColumnLast(temp,Columnnumber);
00339 Result = Matrix_Alloc (temp->NbRows, temp->NbColumns-1);
00340
00341 for (i = 0; i < Result->NbRows; i ++)
00342 for (j = 0; j < Result->NbColumns; j ++)
00343 value_assign(Result->p[i][j],temp->p[i][j]);
00344 return Result;
00345 }
00346
00347
00348
00349
00350
00351
00352
00353 int findHermiteBasis(Matrix *M, Matrix **Result) {
00354
00355 int i, j;
00356 Matrix *C, *curMat, *temp1, *temp2;
00357 Matrix *H, *U;
00358 Vector *V;
00359 int dim, curDim, curVect,rank;
00360
00361 if (M->NbRows == 0) {
00362 Result[0] = Identity (M->NbColumns);
00363 return 0;
00364 }
00365
00366 if (M->NbRows <= M->NbColumns) {
00367 Hermite(M, &H, &U);
00368
00369 for (i = 0; i < H->NbRows; i++)
00370 if (value_zero_p(H->p[i][i]))
00371 break;
00372
00373 if (i == H->NbRows) {
00374 Result[0] = Transpose(U);
00375 Matrix_Free(H);
00376 Matrix_Free(U);
00377 return(i);
00378 }
00379 Matrix_Free (H);
00380 Matrix_Free (U);
00381 }
00382
00383
00384
00385 C = Matrix_Copy (M);
00386 for (i = 0; i < C->NbRows; i++) {
00387 for (j = 0; j < C->NbColumns; j++)
00388 if (value_notzero_p(C->p[i][j]))
00389 break;
00390 if (j == C->NbColumns) {
00391 Matrix *temp;
00392 temp = RemoveRow(C, i);
00393 Matrix_Free(C);
00394 C = Matrix_Copy(temp);
00395 Matrix_Free(temp);
00396 i --;
00397 }
00398 }
00399
00400
00401
00402 curDim = 1;
00403 curVect = 1;
00404 dim = C->NbColumns;
00405
00406 curMat = Matrix_Alloc(1,C->NbColumns);
00407 for (i = 0; i < C->NbColumns; i ++)
00408 value_assign(curMat->p[0][i],C->p[0][i]);
00409
00410 while((curVect < C->NbRows) && (curDim < dim)) {
00411 Matrix *temp;
00412 temp = AddANullRow(curMat);
00413 for (i = 0; i < C->NbColumns; i++)
00414 value_assign(temp->p[temp->NbRows-1][i],C->p[curVect][i]);
00415
00416 temp1 = AddANullRow(temp);
00417 temp2 = AddANullColumn(temp1);
00418 rank = SolveDiophantine(temp2, &U, &V);
00419 if (rank == temp->NbRows) {
00420 Matrix_Free(curMat);
00421 curMat = Matrix_Copy(temp);
00422 curDim ++;
00423 }
00424 curVect ++;
00425 Matrix_Free (U);
00426 Vector_Free (V);
00427 Matrix_Free (temp1);
00428 Matrix_Free (temp);
00429 Matrix_Free (temp2);
00430 }
00431
00432 Hermite(curMat, &H, &U);
00433 rank = curMat->NbRows;
00434
00435 Result[0] = Transpose (U);
00436 Matrix_Free (H);
00437 Matrix_Free (U);
00438 return (rank);
00439 }
00440
00441
00442
00443