Annotation of OpenXM_contrib/PHC/Ada/Math_Lib/Supports/integer_face_enumerators.adb, Revision 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>