Annotation of OpenXM_contrib/PHC/Ada/Math_Lib/Supports/integer_face_enumerators.adb, Revision 1.1.1.1
1.1 maekawa 1: with Standard_Integer_Matrices; use Standard_Integer_Matrices;
2: with Standard_Common_Divisors; use Standard_Common_Divisors;
3: with Standard_Integer_Linear_Solvers; use Standard_Integer_Linear_Solvers;
4: with Face_Enumerators_Utilities; use Face_Enumerators_Utilities;
5: with Integer_Linear_Inequalities; use Integer_Linear_Inequalities;
6:
7: package body Integer_Face_Enumerators is
8:
9: -- ELIMINATE TO MAKE UPPER TRIANGULAR :
10:
11: procedure Eliminate ( pivot : in integer; elim : in Vector;
12: target : in out Vector ) is
13:
14: -- DESCRIPTION :
15: -- Makes target(pivot) = 0 by means of making a linear
16: -- combination of the vectors target and elim.
17:
18: -- REQUIRED ON ENTRY :
19: -- target(pivot) /= 0 and elim(pivot) /= 0
20:
21: a,b,lcmab,faca,facb : integer;
22:
23: begin
24: a := elim(pivot); b := target(pivot);
25: lcmab := lcm(a,b);
26: if lcmab < 0 then lcmab := -lcmab; end if;
27: faca := lcmab/a; facb := lcmab/b;
28: if facb < 0
29: then facb := -facb; faca := -faca;
30: end if;
31: for j in target'range loop
32: target(j) := facb*target(j) - faca*elim(j);
33: end loop;
34: Scale(target);
35: end Eliminate;
36:
37: procedure Eliminate ( l : in natural; pivots : in Vector;
38: elim : in VecVec; target : in out Vector ) is
39:
40: -- DESCRIPTION :
41: -- Makes target(pivots(i)) = 0 by means of making a linear
42: -- combination of the vectors target and elim(i), for i in 1..l.
43:
44: -- REQUIRED ON ENTRY :
45: -- elim(i)(pivots(i)) /= 0
46:
47: begin
48: for i in 1..l loop
49: if target(pivots(i)) /= 0
50: then Eliminate(pivots(i),elim(i).all,target);
51: end if;
52: end loop;
53: end Eliminate;
54:
55: function Pivot_after_Elimination
56: ( l,k : in natural; point,face,pivots : in Vector;
57: elim : in VecVec ) return natural is
58:
59: -- DESCRIPTION :
60: -- Returns the first nonzero element of the given point after elimination
61: -- w.r.t. the entries in the face with lower index.
62:
63: work : Vector(point'range) := point - elim(1-k).all;
64: pivot : integer;
65:
66: begin
67: for i in (face'first+1)..face'last loop
68: if (face(i) < l) and then (work(pivots(i)) /= 0)
69: then Eliminate(pivots(i),elim(i).all,work);
70: end if;
71: exit when (face(i) > l);
72: end loop;
73: pivot := 0;
74: for i in work'range loop
75: if work(pivots(i)) /= 0
76: then pivot := i;
77: end if;
78: exit when (pivot /= 0);
79: end loop;
80: return pivot;
81: end Pivot_after_Elimination;
82:
83: procedure Update_Pivots ( point : in Vector; l : in natural;
84: pivots : in out Vector; pivot : out natural ) is
85:
86: -- DESCRIPTION :
87: -- Searches in the point(l..point'last) for the first nonzero entry
88: -- and updates the pivoting information.
89:
90: temp,piv : integer;
91:
92: begin
93: piv := 0;
94: for i in l..point'last loop
95: if point(pivots(i)) /= 0
96: then piv := i;
97: end if;
98: exit when (piv /= 0);
99: end loop;
100: if piv /= 0 and then (piv /= l)
101: then temp := pivots(l);
102: pivots(l) := pivots(piv);
103: pivots(piv) := temp;
104: end if;
105: pivot := piv;
106: end Update_Pivots;
107:
108: procedure Update_Eliminator ( elim : in out VecVec; l : in natural;
109: pivots : in out Vector;
110: point : in Vector; pivot : out natural ) is
111:
112: -- DESCRIPTION :
113: -- Updates the vector of eliminators, by adding the lth elimination
114: -- equation. This procedure ensures the invariant condition on the
115: -- eliminator, which has to be upper triangular. If this cannot be
116: -- achieved, degeneracy is indicated by pivot = 0.
117:
118: -- ON ENTRY :
119: -- elim vector of elimination equations: elim(i)(pivots(i)) /= 0
120: -- and for j in 1..(i-1) : elim(i)(pivots(j)) = 0,
121: -- for i in 1..(l-1), elim(0) contains the basis point;
122: -- l index of current elimination equation to be made;
123: -- pivots contains the pivoting information;
124: -- point new point to make the equation `point - elim(0) = 0'.
125:
126: -- ON RETURN :
127: -- elim if not degen, then elim(l)(pivots(l)) /= 0 and
128: -- for i in 1..(l-1): elim(l)(pivots(i)) = 0;
129: -- pivots updated pivot information;
130: -- pivot the pivot that has been used for elim(l)(pivots(l)) /= 0;
131: -- piv = 0 when the new elimination equation elim(l)
132: -- became entirely zero after ensuring the invariant condition.
133:
134: begin
135: elim(l) := new Vector'(point - elim(0).all);
136: Eliminate(l-1,pivots,elim,elim(l).all);
137: Update_Pivots(elim(l).all,l,pivots,pivot);
138: end Update_Eliminator;
139:
140: procedure Update_Eliminator_for_Sum
141: ( elim : in out VecVec; l : in natural; pivots : in out Vector;
142: point : in Vector; index : in natural; pivot : out natural ) is
143:
144: -- DESCRIPTION :
145: -- Updates the vector of eliminators, by adding the lth elimination
146: -- equation. This procedure ensures the invariant condition on the
147: -- eliminator, which has to be upper triangular. If this cannot be
148: -- achieved, degeneracy is indicated by pivot = 0.
149:
150: -- ON ENTRY :
151: -- elim vector of elimination equations: elim(i)(pivots(i)) /= 0
152: -- and for j in 1..(i-1) : elim(i)(pivots(j)) = 0,
153: -- for i in 1..(l-1), elim(1-index) contains the basis point;
154: -- l index of current elimination equation to be made;
155: -- pivots contains the pivoting information;
156: -- point new point to make the equation `point - elim(1-index) = 0';
157: -- index indicates the current polytope.
158:
159: -- ON RETURN :
160: -- elim if not degen, then elim(l)(pivots(l)) /= 0 and
161: -- for i in 1..(l-1): elim(l)(pivots(i)) = 0;
162: -- pivots updated pivot information;
163: -- piv the pivot that has been used for elim(l)(pivots(l)) /= 0;
164: -- piv = 0 when the new elimination equation elim(l)
165: -- became entirely zero after ensuring the invariant condition.
166:
167: begin
168: elim(l) := new Vector'(point - elim(1-index).all);
169: Eliminate(l-1,pivots,elim,elim(l).all);
170: Update_Pivots(elim(l).all,l,pivots,pivot);
171: end Update_Eliminator_for_Sum;
172:
173: -- CREATE TABLEAU OF INEQUALITIES :
174:
175: procedure Create_Tableau_for_Vertices
176: ( i,n : in integer; pts : in VecVec; tab : out matrix ) is
177:
178: column : integer := tab'first(2);
179:
180: begin
181: for j in pts'range loop
182: if j /= i
183: then
184: for k in pts(j)'range loop
185: tab(k,column) := pts(j)(k);
186: end loop;
187: tab(tab'last(1),column) := 1;
188: column := column + 1;
189: end if;
190: end loop;
191: for k in pts(i)'range loop
192: tab(k,tab'last(2)) := pts(i)(k);
193: end loop;
194: tab(tab'last(1),tab'last(2)) := 1;
195: end Create_Tableau_for_Vertices;
196:
197: procedure Create_Tableau_for_Edges
198: ( i,j,n,pivot : in integer; elim : in Vector;
199: pts : in VecVec; tab : out matrix;
200: lastcol : out integer; degenerate : out boolean ) is
201:
202: column : integer := 1;
203: ineq : Vector(1..n);
204:
205: begin
206: degenerate := false;
207: for k in pts'range loop
208: if (k/=i) and then (k/=j)
209: then
210: ineq := pts(k).all - pts(i).all; -- compute inequality
211: -- put("Inequality before eliminate : "); put(ineq); new_line;
212: if ineq(pivot) /= 0 -- make ineq(pivot) = 0
213: then Eliminate(pivot,elim,ineq);
214: end if;
215: -- put("Inequality after eliminate : "); put(ineq); new_line;
216: if Is_Zero(ineq) -- check if degenerate
217: then
218: if not In_Edge(pts(k).all,pts(i).all,pts(j).all)
219: then degenerate := true; return;
220: end if;
221: else
222: for l in 1..n loop -- fill in the column
223: if l < pivot
224: then tab(l,column) := ineq(l);
225: elsif l > pivot
226: then tab(l-1,column) := ineq(l);
227: end if;
228: end loop;
229: tab(tab'last(1),column) := 1;
230: column := column + 1;
231: end if;
232: end if;
233: end loop;
234: for k in tab'first(1)..(tab'last(1)-1) loop -- right hand side
235: tab(k,tab'last(2)) := 0;
236: end loop;
237: tab(tab'last(1),tab'last(2)) := 1;
238: lastcol := column-1;
239: end Create_Tableau_for_Edges;
240:
241: procedure Create_Tableau_for_Faces
242: ( k,n : in natural; face,pivots : in Vector;
243: pts,elim : in VecVec; tab : out matrix; lastcol : out integer;
244: degenerate : out boolean ) is
245:
246: column : integer := 1;
247: ineq : Vector(1..n);
248:
249: begin
250: degenerate := false;
251: for l in pts'range loop
252: if not Is_In(l,face)
253: then
254: ineq := pts(l).all - elim(0).all; -- new inequality
255: -- put("Inequality before : "); put(ineq); new_line;
256: Eliminate(k,pivots,elim,ineq); -- ineq(pivots(i)) = 0, i=1,2,..k
257: -- put("and after elimination : "); put(ineq); new_line;
258: if Is_Zero(ineq)
259: then
260: if --not In_Face(k,face,pts(l).all,pts)
261: --and then
262: l < face(face'last) -- lexicographic enumeration
263: and then (Pivot_after_Elimination
264: (l,1,pts(l).all,face,pivots,elim) /= 0)
265: then -- put("Degenerate for l = "); put(l,1); new_line;
266: degenerate := true; return;
267: end if;
268: else
269: for ll in (k+1)..n loop -- fill in the column
270: tab(ll-k,column) := ineq(pivots(ll));
271: end loop;
272: tab(tab'last(1),column) := 1;
273: column := column + 1;
274: end if;
275: end if;
276: end loop;
277: for l in tab'first(1)..(tab'last(1)-1) loop -- right hand side
278: tab(l,tab'last(2)) := 0;
279: end loop;
280: tab(tab'last(1),tab'last(2)) := 1;
281: lastcol := column-1;
282: end Create_Tableau_for_Faces;
283:
284: procedure Create_Tableau_for_Faces_of_Sum
285: ( k,n,i,r : in natural; ind,pivots : in Vector;
286: pts,elim,face : in VecVec; tab : out matrix;
287: lastcol : out integer; degenerate : out boolean ) is
288:
289: -- DESCRIPTION :
290: -- Creates the table of inequalities for determining whether the given
291: -- candidate face spans a face of the sum polytope.
292:
293: -- ON ENTRY :
294: -- k dimension of the face on the sum;
295: -- n dimension of the points;
296: -- i current polytope;
297: -- r number of polytopes;
298: -- ind indicate the beginning vector in pts of each polytope;
299: -- etc...
300:
301: column : integer := 1;
302: ineq : Vector(1..n);
303: last : integer;
304:
305: begin
306: degenerate := false;
307: for l1 in face'first..i loop
308: if l1 = r
309: then last := pts'last;
310: else last := ind(l1+1)-1;
311: end if;
312: for l2 in ind(l1)..last loop
313: if not Is_In(l2,face(l1).all)
314: then
315: ineq := pts(l2).all - elim(1-l1).all; -- new inequality
316: Eliminate(k,pivots,elim,ineq); -- ineq(pivots(i)) = 0, i=1,2,..k
317: if Is_Zero(ineq)
318: then
319: if --not In_Face(face(l1)'length-1,face(l1).all,pts(l2).all,pts)
320: --and then
321: face(l1)(face(l1)'first) <= l2
322: and then l2 < face(l1)(face(l1)'last)
323: -- lexicographic enumeration
324: and then (Pivot_after_Elimination
325: (l2,l1,pts(l2).all,face(l1).all,pivots,elim) /= 0)
326: then degenerate := true; return;
327: end if;
328: else
329: for ll in (k+1)..n loop -- fill in the column
330: tab(ll-k,column) := ineq(pivots(ll));
331: end loop;
332: tab(tab'last(1),column) := 1;
333: column := column + 1;
334: end if;
335: end if;
336: end loop;
337: end loop;
338: for l in tab'first(1)..(tab'last(1)-1) loop -- right hand side
339: tab(l,tab'last(2)) := 0;
340: end loop;
341: tab(tab'last(1),tab'last(2)) := 1;
342: lastcol := column-1;
343: end Create_Tableau_for_Faces_of_Sum;
344:
345: procedure Create_Tableau_for_Lower_Edges
346: ( i,j,n,pivot : in integer; elim : in Vector;
347: pts : in VecVec; tab : out matrix;
348: lastcol : out integer; degenerate : out boolean ) is
349:
350: column : integer := 1;
351: ineq : Vector(1..n);
352:
353: begin
354: -- put("The elimination vector : "); put(elim); new_line;
355: degenerate := false;
356: for k in pts'range loop
357: if (k/=i) and then (k/=j)
358: then
359: ineq := pts(k).all - pts(i).all; -- compute inequality
360: -- put("Inequality before eliminate : "); put(ineq); new_line;
361: if ineq(pivot) /= 0 -- make ineq(pivot) = 0
362: then Eliminate(pivot,elim,ineq);
363: end if;
364: -- put("Inequality after eliminate : "); put(ineq); new_line;
365: if Is_Zero(ineq) -- check if degenerate
366: then
367: if not In_Edge(pts(k).all,pts(i).all,pts(j).all)
368: then degenerate := true; return;
369: end if;
370: else
371: for l in 1..n loop -- fill in the column
372: if l < pivot
373: then tab(l,column) := ineq(l);
374: elsif l > pivot
375: then tab(l-1,column) := ineq(l);
376: end if;
377: end loop;
378: column := column + 1;
379: end if;
380: end if;
381: end loop;
382: for k in tab'first(1)..(tab'last(1)-1) loop -- right hand side
383: tab(k,tab'last(2)) := 0;
384: end loop;
385: tab(tab'last(1),tab'last(2)) := -1;
386: lastcol := column-1;
387: end Create_Tableau_for_Lower_Edges;
388:
389: procedure Create_Tableau_for_Lower_Faces
390: ( k,n : in natural; face,pivots : in Vector;
391: pts,elim : in VecVec; tab : out matrix; lastcol : out integer;
392: degenerate : out boolean ) is
393:
394: column : integer := 1;
395: ineq : Vector(1..n);
396:
397: begin
398: degenerate := false;
399: for l in pts'range loop
400: if not Is_In(l,face)
401: then
402: ineq := pts(l).all - elim(0).all; -- new inequality
403: -- put("Inequality before : "); put(ineq); new_line;
404: Eliminate(k,pivots,elim,ineq); -- ineq(pivots(i)) = 0, i=1,2,..k
405: -- put("and after elimination : "); put(ineq); new_line;
406: if Is_Zero(ineq)
407: then
408: if --not In_Face(k,face,pts(l).all,pts)
409: --and then
410: l < face(face'last) -- lexicographic enumeration
411: and then (Pivot_after_Elimination
412: (l,1,pts(l).all,face,pivots,elim) /= 0)
413: then --put_line("Degenerate choice");
414: degenerate := true; return;
415: end if;
416: else
417: for ll in (k+1)..n loop -- fill in the column
418: tab(ll-k,column) := ineq(pivots(ll));
419: end loop;
420: column := column + 1;
421: end if;
422: end if;
423: end loop;
424: for l in tab'first(1)..(tab'last(1)-1) loop -- right hand side
425: tab(l,tab'last(2)) := 0;
426: end loop;
427: tab(tab'last(1),tab'last(2)) := -1;
428: lastcol := column-1;
429: end Create_Tableau_for_Lower_Faces;
430:
431: -- DETERMINE WHETHER THE CANDIDATE IS VERTEX, SPANS AN EDGE OR A K-FACE :
432:
433: function Is_Vertex ( i,m,n : integer; pts : VecVec ) return boolean is
434:
435: tableau : matrix(1..n+1,1..m);
436: feasible : boolean;
437:
438: begin
439: Create_Tableau_for_Vertices(i,n,pts,tableau);
440: -- put_line("The tableau :"); put(tableau);
441: Integer_Complementary_Slackness(tableau,feasible);
442: return not feasible;
443: end Is_Vertex;
444:
445: function Is_Edge ( i,j,m,n : integer; pts : VecVec ) return boolean is
446:
447: elim : Vector(1..n) := pts(i).all - pts(j).all;
448: pivot : integer;
449:
450: begin
451: pivot := elim'first - 1;
452: for k in elim'range loop
453: if elim(k) /= 0
454: then pivot := k;
455: end if;
456: exit when pivot >= elim'first;
457: end loop;
458: if pivot < elim'first
459: then return false;
460: else Scale(elim);
461: declare
462: tab : matrix(1..n,1..m-1);
463: deg,feasible : boolean;
464: lst : integer;
465: begin
466: -- put("The elimination vector : "); put(elim); new_line;
467: Create_Tableau_for_Edges(i,j,n,pivot,elim,pts,tab,lst,deg);
468: -- put_line("The tableau :"); put(tab);
469: if deg
470: then return false;
471: elsif lst = 0
472: then return true;
473: else Integer_Complementary_Slackness(tab,lst,feasible);
474: return not feasible;
475: end if;
476: end;
477: end if;
478: end Is_Edge;
479:
480: function Is_Face ( k,n,m : natural; elim,pts : VecVec;
481: pivots,face : Vector ) return boolean is
482:
483: -- DESCRIPTION :
484: -- Applies Complementary Slackness to determine whether the given
485: -- candidate face is a face of the polytope.
486:
487: -- ON ENTRY :
488: -- k dimension of the candidate face;
489: -- n dimension of the vector space;
490: -- m number of points which span the polytope;
491: -- elim elimination equations in upper triangular form;
492: -- pts the points which span the polytope;
493: -- pivots pivoting information for the elimination equations;
494: -- face entries of the points which span the candidate face.
495:
496: nn : constant natural := n-k+1;
497: tab : matrix(1..nn,1..(m-k));
498: deg,feasible : boolean;
499: lst : integer;
500:
501: begin
502: -- put("The face being tested : "); put(face); new_line;
503: -- put("The pivots : "); put(pivots); new_line;
504: -- put_line("The elimination equations : ");
505: -- for i in 1..elim'last loop
506: -- put(elim(i)); put(" = 0 ");
507: -- end loop;
508: -- new_line;
509: if m - k <= 1
510: then return true;
511: else
512: Create_Tableau_for_Faces(k,n,face,pivots,pts,elim,tab,lst,deg);
513: -- put_line("The tableau of inequalities : "); put(tab);
514: if deg
515: then -- put_line("Tableau is degenerate: no solution :");
516: return false;
517: elsif lst = 0
518: then return true;
519: else Integer_Complementary_Slackness(tab,lst,feasible);
520: -- if feasible
521: -- then put_line(" is feasible");
522: -- else put_line(" is not feasible");
523: -- end if;
524: return not feasible;
525: end if;
526: end if;
527: end Is_Face;
528:
529: function Is_Face_of_Sum
530: ( k,n,m,i,r : natural; elim,pts,face : VecVec;
531: ind,pivots : Vector ) return boolean is
532:
533: -- DESCRIPTION :
534: -- Applies Complementary Slackness to determine whether the given
535: -- candidate face is a face of the polytope.
536:
537: -- ON ENTRY :
538: -- k dimension of the candidate face;
539: -- n dimension of the vector space;
540: -- m number of total points which span the polytope;
541: -- i current polytope;
542: -- r number of different polytopes;
543: -- elim elimination equations in upper triangular form;
544: -- pts the points which span the polytope;
545: -- face entries of the points which span the candidate face;
546: -- ind indicates the starting vector in pts of each polytope;
547: -- pivots pivoting information for the elimination equations.
548:
549: nn : constant natural := n-k+1;
550: tab : matrix(1..nn,1..(m-k));
551: deg,feasible : boolean;
552: lst : integer;
553:
554: begin
555: if m - k <= 1
556: then return true;
557: else
558: Create_Tableau_for_Faces_of_Sum
559: (k,n,i,r,ind,pivots,pts,elim,face,tab,lst,deg);
560: -- put_line("The tableau of inequalities : "); put(tab);
561: if deg
562: then --put_line("Tableau is degenerate: no solution :");
563: return false;
564: elsif lst = 0
565: then return true;
566: else Integer_Complementary_Slackness(tab,lst,feasible);
567: --if feasible
568: -- then put_line(" is feasible");
569: -- else put_line(" is not feasible");
570: --end if;
571: return not feasible;
572: end if;
573: end if;
574: end Is_Face_of_Sum;
575:
576: function Is_Lower_Edge ( i,j,m,n : integer; pts : VecVec )
577: return boolean is
578:
579: elim : Vector(1..n) := pts(i).all - pts(j).all;
580: pivot : integer;
581:
582: begin
583: pivot := elim'first - 1;
584: for k in elim'range loop
585: if elim(k) /= 0
586: then pivot := k;
587: end if;
588: exit when pivot >= elim'first;
589: end loop;
590: if pivot < elim'first or else (pivot = elim'last)
591: then return false;
592: else Scale(elim);
593: declare
594: tab : matrix(1..n-1,1..m-1);
595: deg,feasible : boolean;
596: lst : integer;
597: begin
598: Create_Tableau_for_Lower_Edges(i,j,n,pivot,elim,pts,tab,lst,deg);
599: -- put_line("The tableau :"); put(tab);
600: if deg
601: then return false;
602: elsif lst = 0
603: then return true;
604: else Integer_Complementary_Slackness(tab,lst,feasible);
605: return not feasible;
606: end if;
607: end;
608: end if;
609: end Is_Lower_Edge;
610:
611: function Is_Lower_Face
612: ( k,n,m : in natural; elim,pts : VecVec;
613: pivots,face : Vector ) return boolean is
614:
615: -- DESCRIPTION :
616: -- Applies Complementary Slackness to determine whether the given
617: -- candidate face is a face of the lower hull of the polytope.
618:
619: -- ON ENTRY :
620: -- k dimension of the candidate face;
621: -- n dimension of the vector space;
622: -- m number of points which span the polytope;
623: -- elim elimination equations in upper triangular form;
624: -- pts the points which span the polytope;
625: -- pivots pivoting information for the elimination equations;
626: -- face entries of the points which span the candidate face.
627:
628: nn : constant natural := n-k;
629: tab : matrix(1..nn,1..(m-k));
630: deg,feasible : boolean;
631: lst : integer;
632:
633: begin
634: -- put("The pivots : "); put(pivots); new_line;
635: -- put_line("The elimination equations : ");
636: -- for i in 1..elim'last loop
637: -- put(elim(i)); put(" = 0 ");
638: -- end loop;
639: -- new_line;
640: if m - k <= 1
641: then return true;
642: else
643: Create_Tableau_for_Lower_Faces(k,n,face,pivots,pts,elim,tab,lst,deg);
644: -- put_line("The tableau of inequalities : "); put(tab);
645: if deg
646: then --put_line("Degenerate tableau");
647: return false;
648: elsif lst = 0
649: then --put_line("lst = 0");
650: return true;
651: else Integer_Complementary_Slackness(tab,lst,feasible);
652: --if feasible
653: -- then put_line(" is feasible");
654: -- else put_line(" is not feasible");
655: --end if;
656: return not feasible;
657: end if;
658: end if;
659: end Is_Lower_Face;
660:
661: -- TARGET ROUTINES :
662:
663: procedure Enumerate_Vertices ( pts : in VecVec ) is
664:
665: continue : boolean := true;
666: n : constant natural := pts(pts'first).all'length;
667: m : constant natural := pts'length;
668:
669: begin
670: for i in pts'range loop
671: if Is_Vertex(i,m,n,pts)
672: then Process(i,continue);
673: end if;
674: exit when not continue;
675: end loop;
676: end Enumerate_Vertices;
677:
678: procedure Enumerate_Edges ( pts : in VecVec ) is
679:
680: continue : boolean := true;
681: n : constant natural := pts(pts'first).all'length;
682: m : constant natural := pts'length;
683:
684: procedure Candidate_Edges ( i,n : in integer ) is
685: begin
686: for j in (i+1)..pts'last loop -- enumerate all candidates
687: -- put("Verifying "); put(pts(i).all); put(" and");
688: -- put(pts(j).all); put(" :"); new_line;
689: if Is_Edge(i,j,m,n,pts)
690: then Process(i,j,continue);
691: end if;
692: exit when not continue;
693: end loop;
694: end Candidate_Edges;
695:
696: begin
697: for i in pts'first..(pts'last-1) loop
698: Candidate_Edges(i,n);
699: end loop;
700: end Enumerate_Edges;
701:
702: procedure Enumerate_Lower_Edges ( pts : in VecVec ) is
703:
704: continue : boolean := true;
705: n : constant natural := pts(pts'first).all'length;
706: m : constant natural := pts'length;
707:
708: procedure Candidate_Lower_Edges ( i,n : in integer ) is
709: begin
710: for j in (i+1)..pts'last loop -- enumerate all candidates
711: -- put("Verifying "); put(pts(i).all); put(" and");
712: -- put(pts(j).all); put(" :"); new_line;
713: if Is_Lower_Edge(i,j,m,n,pts)
714: then Process(i,j,continue);
715: end if;
716: exit when not continue;
717: end loop;
718: end Candidate_Lower_Edges;
719:
720: begin
721: for i in pts'first..(pts'last-1) loop
722: Candidate_Lower_Edges(i,n);
723: end loop;
724: end Enumerate_Lower_Edges;
725:
726: procedure Enumerate_Faces ( k : in natural; pts : in VecVec ) is
727:
728: m : constant natural := pts'length;
729: n : constant natural := pts(pts'first).all'length;
730: candidate : Vector(0..k);
731: elim : VecVec(0..k);
732: continue : boolean := true;
733:
734: procedure Candidate_Faces ( ipvt : in Vector; i,l : in integer ) is
735:
736: -- DESCRIPTION :
737: -- Enumerates all candidate k-faces in lexicographic order.
738:
739: piv : natural;
740: pivots : Vector(1..n);
741:
742: begin
743: if l > k
744: then if (k = m)
745: or else Is_Face(k,n,m,elim,pts,ipvt,candidate)
746: then Process(candidate,continue);
747: end if;
748: else for j in (i+1)..pts'last loop
749: candidate(l) := j;
750: pivots := ipvt;
751: Update_Eliminator(elim,l,pivots,pts(j).all,piv);
752: if piv /= 0
753: then Candidate_Faces(pivots,j,l+1);
754: end if;
755: Clear(elim(l));
756: exit when not continue;
757: end loop;
758: end if;
759: end Candidate_Faces;
760:
761: begin
762: if k <= m
763: then
764: declare
765: ipvt : Vector(1..n);
766: begin
767: for i in ipvt'range loop
768: ipvt(i) := i;
769: end loop;
770: for i in pts'first..(pts'last-k) loop
771: candidate(0) := i;
772: elim(0) := pts(i); -- basis point
773: Candidate_Faces(ipvt,i,1);
774: end loop;
775: end;
776: end if;
777: end Enumerate_Faces;
778:
779: procedure Enumerate_Lower_Faces ( k : in natural; pts : VecVec ) is
780:
781: m : constant natural := pts'length;
782: n : constant natural := pts(pts'first).all'length;
783: candidate : Vector(0..k);
784: elim : VecVec(0..k);
785: continue : boolean := true;
786:
787: procedure Candidate_Lower_Faces ( ipvt : in Vector; i,l : in integer ) is
788:
789: -- DESCRIPTION :
790: -- Enumerates all candidate k-faces in lexicographic order.
791:
792: piv : natural;
793: pivots : Vector(1..n);
794:
795: begin
796: if l > k
797: then --put_line("Testing the following candidate face :");
798: --for ii in candidate'first..candidate'last-1 loop
799: -- put(pts(candidate(ii))); put(" & ");
800: --end loop;
801: --put(pts(candidate(candidate'last))); new_line;
802: if (k = m) or else Is_Lower_Face(k,n,m,elim,pts,ipvt,candidate)
803: then Process(candidate,continue);
804: end if;
805: else for j in (i+1)..pts'last loop
806: candidate(l) := j;
807: pivots := ipvt;
808: -- put("Picking "); put(pts(j));
809: -- put(" Pivots : "); put(pivots); new_line;
810: Update_Eliminator(elim,l,pivots,pts(j).all,piv);
811: -- put(" update of eliminator piv = "); put(piv,1);
812: -- put(" Pivots : "); put(pivots); new_line;
813: if (piv /= 0) and (piv /= n)
814: then Candidate_Lower_Faces(pivots,j,l+1);
815: end if;
816: Clear(elim(l));
817: exit when not continue;
818: end loop;
819: end if;
820: end Candidate_Lower_Faces;
821:
822: begin
823: if k <= m
824: then
825: declare
826: ipvt : Vector(1..n);
827: begin
828: for i in ipvt'range loop
829: ipvt(i) := i;
830: end loop;
831: for i in pts'first..(pts'last-k) loop
832: candidate(0) := i;
833: elim(0) := pts(i); -- basis point
834: Candidate_Lower_Faces(ipvt,i,1);
835: end loop;
836: end;
837: end if;
838: end Enumerate_Lower_Faces;
839:
840: procedure Enumerate_Faces_of_Sum
841: ( ind,typ : in Vector; k : in natural; pts : in VecVec ) is
842:
843: m : constant natural := pts'length; -- number of points
844: n : constant natural := pts(pts'first)'length; -- dimension of vectors
845: r : constant natural := ind'length; -- number of polytopes
846: candidates : VecVec(1..r);
847: elim : VecVec(1-r..k);
848: pivots : Vector(1..n);
849: continue : boolean := true;
850: lasti,sum : natural;
851:
852: procedure Candidate_Faces_of_Sum ( ipvt : in Vector; i : in integer ) is
853:
854: -- DESCRIPTION :
855: -- Enumerates all faces of the given type on the sum,
856: -- i indicates the current polytope.
857:
858: procedure Candidate_Faces ( ipvt : in Vector;
859: start,l : in integer ) is
860:
861: -- DESCRIPTION :
862: -- Enumerates all candidate k-faces, with k = typ(i).
863: -- The parameter l indicates the current element of pts to be chosen.
864: -- The previously chosen point is given by start.
865:
866: piv,last : natural;
867:
868: begin
869: if i = r
870: then last := m;
871: else last := ind(i+1)-1;
872: end if;
873: if l > typ(i)
874: then
875: if (typ(i) = last-ind(i)+1)
876: or else Is_Face_of_Sum
877: (sum,n,last-i+1,i,r,elim,pts(pts'first..last),
878: candidates,ind,ipvt)
879: then
880: if i = r
881: then Process(candidates,continue);
882: else Candidate_Faces_of_Sum(ipvt,i+1);
883: end if;
884: end if;
885: else
886: for j in (start+1)..(last-typ(i)+l) loop
887: candidates(i)(l) := j;
888: if l = 0
889: then
890: Candidate_Faces(ipvt,j,l+1);
891: else
892: pivots := ipvt;
893: Update_Eliminator_for_Sum
894: (elim,sum-typ(i)+l,pivots,pts(j).all,i,piv);
895: if piv /= 0
896: then Candidate_Faces(pivots,j,l+1);
897: end if;
898: Clear(elim(sum-typ(i)+l));
899: end if;
900: exit when not continue;
901: end loop;
902: end if;
903: end Candidate_Faces;
904:
905: begin
906: candidates(i) := new Vector(0..typ(i));
907: if i = r
908: then lasti := pts'last;
909: else lasti := ind(i+1)-1;
910: end if;
911: sum := sum + typ(i);
912: for j in ind(i)..(lasti-typ(i)) loop
913: candidates(i)(0) := j;
914: elim(1-i) := pts(j);
915: Candidate_Faces(ipvt,j,1);
916: end loop;
917: sum := sum - typ(i);
918: -- for j in (sum+1)..(sum+typ(i)) loop
919: -- Clear(elim(j));
920: -- end loop;
921: Clear(candidates(i));
922: end Candidate_Faces_of_Sum;
923:
924: begin
925: declare
926: ipvt : Vector(1..n);
927: begin
928: for i in ipvt'range loop
929: ipvt(i) := i;
930: end loop;
931: sum := 0;
932: Candidate_Faces_of_Sum(ipvt,1);
933: end;
934: end Enumerate_Faces_of_Sum;
935:
936: end Integer_Face_Enumerators;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>