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
00023
00024
00025
00026
00027
00028
00029 static void moins_l(Value *a,int i,int n,int p) {
00030
00031 int k;
00032 Value *c;
00033
00034 c=a+(i-1)*p;
00035
00036 for(k=1; k<=p; k++) {
00037 value_oppose(*c,*c);
00038 c++;
00039 }
00040 return;
00041 }
00042
00043
00044
00045
00046
00047
00048 static void moins_c(Value *a,int i,int n,int p) {
00049
00050 int k;
00051 Value *c;
00052
00053 c=a+(i-1);
00054
00055 for(k=1;k<=n;k++) {
00056 value_oppose(*c,*c);
00057 c=c+p;
00058 }
00059 return;
00060 }
00061
00062
00063
00064
00065
00066
00067 static void echange_l(Value *a,int i,int j,int n,int p) {
00068
00069 int k;
00070 Value s;
00071 Value *c1,*c2;
00072
00073 value_init(s);
00074 c1=a+(i-1)*p;
00075 c2=a+(j-1)*p;
00076
00077 for(k=1;k<=p;k++) {
00078 value_assign(s,*c1);
00079 value_assign(*c1,*c2);
00080 value_assign(*c2,s);
00081 c1++;
00082 c2++;
00083 }
00084 value_clear(s);
00085 return;
00086 }
00087
00088
00089
00090
00091
00092
00093 static void echange_c(Value *a,int i,int j,int n,int p) {
00094
00095 int k;
00096 Value s;
00097 Value *c1,*c2;
00098
00099 value_init(s);
00100 c1=a+(i-1);
00101 c2=a+(j-1);
00102
00103 for(k=1;k<=n;k++) {
00104 value_assign(s,*c1);
00105 value_assign(*c1,*c2);
00106 value_assign(*c2,s);
00107 c1=c1+p;
00108 c2=c2+p;
00109 }
00110 value_clear(s);
00111 return;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121 static void ligne(Value *a,int i,int j,Value x,int n,int p) {
00122
00123 int k;
00124 Value *c1,*c2;
00125
00126 c1=a+(i-1)*p;
00127 c2=a+(j-1)*p;
00128
00129 for(k=1;k<=p;k++) {
00130
00131 value_addmul(*c1, x, *c2);
00132 c1++;
00133 c2++;
00134 }
00135 return;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 static void colonne(Value *a,int i,int j,Value x,int n,int p) {
00147
00148 int k;
00149 Value *c1,*c2;
00150
00151 c1=a+(i-1);
00152 c2=a+(j-1);
00153
00154 for(k=1;k<=n;k++) {
00155 value_addmul(*c1, x, *c2);
00156 c1=c1+p;
00157 c2=c2+p;
00158 }
00159 return;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 static int petit_l(Value *a,int n,int p,int q) {
00174
00175 int numero=0, k, tousnuls;
00176 Value minus, comp;
00177 Value *c;
00178
00179 value_init(minus); value_init(comp);
00180 c=a+(q-1)*p+(p-1);
00181 tousnuls=1;
00182 for(k=p;k>q;k--) {
00183 value_absolute(comp,*c);
00184 if (value_notzero_p(comp)) {
00185 if (tousnuls==1) {
00186 value_assign(minus,comp);
00187 numero=k;
00188 tousnuls=0;
00189 }
00190 else if (value_ge(minus,comp)) {
00191 value_assign(minus,comp);
00192 numero=k;
00193 }
00194 }
00195 c--;
00196 }
00197 if (tousnuls==1) {
00198 value_clear(minus); value_clear(comp);
00199 return(0);
00200 }
00201 else {
00202 value_absolute(comp,*c);
00203 if ((value_notzero_p(comp))&&(value_ge(minus,comp))) {
00204 value_clear(minus); value_clear(comp);
00205 return(q);
00206 }
00207 else {
00208 value_clear(minus); value_clear(comp);
00209 return(numero);
00210 }
00211 }
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 static int petit_c(Value *a,int n,int p,int q) {
00226
00227 int numero=0, k, tousnuls;
00228 Value minus, comp;
00229 Value *c;
00230
00231 value_init(minus); value_init(comp);
00232 c = a+q-1+p*(n-1);
00233 tousnuls=1;
00234 for(k=n;k>q;k--) {
00235 value_absolute(comp,*c);
00236 if (value_notzero_p(comp)) {
00237 if (tousnuls==1) {
00238 value_assign(minus,comp);
00239 numero=k;
00240 tousnuls=0;
00241 }
00242 else if (value_ge(minus,comp)) {
00243 value_assign(minus,comp);
00244 numero=k;
00245 }
00246 }
00247 c=c-p;
00248 }
00249
00250 if (tousnuls==1) {
00251 value_clear(minus); value_clear(comp);
00252 return(0);
00253 }
00254 else {
00255 value_absolute(comp,*c);
00256 if ((value_notzero_p(comp)) && (value_ge(minus,comp))) {
00257 value_clear(minus); value_clear(comp);
00258 return(q);
00259 }
00260 else {
00261 value_clear(minus); value_clear(comp);
00262 return(numero);
00263 }
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272 static void identite(Value *a,int n,int p) {
00273
00274 int i,j;
00275 Value *b;
00276
00277 b = a;
00278 for(i=1;i<=n;i++) {
00279 for(j=1;j<=p;j++) {
00280 if (i==j)
00281 value_set_si(*b,1);
00282 else
00283 value_set_si(*b,0);
00284 b++;
00285 }
00286 }
00287 return;
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297 static void transpose(Value *a,int n,int q) {
00298
00299 int i;
00300 Value val;
00301 Value *b,*c;
00302
00303 value_init(val);
00304 if (q<n) {
00305 b=a+(q-1)+(q-1)*n;
00306 c=b;
00307 for(i=q+1;i<=n;i++) {
00308 b++;
00309 c=c+n;
00310 value_assign(val,*b);
00311 value_assign(*b,*c);
00312 value_assign(*c,val);
00313 }
00314 transpose(a,n,q+1);
00315 }
00316 value_clear(val);
00317 return;
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 static int encore(Value *a,int n,int p,int q,Value val) {
00330
00331 int k,l;
00332 Value comp, tmp;
00333 Value *c;
00334
00335 if ((q>=n)||(q>=p)) return(0);
00336
00337 value_init(comp); value_init(tmp);
00338 c=a+q*p+q;
00339 k=q+1;
00340 l=q+1;
00341 while (k<=n) {
00342 value_absolute(comp,*c);
00343 if (value_zero_p(val)) {
00344 if (value_notzero_p(comp)) {
00345 value_clear(comp);
00346 value_clear(tmp);
00347 return(l);
00348 }
00349 }
00350 else {
00351 value_modulus(tmp,comp,val);
00352 if (value_notzero_p(tmp)) {
00353 value_clear(comp);
00354 value_clear(tmp);
00355 return(l);
00356 }
00357 }
00358 if (l==p) {
00359 k=k+1;
00360 l=q+1;
00361 c=c+q+1;
00362 }
00363 else {
00364 l++;
00365 c++;
00366 }
00367 }
00368 value_clear(comp);
00369 value_clear(tmp);
00370 return(0);
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 static void smith(Value *a,Value *b,Value *c,Value *b_inverse,Value *c_inverse,int n,int p,int q) {
00384
00385 int i,k,fini;
00386 Value x, pivot, tmp, x_inv;
00387 Value *f;
00388
00389 value_init(pivot); value_init(tmp);
00390 value_init(x); value_init(x_inv);
00391
00392 if ((q<=n)&&(q<=p)) {
00393 fini = 1;
00394
00395 while (fini!=0) {
00396 i=petit_c(a,n,p,q);
00397 while (i!=0) {
00398 if (i!=q) {
00399 echange_l(a,i,q,n,p);
00400 echange_l(b,i,q,n,n);
00401 echange_c(b_inverse,i,q,n,n);
00402 }
00403 f=a+(q-1)+(q-1)*p;
00404 value_assign(pivot,*f);
00405 if (value_neg_p(pivot)) {
00406 moins_l(a,q,n,p);
00407 moins_l(b,q,n,n);
00408 moins_c(b_inverse,q,n,n);
00409 value_oppose(pivot,pivot);
00410 }
00411 for(k=q+1;k<=n;k++) {
00412 f=f+p;
00413 if (value_notzero_p(*f)) {
00414 value_division(x,*f,pivot);
00415 value_modulus(tmp,*f,pivot);
00416 if (value_neg_p(tmp))
00417 value_decrement(x,x);
00418 value_oppose(x_inv,x);
00419 ligne(a,k,q,x_inv,n,p);
00420 ligne(b,k,q,x_inv,n,n);
00421 colonne(b_inverse,q,k,x,n,n);
00422 }
00423 }
00424 i=petit_c(a,n,p,q);
00425 }
00426 fini=0;
00427 i=petit_l(a,n,p,q);
00428 while (i!=0) {
00429 if (i!=q) {
00430 echange_c(a,i,q,n,p);
00431 echange_c(c,i,q,p,p);
00432 echange_l(c_inverse,i,q,p,p);
00433 fini=1;
00434 }
00435 f=a+(q-1)+(q-1)*p;
00436 value_assign(pivot,*f);
00437 if (value_neg_p(pivot)) {
00438 moins_c(a,q,n,p);
00439 moins_c(c,q,p,p);
00440 moins_l(c_inverse,q,p,p);
00441 value_oppose(pivot,pivot);
00442 }
00443 for(k=q+1;k<=p;k++) {
00444 f++;
00445 if (value_notzero_p(*f)) {
00446 value_division(x,*f,pivot);
00447 value_modulus(tmp,*f,pivot);
00448 if (value_neg_p(tmp))
00449 value_decrement(x,x);
00450 value_oppose(x_inv,x);
00451 colonne(a,k,q,x_inv,n,p);
00452 colonne(c,k,q,x_inv,p,p);
00453 ligne(c_inverse,q,k,x,p,p);
00454 }
00455 }
00456 i=petit_l(a,n,p,q);
00457 }
00458 }
00459 value_assign(pivot,*(a+(q-1)+(q-1)*p));
00460 if (value_neg_p(pivot)) {
00461 moins_l(a,q,n,p);
00462 moins_l(b,q,n,n);
00463 moins_c(b_inverse,q,n,n);
00464 value_oppose(pivot,pivot);
00465 }
00466
00467 i=encore(a,n,p,q,pivot);
00468 if (i!=0) {
00469 value_set_si(x,1);
00470 value_set_si(x_inv,-1);
00471 colonne(a,q,i,x,n,p);
00472 colonne(c,q,i,x,p,p);
00473 ligne(c_inverse,i,q,x_inv,p,p);
00474 smith(a,b,c,b_inverse,c_inverse,n,p,q);
00475 }
00476 else smith(a,b,c,b_inverse,c_inverse,n,p,q+1);
00477 }
00478 value_clear(pivot); value_clear(tmp);
00479 value_clear(x); value_clear(x_inv);
00480
00481 return;
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 static void hermite(Value *a,Value *b,Value *d,int n,int p,int q) {
00493
00494 int i,k;
00495 Value x, pivot, x_inv, tmp;
00496 Value *c1;
00497
00498 value_init(pivot); value_init(tmp);
00499 value_init(x); value_init(x_inv);
00500
00501 if ((q<=p)&&(q<=n)) {
00502 i=petit_c(a,n,p,q);
00503 while (i!=0) {
00504 if (i!=q) {
00505 echange_l(a,i,q,n,p);
00506 echange_c(b,i,q,n,n);
00507 echange_l(d,i,q,n,n);
00508 }
00509
00510 c1=a+(q-1)+(q-1)*p;
00511 value_assign(pivot,*c1);
00512 if (value_neg_p(pivot)) {
00513 moins_l(a,q,n,p);
00514 moins_l(d,q,n,n);
00515 moins_c(b,q,n,n);
00516 value_oppose(pivot,pivot);
00517 }
00518 for(k=q+1;k<=n;k++) {
00519 c1=c1+p;
00520 if (value_notzero_p(*c1)) {
00521 value_division(x,*c1,pivot);
00522 value_modulus(tmp,*c1,pivot);
00523 if (value_neg_p(tmp))
00524 value_decrement(x,x);
00525 value_oppose(x_inv,x);
00526 ligne(a,k,q,x_inv,n,p);
00527 colonne(b,q,k,x,n,n);
00528 ligne(d,k,q,x_inv,n,n);
00529 }
00530 }
00531 i=petit_c(a,n,p,q);
00532 }
00533 c1=a+(q-1);
00534 value_assign(pivot,*(c1+(q-1)*p));
00535 if (value_neg_p(pivot)) {
00536 moins_l(a,q,n,p);
00537 moins_l(d,q,n,n);
00538 moins_c(b,q,n,n);
00539 value_oppose(pivot,pivot);
00540 }
00541 if (value_notzero_p(pivot)) {
00542 for(k=1;k<q;k++) {
00543 if (value_notzero_p(*c1)) {
00544 value_division(x,*c1,pivot);
00545 value_modulus(tmp,*c1,pivot);
00546 if (value_neg_p(tmp))
00547 value_decrement(x,x);
00548 value_oppose(x_inv,x);
00549 ligne(a,k,q,x_inv,n,p);
00550 colonne(b,q,k,x,n,n);
00551 ligne(d,k,q,x_inv,n,n);
00552 }
00553 c1=c1+p;
00554 }
00555 }
00556 hermite(a,b,d,n,p,q+1);
00557 }
00558 value_clear(pivot); value_clear(tmp);
00559 value_clear(x); value_clear(x_inv);
00560 return;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 static Value *ConvertPolMattoDarMat(Matrix *A ) {
00581
00582 int i,j;
00583 Value *result;
00584
00585 result = (Value *)malloc(sizeof(Value) * A->NbRows * A->NbColumns);
00586 for(i=0;i<A->NbRows * A->NbColumns;i++)
00587 value_init(result[i]);
00588
00589 for (i = 0; i < A->NbRows; i++)
00590 for (j = 0 ; j < A->NbColumns; j++)
00591 value_assign(result[i*A->NbColumns + j],A->p[i][j]);
00592 return result;
00593 }
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 static Matrix *ConvertDarMattoPolMat (Value *A, int NbRows, int NbCols) {
00605
00606 int i,j;
00607 Matrix *result;
00608
00609 result = Matrix_Alloc(NbRows, NbCols);
00610
00611 for (i = 0; i < NbRows; i ++)
00612 for (j = 0; j < NbCols; j ++)
00613 value_assign(result->p[i][j],A[i*NbCols + j]);
00614 return result;
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 void Smith(Matrix *A, Matrix **U, Matrix **V, Matrix **Product)
00628 {
00629 int i;
00630 Matrix *u, *v;
00631
00632 u = Identity(A->NbRows);
00633 v = Identity(A->NbColumns);
00634
00635 *U = Identity(A->NbRows);
00636 *V = Identity(A->NbColumns);
00637
00638 *Product = Matrix_Copy(A);
00639 smith((*Product)->p_Init, u->p_Init, v->p_Init, (*U)->p_Init, (*V)->p_Init,
00640 A->NbRows, A->NbColumns, 1);
00641
00642 Matrix_Free(u);
00643 Matrix_Free(v);
00644 }
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 void Hermite (Matrix *A, Matrix **H, Matrix **U) {
00671
00672 int i;
00673 Matrix *transpose, *tempH, *tempU ;
00674 Value *darte_matA, *darte_identite, *darte_id_inv;
00675
00676 transpose = Transpose(A);
00677 darte_matA = ConvertPolMattoDarMat(transpose);
00678
00679 darte_identite = (Value *)malloc(sizeof(Value) * A->NbColumns* A->NbColumns);
00680 darte_id_inv = (Value *) malloc(sizeof(Value) * A->NbColumns*A->NbColumns);
00681 for (i=0; i< A->NbColumns * A->NbColumns; i++)
00682 value_init(darte_identite[i]);
00683 for (i=0; i< A->NbColumns * A->NbColumns; i++)
00684 value_init(darte_id_inv[i]);
00685
00686 identite(darte_identite, transpose->NbRows, transpose->NbRows);
00687 identite(darte_id_inv, transpose->NbRows, transpose->NbRows);
00688 hermite(darte_matA, darte_identite, darte_id_inv,A->NbColumns,A->NbRows, 1);
00689 Matrix_Free (transpose);
00690 transpose = ConvertDarMattoPolMat(darte_matA, A->NbColumns, A->NbRows);
00691 tempU = ConvertDarMattoPolMat(darte_identite, A->NbColumns, A->NbColumns);
00692
00693
00694 tempH = Transpose(transpose);
00695 Matrix_Free(transpose);
00696
00697
00698 transpose = Transpose(tempU);
00699
00700 H[0] = Matrix_Copy(tempH);
00701 U[0] = Matrix_Copy(transpose);
00702
00703 Matrix_Free (tempH);
00704 Matrix_Free (transpose);
00705 Matrix_Free (tempU);
00706
00707 for (i=0; i< A->NbRows * A->NbColumns; i++)
00708 value_clear(darte_matA[i]);
00709 for (i=0; i< A->NbColumns * A->NbColumns; i++)
00710 value_clear(darte_identite[i]);
00711 for (i=0; i< A->NbColumns * A->NbColumns; i++)
00712 value_clear(darte_id_inv[i]);
00713 free (darte_matA);
00714 free (darte_identite);
00715 free (darte_id_inv);
00716 return;
00717 }
00718
00719