[BACK]Return to floating_face_enumerators.adb CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / PHC / Ada / Math_Lib / Supports

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