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