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