polylib 7.01
polyparam.c
Go to the documentation of this file.
1/***********************************************************************/
2/* Parametrized polyhedra V4.20 */
3/* copyright 1995-2000 Vincent Loechner */
4/* copyright 1996-1997, Doran Wilde */
5/***********************************************************************/
6
7/********************* -----------USER #DEFS-------- ***********************/
8/* These are mainly for debug purposes. You shouldn't need to change */
9/* anything for daily usage... */
10/***************************************************************************/
11
12/* you may define each macro independently */
13/* #define DEBUGPP */
14/* #define DEBUGPP3 */ /* initialization of domain, context, ... */
15/* #define DEBUGPP31 */ /* even more init-domains */
16/* #define DEBUGPP32 */ /* even even more... (Elim_Columns) */
17/* #define DEBUGPP4 */ /* m-faces scan */
18/* #define DEBUGPP41 */ /* inverse Di in scan */
19/* #define DEBUGPP5 */ /* Compute_PDomains */
20/********************* ---------END USER #DEFS------ ***********************/
21
22#include <assert.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#ifdef DEBUGPP
27#include <time.h>
28#endif
29
30#include <polylib/polylib.h>
31
32static void traite_m_face(Polyhedron *, unsigned int *, unsigned int *);
33static void scan_m_face(int, int, Polyhedron *, unsigned int *);
34
35/*
36 * Return the intersection of two polyhedral domains 'Pol1' and 'Pol2' such
37 * that if the intersection is a polyhedron of lower dimension (a degenerate
38 * polyhedron) than the operands, it is discarded from the resulting polyhedra
39 * list.
40 */
42 unsigned NbMaxRays) {
43
44 Polyhedron *p1, *p2, *p3, *d;
45
46 if (!Pol1 || !Pol2)
47 return (Polyhedron *)0;
48 if ((Pol1->Dimension != Pol2->Dimension) || (Pol1->NbEq != Pol2->NbEq)) {
49 fprintf(stderr,
50 "? PDomainIntersection: operation on different dimensions\n");
51 return (Polyhedron *)0;
52 }
53
58
59 d = (Polyhedron *)0;
60 for (p1 = Pol1; p1; p1 = p1->next) {
61 for (p2 = Pol2; p2; p2 = p2->next) {
62 p3 = AddConstraints(p2->Constraint[0], p2->NbConstraints, p1, NbMaxRays);
63 if (!p3)
64 continue;
65
66 /* If the new polyhedron 'p3' has lower dimension, discard it */
67 if (p3->NbEq != Pol1->NbEq)
69
70 /* Otherwise add it to the new polyhderal domain 'd'. */
71 else
72 d = AddPolyToDomain(p3, d);
73 }
74 }
75 return d;
76} /* PDomainIntersection */
77
78/*
79 * Given polyhderal domains 'Pol1' and 'Pol2', return the difference of the
80 * two domains with a modification that the resulting polyhedra in the new
81 * domain don't have a 1 unit space around cut and the degenerate results
82 * (of smaller dimension) are discarded.
83 */
85 unsigned NbMaxRays) {
86
87 Polyhedron *p1, *p2, *p3, *d;
88 int i;
89
90 if (!Pol1 || !Pol2)
91 return (Polyhedron *)0;
92 if ((Pol1->Dimension != Pol2->Dimension) || (Pol1->NbEq != Pol2->NbEq)) {
93 fprintf(stderr, "? PDomainDifference: operation on different dimensions\n");
94 return (Polyhedron *)0;
95 }
96
101
102 d = (Polyhedron *)0;
103 for (p2 = Pol2; p2; p2 = p2->next) {
104 for (p1 = Pol1; p1; p1 = p1->next) {
105 for (i = 0; i < p2->NbConstraints; i++) {
106
107 /* Add the constraint (-p2->Constraint[i]) >= 0 in 'p1' */
108 p3 = SubConstraint(p2->Constraint[i], p1, NbMaxRays, 2);
109 if (!p3)
110 continue;
111
112 /* If the new polyhedron 'p3' is empty or is a polyhedron of lower */
113 /* dimension, discard it. */
114 if (emptyQ(p3) || p3->NbEq != Pol1->NbEq)
115 Polyhedron_Free(p3);
116
117 /* Otherwise add 'p3' to the new polyhderal domain 'd' */
118 else
119 d = AddPolyToDomain(p3, d);
120 }
121 }
122 if (p2 != Pol2)
123 Domain_Free(Pol1);
124 Pol1 = d;
125 d = (Polyhedron *)0;
126 }
127 return Pol1;
128} /* PDomainDifference */
129
130/*
131 * Return 1 if matrix 'Mat' is full column ranked, otherwise return 0.
132 */
133static int TestRank(Matrix *Mat) {
134
135 int i, j, k;
136 Value m1, m2, m3, gcd, tmp;
137
138 /* Initialize all the 'Value' variables */
139 value_init(m1);
140 value_init(m2);
141 value_init(m3);
142 value_init(gcd);
143 value_init(tmp);
144
145 for (k = 0; k < Mat->NbColumns; ++k) {
146
147 /* If the digonal entry (k,k) is zero, search down the column(k) */
148 /* starting from row(k) to find a non-zero entry */
149 if (value_zero_p(Mat->p[k][k])) {
150 for (j = k + 1; j < Mat->NbRows; ++j) {
151
152 /* If a non-zero entry (j,k) is found */
153 if (value_notzero_p(Mat->p[j][k])) {
154
155 /* Exchange row(k) and row(j) */
156 for (i = k; i < Mat->NbColumns; ++i) {
157 value_assign(tmp, Mat->p[j][i]);
158 value_assign(Mat->p[j][i], Mat->p[k][i]);
159 value_assign(Mat->p[k][i], tmp);
160 }
161 break;
162 }
163 }
164
165 /* If no non-zero entry is found then the matrix 'Mat' is not full */
166 /* ranked. Return zero. */
167 if (j >= Mat->NbRows) {
168
169 /* Clear all the 'Value' variables */
170 value_clear(m1);
171 value_clear(m2);
172 value_clear(m3);
173 value_clear(gcd);
174 value_clear(tmp);
175 return 0;
176 }
177 }
178
179 /* Now Mat[k][k] is the pivot element */
180 for (j = k + 1; j < Mat->NbRows; ++j) {
181
182 /* Make every other entry (below row(k)) in column(k) zero */
183 value_gcd(gcd, Mat->p[j][k], Mat->p[k][k]);
184 for (i = k + 1; i < Mat->NbColumns; ++i) {
185
186 /* pour tous les indices i > k */
187 value_multiply(m1, Mat->p[j][i], Mat->p[k][k]);
188 value_multiply(m2, Mat->p[j][k], Mat->p[k][i]);
189 value_subtract(m3, m1, m2);
190 value_division(Mat->p[j][i], m3, gcd);
191 }
192 }
193 }
194
195 /* Clear all the 'Value' variables */
196 value_clear(m1);
197 value_clear(m2);
198 value_clear(m3);
199 value_clear(gcd);
200 value_clear(tmp);
201
202 /* The matrix 'Mat' is full ranked, return 1 */
203 return 1;
204} /* TestRank */
205
206/*
207 * The Saturation matrix is defined to be an integer (int type) matrix. It is
208 * a boolean matrix which has a row for every constraint and a column for
209 * every line or ray. The bits in the binary format of each integer in the
210 * saturation matrix stores the information whether the corresponding constr-
211 * aint is saturated by ray(line) or not.
212 */
213typedef struct {
214 unsigned int NbRows;
215 unsigned int NbColumns;
216 unsigned int **p;
217 unsigned int *p_init;
218} SatMatrix;
219
220static SatMatrix *SMAlloc(int rows, int cols) {
221
222 unsigned int **q, *p;
223 int i;
224
225 SatMatrix *result = (SatMatrix *)malloc(sizeof(SatMatrix));
226 assert(result != NULL);
227
228 result->NbRows = rows;
229 result->NbColumns = cols;
230 result->p = q = (unsigned int **)malloc(rows * sizeof(unsigned int *));
231 assert(result->p != NULL);
232 result->p_init = p =
233 (unsigned int *)malloc(rows * cols * sizeof(unsigned int));
234 assert(result->p_init != NULL);
235
236 for (i = 0; i < rows; i++) {
237 *q++ = p;
238 p += cols;
239 }
240
241 return result;
242} /* SMAlloc */
243
244#if defined(DEBUGPP4)
245static void SMPrint(SatMatrix *matrix) {
246
247 unsigned int *p;
248 int i, j;
249 unsigned NbRows, NbColumns;
250
251 fprintf(stderr, "%d %d\n", NbRows = matrix->NbRows,
252 NbColumns = matrix->NbColumns);
253 for (i = 0; i < NbRows; i++) {
254 p = *(matrix->p + i);
255 for (j = 0; j < NbColumns; j++)
256 fprintf(stderr, " %10X ", *p++);
257 fprintf(stderr, "\n");
258 }
259} /* SMPrint */
260#endif
261
262static void SMFree(SatMatrix *matrix) {
263
264 free((char *)matrix->p_init);
265 free((char *)matrix->p);
266 free((char *)matrix);
267 return;
268} /* SMFree */
269
270/* -------------------------------------------------------------------------
271 * Shared Global Variables:
272 * Used by procedures: Find_m_face, scan_m_face, Poly2Sat, traite_m_face,
273 * count_sat
274 * -------------------------------------------------------------------------
275 */
276static int m; /* number of parameters */
277static int m_dim; /* dimension of m-face */
278static int n; /* dimension (not including parameters) */
279static int ws; /* Working Space size */
280static int nr; /* (NbRays-1)/32 + 1 */
281
282static Polyhedron *CEqualities; /* Equalities in the context */
283static SatMatrix *Sat; /* Saturation Matrix (row=constraint, col=ray)*/
284static unsigned int *egalite; /* Bool vector marking constraints in m-face */
285static Matrix *Xi, *Pi; /* Xi and Pi */
286static Matrix *PiTest; /* Matrix used to test if Pi is full ranked? */
287static Matrix *CTest;
288static Matrix *PiInv; /* Matrix inverse Pi, with the last col of */
289 /* each line = denominator of the line */
290static Matrix *RaysDi; /* Constraint matrix for computing Di */
291
292static int KD; /* Flag : keep the full domains in memory ? */
293 /* 1 = yes; 0 = no, keep constraints only */
294
295static int nbPV; /* The number of parameterized vertices */
296static Param_Vertices *PV_Result; /* List of parameterized vertices */
297static Param_Domain *PDomains; /* List of domains. */
298
299#ifdef DEBUGPP
300static int nbfaces;
301#endif
302
303/*
304 * Add the constraints from the context polyhedron 'CEqualities' to the
305 * constraints of polyhedra in the polyhedral domain 'D' and return the new
306 * polyhedral domain. Polyhedral domain 'D' is subsequently deleted from memory
307 */
309
310 Polyhedron *d, *r, *tmp;
311
312 if (!CEqualities)
313 return D;
314 else {
315 if (!D || emptyQ(D)) {
316 if (D)
317 Domain_Free(D);
319 }
321 tmp = r;
322 for (d = D->next; d; d = d->next) {
323 tmp->next =
325 tmp = tmp->next;
326 }
327 Domain_Free(D);
328 return (r);
329 }
330} /* Add_CEqualities */
331
332#define INT_BITS (sizeof(unsigned) * 8)
333
334unsigned int *int_array2bit_vector(unsigned int *array, int n) {
335 int i, ix;
336 unsigned bx;
337 int words = (n + INT_BITS - 1) / INT_BITS;
338 unsigned int *bv = (unsigned int *)calloc(words, sizeof(unsigned));
339 assert(bv);
340 for (i = 0, ix = 0, bx = MSB; i < n; ++i) {
341 if (array[i])
342 bv[ix] |= bx;
343 NEXT(ix, bx);
344 }
345 return bv;
346}
347
348/*----------------------------------------------------------------------*/
349/* traite_m_face */
350/* Given an m-face, compute the parameterized vertex */
351/* D - The entire domain */
352/* mf - Bit vector marking the lines/rays in the m-face */
353/* egalite - boolean vector marking saturated constraints in m-face */
354/*----------------------------------------------------------------------*/
355static void traite_m_face(Polyhedron *D, unsigned int *mf,
356 unsigned int *egalite) {
357 Matrix *Si; /* Solution */
358 Polyhedron *PDi; /* polyhedron Di */
359 Param_Vertices *PV;
360 int j, k, c, r;
361 unsigned kx, bx;
362
363#ifdef DEBUGPP
364 ++nbfaces;
365#endif
366
367 /* Extract Xi, Pi, and RaysDi from D */
368 RaysDi->NbRows = 0;
369 for (k = 0, c = 0, kx = 0, bx = MSB; k < D->NbRays; ++k) {
370 if (mf[kx] & bx) { /* this ray is in the current m-face */
371 if (c < m + 1) {
372 int i;
373
374 /* tester si cette nouvelle colonne est lin. indep. des autres */
375 /* i.e. si gauss ne donne pas de '0' sur la colonne Pi */
376 /* jusqu'a l'indice 'c' */
377
378 /* construit PiTest */
379 for (j = 0; j < m + 1; ++j) {
380 for (i = 0; i < c; ++i)
381
382 /* les c premieres colonnes */
383 value_assign(PiTest->p[j][i], Pi->p[j][i]);
384
385 /* la nouvelle */
386 value_assign(PiTest->p[j][c], D->Ray[k][j + 1 + n]);
387 }
388 PiTest->NbColumns = c + 1;
389 r = TestRank(PiTest);
390 if (r /* TestRank(PiTest) */) {
391
392 /* Ok, c'est lin. indep. */
393 for (j = 0; j < n; j++)
394 value_assign(Xi->p[j][c], D->Ray[k][j + 1]); /* Xi */
395 for (j = 0; j < m; j++)
396 value_assign(Pi->p[j][c], D->Ray[k][j + 1 + n]); /* Pi */
397 value_assign(Xi->p[n][c], D->Ray[k][n + m + 1]); /* const */
398 value_assign(Pi->p[m][c], D->Ray[k][n + m + 1]); /* const */
399 c++;
400 }
401 }
402
403 /* Status bit */
404 value_assign(RaysDi->p[RaysDi->NbRows][0], D->Ray[k][0]);
405 Vector_Copy(&D->Ray[k][n + 1], &RaysDi->p[RaysDi->NbRows][1], (m + 1));
406 ++RaysDi->NbRows;
407 }
408 NEXT(kx, bx);
409 }
410
411#ifdef DEBUGPP41
412 fprintf(stderr, "\nRaysDi=\n");
414 if (c < m + 1)
415 fprintf(stderr, "Invalid ");
416 fprintf(stderr, "Pi=\n");
417 Matrix_Print(stderr, P_VALUE_FMT, Pi);
418#endif
419
420#ifdef DEBUGPP4
421 if (c < m + 1)
422 fprintf(stderr, "Eliminated because of no vertex\n");
423#endif
424
425 if (c < m + 1)
426 return;
427
428 /* RaysDi->numColumns = m+2; */ /* stays the same */
429
430 /* Xi->NbColumns = m+1;*/ /* VIN100: stays the same. was 'c'! */
431 /* Xi->NbRows = n+1; */ /* stays the same */
432 /* Pi->NbColumns = m+1;*/ /* VIN100: stays the same. was 'c'! */
433 /* Pi->NbRows = m+1; */ /* stays the same */
434
435#ifdef DEBUGPP4
436 fprintf(stderr, "Xi = ");
437 Matrix_Print(stderr, P_VALUE_FMT, Xi);
438 fprintf(stderr, "Pi = ");
439 Matrix_Print(stderr, P_VALUE_FMT, Pi);
440#endif
441
442 /* (Right) invert Pi if POSSIBLE, if not then next m-face */
443 /* Pi is destroyed */
444 if (!MatInverse(Pi, PiInv)) {
445
446#ifdef DEBUGPP4
447 fprintf(stderr, "Eliminated because of no inverse Pi\n");
448#endif
449
450 return;
451 }
452
453#ifdef DEBUGPP4
454 fprintf(stderr, "FACE GENERATED!\n");
455 fprintf(stderr, "PiInv = ");
457#endif
458
459 /* Compute Si (now called Ti in the paper) */
461 rat_prodmat(Si, Xi, PiInv);
462
463#ifdef DEBUGPP4
464 fprintf(stderr, "Si = ");
465 Matrix_Print(stderr, P_VALUE_FMT, Si);
466#endif
467
468 Si->NbRows--; /* throw out the last row = 0 ... 0 1 */
469
470 /* Copy all of that into the PV structure */
471 PV = (Param_Vertices *)malloc(sizeof(Param_Vertices));
472 PV->next = PV_Result;
473 PV->Vertex = Si;
474 PV->Domain = NULL;
476 PV_Result = PV;
477 nbPV++; /* increment vertex count */
478
479 /* Ok... now compute the parameter domain */
480 PDi = Rays2Polyhedron(RaysDi, ws);
481
482#ifdef DEBUGPP3
483 fprintf(stderr, "RaysDi = ");
485 fprintf(stderr, "PDi = ");
486 Polyhedron_Print(stderr, P_VALUE_FMT, PDi);
487#endif
488
489 if (KD == 0) {
490
491 /* Add the equalities again to the domain */
492 PDi = Add_CEqualities(PDi);
494 Polyhedron_Free(PDi);
495 } else {
496 Param_Domain *PD;
497 PD = (Param_Domain *)malloc(sizeof(Param_Domain));
498 PD->Domain = PDi;
499 PD->F = NULL;
500 PD->next = PDomains;
501 PDomains = PD;
502 }
503 return;
504} /* traite_m_face */
505
506/*----------------------------------------------------------------------*/
507/* count_sat */
508/* count the number of saturated rays in the bit vector mf */
509/* Uses nr from global area */
510/*----------------------------------------------------------------------*/
511int cntbit[256] = {/* counts for 8 bits */
512 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
513 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
514 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
515 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
516
517 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
518 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
519 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
520 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
521
522 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
523 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
524 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
525 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
526
527 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
528 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
529 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
530 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
531
532static int count_sat(unsigned int *mf) {
533
534 register unsigned int i, tmp, cnt = 0;
535
536 for (i = 0; i < nr; i++) {
537 tmp = mf[i];
538 cnt = cnt + cntbit[tmp & 0xff] + cntbit[(tmp >> 8) & 0xff] +
539 cntbit[(tmp >> 16) & 0xff] + cntbit[(tmp >> 24) & 0xff];
540 }
541 return cnt;
542} /* count_sat */
543
544/* Returns true if all bits in part are also set in bv */
545static int bit_vector_includes(unsigned int *bv, int len, unsigned int *part) {
546 int j;
547
548 for (j = 0; j < len; j++) {
549#ifdef DEBUGPP4
550 fprintf(stderr, "mf=%08X Sat=%08X &=%08X\n", part[j], bv[j],
551 (part[j] & bv[j]));
552#endif
553 if ((part[j] & bv[j]) != part[j])
554 return 0;
555 }
556 return 1;
557}
558
559/*----------------------------------------------------------------------*/
560/* let D + E + L be the dimension of the polyhedron */
561/* D = Dimension of polytope (ray space) */
562/* L = Dimension of Lineality space (number of lines, bid) */
563/* E = Dimension of Affine hull (number of equations) */
564/* n = number of data indices */
565/* m = number of parameters */
566/* full domain: */
567/* n + m = D + E + L */
568/* projected domains: */
569/* m = D_m + E_m + L_m */
570/* n = D_n + E_n + L_n */
571/* What dimension M-face, when projected onto parameter space, */
572/* will give an L_m-face? */
573/* What are the conditions? */
574/* - at least one vertex */
575/* - number of rays >= D_m+1 after removal of redundants */
576/* */
577/* dim of face nb saturated constraints nb saturated lines,rays */
578/* ----------- ------------------------ ----------------------- */
579/* (0+L)-face all E eqns + >=D ineq all L lines + 1 ray */
580/* (M+L)-face all E eqns + >=(D-M) ineq all L lines + >=(M+1) rays */
581/* (D+L)-face all E eqns + 0 ineq all L lines + >=(D+1) rays */
582/*----------------------------------------------------------------------*/
583/*----------------------------------------------------------------------*/
584/* scan_m_face */
585/* pos : the next candidate constraint position */
586/* nb_un : number of saturated constraints needed to finish a face */
587/* D : the source polyhedron (context included ) */
588/* mf : bit-array marking rays which are saturated so far */
589/* From Global area: */
590/* ---------------- */
591/* n : number of data indices */
592/* m : number of parameters */
593/* egalite : boolean vector marking saturated constraints in m-face */
594/* Sat : Saturation Matrix (row=constraints, col=rays) */
595/* ws : working space size */
596/* nr : (NbRays-1)/32 + 1 */
597/* */
598/* Recursive function to find the rays and vertices of each m-face */
599/*----------------------------------------------------------------------*/
600static void scan_m_face(int pos, int nb_un, Polyhedron *D, unsigned int *mf) {
601 /* pos - the next candidate constraint position */
602 /* nb_un - the number of constraints needed to finish a face */
603 /* D - the source polyhedron */
604 /* mf - (bit vector) marks rays that are saturated so far */
605
606 unsigned int *new_mf;
607
608#ifdef DEBUGPP4
609 fprintf(stderr, "Start scan_m_face(pos=%d, nb_un=%d, n=%d, m=%d\n", pos,
610 nb_un, n, m);
611 fprintf(stderr, "mf = ");
612 {
613 int i;
614 for (i = 0; i < nr; i++)
615 fprintf(stderr, "%08X", mf[i]);
616 fprintf(stderr, "\nequality = [");
617 for (i = 0; i < D->NbConstraints; i++)
618 fprintf(stderr, " %1d", egalite[i]);
619 fprintf(stderr, "]\n");
620 }
621#endif
622
623 if (nb_un == 0) { /* Base case */
624 int i;
625
626 /*********** ELIMINATION OF REDUNDANT FACES ***********/
627 /* if all these vertices also verify a previous constraint */
628 /* which is NOT already selected, we eliminate this face */
629 /* This keeps the lexicographically greatest selection */
630 for (i = 0; i < pos - 1; i++) {
631 if (egalite[i])
632 continue; /* already selected */
633
634 /* if Sat[i] & mf == mf then it's redundant */
635#ifdef DEBUGPP4
636 fprintf(stderr, "Sat[%d]\n", i);
637#endif
638 if (bit_vector_includes(Sat->p[i], nr, mf)) {
639#ifdef DEBUGPP4
640 fprintf(stderr, "Redundant with constraint %d\n", i);
641#endif
642 return; /* it is redundant */
643 }
644 }
645 /********* END OF ELIMINATION OF DEGENERATE FACES *********/
646 /* Now check for other constraints that are verified */
647 for (i = pos; i < D->NbConstraints; ++i) {
648 if (bit_vector_includes(Sat->p[i], nr, mf))
649 egalite[i] = 1;
650 }
651 /* if we haven't found a constraint verified by all */
652 /* the rays, its OK, it's a new face. */
653 traite_m_face(D, mf, egalite);
654 for (i = pos; i < D->NbConstraints; ++i)
655 egalite[i] = 0;
656 return;
657 }
658
659 /* See if there are enough constraints left to finish */
660 if ((pos + nb_un) > D->NbConstraints)
661 return;
662
663 /* Recurring part of the procedure */
664 /* Add the pos'th constraint, compute new saturation vector */
665 {
666 int k;
667 new_mf = (unsigned int *)malloc(nr * sizeof(unsigned int));
668 for (k = 0; k < nr; k++)
669 new_mf[k] = mf[k] & Sat->p[pos][k];
670 }
671#ifdef DEBUGPP4
672 fprintf(stderr, "new_mf = ");
673 {
674 int i;
675 for (i = 0; i < nr; i++) {
676 fprintf(stderr, "%08X", new_mf[i]);
677 }
678 fprintf(stderr, "\ncount(new_mf) = %d\n", count_sat(new_mf));
679 }
680#endif
681
682 {
683 int c;
684 c = count_sat(new_mf);
685 /* optimization : at least m_dim+1 rays must be saturated to add this
686 * constraint */
687 if (c > m_dim) {
688 int redundant = 0;
689
690 egalite[pos] = 1; /* Try it with the pos-th constraint */
691
692 /* If this constraint does not change anything,
693 * it is redundant with respect to the selected
694 * equalities and the remaining inequalities.
695 * Check whether it is redundant with respect
696 * to just the selected equalities.
697 */
698 if (c == count_sat(mf)) {
699 int i, c, j;
700
701 for (i = 0, c = 0; i < D->NbConstraints; ++i) {
702 if (egalite[i] == 0 || egalite[i] == -1)
703 continue;
704 for (j = 0; j < D->Dimension + 1; ++j)
705 value_assign(CTest->p[j][c], D->Constraint[i][j + 1]);
706 ++c;
707 }
708 CTest->NbColumns = c;
709#ifdef DEBUGPP41
711#endif
712 redundant = !TestRank(CTest);
713 }
714
715 /* Do not decrement nb_un if equality is redundant. */
716 if (redundant) {
717 egalite[pos] = -1; /* Don't use in further redundance test
718 */
719 scan_m_face(pos + 1, nb_un, D, new_mf);
720 } else {
721 scan_m_face(pos + 1, nb_un - 1, D, new_mf);
722 }
723 }
724 }
725 free(new_mf);
726 egalite[pos] = 0; /* Try it without the pos-th constraint */
727 if ((pos + nb_un) >= D->NbConstraints)
728 return;
729 scan_m_face(pos + 1, nb_un, D, mf);
730 return;
731} /* scan_m_face */
732
733/*
734 * Create a saturation matrix with rows correspond to the constraints and
735 * columns correspond to the rays of the polyhedron 'Pol'. Global variable
736 * 'nr' is set in the function.
737 */
738static SatMatrix *Poly2Sat(Polyhedron *Pol, unsigned int **L) {
739
740 SatMatrix *Sat;
741 int i, j, k, kx;
742 unsigned int *Temp;
743 Value *p1, *p2, p3, tmp;
744 unsigned Dimension, NbRay, NbCon, bx;
745
746 /* Initialize all the 'Value' variables */
747 value_init(p3);
748 value_init(tmp);
749
750 NbRay = Pol->NbRays;
751 NbCon = Pol->NbConstraints;
752 Dimension = Pol->Dimension + 1; /* Homogeneous Dimension */
753
754 /* Build the Sat matrix */
755 nr = (NbRay - 1) / (sizeof(int) * 8) + 1; /* Set globally */
756 Sat = SMAlloc(NbCon, nr);
757 Temp = (unsigned int *)malloc(nr * sizeof(unsigned int));
758 memset(Sat->p_init, 0, nr * NbCon * sizeof(int));
759 memset(Temp, 0, nr * sizeof(unsigned int));
760 kx = 0;
761 bx = MSB;
762 for (k = 0; k < NbRay; k++) {
763 for (i = 0; i < NbCon; i++) {
764 p1 = &Pol->Constraint[i][1];
765 p2 = &Pol->Ray[k][1];
766 value_set_si(p3, 0);
767 for (j = 0; j < Dimension; j++) {
768 value_multiply(tmp, *p1, *p2);
769 value_addto(p3, p3, tmp);
770 p1++;
771 p2++;
772 }
773 if (value_zero_p(p3))
774 Sat->p[i][kx] |= bx;
775 }
776 Temp[kx] |= bx;
777 NEXT(kx, bx);
778 }
779
780 /* Set 'L' to an array containing ones in every bit position of its */
781 /* elements. */
782 *L = Temp;
783
784 /* Clear all the 'Value' variables */
785 value_clear(p3);
786 value_clear(tmp);
787
788 return Sat;
789} /* Poly2Sat */
790
791/*
792 * Create a parametrized polyhedron with zero parameters. This function was
793 * first written by Xavier Redon, and was later modified by others.
794 */
796 Param_Polyhedron *result;
797 int nbRows, nbColumns;
798 int i, size, rays;
799
800 nbRows = Pol->NbRays;
801 nbColumns = Pol->Dimension + 2;
802
803 /* Count the number of rays */
804 for (i = 0, rays = 0; i < nbRows; i++)
805 if (value_notone_p(Pol->Ray[i][0]) ||
806 value_zero_p(Pol->Ray[i][nbColumns - 1]))
807 ++rays;
808
809 /* Initialize the result */
810 result = (Param_Polyhedron *)malloc(sizeof(Param_Polyhedron));
811 result->nbV = nbRows - rays;
812 result->V = NULL;
813 result->Constraints = Polyhedron2Constraints(Pol);
814 result->Rays = Rays;
815
816 /* Build the parametric vertices */
817 for (i = 0; i < nbRows; i++) {
818 Matrix *vertex;
819 Param_Vertices *paramVertex;
820 int j;
821
822 if (value_notone_p(Pol->Ray[i][0]) ||
823 value_zero_p(Pol->Ray[i][nbColumns - 1]))
824 continue;
825
826 vertex = Matrix_Alloc(nbColumns - 2, 2);
827 for (j = 1; j < nbColumns - 1; j++) {
828 value_assign(vertex->p[j - 1][0], Pol->Ray[i][j]);
829 value_assign(vertex->p[j - 1][1], Pol->Ray[i][nbColumns - 1]);
830 }
831 paramVertex = (Param_Vertices *)malloc(sizeof(Param_Vertices));
832 paramVertex->Vertex = vertex;
833
834 /* There is one validity domain : universe of dimension 0 */
835 paramVertex->Domain = Matrix_Alloc(1, 2);
836 value_set_si(paramVertex->Domain->p[0][0], 1);
837 value_set_si(paramVertex->Domain->p[0][1], 1);
838 paramVertex->Facets = NULL;
839 paramVertex->next = result->V;
840 result->V = paramVertex;
841 }
842
843 /* Build the parametric domains (only one here) */
844 if (nbRows > 1)
845 size = (nbRows - 1) / (8 * sizeof(int)) + 1;
846 else
847 size = 1;
848 result->D = (Param_Domain *)malloc(sizeof(Param_Domain));
849 result->D->next = NULL;
850 result->D->Domain = Universe_Polyhedron(0);
851 result->D->F = (unsigned int *)malloc(size * sizeof(int));
852 memset(&result->D->F[0], 0xFF, size * sizeof(int));
853
854 return result;
855} /* GenParamPolyhedron */
856
857/*----------------------------------------------------------------------*/
858/* PreElim_Columns */
859/* function being called before Elim_Columns */
860/* Equalities in E are analysed to initialize ref and p. */
861/* These two vectors are used to construct the new constraint matrix */
862/* PreElim_Columns returns the transformation matrix to re-convert the */
863/* resulting domains in the same format (by adding empty columns) */
864/* in the parameter space */
865/*----------------------------------------------------------------------*/
866Matrix *PreElim_Columns(Polyhedron *E, int *p, int *ref, int m) {
867
868 int i, j, l;
869 Matrix *T;
870
871 /* find which columns to eliminate */
872 /* p contains, for each line in E, the column to eliminate */
873 /* (i.e. the corresponding parameter index to eliminate) */
874 /* 0 <= i <= E->NbEq, and 1 <= p[i] <= E->Dimension */
875 memset(p, 0, sizeof(int) * (E->NbEq));
876
877#ifdef DEBUGPP32
878 fprintf(stderr, "\n\nPreElim_Columns starting\n");
879 fprintf(stderr, "E =\n");
880 Polyhedron_Print(stderr, P_VALUE_FMT, E);
881#endif
882
883 for (l = 0; l < E->NbEq; ++l) {
884 if (value_notzero_p(E->Constraint[l][0])) {
885 fprintf(stderr, "Internal error: Elim_Columns (polyparam.c), expecting "
886 "equalities first in E.\n");
887 free(p);
888 return (NULL);
889 }
890 for (i = 1; value_zero_p(E->Constraint[l][i]); ++i) {
891 if (i == E->Dimension + 1) {
892 fprintf(stderr, "Internal error: Elim_Columns (polyparam.c), expecting "
893 "non-empty constraint in E.\n");
894 free(p);
895 return (NULL);
896 }
897 }
898 p[l] = i;
899
900#ifdef DEBUGPP32
901 fprintf(stderr, "p[%d] = %d,", l, p[l]);
902#endif
903 }
904
905 /* Reference vector: column ref[i] in A corresponds to column i in M */
906 for (i = 0; i < E->Dimension + 2 - E->NbEq; ++i) {
907 ref[i] = i;
908 for (j = 0; j < E->NbEq; ++j)
909 if (p[j] <= ref[i])
910 ref[i]++;
911
912#ifdef DEBUGPP32
913 fprintf(stderr, "ref[%d] = %d,", i, ref[i]);
914#endif
915 }
916
917 /* Size of T : phdim-nbEq * phdim */
918 T = Matrix_Alloc(m + 1 - E->NbEq, m + 1);
919 for (i = 0; i < T->NbColumns; i++)
920 for (j = 0; j < T->NbRows; j++)
921 if (ref[E->Dimension - m + j + 1] == E->Dimension - m + i + 1)
922 value_set_si(T->p[j][i], 1);
923 else
924 value_set_si(T->p[j][i], 0);
925
926#ifdef DEBUGPP32
927 fprintf(stderr, "\nTransMatrix =\n");
928 Matrix_Print(stderr, P_VALUE_FMT, T);
929#endif
930
931 return (T);
932
933} /* PreElim_Columns */
934
935/*----------------------------------------------------------------------*/
936/* Elim_Columns */
937/* Eliminate columns from A, using the equalities in E. */
938/* ref and p are precalculated by PreElim_Columns, using E; */
939/* these two vectors are used to construct the new constraint matrix */
940/*----------------------------------------------------------------------*/
941Polyhedron *Elim_Columns(Polyhedron *A, Polyhedron *E, int *p, int *ref) {
942
943 int i, l, c;
944 Matrix *M, *C;
945 Polyhedron *R;
946 Value tmp1, tmp2;
947
948 /* Initialize all the 'Value' variables */
949 value_init(tmp1);
950 value_init(tmp2);
951
952#ifdef DEBUGPP32
953 fprintf(stderr, "\nElim_Columns starting\n");
954 fprintf(stderr, "A =\n");
955 Polyhedron_Print(stderr, P_VALUE_FMT, A);
956#endif
957
958 /* Builds M = constraint matrix of A, useless columns zeroed */
960 for (l = 0; l < E->NbEq; ++l) {
961 for (c = 0; c < M->NbRows; ++c) {
962 if (value_notzero_p(M->p[c][p[l]])) {
963
964 /* A parameter to eliminate here ! */
965 for (i = 1; i < M->NbColumns; ++i) {
966 value_multiply(tmp1, M->p[c][i], E->Constraint[l][p[l]]);
967 value_multiply(tmp2, E->Constraint[l][i], M->p[c][p[l]]);
968 value_subtract(M->p[c][i], tmp1, tmp2);
969 }
970 }
971 }
972 }
973
974#ifdef DEBUGPP32
975 fprintf(stderr, "\nElim_Columns after zeroing columns of A.\n");
976 fprintf(stderr, "M =\n");
977 Matrix_Print(stderr, P_VALUE_FMT, M);
978#endif
979
980 /* Builds C = constraint matrix, useless columns eliminated */
981 C = Matrix_Alloc(M->NbRows, M->NbColumns - E->NbEq);
982 for (l = 0; l < C->NbRows; ++l)
983 for (c = 0; c < C->NbColumns; ++c) {
984 value_assign(C->p[l][c], M->p[l][ref[c]]);
985 }
986
987#ifdef DEBUGPP32
988 fprintf(stderr, "\nElim_Columns after eliminating columns of A.\n");
989 fprintf(stderr, "C =\n");
990 Matrix_Print(stderr, P_VALUE_FMT, C);
991#endif
992
994 Matrix_Free(C);
995 Matrix_Free(M);
996 value_clear(tmp1);
997 value_clear(tmp2);
998 return (R);
999} /* Elim_Columns */
1000
1001static Polyhedron *Recession_Cone(Polyhedron *P, unsigned nvar,
1002 unsigned MaxRays) {
1003 int i;
1004 Matrix *M = Matrix_Alloc(P->NbConstraints, 1 + nvar + 1);
1005 Polyhedron *R;
1006 for (i = 0; i < P->NbConstraints; ++i)
1007 Vector_Copy(P->Constraint[i], M->p[i], 1 + nvar);
1008 R = Constraints2Polyhedron(M, MaxRays);
1009 Matrix_Free(M);
1010 return R;
1011}
1012
1013/* Compute lines/unidirectional rays of the (non parametric) polyhedron */
1014/* Input :
1015 * D1 : combined polyhedron,
1016 * Output :
1017 * Rays : non parametric ray matrix
1018 * return value : number of lines
1019 */
1020static int ComputeNPLinesRays(int n, Polyhedron *D1, Matrix **Rays) {
1021 int i, j, nbr, dimfaces;
1022 Polyhedron *RC; /* Recession Cone */
1023
1024 RC = Recession_Cone(D1, n, ws);
1025
1026 /* get the rays/lines from RC */
1027 nbr = 0;
1028 for (i = 0; i < RC->NbRays; i++)
1029 if (value_zero_p(RC->Ray[i][n + 1]))
1030 nbr++;
1031 *Rays = Matrix_Alloc(nbr, n + 2);
1032 for (i = 0, j = 0; j < nbr; i++)
1033 if (value_zero_p(RC->Ray[i][n + 1]))
1034 Vector_Copy(RC->Ray[i], (*Rays)->p[j++], n + 2);
1035
1036 dimfaces = RC->NbBid;
1037 Polyhedron_Free(RC);
1038
1039#ifdef DEBUGPP31
1040 fprintf(stderr, "Rays = ");
1041 Matrix_Print(stderr, P_VALUE_FMT, *Rays);
1042 fprintf(stderr, "dimfaces = %d\n", dimfaces);
1043#endif
1044
1045 return dimfaces;
1046}
1047
1048/*
1049 * Given a polyhedron 'Di' in combined data and parameter space and a context
1050 * polyhedron 'C' representing the constraints on the parameter space, create
1051 * a list of parameterized vertices and assign values to global variables:
1052 * m,n,ws,Sat,egalite,mf,Xi,Pi,PiInv,RaysDi,CEqualities.
1053 */
1055 int working_space, Polyhedron **CEq,
1056 Matrix **CT) {
1057
1058 unsigned int *mf;
1059 int i, j, dimfaces;
1060 Polyhedron *D = *Di, *C1, /* true context */
1061 *D1; /* the combined polyhedron, including context C */
1062 Matrix *Rays, /* lines/rays (non parametric) */
1063 *M;
1064 Param_Polyhedron *res;
1065 int *p, *ref;
1066
1067 CEqualities = NULL;
1068
1069 if (CT) {
1070 *CEq = NULL;
1071 *CT = NULL;
1072 }
1073
1074 if (!D || !C)
1075 return (Param_Polyhedron *)0;
1076
1077 ws = working_space;
1078 m = C->Dimension;
1079 n = D->Dimension - m;
1080 if (n < 0) {
1081 fprintf(stderr, "Find_m_faces: ?%d parameters of a %d-polyhedron !\n", m,
1082 n);
1083 return (Param_Polyhedron *)0;
1084 }
1085 if (m == 0)
1086 return GenParamPolyhedron(D, Matrix_Alloc(0, 2));
1087
1088 /* Add constraints from Context to D -> result in D1 */
1089 C1 = align_context(C, D->Dimension, ws);
1090
1091#ifdef DEBUGPP31
1092 fprintf(stderr, "m = %d\n", m);
1093 fprintf(stderr, "D = ");
1094 Polyhedron_Print(stderr, P_VALUE_FMT, D);
1095 fprintf(stderr, "C1 = ");
1096 Polyhedron_Print(stderr, P_VALUE_FMT, C1);
1097#endif
1098
1099 D1 = DomainIntersection(D, C1, ws);
1100
1101#ifdef DEBUGPP31
1102 fprintf(stderr, "D1 = ");
1103 Polyhedron_Print(stderr, P_VALUE_FMT, D1);
1104#endif
1105
1106 Domain_Free(C1);
1107
1108 if (!D1)
1109 return (NULL);
1110 if (emptyQ(D1)) {
1111 Polyhedron_Free(D1);
1112 return (NULL);
1113 }
1114
1115 /* Compute the true context C1 */
1116 /* M : lines in the direction of the first n indices (index space) */
1117 M = Matrix_Alloc(n, D1->Dimension + 2);
1118 for (i = 0; i < n; i++)
1119 value_set_si(M->p[i][i + 1], 1);
1120 C1 = DomainAddRays(D1, M, ws);
1121 Matrix_Free(M);
1122
1123#ifdef DEBUGPP31
1124 fprintf(stderr, "True context C1 = ");
1125 Polyhedron_Print(stderr, P_VALUE_FMT, C1);
1126#endif
1127
1128 dimfaces = ComputeNPLinesRays(n, D1, &Rays);
1129
1130 /* CEqualities contains the constraints (to be added again later) */
1131 /* *CT is the transformation matrix to add the removed parameters */
1132 if (!CT) {
1133 if (C1->NbEq == 0) {
1134 Polyhedron_Free(C1);
1135 C1 = NULL;
1136 } else {
1137 Polyhedron *CEq1, /* CEqualities, in homogeneous dim */
1138 *D2; /* D1, (temporary) simplified */
1139
1140 /* Remove equalities from true context C1 and from D1 */
1141 /* Compute CEqualities = matrix of equalities in C1, projected in */
1142 /* the parameter space */
1143 M = Matrix_Alloc(C1->NbEq, m + 2);
1144 for (j = 0, i = 0; i < C1->NbEq; ++i, ++j) {
1145 while (value_notzero_p(C1->Constraint[j][0]))
1146 ++j;
1147 value_assign(M->p[i][0], C1->Constraint[j][0]);
1148 Vector_Copy(&C1->Constraint[j][D->Dimension - m + 1], &M->p[i][1],
1149 (m + 1));
1150 }
1152 Matrix_Free(M);
1154
1155 /* Simplify D1 and C1 (remove the equalities) */
1156 D2 = DomainSimplify(D1, CEq1, ws);
1157 Polyhedron_Free(D1);
1158 Polyhedron_Free(C1);
1159 Polyhedron_Free(CEq1);
1160 D1 = D2;
1161 C1 = NULL;
1162 }
1163 } else { /* if( CT ) */
1164 Polyhedron *CEq1, /* CEqualities */
1165 *D2; /* D1, (temporary) simplified */
1166
1167 /* Suppress all useless constraints in parameter domain */
1168 /* when CT is not NULL (ehrhart) */
1169 /* Vin100, march 01 */
1170 CEq1 = C1;
1171 M = Matrix_Alloc(C1->NbConstraints, m + 2);
1172 for (i = 0; i < C1->NbConstraints; ++i) {
1173 value_assign(M->p[i][0], C1->Constraint[i][0]);
1174 Vector_Copy(&C1->Constraint[i][D->Dimension - m + 1], &M->p[i][1],
1175 (m + 1));
1176 }
1178 Matrix_Free(M);
1179
1180 D2 = DomainSimplify(D1, CEq1, ws);
1181 Polyhedron_Free(D1);
1182 D1 = D2;
1184
1185 /* if CT is not NULL, the constraints are eliminated */
1186 /* *CT will contain the transformation matrix to come back to the */
1187 /* original dimension (for a polyhedron, in the parameter space) */
1188 if (CEq1->NbEq) {
1189 m -= CEq1->NbEq;
1190 p = (int *)malloc(sizeof(int) * (CEq1->NbEq));
1191 } else
1192 p = NULL;
1193 ref = (int *)malloc(sizeof(int) * (CEq1->Dimension + 2 - CEq1->NbEq));
1194 *CT = PreElim_Columns(CEq1, p, ref, CEqualities->Dimension);
1195 D2 = Elim_Columns(D1, CEq1, p, ref);
1196 if (p)
1197 free(p);
1198 free(ref);
1199
1200#ifdef DEBUGPP3
1201 fprintf(stderr, "D2\t Dim = %3d\tNbEq = %3d\tLines = %3d\n", D2->Dimension,
1202 D2->NbEq, D2->NbBid);
1203 C2 = Elim_Columns(C1, CEq1, p, ref);
1204 fprintf(stderr, "C2\t Dim = %3d\tNbEq = %3d\tLines = %3d\n", C2->Dimension,
1205 C2->NbEq, C2->NbBid);
1206 Polyhedron_Free(C2);
1207#endif
1208
1209 Polyhedron_Free(D1);
1210 Polyhedron_Free(C1);
1211 D1 = D2;
1212 C1 = NULL;
1213 *CEq = CEqualities;
1214
1215#ifdef DEBUGPP3
1216 fprintf(stderr, "Polyhedron CEq = ");
1217 Polyhedron_Print(stderr, P_VALUE_FMT, *CEq);
1218 fprintf(stderr, "Matrix CT = ");
1219 Matrix_Print(stderr, P_VALUE_FMT, *CT);
1220#endif
1221
1222 Polyhedron_Free(CEq1);
1223 CEqualities = NULL; /* don't simplify ! */
1224
1225 /* m changed !!! */
1226 if (m == 0) {
1227 /* return the new D1 too */
1228 *Di = D1;
1229
1230 return GenParamPolyhedron(D1, Rays);
1231 }
1232 }
1233
1234#ifdef DEBUGPP3
1235 fprintf(stderr, "Polyhedron D1 (D AND C) = ");
1236 Polyhedron_Print(stderr, P_VALUE_FMT, D1);
1237 fprintf(stderr, "Polyhedron CEqualities = ");
1238 if (CEqualities)
1240 else
1241 fprintf(stderr, "NULL\n");
1242#endif
1243
1244 KD = keep_dom;
1245 PDomains = NULL;
1246 PV_Result = NULL;
1247 nbPV = 0;
1248
1249 if (emptyQ(D1)) {
1250 Polyhedron_Free(D1);
1251 Matrix_Free(Rays);
1252 return NULL;
1253 }
1254
1255 /* mf : a bit array indicating which rays are part of the m-face */
1256 /* Poly2Sat initializes mf to all ones */
1257 /* set global variable nr to size (number of words) of mf */
1258 Sat = Poly2Sat(D1, &mf);
1259
1260#ifdef DEBUGPP4
1261 fprintf(stderr, "Sat = ");
1262 SMPrint(Sat);
1263
1264 fprintf(stderr, "mf = ");
1265 for (i = 0; i < nr; i++)
1266 fprintf(stderr, "%08X", mf[i]);
1267 fprintf(stderr, "\n");
1268#endif
1269
1270 /* A boolean array saying which constraints are part of the m-face */
1271 egalite = (unsigned int *)malloc(sizeof(int) * D1->NbConstraints);
1272 memset(egalite, 0, sizeof(int) * D1->NbConstraints);
1273
1274 for (i = 0; i < D1->NbEq; i++)
1275 egalite[i] = 1;
1276
1277 Xi = Matrix_Alloc(n + 1, m + 1);
1278 Pi = Matrix_Alloc(m + 1, m + 1);
1279 PiTest = Matrix_Alloc(m + 1, m + 1);
1281 PiInv = Matrix_Alloc(m + 1, m + 2);
1282 RaysDi = Matrix_Alloc(D1->NbRays, m + 2);
1283 m_dim = m;
1284
1285 /* m_dim has to be increased by the dimension of the smallest faces
1286 * of the (non parametric) polyhedron
1287 */
1288 m_dim += dimfaces;
1289
1290 /* if the smallest face is of smaller dimension than m_dim,
1291 * then increase m_dim (I think this should never happen --Vincent)
1292 */
1293#ifdef DEBUGPP3
1294 if (m_dim < D1->NbBid)
1295 fprintf(stderr, "m_dim (%d) < D1->NbBid (%d)\n", m_dim, D1->NbBid);
1296#endif
1297 if (m_dim < D1->NbBid)
1298 m_dim = D1->NbBid;
1299
1300#ifdef DEBUGPP
1301 nbfaces = 0;
1302#endif
1303#ifdef DEBUGPP3
1304 fprintf(stderr, "m_dim = %d\n", m_dim);
1305 fprintf(stderr,
1306 "Target: find faces that saturate %d constraints and %d rays/lines\n",
1307 D1->Dimension - m_dim, m_dim + 1);
1308#endif
1309
1310 /* D1->NbEq constraints already saturated ! */
1311 scan_m_face(D1->NbEq, (D1->Dimension - m_dim - D1->NbEq), D1, mf);
1312
1313 /* pos, number of constraints needed */
1314
1315#ifdef DEBUGPP
1316 fprintf(stderr, "Number of m-faces: %d\n", nbfaces);
1317#endif
1318
1323 Matrix_Free(Pi);
1324 Matrix_Free(Xi);
1325 free(egalite);
1326 free(mf);
1327 SMFree(Sat);
1328
1329 /* if(CEqualities && keep_dom==0) {
1330 Domain_Free(CEqualities);
1331 }
1332 */
1333
1334 res = (Param_Polyhedron *)malloc(sizeof(Param_Polyhedron));
1335 res->nbV = nbPV;
1336 res->V = PV_Result;
1337 res->D = PDomains;
1339 res->Rays = Rays;
1340
1341 if (CT) /* return the new D1 too ! */
1342 *Di = D1;
1343 else
1344 Domain_Free(D1);
1345
1346 return (res);
1347} /* Find_m_faces */
1348
1349/*
1350 * Given parametric domain 'PD' and number of parametric vertices 'nb_domains',
1351 * find the vertices that belong to distinct sub-domains.
1352 */
1353void Compute_PDomains(Param_Domain *PD, int nb_domains, int working_space) {
1354
1355 unsigned bx;
1356 int i, ix, nv;
1357 Polyhedron *dx, *d1, *d2;
1358 Param_Domain *p1, *p2, *p2prev, *PDNew;
1359
1360 if (nb_domains == 0) {
1361
1362#ifdef DEBUGPP5
1363 fprintf(stderr, "No domains\n");
1364#endif
1365
1366 return;
1367 }
1368
1369 /* Already filled out by GenParamPolyhedron */
1370 if (!PD->next && PD->F)
1371 return;
1372
1373 /* Initialization */
1374 nv = (nb_domains - 1) / (8 * sizeof(int)) + 1;
1375
1376#ifdef DEBUGPP5
1377 fprintf(stderr, "nv = %d\n", nv);
1378#endif
1379
1380 for (p1 = PD, i = 0, ix = 0, bx = MSB; p1; p1 = p1->next, i++) {
1381
1382 /* Assign a bit array 'p1->F' of suitable size to include the vertices */
1383 p1->F = (unsigned *)malloc(nv * sizeof(unsigned));
1384
1385 /* Set the bit array to zeros */
1386 memset(p1->F, 0, nv * sizeof(unsigned));
1387 p1->F[ix] |= bx; /* Set i'th bit to one */
1388 NEXT(ix, bx);
1389 }
1390
1391#ifdef DEBUGPP5
1392 fprintf(stderr, "nb of vertices=%d\n", i);
1393#endif
1394
1395 /* Walk the PD list with two pointers */
1396 ix = 0;
1397 bx = MSB;
1398 for (p1 = PD; p1; p1 = p1->next) {
1399 for (p2prev = p1, p2 = p1->next; p2; p2prev = p2, p2 = p2->next) {
1400
1401 /* Find intersection */
1402 dx = PDomainIntersection(p1->Domain, p2->Domain, working_space);
1403
1404 if (!dx || emptyQ(dx)) {
1405
1406#ifdef DEBUGPP5
1407 fprintf(stderr, "Empty dx (p1 inter p2). Continuing\n");
1408#endif
1409 if (dx)
1410 Domain_Free(dx);
1411 continue;
1412 }
1413
1414#ifdef DEBUGPP5
1415 fprintf(stderr, "Begin PDomainDifference\n");
1416 fprintf(stderr, "p1=");
1417 Polyhedron_Print(stderr, P_VALUE_FMT, p1->Domain);
1418 fprintf(stderr, "p2=");
1419 Polyhedron_Print(stderr, P_VALUE_FMT, p2->Domain);
1420#endif
1421 d1 = PDomainDifference(p1->Domain, p2->Domain, working_space);
1422 d2 = PDomainDifference(p2->Domain, p1->Domain, working_space);
1423
1424#ifdef DEBUGPP5
1425 fprintf(stderr, "p1\\p2=");
1426 Polyhedron_Print(stderr, P_VALUE_FMT, d1);
1427 fprintf(stderr, "p2\\p1=");
1428 Polyhedron_Print(stderr, P_VALUE_FMT, d2);
1429 fprintf(stderr, "END PDomainDifference\n\n");
1430#endif
1431 if (!d1 || emptyQ(d1) || d1->NbEq != 0) {
1432
1433#ifdef DEBUGPP5
1434 fprintf(stderr, "Empty d1\n");
1435#endif
1436 if (d1)
1437 Domain_Free(d1);
1438 Domain_Free(dx);
1439
1440 if (!d2 || emptyQ(d2) || d2->NbEq != 0) {
1441
1442#ifdef DEBUGPP5
1443 fprintf(stderr, "Empty d2 (deleting)\n");
1444#endif
1445 /* dx = p1->Domain = p2->Domain */
1446 if (d2)
1447 Domain_Free(d2);
1448
1449 /* Update p1 */
1450 for (i = 0; i < nv; i++)
1451 p1->F[i] |= p2->F[i];
1452
1453 /* Delete p2 */
1454 p2prev->next = p2->next;
1455 Domain_Free(p2->Domain);
1456 free(p2->F);
1457 free(p2);
1458 p2 = p2prev;
1459 } else { /* d2 is not empty --> dx==p1->domain */
1460
1461#ifdef DEBUGPP5
1462 fprintf(stderr, "p2 replaced by d2\n");
1463#endif
1464 /* Update p1 */
1465 for (i = 0; i < nv; i++)
1466 p1->F[i] |= p2->F[i];
1467
1468 /* Replace p2 with d2 */
1469 Domain_Free(p2->Domain);
1470 p2->Domain = d2;
1471 }
1472 } else { /* d1 is not empty */
1473 if (!d2 || emptyQ(d2) || d2->NbEq != 0) {
1474
1475#ifdef DEBUGPP5
1476 fprintf(stderr, "p1 replaced by d1\n");
1477#endif
1478 if (d2)
1479 Domain_Free(d2);
1480
1481 /* dx = p2->domain */
1482 Domain_Free(dx);
1483
1484 /* Update p2 */
1485 for (i = 0; i < nv; i++)
1486 p2->F[i] |= p1->F[i];
1487
1488 /* Replace p1 with d1 */
1489 Domain_Free(p1->Domain);
1490 p1->Domain = d1;
1491 } else { /*d2 is not empty-->d1,d2,dx are distinct */
1492
1493#ifdef DEBUGPP5
1494 fprintf(stderr, "Non-empty d1 and d2\nNew node created\n");
1495#endif
1496 /* Create a new node for dx */
1497 PDNew = (Param_Domain *)malloc(sizeof(Param_Domain));
1498 PDNew->F = (unsigned int *)malloc(nv * sizeof(int));
1499 memset(PDNew->F, 0, nv * sizeof(int));
1500 PDNew->Domain = dx;
1501
1502 for (i = 0; i < nv; i++)
1503 PDNew->F[i] = p1->F[i] | p2->F[i];
1504
1505 /* Replace p1 with d1 */
1506 Domain_Free(p1->Domain);
1507 p1->Domain = d1;
1508
1509 /* Replace p2 with d2 */
1510 Domain_Free(p2->Domain);
1511 p2->Domain = d2;
1512
1513 /* Insert new node after p1 */
1514 PDNew->next = p1->next;
1515 p1->next = PDNew;
1516 }
1517 }
1518 } /* end of p2 scan */
1519 if (p1->Domain->next) {
1520 Polyhedron *C = DomainConvex(p1->Domain, working_space);
1521 Domain_Free(p1->Domain);
1522 p1->Domain = C;
1523 }
1524 } /* end of p1 scan */
1525} /* Compute_PDomains */
1526
1527/*
1528 * Given a polyhedron 'Din' in combined data and parametre space, a context
1529 * polyhedron 'Cin' representing the constraints on the parameter space and
1530 * a working space size 'working_space', return a parametric polyhedron with
1531 * a list of parametric vertices and their defining domains.
1532 */
1534 int working_space) {
1535
1536 Param_Polyhedron *result;
1537
1538 POL_ENSURE_FACETS(Din);
1540 POL_ENSURE_FACETS(Cin);
1542
1543#ifdef DEBUGPP
1544 fprintf(stderr, "Polyhedron2Param_Vertices algorithm starting at : %.2fs\n",
1545 (float)clock() / CLOCKS_PER_SEC);
1546#endif
1547
1548 /***************** Scan the m-faces ****************/
1549 result = Find_m_faces(&Din, Cin, 0, working_space, NULL, NULL);
1550
1551#ifdef DEBUGPP
1552 fprintf(stderr, "nb of points : %d\n", result->nbV);
1553#endif
1554
1555#ifdef DEBUGPP
1556 fprintf(stderr, "end main loop : %.2fs\n", (float)clock() / CLOCKS_PER_SEC);
1557#endif
1558
1559 return (result);
1560} /* Polyhedron2Param_Vertices */
1561
1562/*
1563 * Free the memory allocated to a list of parametrized vertices
1564 */
1566
1567 Param_Vertices *next_pv;
1568
1569 while (PV) {
1570 next_pv = PV->next;
1571 if (PV->Vertex)
1572 Matrix_Free(PV->Vertex);
1573 if (PV->Domain)
1574 Matrix_Free(PV->Domain);
1575 if (PV->Facets)
1576 free(PV->Facets);
1577 free(PV);
1578 PV = next_pv;
1579 }
1580} /* Param_Vertices_Free */
1581
1582/*
1583 * Print a list of parametrized vertices *
1584 */
1585void Print_Vertex(FILE *DST, Matrix *V, char **param_names) {
1586 int l, v;
1587 int first;
1588 Value gcd, tmp;
1589
1590 value_init(gcd);
1591 value_init(tmp);
1592
1593 fprintf(DST, "[");
1594 for (l = 0; l < V->NbRows; ++l) {
1595
1596 /* Variables */
1597 first = 1;
1598 fprintf(DST, " ");
1599 for (v = 0; v < V->NbColumns - 2; ++v) {
1600 if (value_notzero_p(V->p[l][v])) {
1601 value_gcd(gcd, V->p[l][v], V->p[l][V->NbColumns - 1]);
1602 value_divexact(tmp, V->p[l][v], gcd);
1603 if (value_posz_p(tmp)) {
1604 if (!first)
1605 fprintf(DST, "+");
1606 if (value_notone_p(tmp)) {
1607 value_print(DST, VALUE_FMT, tmp);
1608 }
1609 } else { /* V->p[l][v]/gcd<0 */
1610 if (value_mone_p(tmp))
1611 fprintf(DST, "-");
1612 else {
1613 value_print(DST, VALUE_FMT, tmp);
1614 }
1615 }
1616 value_divexact(tmp, V->p[l][V->NbColumns - 1], gcd);
1617 if (value_notone_p(tmp)) {
1618 fprintf(DST, "%s/", param_names[v]);
1619 value_print(DST, VALUE_FMT, tmp);
1620 } else
1621 fprintf(DST, "%s", param_names[v]);
1622 first = 0;
1623 }
1624 }
1625
1626 /* Constant */
1627 if (value_notzero_p(V->p[l][v]) || first) {
1628 if (value_posz_p(V->p[l][v]) && !first)
1629 fprintf(DST, "+");
1630 value_gcd(gcd, V->p[l][v], V->p[l][V->NbColumns - 1]);
1631 value_divexact(tmp, V->p[l][v], gcd);
1632 value_print(DST, VALUE_FMT, tmp);
1633 value_divexact(tmp, V->p[l][V->NbColumns - 1], gcd);
1634 if (value_notone_p(tmp)) {
1635 fprintf(DST, "/");
1636 value_print(DST, VALUE_FMT, tmp);
1637 fprintf(DST, " ");
1638 }
1639 }
1640 if (l < V->NbRows - 1)
1641 fprintf(DST, ", ");
1642 }
1643 fprintf(DST, " ]");
1644 value_clear(gcd);
1645 value_clear(tmp);
1646 return;
1647} /* Print_Vertex */
1648
1649/*----------------------------------------------------------------------*/
1650/* VertexCT */
1651/* convert a paramvertex from reduced space to normal m-space */
1652/*----------------------------------------------------------------------*/
1654
1655 Matrix *Vt;
1656 int i, j, k;
1657
1658 if (CT) {
1659
1660 /* Have to transform the vertices to original dimension */
1661 Vt = Matrix_Alloc(V->NbRows, CT->NbColumns + 1);
1662 for (i = 0; i < V->NbRows; ++i) {
1663 value_assign(Vt->p[i][CT->NbColumns], V->p[i][V->NbColumns - 1]);
1664 for (j = 0; j < CT->NbColumns; j++) {
1665 for (k = 0; k < CT->NbRows; k++)
1666 if (value_notzero_p(CT->p[k][j]))
1667 break;
1668 if (k < CT->NbRows)
1669 value_assign(Vt->p[i][j], V->p[i][k]);
1670 else
1671 value_set_si(Vt->p[i][j], 0);
1672 }
1673 }
1674 return (Vt);
1675 } else
1676 return (NULL);
1677} /* VertexCT */
1678
1679/*
1680 * Print the validity Domain 'D' of a parametric polyhedron
1681 */
1682void Print_Domain(FILE *DST, Polyhedron *D, char **pname) {
1683 int l, v;
1684 int first;
1685
1688
1689 for (l = 0; l < D->NbConstraints; ++l) {
1690 fprintf(DST, " ");
1691 first = 1;
1692 for (v = 1; v <= D->Dimension; ++v) {
1693 if (value_notzero_p(D->Constraint[l][v])) {
1694 if (value_one_p(D->Constraint[l][v])) {
1695 if (first)
1696 fprintf(DST, "%s ", pname[v - 1]);
1697 else
1698 fprintf(DST, "+ %s ", pname[v - 1]);
1699 } else if (value_mone_p(D->Constraint[l][v]))
1700 fprintf(DST, "- %s ", pname[v - 1]);
1701 else {
1702 if (value_pos_p(D->Constraint[l][v]) && !first)
1703 fprintf(DST, "+ ");
1704 value_print(DST, VALUE_FMT, D->Constraint[l][v]);
1705 fprintf(DST, "%s ", pname[v - 1]);
1706 }
1707 first = 0;
1708 }
1709 }
1710 if (value_notzero_p(D->Constraint[l][v])) {
1711 if (value_pos_p(D->Constraint[l][v]) && !first)
1712 fprintf(DST, "+");
1713 fprintf(DST, " ");
1714 value_print(DST, VALUE_FMT, D->Constraint[l][v]);
1715 }
1716 fprintf(DST, (value_notzero_p(D->Constraint[l][0])) ? " >= 0" : " = 0");
1717 fprintf(DST, "\n");
1718 }
1719 fprintf(DST, "\n");
1720
1721 if (D->next) {
1722 fprintf(DST, "UNION\n");
1723 Print_Domain(DST, D->next, pname);
1724 }
1725 return;
1726} /* Print_Domain */
1727
1728/*
1729 * Given a list of parametrized vertices and an array of parameter names, Print
1730 * a list of parametrized vertices in a comprehensible format.
1731 */
1733 char **param_names) {
1734 Polyhedron *poly;
1735
1736 while (PV) {
1737 fprintf(DST, "Vertex :\n");
1738 Print_Vertex(DST, PV->Vertex, param_names);
1739
1740 /* Pour le domaine : */
1741 fprintf(DST, " If :\n");
1742 poly = Constraints2Polyhedron(PV->Domain, 200);
1743 Print_Domain(DST, poly, param_names);
1744 Domain_Free(poly);
1745 PV = PV->next;
1746 }
1747 return;
1748} /* Param_Vertices_Print */
1749
1750/*
1751 * Given a polyhedron 'Din' in combined data and parametre space, a context
1752 * polyhedron 'Cin' representing the constraints on the parameter space and
1753 * a working space size 'working_space', return a parametric polyhedron with
1754 * a list of distinct validity domains and a complete list of valid vertices
1755 * associated to each validity domain.
1756 */
1758 int working_space) {
1759
1760 Param_Polyhedron *result;
1761 Param_Domain *D;
1762
1763 POL_ENSURE_FACETS(Din);
1765 POL_ENSURE_FACETS(Cin);
1767
1768 if (emptyQ(Din) || emptyQ(Cin))
1769 return NULL;
1770
1771#ifdef DEBUGPP
1772 fprintf(stderr, "Polyhedron2Param_Polyhedron algorithm starting at : %.2fs\n",
1773 (float)clock() / CLOCKS_PER_SEC);
1774#endif
1775
1776 /* Find the m-faces, keeping the corresponding domains */
1777 /* in the linked list PDomains */
1778 result = Find_m_faces(&Din, Cin, 1, working_space, NULL, NULL);
1779
1780#ifdef DEBUGPP
1781 if (result)
1782 fprintf(stderr, "Number of vertices : %d\n", result->nbV);
1783 fprintf(stderr, "Vertices found at : %.2fs\n",
1784 (float)clock() / CLOCKS_PER_SEC);
1785#endif
1786
1787 /* Processing of PVResult and PDomains */
1788 if (result && Cin->Dimension > 0) /* at least 1 parameter */
1789 Compute_PDomains(result->D, result->nbV, working_space);
1790 if (result && CEqualities)
1791 for (D = result->D; D; D = D->next)
1792 D->Domain = Add_CEqualities(D->Domain);
1794
1795#ifdef DEBUGPP
1796 fprintf(stderr, "domains found at : %.2fs\n",
1797 (float)clock() / CLOCKS_PER_SEC);
1798#endif
1799
1800 return (result);
1801} /* Polyhedon2Param_Domain */
1802
1803/*
1804 *
1805 */
1807 Polyhedron *Cin,
1808 int working_space,
1809 Polyhedron **CEq,
1810 Matrix **CT) {
1811
1812 Param_Polyhedron *result;
1813
1814 assert(CEq != NULL);
1815 assert(CT != NULL);
1816
1817 POL_ENSURE_FACETS(*Din);
1818 POL_ENSURE_VERTICES(*Din);
1819 POL_ENSURE_FACETS(Cin);
1821
1822#ifdef DEBUGPP
1823 fprintf(stderr, "Polyhedron2Param_Polyhedron algorithm starting at : %.2fs\n",
1824 (float)clock() / CLOCKS_PER_SEC);
1825#endif
1826
1827 /* Find the m-faces, keeping the corresponding domains */
1828 /* in the linked list PDomains */
1829 result = Find_m_faces(Din, Cin, 1, working_space, CEq, CT);
1830
1831#ifdef DEBUGPP
1832 if (result)
1833 fprintf(stderr, "Number of vertices : %d\n", result->nbV);
1834 fprintf(stderr, "Vertices found at : %.2fs\n",
1835 (float)clock() / CLOCKS_PER_SEC);
1836#endif
1837
1838 /* Processing of PVResult and PDomains */
1839 if (result && Cin->Dimension > 0) /* at least 1 parameter */
1840 Compute_PDomains(result->D, result->nbV, working_space);
1841
1842 /* Removed this, Vin100, March 01 */
1843 /* if(result && CEqualities )
1844 for(D=result->D;D;D=D->next)
1845 D->Domain = Add_CEqualities(D->Domain);
1846 */
1847
1848#ifdef DEBUGPP
1849 fprintf(stderr, "domains found at : %.2fs\n",
1850 (float)clock() / CLOCKS_PER_SEC);
1851#endif
1852
1853 return (result);
1854} /* Polyhedron2Param_SimplifiedDomain */
1855
1856/*
1857 * Free the memory allocated to a list of validity domain of a parametrized
1858 * polyhedron.
1859 */
1861
1862 Param_Domain *next_pd;
1863
1864 while (PD) {
1865 free(PD->F);
1866 Domain_Free(PD->Domain);
1867 next_pd = PD->next;
1868 free(PD);
1869 PD = next_pd;
1870 }
1871 return;
1872} /* Param_Domain_Free */
1873
1874/*
1875 * Free the memory allocated to a parametric polyhedron 'P'
1876 */
1878
1879 if (!P)
1880 return;
1882 Param_Domain_Free(P->D);
1883 if (P->Constraints)
1885 if (P->Rays)
1886 Matrix_Free(P->Rays);
1887 free(P);
1888 return;
1889} /* Param_Polyhedron_Free */
1890
1891/*
1892 * Scales the parametric polyhedron such that all vertices are integer.
1893 */
1895 Value *det, unsigned MaxRays) {
1896 int i;
1897 int nb_param, nb_vars;
1898 Vector *denoms;
1899 Param_Vertices *V;
1900 Value global_var_lcm;
1901 Matrix *expansion;
1902
1903 value_set_si(*det, 1);
1904 if (!PP->nbV)
1905 return;
1906
1907 nb_param = PP->D->Domain->Dimension;
1908 nb_vars = PP->V->Vertex->NbRows;
1909
1910 /* Scan the vertices and make an orthogonal expansion of the variable
1911 space */
1912 /* a- prepare the array of common denominators */
1913 denoms = Vector_Alloc(nb_vars);
1914 value_init(global_var_lcm);
1915
1916 /* b- scan the vertices and compute the variables' global lcms */
1917 for (V = PP->V; V; V = V->next)
1918 for (i = 0; i < nb_vars; i++)
1919 value_lcm(denoms->p[i], denoms->p[i], V->Vertex->p[i][nb_param + 1]);
1920
1921 value_set_si(global_var_lcm, 1);
1922 for (i = 0; i < nb_vars; i++) {
1923 value_multiply(*det, *det, denoms->p[i]);
1924 value_lcm(global_var_lcm, global_var_lcm, denoms->p[i]);
1925 }
1926
1927 /* scale vertices */
1928 for (V = PP->V; V; V = V->next)
1929 for (i = 0; i < nb_vars; i++) {
1930 Vector_Scale(V->Vertex->p[i], V->Vertex->p[i], denoms->p[i],
1931 nb_param + 1);
1932 Vector_Normalize(V->Vertex->p[i], nb_param + 2);
1933 }
1934
1935 /* the expansion can be actually writen as global_var_lcm.L^{-1} */
1936 /* this is equivalent to multiply the rows of P by denoms_det */
1937 for (i = 0; i < nb_vars; i++)
1938 value_division(denoms->p[i], global_var_lcm, denoms->p[i]);
1939
1940 /* OPT : we could use a vector instead of a diagonal matrix here (c- and
1941 * d-).*/
1942 /* c- make the quick expansion matrix */
1943 expansion = Matrix_Alloc(nb_vars + nb_param + 1, nb_vars + nb_param + 1);
1944 for (i = 0; i < nb_vars; i++)
1945 value_assign(expansion->p[i][i], denoms->p[i]);
1946 for (i = nb_vars; i < nb_vars + nb_param + 1; i++)
1947 value_assign(expansion->p[i][i], global_var_lcm);
1948
1949 /* d- apply the variable expansion to the polyhedron */
1950 if (P)
1951 *P = Polyhedron_Preimage(*P, expansion, MaxRays);
1952
1953 Matrix_Free(expansion);
1954 value_clear(global_var_lcm);
1955 Vector_Free(denoms);
1956}
#define value_pos_p(val)
Definition: arithmetique.h:574
#define value_mone_p(val)
Definition: arithmetique.h:582
#define value_notzero_p(val)
Definition: arithmetique.h:579
#define value_divexact(ref, val1, val2)
Definition: arithmetique.h:551
#define value_gcd(ref, val1, val2)
Definition: arithmetique.h:559
#define value_notone_p(val)
Definition: arithmetique.h:581
#define value_one_p(val)
Definition: arithmetique.h:580
#define value_lcm(ref, val1, val2)
Definition: arithmetique.h:560
#define VALUE_FMT
Definition: arithmetique.h:295
#define value_zero_p(val)
Definition: arithmetique.h:578
#define value_assign(v1, v2)
Definition: arithmetique.h:485
int Value
Definition: arithmetique.h:294
#define value_set_si(val, i)
Definition: arithmetique.h:486
#define value_clear(val)
Definition: arithmetique.h:488
#define value_division(ref, val1, val2)
Definition: arithmetique.h:550
#define value_multiply(ref, val1, val2)
Definition: arithmetique.h:546
#define value_print(Dst, fmt, val)
Definition: arithmetique.h:490
#define value_subtract(ref, val1, val2)
Definition: arithmetique.h:547
#define value_addto(ref, val1, val2)
Definition: arithmetique.h:540
#define value_init(val)
Definition: arithmetique.h:484
#define value_posz_p(val)
Definition: arithmetique.h:576
#define assert(ex)
Definition: assert.h:16
Matrix * Matrix_Alloc(unsigned NbRows, unsigned NbColumns)
Definition: matrix.c:24
void Matrix_Print(FILE *Dst, const char *Format, Matrix *Mat)
Definition: matrix.c:118
void rat_prodmat(Matrix *S, Matrix *X, Matrix *P)
Definition: matrix.c:749
int MatInverse(Matrix *Mat, Matrix *MatInv)
Definition: matrix.c:611
void Matrix_Free(Matrix *Mat)
Definition: matrix.c:69
Polyhedron * DomainAddRays(Polyhedron *Pol, Matrix *Ray, unsigned NbMaxConstrs)
Add rays pointed by 'Ray' to each and every polyhedron in the polyhedral domain 'Pol'.
Definition: polyhedron.c:2805
Polyhedron * align_context(Polyhedron *Pol, int align_dimension, int NbMaxRays)
Definition: polyhedron.c:3704
void Polyhedron_Free(Polyhedron *Pol)
Definition: polyhedron.c:1621
Polyhedron * DomainConvex(Polyhedron *Pol, unsigned NbMaxConstrs)
Definition: polyhedron.c:3606
Polyhedron * AddPolyToDomain(Polyhedron *Pol, Polyhedron *PolDomain)
Definition: polyhedron.c:2460
Polyhedron * Polyhedron_Preimage(Polyhedron *Pol, Matrix *Func, unsigned NbMaxRays)
Definition: polyhedron.c:4076
Polyhedron * DomainIntersection(Polyhedron *Pol1, Polyhedron *Pol2, unsigned NbMaxRays)
Definition: polyhedron.c:2648
Polyhedron * Polyhedron_Copy(Polyhedron *Pol)
Definition: polyhedron.c:2851
Polyhedron * DomainSimplify(Polyhedron *Pol1, Polyhedron *Pol2, unsigned NbMaxRays)
Definition: polyhedron.c:3291
Polyhedron * Universe_Polyhedron(unsigned Dimension)
Definition: polyhedron.c:1761
Polyhedron * Rays2Polyhedron(Matrix *Ray, unsigned NbMaxConstrs)
Given a matrix of rays 'Ray', create and return a polyhedron.
Definition: polyhedron.c:2094
Matrix * Polyhedron2Constraints(Polyhedron *Pol)
Definition: polyhedron.c:2067
Polyhedron * Constraints2Polyhedron(Matrix *Constraints, unsigned NbMaxRays)
Given a matrix of constraints ('Constraints'), construct and return a polyhedron.
Definition: polyhedron.c:1912
Polyhedron * AddConstraints(Value *Con, unsigned NbConstraints, Polyhedron *Pol, unsigned NbMaxRays)
Definition: polyhedron.c:2311
void Polyhedron_Print(FILE *Dst, const char *Format, const Polyhedron *Pol)
Definition: polyhedron.c:1646
void Domain_Free(Polyhedron *Pol)
Definition: polyhedron.c:1633
Polyhedron * SubConstraint(Value *Con, Polyhedron *Pol, unsigned NbMaxRays, int Pass)
Definition: polyhedron.c:2540
#define POL_ENSURE_VERTICES(P)
Definition: polyhedron.h:17
#define POL_ENSURE_FACETS(P)
Definition: polyhedron.h:13
void Param_Vertices_Free(Param_Vertices *PV)
Definition: polyparam.c:1565
static int nbPV
Definition: polyparam.c:295
Polyhedron * Elim_Columns(Polyhedron *A, Polyhedron *E, int *p, int *ref)
Definition: polyparam.c:941
static Param_Domain * PDomains
Definition: polyparam.c:297
int cntbit[256]
Definition: polyparam.c:511
void Param_Vertices_Print(FILE *DST, Param_Vertices *PV, char **param_names)
Definition: polyparam.c:1732
static Matrix * PiTest
Definition: polyparam.c:286
static void traite_m_face(Polyhedron *, unsigned int *, unsigned int *)
Definition: polyparam.c:355
static Matrix * Pi
Definition: polyparam.c:285
static int nr
Definition: polyparam.c:280
static int m_dim
Definition: polyparam.c:277
Param_Polyhedron * Polyhedron2Param_Vertices(Polyhedron *Din, Polyhedron *Cin, int working_space)
Definition: polyparam.c:1533
static SatMatrix * Poly2Sat(Polyhedron *Pol, unsigned int **L)
Definition: polyparam.c:738
static Matrix * Xi
Definition: polyparam.c:285
static SatMatrix * Sat
Definition: polyparam.c:283
static int ComputeNPLinesRays(int n, Polyhedron *D1, Matrix **Rays)
Definition: polyparam.c:1020
void Param_Polyhedron_Free(Param_Polyhedron *P)
Definition: polyparam.c:1877
static int ws
Definition: polyparam.c:279
void Print_Vertex(FILE *DST, Matrix *V, char **param_names)
Definition: polyparam.c:1585
Param_Polyhedron * Find_m_faces(Polyhedron **Di, Polyhedron *C, int keep_dom, int working_space, Polyhedron **CEq, Matrix **CT)
Definition: polyparam.c:1054
static Param_Vertices * PV_Result
Definition: polyparam.c:296
void Param_Domain_Free(Param_Domain *PD)
Definition: polyparam.c:1860
static SatMatrix * SMAlloc(int rows, int cols)
Definition: polyparam.c:220
void Compute_PDomains(Param_Domain *PD, int nb_domains, int working_space)
Definition: polyparam.c:1353
void Param_Polyhedron_Scale_Integer(Param_Polyhedron *PP, Polyhedron **P, Value *det, unsigned MaxRays)
Definition: polyparam.c:1894
static int m
Definition: polyparam.c:276
void Print_Domain(FILE *DST, Polyhedron *D, char **pname)
Definition: polyparam.c:1682
Matrix * VertexCT(Matrix *V, Matrix *CT)
Definition: polyparam.c:1653
static int n
Definition: polyparam.c:278
static unsigned int * egalite
Definition: polyparam.c:284
static int count_sat(unsigned int *mf)
Definition: polyparam.c:532
static Matrix * CTest
Definition: polyparam.c:287
static int TestRank(Matrix *Mat)
Definition: polyparam.c:133
Param_Polyhedron * GenParamPolyhedron(Polyhedron *Pol, Matrix *Rays)
Definition: polyparam.c:795
unsigned int * int_array2bit_vector(unsigned int *array, int n)
Definition: polyparam.c:334
Param_Polyhedron * Polyhedron2Param_SimplifiedDomain(Polyhedron **Din, Polyhedron *Cin, int working_space, Polyhedron **CEq, Matrix **CT)
Definition: polyparam.c:1806
#define INT_BITS
Definition: polyparam.c:332
static Matrix * PiInv
Definition: polyparam.c:288
static Polyhedron * Add_CEqualities(Polyhedron *D)
Definition: polyparam.c:308
static void scan_m_face(int, int, Polyhedron *, unsigned int *)
Definition: polyparam.c:600
static int bit_vector_includes(unsigned int *bv, int len, unsigned int *part)
Definition: polyparam.c:545
static Polyhedron * Recession_Cone(Polyhedron *P, unsigned nvar, unsigned MaxRays)
Definition: polyparam.c:1001
static void SMFree(SatMatrix *matrix)
Definition: polyparam.c:262
Matrix * PreElim_Columns(Polyhedron *E, int *p, int *ref, int m)
Definition: polyparam.c:866
Polyhedron * PDomainIntersection(Polyhedron *Pol1, Polyhedron *Pol2, unsigned NbMaxRays)
Definition: polyparam.c:41
static Matrix * RaysDi
Definition: polyparam.c:290
Polyhedron * PDomainDifference(Polyhedron *Pol1, Polyhedron *Pol2, unsigned NbMaxRays)
Definition: polyparam.c:84
static int KD
Definition: polyparam.c:292
Param_Polyhedron * Polyhedron2Param_Domain(Polyhedron *Din, Polyhedron *Cin, int working_space)
Definition: polyparam.c:1757
static Polyhedron * CEqualities
Definition: polyparam.c:282
unsigned int NbRows
Definition: polyhedron.c:84
int ** p
Definition: polyhedron.c:86
unsigned int NbColumns
Definition: polyhedron.c:85
unsigned int * p_init
Definition: polyparam.c:217
unsigned int ** p
Definition: polyparam.c:216
int * p_init
Definition: polyhedron.c:87
Definition: types.h:82
Value * p
Definition: types.h:84
struct _Param_Domain * next
Definition: types.h:157
Polyhedron * Domain
Definition: types.h:156
unsigned * F
Definition: types.h:155
Param_Vertices * V
Definition: types.h:162
Param_Domain * D
Definition: types.h:163
Matrix * Rays
Definition: types.h:165
Matrix * Constraints
Definition: types.h:164
Matrix * Domain
Definition: types.h:149
struct _Param_Vertex * next
Definition: types.h:151
Matrix * Vertex
Definition: types.h:145
unsigned * Facets
Definition: types.h:150
Definition: types.h:88
unsigned NbRows
Definition: types.h:89
Value ** p
Definition: types.h:90
unsigned NbColumns
Definition: types.h:89
Value ** Ray
Definition: types.h:112
unsigned Dimension
Definition: types.h:110
unsigned NbConstraints
Definition: types.h:110
unsigned NbRays
Definition: types.h:110
unsigned NbBid
Definition: types.h:110
struct polyhedron * next
Definition: types.h:115
Value ** Constraint
Definition: types.h:111
unsigned NbEq
Definition: types.h:110
#define MSB
Definition: types.h:57
#define emptyQ(P)
Definition: types.h:134
#define NEXT(j, b)
Definition: types.h:63
#define P_VALUE_FMT
Definition: types.h:42
void Vector_Free(Vector *vector)
Definition: vector.c:187
void Vector_Scale(Value *p1, Value *p2, Value lambda, unsigned length)
Definition: vector.c:360
void Vector_Normalize(Value *p, unsigned length)
Definition: vector.c:588
Vector * Vector_Alloc(unsigned length)
Definition: vector.c:134
void Vector_Copy(Value *p1, Value *p2, unsigned length)
Definition: vector.c:276