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/polylib.h>
00034
00035
00036
00037
00038 #define dbgCompParm 0
00039 #define dbgCompParmMore 0
00040
00041 #define dbgStart(a) if (dbgCompParmMore) { printf(" -- begin "); \
00042 printf(#a); \
00043 printf(" --\n"); } \
00044 while(0)
00045 #define dbgEnd(a) if (dbgCompParmMore) { printf(" -- end "); \
00046 printf(#a); \
00047 printf(" --\n"); } \
00048 while(0)
00049
00050
00051
00052
00053
00054
00055
00056 Matrix * int_ker(Matrix * M) {
00057 Matrix *U, *Q, *H, *H2, *K=NULL;
00058 int i, j, rk;
00059
00060 if (dbgCompParm)
00061 show_matrix(M);
00062
00063 right_hermite(M, &H, &Q, &U);
00064 for (rk=H->NbRows-1; (rk>=0) && Vector_IsZero(H->p[rk], H->NbColumns); rk--);
00065 rk++;
00066 if (dbgCompParmMore) {
00067 printf("rank = %d\n", rk);
00068 }
00069
00070
00071
00072
00073 if (M->NbColumns <= rk) {
00074 Matrix_Free(H);
00075 Matrix_Free(Q);
00076 Matrix_Free(U);
00077 K = Matrix_Alloc(M->NbColumns, 0);
00078 return K;
00079 }
00080 Matrix_Free(U);
00081 Matrix_Free(Q);
00082
00083 H->NbRows=rk;
00084
00085 left_hermite(H, &H2, &Q, &U);
00086 if (dbgCompParmMore) {
00087 printf("-- Int. Kernel -- \n");
00088 show_matrix(M);
00089 printf(" = \n");
00090 show_matrix(H2);
00091 show_matrix(U);
00092 }
00093 H->NbRows==M->NbRows;
00094 Matrix_Free(H);
00095
00096 Matrix_subMatrix(U, 0, rk, U->NbRows, U->NbColumns, &K);
00097
00098
00099 Matrix_Free(H2);
00100 Matrix_Free(U);
00101 Matrix_Free(Q);
00102 return K;
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 static void linearInter(Matrix * A, Matrix * B, Matrix ** I, Matrix **Lb) {
00120 Matrix * AB=NULL;
00121 int rk = A->NbRows;
00122 int a = A->NbColumns;
00123 int b = B->NbColumns;
00124 int i,j, z=0;
00125
00126 Matrix * H, *U, *Q;
00127
00128 assert(B->NbRows==rk);
00129
00130
00131
00132
00133 AB = Matrix_Alloc(2*rk, a+b+rk);
00134 Matrix_copySubMatrix(A, 0, 0, rk, a, AB, 0, 0);
00135 Matrix_copySubMatrix(B, 0, 0, rk, b, AB, rk, a);
00136 for (i=0; i< rk; i++) {
00137 value_set_si(AB->p[i][a+b+i], 1);
00138 value_set_si(AB->p[i+rk][a+b+i], 1);
00139 }
00140 if (dbgCompParm) {
00141 show_matrix(AB);
00142 }
00143
00144
00145 left_hermite(AB, &H, &Q, &U);
00146 Matrix_Free(AB);
00147 Matrix_Free(Q);
00148
00149 for (z=H->NbColumns-1; value_zero_p(H->p[H->NbRows-1][z]); z--);
00150 z++;
00151 if (dbgCompParm) {
00152 show_matrix(H);
00153 printf("z=%d\n", z);
00154 }
00155 Matrix_Free(H);
00156
00157
00158
00159
00160
00161
00162
00163 Matrix_subMatrix(U, a+b, z, U->NbColumns, U->NbColumns, I);
00164 Matrix_subMatrix(U, a, z, a+b, U->NbColumns, Lb);
00165 if (dbgCompParm) {
00166 show_matrix(U);
00167 }
00168 Matrix_Free(U);
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 void Equalities_integerSolution(Matrix * Eqs, Matrix **I) {
00182 Matrix * Hm, *H=NULL, *U, *Q, *M=NULL, *C=NULL, *Hi;
00183 Matrix *Ip;
00184 int i;
00185 Value mod;
00186 unsigned int rk;
00187 if (Eqs==NULL){
00188 if ((*I)!=NULL) Matrix_Free(*I);
00189 I = NULL;
00190 return;
00191 }
00192
00193
00194
00195
00196 rk = Eqs->NbRows;
00197 Matrix_subMatrix(Eqs, 0, 1, rk, Eqs->NbColumns-1, &M);
00198 left_hermite(M, &Hm, &Q, &U);
00199 Matrix_Free(M);
00200 Matrix_subMatrix(Hm, 0, 0, rk, rk, &H);
00201 if (dbgCompParmMore) {
00202 show_matrix(Hm);
00203 show_matrix(H);
00204 show_matrix(U);
00205 }
00206 Matrix_Free(Q);
00207 Matrix_Free(Hm);
00208 Matrix_subMatrix(Eqs, 0, Eqs->NbColumns-1, rk, Eqs->NbColumns, &C);
00209 Matrix_oppose(C);
00210 Hi = Matrix_Alloc(rk, rk+1);
00211 MatInverse(H, Hi);
00212 if (dbgCompParmMore) {
00213 show_matrix(C);
00214 show_matrix(Hi);
00215 }
00216
00217 Matrix_subMatrix(Hi, 0, 0, rk, rk, &H);
00218 Ip = Matrix_Alloc(Eqs->NbColumns-2, 1);
00219
00220 Ip->NbRows = rk;
00221 Matrix_Product(H, C, Ip);
00222 Ip->NbRows = Eqs->NbColumns-2;
00223 Matrix_Free(H);
00224 Matrix_Free(C);
00225 value_init(mod);
00226 for (i=0; i< rk; i++) {
00227
00228 value_pmodulus(mod, Ip->p[i][0], Hi->p[i][rk]);
00229 if (value_notzero_p(mod)) {
00230 if ((*I)!=NULL) Matrix_Free(*I);
00231 value_clear(mod);
00232 Matrix_Free(U);
00233 Matrix_Free(Ip);
00234 Matrix_Free(Hi);
00235 I = NULL;
00236 return;
00237 }
00238 else {
00239 value_pdivision(Ip->p[i][0], Ip->p[i][0], Hi->p[i][rk]);
00240 }
00241 }
00242
00243 for (i=rk; i< Eqs->NbColumns-2; i++) {
00244 value_set_si(Ip->p[i][0], 0);
00245 }
00246 value_clear(mod);
00247 Matrix_Free(Hi);
00248
00249 ensureMatrix((*I), Eqs->NbColumns-2, 1);
00250 Matrix_Product(U, Ip, (*I));
00251 Matrix_Free(U);
00252 Matrix_Free(Ip);
00253 if (dbgCompParm) {
00254 show_matrix(*I);
00255 }
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 void Equalities_validityLattice(Matrix * Eqs, int a, Matrix** vl) {
00272 unsigned int b = Eqs->NbColumns-2-a;
00273 unsigned int r = Eqs->NbRows;
00274 Matrix * A=NULL, * B=NULL, *I = NULL, *Lb=NULL, *sol=NULL;
00275 Matrix *H, *U, *Q;
00276 unsigned int i;
00277
00278 if (dbgCompParm) {
00279 printf("Computing validity lattice induced by the %d first variables of:"
00280 ,a);
00281 show_matrix(Eqs);
00282 }
00283 if (b==0) {
00284 ensureMatrix((*vl), 1, 1);
00285 value_set_si((*vl)->p[0][0], 1);
00286 return;
00287 }
00288
00289
00290
00291 Equalities_integerSolution(Eqs, &sol);
00292
00293 if (sol==NULL) {
00294 if ((*vl)!=NULL) Matrix_Free(*vl);
00295 return;
00296 }
00297 Matrix_subMatrix(Eqs, 0, 1, r, 1+a, &A);
00298 Matrix_subMatrix(Eqs, 0, 1+a, r, 1+a+b, &B);
00299 linearInter(A, B, &I, &Lb);
00300 Matrix_Free(A);
00301 Matrix_Free(B);
00302 Matrix_Free(I);
00303 if (dbgCompParm) {
00304 show_matrix(Lb);
00305 }
00306
00307
00308 left_hermite(Lb, &H, &Q, &U);
00309 Matrix_Free(Lb);
00310 Matrix_Free(Q);
00311 Matrix_Free(U);
00312
00313
00314 ensureMatrix((*vl), b+1, b+1);
00315 Matrix_copySubMatrix(H, 0, 0, b, b, (*vl), 0,0);
00316 Matrix_Free(H);
00317 for (i=0; i< b; i++) {
00318 value_assign((*vl)->p[i][b], sol->p[0][a+i]);
00319 }
00320 Matrix_Free(sol);
00321 Vector_Set((*vl)->p[b],0, b);
00322 value_set_si((*vl)->p[b][b], 1);
00323
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 void Constraints_removeElimCols(Matrix * M, unsigned int nbVars,
00336 unsigned int *elimParms, Matrix ** newM) {
00337 unsigned int i, j, k;
00338 if (elimParms[0]==0) {
00339 Matrix_clone(M, newM);
00340 return;
00341 }
00342 if ((*newM)==NULL) {
00343 (*newM) = Matrix_Alloc(M->NbRows, M->NbColumns - elimParms[0]);
00344 }
00345 else {
00346 assert ((*newM)->NbColumns==M->NbColumns - elimParms[0]);
00347 }
00348 for (i=0; i< M->NbRows; i++) {
00349 value_assign((*newM)->p[i][0], M->p[i][0]);
00350 k=0;
00351 Vector_Copy(&(M->p[i][1]), &((*newM)->p[i][1]), nbVars);
00352 for (j=0; j< M->NbColumns-2-nbVars; j++) {
00353 if (j!=elimParms[k+1]) {
00354 value_assign((*newM)->p[i][j-k+nbVars+1], M->p[i][j+nbVars+1]);
00355 }
00356 else {
00357 k++;
00358 }
00359 }
00360 value_assign((*newM)->p[i][(*newM)->NbColumns-1],
00361 M->p[i][M->NbColumns-1]);
00362 }
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 void Constraints_fullDimensionize(Matrix ** M, Matrix ** C, Matrix ** VL,
00387 Matrix ** Eqs, Matrix ** ParmEqs,
00388 unsigned int ** elimVars,
00389 unsigned int ** elimParms,
00390 int maxRays) {
00391 unsigned int i, j;
00392 Matrix * A=NULL, *B=NULL;
00393 Matrix * Ineqs=NULL;
00394 unsigned int nbVars = (*M)->NbColumns - (*C)->NbColumns;
00395 unsigned int nbParms;
00396 int nbElimVars;
00397 Matrix * fullDim = NULL;
00398
00399
00400 unsigned int * permutation;
00401 Matrix * permutedEqs=NULL, * permutedIneqs=NULL;
00402
00403
00404 (*ParmEqs) = Constraints_removeParmEqs(M, C, 0, elimParms);
00405
00406 if ((*M)->NbColumns==0) return;
00407
00408 if (elimParms[0]!=0) {
00409 Constraints_removeElimCols(*M, nbVars, (*elimParms), &A);
00410 Matrix_Free(*M);
00411 (*M) = A;
00412 Constraints_removeElimCols(*C, 0, (*elimParms), &B);
00413 Matrix_Free(*C);
00414 (*C) = B;
00415 if (dbgCompParm) {
00416 printf("After false parameter elimination: \n");
00417 show_matrix(*M);
00418 show_matrix(*C);
00419 }
00420 }
00421 nbParms = (*C)->NbColumns-2;
00422
00423
00424
00425 split_constraints((*M), Eqs, &Ineqs);
00426 nbElimVars = (*Eqs)->NbRows;
00427
00428 if ((*Eqs)->NbRows==0) {
00429 Matrix_identity(nbParms+1, VL);
00430 return;
00431 }
00432
00433 permutation = find_a_permutation((*Eqs), nbParms);
00434
00435 if (dbgCompParm) {
00436 printf("Permuting the vars/parms this way: [ ");
00437 for (i=0; i< (*Eqs)->NbColumns-2; i++) {
00438 printf("%d ", permutation[i]);
00439 }
00440 printf("]\n");
00441 }
00442
00443 Constraints_permute((*Eqs), permutation, &permutedEqs);
00444 Equalities_validityLattice(permutedEqs, (*Eqs)->NbRows, VL);
00445
00446 if (dbgCompParm) {
00447 printf("Validity lattice: ");
00448 show_matrix(*VL);
00449 }
00450 Constraints_compressLastVars(permutedEqs, (*VL));
00451 Constraints_permute(Ineqs, permutation, &permutedIneqs);
00452 if (dbgCompParmMore) {
00453 show_matrix(permutedIneqs);
00454 show_matrix(permutedEqs);
00455 }
00456 Matrix_Free(*Eqs);
00457 Matrix_Free(Ineqs);
00458 Constraints_compressLastVars(permutedIneqs, (*VL));
00459 if (dbgCompParm) {
00460 printf("After compression: ");
00461 show_matrix(permutedIneqs);
00462 }
00463
00464 assert(Constraints_eliminateFirstVars(permutedEqs, permutedIneqs));
00465 if (dbgCompParmMore) {
00466 printf("After elimination of the variables: ");
00467 show_matrix(permutedIneqs);
00468 }
00469
00470
00471
00472 fullDim = Matrix_Alloc(permutedIneqs->NbRows,
00473 permutedIneqs->NbColumns-nbElimVars);
00474 for (i=0; i< permutedIneqs->NbRows; i++) {
00475 value_set_si(fullDim->p[i][0], 1);
00476 for (j=0; j< nbParms; j++) {
00477 value_assign(fullDim->p[i][j+fullDim->NbColumns-nbParms-1],
00478 permutedIneqs->p[i][j+nbElimVars+1]);
00479 }
00480 for (j=0; j< permutedIneqs->NbColumns-nbParms-2-nbElimVars; j++) {
00481 value_assign(fullDim->p[i][j+1],
00482 permutedIneqs->p[i][nbElimVars+nbParms+j+1]);
00483 }
00484 value_assign(fullDim->p[i][fullDim->NbColumns-1],
00485 permutedIneqs->p[i][permutedIneqs->NbColumns-1]);
00486 }
00487 Matrix_Free(permutedIneqs);
00488
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 void Lattice_extractSubLattice(Matrix * lat, unsigned int k, Matrix ** subLat) {
00500 Matrix * H, *Q, *U, *linLat = NULL;
00501 unsigned int i;
00502 dbgStart(Lattice_extractSubLattice);
00503
00504 if (k==lat->NbRows-1) {
00505 if (*subLat==NULL) {
00506 (*subLat) = Matrix_Copy(lat);
00507 }
00508 else {
00509 Matrix_copySubMatrix(lat, 0, 0, lat->NbRows, lat->NbColumns, (*subLat), 0, 0);
00510 }
00511 return;
00512 }
00513 assert(k<lat->NbRows-1);
00514
00515
00516 Matrix_subMatrix(lat, 0, 0, lat->NbRows, lat->NbColumns-1, &linLat);
00517
00518
00519 left_hermite(linLat, &H, &Q, &U);
00520 if (dbgCompParmMore) {
00521 show_matrix(H);
00522 }
00523 Matrix_Free(Q);
00524 Matrix_Free(U);
00525 Matrix_Free(linLat);
00526
00527 if (*subLat==NULL) {
00528 (*subLat) = Matrix_Alloc(k+1, k+1);
00529 }
00530 Matrix_copySubMatrix(H, 0, 0, k, k, (*subLat), 0, 0);
00531 Matrix_Free(H);
00532 Matrix_copySubMatrix(lat, 0, lat->NbColumns-1, k, 1, (*subLat), 0, k);
00533 for (i=0; i<k; i++) {
00534 value_set_si((*subLat)->p[k][i], 0);
00535 }
00536 value_set_si((*subLat)->p[k][k], 1);
00537 dbgEnd(Lattice_extractSubLattice);
00538 }
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 Matrix * affine_periods(Matrix * M, Matrix * d) {
00549 Matrix * S;
00550 unsigned int i,j;
00551 Value tmp;
00552 Value * periods = (Value *)malloc(sizeof(Value) * M->NbColumns);
00553 value_init(tmp);
00554 for(i=0; i< M->NbColumns; i++) {
00555 value_init(periods[i]);
00556 value_set_si(periods[i], 1);
00557 }
00558 for (i=0; i<M->NbRows; i++) {
00559 for (j=0; j< M->NbColumns; j++) {
00560 value_gcd(tmp, d->p[i][0], M->p[i][j]);
00561 value_divexact(tmp, d->p[i][0], tmp);
00562 value_lcm(periods[j], periods[j], tmp);
00563 }
00564 }
00565 value_clear(tmp);
00566
00567
00568 S = Matrix_Alloc(M->NbColumns, M->NbColumns);
00569 for (i=0; i< M->NbColumns; i++)
00570 for (j=0; j< M->NbColumns; j++)
00571 if (i==j) value_assign(S->p[i][j],periods[j]);
00572 else value_set_si(S->p[i][j], 0);
00573
00574
00575 for(i=0; i< M->NbColumns; i++) value_clear(periods[i]);
00576 free(periods);
00577 return S;
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 void Equalities_intModBasis(Matrix * B, Matrix * C, Matrix * d, Matrix ** imb) {
00593 int b = B->NbColumns;
00594
00595
00596 int nbEqs = B->NbRows;
00597 unsigned int i;
00598
00599
00600 Matrix * eqs = Matrix_Alloc(nbEqs, nbEqs+b+1);
00601 for (i=0; i< nbEqs; i++) {
00602 value_assign(eqs->p[i][i], d->p[0][i]);
00603 }
00604 Matrix_copySubMatrix(B, 0, 0, nbEqs, b, eqs, 0, nbEqs);
00605 Matrix_copySubMatrix(C, 0, 0, nbEqs, 1, eqs, 0, nbEqs+b);
00606
00607
00608 Equalities_validityLattice(eqs, nbEqs, imb);
00609 Matrix_Free(eqs);
00610 }
00611
00612
00613
00614 Matrix * int_mod_basis(Matrix * B, Matrix * C, Matrix * d) {
00615 Matrix * imb = NULL;
00616 Equalities_intModBasis(B, C, d, &imb);
00617 return imb;
00618 }
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 Matrix * compress_parms(Matrix * E, int nbParms) {
00631 Matrix * vl=NULL;
00632 Equalities_validityLattice(E, E->NbColumns-2-nbParms, &vl);
00633 return vl;
00634 }
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649 Matrix * Constraints_Remove_parm_eqs(Matrix ** M1, Matrix ** Ctxt1,
00650 int renderSpace,
00651 unsigned int ** elimParms) {
00652 int i, j, k, nbEqsParms =0;
00653 int nbEqsM, nbEqsCtxt, allZeros, nbTautoM = 0, nbTautoCtxt = 0;
00654 Matrix * M = (*M1);
00655 Matrix * Ctxt = (*Ctxt1);
00656 int nbVars = M->NbColumns-Ctxt->NbColumns;
00657 Matrix * Eqs;
00658 Matrix * EqsMTmp;
00659
00660
00661 nbEqsM = 0;
00662 for (i=0; i< M->NbRows; i++) {
00663 k = First_Non_Zero(M->p[i], M->NbColumns);
00664
00665 if (k==-1) {
00666 nbTautoM++;
00667 }
00668 else {
00669
00670 if (k>= nbVars+1) nbEqsM++;
00671 }
00672 }
00673
00674 nbEqsCtxt = 0;
00675 for (i=0; i< Ctxt->NbRows; i++) {
00676 if (value_zero_p(Ctxt->p[i][0])) {
00677 if (First_Non_Zero(Ctxt->p[i], Ctxt->NbColumns)==-1) {
00678 nbTautoCtxt++;
00679 }
00680 else {
00681 nbEqsCtxt ++;
00682 }
00683 }
00684 }
00685 nbEqsParms = nbEqsM + nbEqsCtxt;
00686
00687
00688 if (nbEqsParms+nbTautoM+nbTautoCtxt==0) {
00689 (*elimParms) = (unsigned int*) malloc(sizeof(int));
00690 (*elimParms)[0] = 0;
00691 if (renderSpace==0) {
00692 return Matrix_Alloc(0,Ctxt->NbColumns);
00693 }
00694 else {
00695 return Matrix_Alloc(0,M->NbColumns);
00696 }
00697 }
00698
00699 Eqs= Matrix_Alloc(nbEqsParms, Ctxt->NbColumns);
00700 EqsMTmp= Matrix_Alloc(nbEqsParms, M->NbColumns);
00701
00702
00703 k = 0;
00704 for (i=0; i< Ctxt->NbRows; i++) {
00705 if (value_zero_p(Ctxt->p[i][0])
00706 && First_Non_Zero(Ctxt->p[i], Ctxt->NbColumns)!=-1) {
00707 Vector_Copy(Ctxt->p[i], Eqs->p[k], Ctxt->NbColumns);
00708 Vector_Copy(Ctxt->p[i]+1, EqsMTmp->p[k]+nbVars+1,
00709 Ctxt->NbColumns-1);
00710 k++;
00711 }
00712 }
00713 for (i=0; i< M->NbRows; i++) {
00714 j=First_Non_Zero(M->p[i], M->NbColumns);
00715
00716 if (j>=nbVars+1) {
00717 Vector_Copy(M->p[i]+nbVars+1, Eqs->p[k]+1, Ctxt->NbColumns-1);
00718 Vector_Copy(M->p[i]+nbVars+1, EqsMTmp->p[k]+nbVars+1,
00719 Ctxt->NbColumns-1);
00720
00721 value_set_si(M->p[i][0], 2);
00722 k++;
00723 }
00724
00725 if (j==-1) {
00726 value_set_si(M->p[i][0], 2);
00727 }
00728 }
00729
00730
00731
00732 (*elimParms) = (unsigned int *) malloc((Eqs->NbRows+1) * sizeof(int));
00733 (*elimParms)[0] = 0;
00734 allZeros = 0;
00735 for (i=0; i< Eqs->NbRows; i++) {
00736
00737 k = First_Non_Zero(Eqs->p[i], Eqs->NbColumns);
00738 if (k!=-1) {
00739
00740
00741 if (k==Eqs->NbColumns-1) {
00742 printf("Contradiction in %dth row of Eqs: ",k);
00743 show_matrix(Eqs);
00744 Matrix_Free(Eqs);
00745 Matrix_Free(EqsMTmp);
00746 (*M1) = Matrix_Alloc(0, M->NbColumns);
00747 Matrix_Free(M);
00748 (*Ctxt1) = Matrix_Alloc(0,Ctxt->NbColumns);
00749 Matrix_Free(Ctxt);
00750 free(*elimParms);
00751 (*elimParms) = (unsigned int *) malloc(sizeof(int));
00752 (*elimParms)[0] = 0;
00753 if (renderSpace==1) {
00754 return Matrix_Alloc(0,(*M1)->NbColumns);
00755 }
00756 else {
00757 return Matrix_Alloc(0,(*Ctxt1)->NbColumns);
00758 }
00759 }
00760
00761
00762 else {
00763 k--;
00764 (*elimParms)[0]++;
00765 (*elimParms)[(*elimParms[0])]=k;
00766 for (j=0; j< Eqs->NbRows; j++) {
00767 if (i!=j) {
00768 eliminate_var_with_constr(Eqs, i, Eqs, j, k);
00769 eliminate_var_with_constr(EqsMTmp, i, EqsMTmp, j, k+nbVars);
00770 }
00771 }
00772 for (j=0; j< Ctxt->NbRows; j++) {
00773 if (value_notzero_p(Ctxt->p[i][0])) {
00774 eliminate_var_with_constr(Eqs, i, Ctxt, j, k);
00775 }
00776 }
00777 for (j=0; j< M->NbRows; j++) {
00778 if (value_cmp_si(M->p[i][0], 2)) {
00779 eliminate_var_with_constr(EqsMTmp, i, M, j, k+nbVars);
00780 }
00781 }
00782 }
00783 }
00784
00785 else {
00786 allZeros++;
00787 }
00788 }
00789
00790
00791
00792 if (!realloc((*elimParms), ((*elimParms)[0]+1)*sizeof(int))) {
00793 fprintf(stderr, "Constraints_Remove_parm_eqs > cannot realloc()");
00794 }
00795
00796 Matrix_Free(EqsMTmp);
00797
00798
00799
00800 EqsMTmp = Matrix_Alloc(M->NbRows-nbEqsM-nbTautoM, M->NbColumns);
00801 k=0;
00802 for (i=0; i< M->NbRows; i++) {
00803 if (value_cmp_si(M->p[i][0], 2)) {
00804 Vector_Copy(M->p[i], EqsMTmp->p[k], M->NbColumns);
00805 k++;
00806 }
00807 }
00808 Matrix_Free(M);
00809 (*M1) = EqsMTmp;
00810
00811 EqsMTmp = Matrix_Alloc(Ctxt->NbRows-nbEqsCtxt-nbTautoCtxt, Ctxt->NbColumns);
00812 k=0;
00813 for (i=0; i< Ctxt->NbRows; i++) {
00814 if (value_notzero_p(Ctxt->p[i][0])) {
00815 Vector_Copy(Ctxt->p[i], EqsMTmp->p[k], Ctxt->NbColumns);
00816 k++;
00817 }
00818 }
00819 Matrix_Free(Ctxt);
00820 (*Ctxt1) = EqsMTmp;
00821
00822 if (renderSpace==0) {
00823 EqsMTmp = Matrix_Alloc(Eqs->NbRows-allZeros, Eqs->NbColumns);
00824 k=0;
00825 for (i=0; i<Eqs->NbRows; i++) {
00826 if (First_Non_Zero(Eqs->p[i], Eqs->NbColumns)!=-1) {
00827 Vector_Copy(Eqs->p[i], EqsMTmp->p[k], Eqs->NbColumns);
00828 k++;
00829 }
00830 }
00831 }
00832 else {
00833 EqsMTmp = Matrix_Alloc(Eqs->NbRows-allZeros, (*M1)->NbColumns);
00834 k=0;
00835 for (i=0; i<Eqs->NbRows; i++) {
00836 if (First_Non_Zero(Eqs->p[i], Eqs->NbColumns)!=-1) {
00837 Vector_Copy(Eqs->p[i], &(EqsMTmp->p[k][nbVars]), Eqs->NbColumns);
00838 k++;
00839 }
00840 }
00841 }
00842 Matrix_Free(Eqs);
00843 Eqs = EqsMTmp;
00844
00845 return Eqs;
00846 }
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856 Polyhedron * Polyhedron_Remove_parm_eqs(Polyhedron ** P, Polyhedron ** C,
00857 int renderSpace,
00858 unsigned int ** elimParms,
00859 int maxRays) {
00860 Matrix * Eqs;
00861 Polyhedron * Peqs;
00862 Matrix * M = Polyhedron2Constraints((*P));
00863 Matrix * Ct = Polyhedron2Constraints((*C));
00864
00865
00866
00867 if (F_ISSET((*P), POL_VALID | POL_INEQUALITIES) &&
00868 (F_ISSET((*C), POL_VALID | POL_INEQUALITIES))) {
00869 FL_INIT(maxRays, POL_NO_DUAL);
00870 }
00871
00872 Eqs = Constraints_Remove_parm_eqs(&M, &Ct, renderSpace, elimParms);
00873 Peqs = Constraints2Polyhedron(Eqs, maxRays);
00874 Matrix_Free(Eqs);
00875
00876
00877 if (Eqs->NbRows==0) {
00878 Matrix_Free(M);
00879 Matrix_Free(Ct);
00880 return Peqs;
00881 }
00882 Polyhedron_Free(*P);
00883 Polyhedron_Free(*C);
00884 (*P) = Constraints2Polyhedron(M, maxRays);
00885 (*C) = Constraints2Polyhedron(Ct, maxRays);
00886 Matrix_Free(M);
00887 Matrix_Free(Ct);
00888 return Peqs;
00889 }
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904 Matrix * full_dimensionize(Matrix const * M, int nbParms,
00905 Matrix ** validityLattice) {
00906 Matrix * Eqs, * Ineqs;
00907 Matrix * permutedEqs, * permutedIneqs;
00908 Matrix * Full_Dim;
00909 Matrix * WVL;
00910 unsigned int i,j;
00911 int nbElimVars;
00912 unsigned int * permutation, * permutationInv;
00913
00914 split_constraints(M, &Eqs, &Ineqs);
00915
00916
00917 if (Eqs->NbRows==0) {
00918 Matrix_Free(Eqs);
00919 (*validityLattice) = Identity_Matrix(nbParms+1);
00920 return Ineqs;
00921 }
00922 nbElimVars = Eqs->NbRows;
00923
00924
00925
00926
00927 permutation = find_a_permutation(Eqs, nbParms);
00928 if (dbgCompParm) {
00929 printf("Permuting the vars/parms this way: [ ");
00930 for (i=0; i< Eqs->NbColumns; i++) {
00931 printf("%d ", permutation[i]);
00932 }
00933 printf("]\n");
00934 }
00935 permutedEqs = mpolyhedron_permute(Eqs, permutation);
00936 WVL = compress_parms(permutedEqs, Eqs->NbColumns-2-Eqs->NbRows);
00937 if (dbgCompParm) {
00938 printf("Whole validity lattice: ");
00939 show_matrix(WVL);
00940 }
00941 mpolyhedron_compress_last_vars(permutedEqs, WVL);
00942 permutedIneqs = mpolyhedron_permute(Ineqs, permutation);
00943 if (dbgCompParm) {
00944 show_matrix(permutedEqs);
00945 }
00946 Matrix_Free(Eqs);
00947 Matrix_Free(Ineqs);
00948 mpolyhedron_compress_last_vars(permutedIneqs, WVL);
00949 if (dbgCompParm) {
00950 printf("After compression: ");
00951 show_matrix(permutedIneqs);
00952 }
00953
00954 if (!mpolyhedron_eliminate_first_variables(permutedEqs, permutedIneqs)) {
00955 fprintf(stderr,"full-dimensionize > variable elimination failed. \n");
00956 return NULL;
00957 }
00958 if (dbgCompParm) {
00959 printf("After elimination of the variables: ");
00960 show_matrix(permutedIneqs);
00961 }
00962
00963
00964
00965 Full_Dim = Matrix_Alloc(permutedIneqs->NbRows,
00966 permutedIneqs->NbColumns-nbElimVars);
00967 for (i=0; i< permutedIneqs->NbRows; i++) {
00968 value_set_si(Full_Dim->p[i][0], 1);
00969 for (j=0; j< nbParms; j++)
00970 value_assign(Full_Dim->p[i][j+Full_Dim->NbColumns-nbParms-1],
00971 permutedIneqs->p[i][j+nbElimVars+1]);
00972 for (j=0; j< permutedIneqs->NbColumns-nbParms-2-nbElimVars; j++)
00973 value_assign(Full_Dim->p[i][j+1],
00974 permutedIneqs->p[i][nbElimVars+nbParms+j+1]);
00975 value_assign(Full_Dim->p[i][Full_Dim->NbColumns-1],
00976 permutedIneqs->p[i][permutedIneqs->NbColumns-1]);
00977 }
00978 Matrix_Free(permutedIneqs);
00979
00980
00981 *validityLattice = Matrix_Alloc(nbParms+1, nbParms+1);
00982 for (i=0; i< nbParms; i++) {
00983 for (j=0; j< nbParms; j++)
00984 value_assign((*validityLattice)->p[i][j],
00985 WVL->p[i][j]);
00986 value_assign((*validityLattice)->p[i][nbParms],
00987 WVL->p[i][WVL->NbColumns-1]);
00988 }
00989 for (j=0; j< nbParms; j++)
00990 value_set_si((*validityLattice)->p[nbParms][j], 0);
00991 value_assign((*validityLattice)->p[nbParms][nbParms],
00992 WVL->p[WVL->NbColumns-1][WVL->NbColumns-1]);
00993
00994
00995 Matrix_Free(WVL);
00996 return Full_Dim;
00997 }
00998
00999 #undef dbgCompParm
01000 #undef dbgCompParmMore