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