[BACK]Return to dynamic_mixed_subdivisions.adb CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / PHC / Ada / Root_Counts / Dynlift

Annotation of OpenXM_contrib/PHC/Ada/Root_Counts/Dynlift/dynamic_mixed_subdivisions.adb, Revision 1.1.1.1

1.1       maekawa     1: with Standard_Integer_VecVecs;           use Standard_Integer_VecVecs;
                      2: with Transforming_Integer_Vector_Lists;  use Transforming_Integer_Vector_Lists;
                      3: with Initial_Mixed_Cell;
                      4: with Vertices,Simplices;                 use Vertices,Simplices;
                      5: with Global_Dynamic_Triangulation;       use Global_Dynamic_Triangulation;
                      6: with Integer_Lifting_Utilities;          use Integer_Lifting_Utilities;
                      7: with Dynamic_Lifting_Functions;          use Dynamic_Lifting_Functions;
                      8: with Flatten_Mixed_Subdivisions;         use Flatten_Mixed_Subdivisions;
                      9: with Enumerate_Faces_of_Polytope;        use Enumerate_Faces_of_Polytope;
                     10: with Common_Faces_of_Polytope;           use Common_Faces_of_Polytope;
                     11: with Integer_Pruning_Methods;            use Integer_Pruning_Methods;
                     12: with Mixed_Volume_Computation;           use Mixed_Volume_Computation;
                     13: with Contributions_to_Mixed_Volume;      use Contributions_to_Mixed_Volume;
                     14:
                     15: package body Dynamic_Mixed_Subdivisions is
                     16:
                     17: -- UTILITIES :
                     18:
                     19:   function Is_Empty ( points : Array_of_Lists ) return boolean is
                     20:   begin
                     21:     for i in points'range loop
                     22:       if not Is_Null(points(i))
                     23:        then return false;
                     24:       end if;
                     25:     end loop;
                     26:     return true;
                     27:   end Is_Empty;
                     28:
                     29:   function First_Non_Empty ( points : Array_of_Lists ) return integer is
                     30:
                     31:   -- DESCRIPTION :
                     32:   --   Returns the index of the first non empty set in the points.
                     33:
                     34:     res : integer := points'first - 1;
                     35:
                     36:   begin
                     37:     for i in points'range loop
                     38:       if not Is_Null(points(i))
                     39:        then res := i;
                     40:       end if;
                     41:       exit when res >= points'first;
                     42:     end loop;
                     43:     return res;
                     44:   end First_Non_Empty;
                     45:
                     46:   function Is_In ( fs : Face_Structure; point : vector ) return boolean is
                     47:   begin
                     48:     if Is_Null(fs.t)
                     49:      then return Is_In(fs.l,point);
                     50:      else return Is_In(fs.t,point);
                     51:     end if;
                     52:   end Is_In;
                     53:
                     54: --  procedure put ( n : in natural; fs : in Face_Structure ) is
                     55: --  begin
                     56: --    put_line("The list of lifted points : "); put(fs.l);
                     57: --    put_line("The list of k-faces : "); put(fs.f);
                     58: --    put_line("The triangulation : "); put(n,fs.t);
                     59: --  end put;
                     60:
                     61: --  procedure put ( n : in natural; fs : in Face_Structures ) is
                     62: --  begin
                     63: --    for i in fs'range loop
                     64: --      put("face structure for component "); put(i,1);
                     65: --      put_line(" :");
                     66: --      put(n,fs(i));
                     67: --    end loop;
                     68: --  end put;
                     69:
                     70: -- FLATTENING :
                     71:
                     72:   procedure Flatten ( points : in out VecVec ) is
                     73:
                     74:     pt : Link_to_Vector;
                     75:
                     76:   begin
                     77:     for i in points'range loop
                     78:       pt := points(i);
                     79:       if pt(pt'last) /= 0
                     80:        then pt(pt'last) := 0;
                     81:       end if;
                     82:     end loop;
                     83:   end Flatten;
                     84:
                     85:   procedure Flatten ( f : in out Face ) is
                     86:   begin
                     87:     Flatten(f.all);
                     88:   end Flatten;
                     89:
                     90:   procedure Flatten ( fs : in out Faces ) is
                     91:
                     92:     tmp : Faces := fs;
                     93:     f : Face;
                     94:
                     95:   begin
                     96:     while not Is_Null(tmp) loop
                     97:       f := Head_Of(tmp);
                     98:       Flatten(f);
                     99:       Set_Head(tmp,f);
                    100:       tmp := Tail_Of(tmp);
                    101:     end loop;
                    102:   end Flatten;
                    103:
                    104:   procedure Flatten ( fs : in out Face_Structure ) is
                    105:   begin
                    106:     Flatten(fs.l); Flatten(fs.t); Flatten(fs.f);
                    107:   end Flatten;
                    108:
                    109:   procedure Flatten ( fs : in out Face_Structures ) is
                    110:   begin
                    111:     for i in fs'range loop
                    112:       Flatten(fs(i));
                    113:     end loop;
                    114:   end Flatten;
                    115:
                    116: -- ZERO CONTRIBUTION :
                    117:
                    118:   function Extract_Facet ( n : natural; s : Simplex ) return Face is
                    119:
                    120:     ver : constant VecVec := Simplices.Vertices(s);
                    121:     res : Face := new VecVec(ver'range);
                    122:
                    123:   begin
                    124:     for i in res'range loop
                    125:       res(i) := new Standard_Integer_Vectors.Vector'(ver(i)(1..n));
                    126:     end loop;
                    127:     return res;
                    128:   end Extract_Facet;
                    129:
                    130:   function Extract_Facets ( n : natural; t : Triangulation; x : Vector )
                    131:                           return Faces is
                    132:
                    133:   -- DESCRIPTION :
                    134:   --   Returns the list of facets in t that all contain x.
                    135:   --   The facets are given in their original coordinates.
                    136:
                    137:   -- REQUIRED : x is lifted, i.e., x'length = n+1.
                    138:
                    139:     tmp : Triangulation := t;
                    140:     res,res_last : Faces;
                    141:
                    142:   begin
                    143:     while not Is_Null(tmp) loop
                    144:       declare
                    145:         s : Simplex := Head_Of(tmp);
                    146:       begin
                    147:         if Is_Vertex(s,x)
                    148:          then Append(res,res_last,Extract_Facet(n,s));
                    149:         end if;
                    150:       end;
                    151:       tmp := Tail_Of(tmp);
                    152:     end loop;
                    153:     return res;
                    154:   end Extract_Facets;
                    155:
                    156:   function Zero_Contribution ( n : natural; fs : Face_Structures;
                    157:                                x : Vector; i : natural ) return boolean is
                    158:
                    159:   -- DESCRIPTION :
                    160:   --   Returns true if the point x does not contribute to the mixed volume
                    161:   --   when considered to the ith component of the already lifted points.
                    162:
                    163:   -- REQUIRED : x'length = n+1, n = dimension before lifting.
                    164:
                    165:     res : boolean := false;
                    166:     supp : Array_of_Lists(fs'range);
                    167:
                    168:   begin
                    169:     for j in supp'range loop
                    170:       supp(j) := Reduce(fs(j).l,n+1);
                    171:     end loop;
                    172:     if Length_Of(fs(i).t) > 1
                    173:      then declare
                    174:             facets : Faces := Extract_Facets(n,fs(i).t,x);
                    175:           begin
                    176:             res := Simple_Zero_Contribution(supp,facets,x(1..n),i);
                    177:           end;
                    178:      else res := Simple_Zero_Contribution(supp,x(1..n),i);
                    179:     end if;
                    180:     Deep_Clear(supp);
                    181:     return res;
                    182:   end Zero_Contribution;
                    183:
                    184: -- INITIALIZATION :
                    185:
                    186:   procedure Initialize
                    187:                ( n : in natural; mix : in Vector; points : in Array_of_Lists;
                    188:                  mixsub : in out Mixed_Subdivision;
                    189:                  fs : in out Face_Structures; rest : in out Array_of_Lists;
                    190:                  done : in out boolean ) is
                    191:
                    192:   -- DESCRIPTION :
                    193:   --   Performs initialization of the dynamic lifting algorithm.
                    194:
                    195:   -- ON ENTRY :
                    196:   --   n         length of the vectors in points;
                    197:   --   mix       type of mixture;
                    198:   --   mixsub    mixed subdivision of the lifted points;
                    199:   --   fs        face structures of the lifted points.
                    200:
                    201:   -- ON RETURN :
                    202:   --   mixsub    if empty on entry, then it contains the initial mixed
                    203:   --             cell, in case the problem is nondegenerate;
                    204:   --   rest      rest of point list to be processed;
                    205:   --   done      if true, then either the mixed volume equals zero,
                    206:   --             or there are no more points to process.
                    207:
                    208:     null_points : Array_of_Lists(points'range);
                    209:
                    210:   begin
                    211:     if Is_Null(mixsub)
                    212:      then -- compute an initial mixed cell
                    213:        declare
                    214:          mic : Mixed_Cell;
                    215:        begin
                    216:          Initial_Mixed_Cell(n,mix,points,mic,rest);
                    217:          if Mixed_Volume(n,mix,mic) > 0 -- check on degeneracy
                    218:           then
                    219:            -- initialize the mixed subdivision :
                    220:             Construct(mic,mixsub);
                    221:            -- initialize the face structures :
                    222:             for i in mic.pts'range loop
                    223:               declare
                    224:                 tmp : List := mic.pts(i);
                    225:                 fc : Face;
                    226:               begin
                    227:                 while not Is_Null(tmp) loop
                    228:                   Append(fs(i).l,fs(i).last,Head_Of(tmp).all);
                    229:                   tmp := Tail_of(tmp);
                    230:                 end loop;
                    231:                 fc := new VecVec'(Shallow_Create(mic.pts(i)));
                    232:                 Construct(fc,fs(i).f);
                    233:               end;
                    234:             end loop;
                    235:             if mix'last = mix'first
                    236:              then declare
                    237:                     v : constant VecVec := Shallow_Create(fs(fs'first).l);
                    238:                     s : Simplex := Create(v);
                    239:                   begin
                    240:                     fs(fs'first).t := Create(s);
                    241:                   end;
                    242:             end if;
                    243:             done := Is_Empty(rest);
                    244:           else -- degenerate problem => mixed volume = 0
                    245:             rest := null_points; done := true;
                    246:          end if;
                    247:        end;
                    248:      else
                    249:        rest := points;
                    250:        done := Is_Empty(rest);
                    251:     end if;
                    252:   end Initialize;
                    253:
                    254:   function Initial_Triangulation
                    255:                 ( n : in natural; l : in List; point : in Link_to_Vector )
                    256:                 return Triangulation is
                    257:
                    258:   -- DESCRIPTION :
                    259:   --   Given a list of lifted points with Length_Of(l) >= n and another
                    260:   --   lifted point, a nonempty triangulation will be returned, when the
                    261:   --   volume of \conv(l U {point}) > 0.
                    262:
                    263:     res : Triangulation;
                    264:     del,span : List;
                    265:     delpoint : Link_to_Vector := new vector(1..n);
                    266:
                    267:     function Deflate ( lifted : in List ) return List is
                    268:
                    269:     -- DESCRIPTION :
                    270:     --   Discards the lifting value of the points in the list l.
                    271:
                    272:       res,res_last : List;
                    273:       tmp : List := lifted;
                    274:       pt : Link_to_Vector;
                    275:
                    276:     begin
                    277:       while not Is_Null(tmp) loop
                    278:         pt := Head_Of(tmp);
                    279:         declare
                    280:           dpt : Link_to_Vector := new vector(1..n);
                    281:         begin
                    282:           dpt.all := pt(dpt'range);
                    283:           Append(res,res_last,dpt);
                    284:         end;
                    285:         tmp := Tail_Of(tmp);
                    286:       end loop;
                    287:       return res;
                    288:     end Deflate;
                    289:
                    290:     function Lift ( pt,liftpt : Link_to_Vector; lifted : List )
                    291:                   return Link_to_Vector is
                    292:
                    293:     -- DESCRIPTION :
                    294:     --   Compares the value of pt with that of liftpt and
                    295:     --   looks up the lifting value of the point pt in the list lifted.
                    296:     --   The lifted point will be returned.
                    297:
                    298:     -- REQUIRED :
                    299:     --   Either the point pt should be equal to Deflate(liftpt)
                    300:     --   or it should belong to Deflate(lifted).
                    301:
                    302:       tmp : List := lifted;
                    303:       res : Link_to_Vector;
                    304:
                    305:     begin
                    306:       if pt.all = liftpt(pt'range)
                    307:        then return liftpt;
                    308:        else while not Is_Null(tmp) loop
                    309:               res := Head_Of(tmp);
                    310:               if pt.all = res(pt'range)
                    311:                then return res;
                    312:                else tmp := Tail_Of(tmp);
                    313:               end if;
                    314:             end loop;
                    315:             return res;
                    316:       end if;
                    317:     end Lift;
                    318:
                    319:   begin
                    320:     del := Deflate(l);
                    321:     delpoint.all := point(delpoint'range);
                    322:     Construct(delpoint,del);
                    323:     span := Extremal_Points(n,del);
                    324:     if Length_Of(span) = n+1
                    325:      then
                    326:        declare
                    327:          verpts : VecVec(1..n+1);
                    328:          tmp : List := span;
                    329:          pt : Link_to_Vector;
                    330:          s : Simplex;
                    331:        begin
                    332:          for i in verpts'range loop
                    333:            verpts(i) := Lift(Head_Of(tmp),point,l);
                    334:            tmp := Tail_Of(tmp);
                    335:          end loop;
                    336:          s := Create(verpts);
                    337:          res := Create(s);
                    338:          tmp := l;
                    339:          while not Is_Null(tmp) loop
                    340:            pt := Head_Of(tmp);
                    341:            if not Is_In(span,pt)
                    342:             then Update(res,pt);
                    343:            end if;
                    344:            tmp := Tail_Of(tmp);
                    345:          end loop;
                    346:        end;
                    347:     end if;
                    348:     Clear(del); Clear(span); Clear(delpoint);
                    349:     return res;
                    350:   end Initial_Triangulation;
                    351:
                    352: -- CHOOSE NEXT POINT :
                    353:
                    354:   procedure Next_Point
                    355:                 ( n : in natural; points : in out Array_of_Lists;
                    356:                   order : in boolean;
                    357:                   index : in out integer; point : out Link_to_Vector ) is
                    358:
                    359:   -- DESCRIPTION :
                    360:   --   Chooses a point out of the lists of points.
                    361:
                    362:   -- ON ENTRY :
                    363:   --   n          length of the elements in the point lists;
                    364:   --   points     nonempty lists of points;
                    365:   --   order      if true, then the first element out of the next first
                    366:   --              nonempty list will be chosen;
                    367:   --   index      indicates component where not Is_Null(points(index)).
                    368:
                    369:   -- ON RETURN :
                    370:   --   points     lists of points with the point removed;
                    371:   --   index      points to the next nonempty list,
                    372:   --              if index < points'first, then Is_Empty(points);
                    373:   --   point      the next point to be processed.
                    374:
                    375:     newindex : integer := points'first-1;
                    376:     pt : Link_to_Vector;
                    377:
                    378:   begin
                    379:     if order
                    380:      then pt := Head_Of(points(index));
                    381:      else pt := Max_Extreme(points(index),n,-3,3);
                    382:           Swap_to_Front(points(index),pt);
                    383:     end if;
                    384:     points(index) := Tail_Of(points(index));
                    385:     for i in (index+1)..points'last loop
                    386:       if not Is_Null(points(i))
                    387:        then newindex := i;
                    388:       end if;
                    389:       exit when newindex >= points'first;
                    390:     end loop;
                    391:     if newindex < points'first
                    392:      then for i in points'first..index loop
                    393:             if not Is_Null(points(i))
                    394:              then newindex := i;
                    395:             end if;
                    396:             exit when newindex >= points'first;
                    397:           end loop;
                    398:     end if;
                    399:     index := newindex;
                    400:     point := pt;
                    401:   end Next_Point;
                    402:
                    403: -- UPDATE ROUTINES :
                    404:
                    405:   procedure Merge ( mic : in out Mixed_Cell;
                    406:                     mixsub : in out Mixed_Subdivision ) is
                    407:
                    408:     tmp : Mixed_Subdivision := mixsub;
                    409:     done : boolean := false;
                    410:
                    411:   begin
                    412:     while not Is_Null(tmp) loop
                    413:       declare
                    414:         mic1 : Mixed_Cell := Head_Of(tmp);
                    415:         last : List;
                    416:       begin
                    417:         if Equal(mic.nor,mic1.nor)
                    418:          then for k in mic1.pts'range loop
                    419:                 last := mic1.pts(k);
                    420:                 while not Is_Null(Tail_Of(last)) loop
                    421:                   last := Tail_Of(last);
                    422:                 end loop;
                    423:                 Deep_Concat_Diff(mic.pts(k),mic1.pts(k),last);
                    424:               end loop;
                    425:               done := true;
                    426:          else tmp := Tail_Of(tmp);
                    427:         end if;
                    428:       end;
                    429:       exit when done;
                    430:     end loop;
                    431:     if done
                    432:      then Deep_Clear(mic);
                    433:      else Construct(mic,mixsub);
                    434:     end if;
                    435:   end Merge;
                    436:
                    437:   procedure Merge ( cells : in Mixed_Subdivision;
                    438:                     mixsub : in out Mixed_Subdivision ) is
                    439:
                    440:     tmp : Mixed_Subdivision := cells;
                    441:
                    442:   begin
                    443:     while not Is_Null(tmp) loop
                    444:       declare
                    445:         mic : Mixed_Cell := Head_Of(tmp);
                    446:       begin
                    447:         Merge(mic,mixsub);
                    448:       end;
                    449:       tmp := Tail_Of(tmp);
                    450:     end loop;
                    451:   end Merge;
                    452:
                    453:   procedure Compute_New_Faces
                    454:                  ( fs : in out Face_Structure; k,n : in natural;
                    455:                    point : in out Link_to_Vector; newfs : out Faces ) is
                    456:
                    457:   -- DESCRIPTION :
                    458:   --   Given a point, the new faces will be computed and returned.
                    459:
                    460:   -- ON ENTRY :
                    461:   --   fs          a face structure;
                    462:   --   k           dimension of the faces to generate;
                    463:   --   n           dimension without the lifting;
                    464:   --   point       point that has to be in all the faces.
                    465:
                    466:   -- ON RETURN :
                    467:   --   fs          face structure with updated triangulation,
                    468:   --               the new faces are not added, also the list is not updated;
                    469:   --   point       lifted conservatively w.r.t. fs.t;
                    470:   --   newfs       k-faces, which all contain the given point.
                    471:
                    472:     res,res_last : Faces;
                    473:
                    474:     procedure Append ( fc : in VecVec ) is
                    475:
                    476:       f : Face;
                    477:
                    478:     begin
                    479:       f := new VecVec'(fc);
                    480:       Append(res,res_last,f);
                    481:     end Append;
                    482:     procedure EnumLis is new Enumerate_Lower_Faces_in_List(Append);
                    483:     procedure EnumTri is new Enumerate_Faces_in_Triangulation(Append);
                    484:
                    485:   begin
                    486:    -- COMPUTE THE NEW FACES AND UPDATE fs :
                    487:     if Is_Null(fs.t)
                    488:      then
                    489:        if Length_Of(fs.l) >= n
                    490:         then
                    491:           fs.t := Initial_Triangulation(n,fs.l,point);
                    492:           if Is_Null(fs.t)
                    493:            then EnumLis(fs.l,point,k);
                    494:            else EnumTri(fs.t,point,k);
                    495:           end if;
                    496:         else
                    497:           EnumLis(fs.l,point,k);
                    498:        end if;
                    499:      else
                    500:        declare
                    501:          newt : Triangulation;
                    502:        begin
                    503:          point(point'last) := Lift_to_Place(fs.t,point.all);
                    504:          Update(fs.t,point,newt);
                    505:          Enumtri(newt,point,k);
                    506:        end;
                    507:     end if;
                    508:     Append(fs.l,fs.last,point);
                    509:     newfs := res;
                    510:   end Compute_New_Faces;
                    511:
                    512:   procedure Swap ( index : in natural; points : in out Array_of_Lists ) is
                    513:
                    514:   -- DESCRIPTION :
                    515:   --   Swaps the first component of points with the component index.
                    516:
                    517:     tmp : List := points(index);
                    518:
                    519:   begin
                    520:     points(index) := points(points'first);
                    521:     points(points'first) := tmp;
                    522:   end Swap;
                    523:
                    524:   procedure Swap ( index : in natural; mixsub : in out Mixed_Subdivision ) is
                    525:
                    526:   -- DESCRIPTION :
                    527:   --   Swaps the first component of each cell with the component index.
                    528:
                    529:     tmp : Mixed_Subdivision := mixsub;
                    530:
                    531:   begin
                    532:     while not Is_Null(tmp) loop
                    533:       declare
                    534:         mic : Mixed_Cell := Head_Of(tmp);
                    535:       begin
                    536:         Swap(index,mic.pts.all);
                    537:        -- Set_Head(tmp,mic);
                    538:       end;
                    539:       tmp := Tail_Of(tmp);
                    540:     end loop;
                    541:   end Swap;
                    542:
                    543:   procedure Create_Cells
                    544:                 ( index,n : in natural; mix : in Vector;
                    545:                   afs : in Array_of_Faces; lif : in Array_of_Lists;
                    546:                   nbsucc,nbfail : in out Standard_Floating_Vectors.Vector;
                    547:                   mixsub : out Mixed_Subdivision ) is
                    548:
                    549:   -- DESCRIPTION :
                    550:   --   Creates a mixed subdivision by considering the faces
                    551:   --   of component index first.
                    552:
                    553:     res : Mixed_Subdivision;
                    554:     wrkmix : Vector(mix'range) := mix;
                    555:     wrkafs : Array_of_Faces(afs'range) := afs;
                    556:     wrklif : Array_of_Lists(lif'range) := lif;
                    557:
                    558:   begin
                    559:     wrkmix(wrkmix'first) := mix(index); wrkmix(index) := mix(mix'first);
                    560:     wrkafs(wrkafs'first) := afs(index); wrkafs(index) := afs(afs'first);
                    561:     wrklif(wrklif'first) := lif(index); wrklif(index) := lif(lif'first);
                    562:     Create_CS(n,wrkmix,wrkafs,wrklif,nbsucc,nbfail,res);
                    563:     Swap(index,res);
                    564:     mixsub := res;
                    565:   end Create_Cells;
                    566:
                    567:   procedure Compute_New_Cells
                    568:                 ( n : in natural; mix : in Vector; mic : in Mixed_Cell;
                    569:                   afs : in Array_of_Faces; index : in integer;
                    570:                   lifted : in Array_of_Lists; mixsub : out Mixed_Subdivision;
                    571:                   nbsucc,nbfail : in out Standard_Floating_Vectors.Vector ) is
                    572:
                    573:   -- DESCRIPTION :
                    574:   --   Computes the new cells by considering a given mixed cell with
                    575:   --   a tuple of faces.
                    576:
                    577:   -- ON ENTRY :
                    578:   --   n          dimension before lifting;
                    579:   --   mix        type of mixture;
                    580:   --   mic        a given mixed cell;
                    581:   --   afs        type of faces;
                    582:   --   index      component where new faces are computed for;
                    583:   --   lifted     tuple of lifted points;
                    584:   --   nbsucc     number of succesful tests of face-face combinations;
                    585:   --   nbfail     number of unsuccesful tests of face-face combinations.
                    586:
                    587:   -- ON RETURN :
                    588:   --   mixsub     the new mixed cells;
                    589:   --   nbsucc     updated number of succesful tests;
                    590:   --   nbfail     updated number of unsuccesful tests;
                    591:
                    592:     res,res2 : Mixed_Subdivision;
                    593:     neiafs : Array_of_Faces(afs'range);
                    594:
                    595:   begin
                    596:     neiafs(index) := Neighboring_Faces(mic,afs(index),index);
                    597:     if not Is_Null(neiafs(index))
                    598:      then
                    599:        for i in neiafs'range loop
                    600:          if i /= index
                    601:           then neiafs(i) := Neighboring_Faces(mic,afs(i),i);
                    602:          end if;
                    603:        end loop;
                    604:        if index /= 1
                    605:         then Create_Cells(index,n,mix,neiafs,lifted,nbsucc,nbfail,res);
                    606:         else Create_CS(n,mix,neiafs,lifted,nbsucc,nbfail,res);
                    607:        end if;
                    608:        for i in neiafs'range loop
                    609:          if i /= index
                    610:           then Shallow_Clear(neiafs(i));
                    611:          end if;
                    612:        end loop;
                    613:     end if;
                    614:     Shallow_Clear(neiafs(index));
                    615:     res2 := Create(lifted,res); -- test on normals
                    616:     Shallow_Clear(res);
                    617:     mixsub := res2;
                    618:   end Compute_New_Cells;
                    619:
                    620:   procedure Compute_New_Cells
                    621:                ( n : in natural; mix : in Vector;
                    622:                  mixsub : in Mixed_Subdivision; index : in integer;
                    623:                  newfaces : in Faces; fs : in Face_Structures;
                    624:                  newcells : out Mixed_Subdivision;
                    625:                  nbsucc,nbfail : in out Standard_Floating_Vectors.Vector ) is
                    626:
                    627:     res : Mixed_Subdivision;
                    628:     afs : Array_of_Faces(fs'range);
                    629:     lifted : Array_of_Lists(fs'range);
                    630:
                    631:   begin
                    632:    -- CREATE NEW CELLS ONLY WITH THE NEW FACES :
                    633:     for i in afs'range loop
                    634:       if i = index
                    635:        then afs(index) := newfaces;
                    636:        else afs(i) := fs(i).f;
                    637:       end if;
                    638:       lifted(i) := fs(i).l;
                    639:     end loop;
                    640:     if not Is_Null(fs(index).t)
                    641:      then
                    642:       -- ENUMERATE ALL CELLS IN mixsub :
                    643:        declare
                    644:          tmp : Mixed_Subdivision := mixsub;
                    645:        begin
                    646:          while not Is_Null(tmp) loop
                    647:            declare
                    648:              newcells2 : Mixed_Subdivision;
                    649:            begin
                    650:              Compute_New_Cells(n,mix,Head_Of(tmp),afs,index,lifted,
                    651:                                newcells2,nbsucc,nbfail);
                    652:              Merge(newcells2,res); Shallow_Clear(newcells2);
                    653:            end;
                    654:            tmp := Tail_Of(tmp);
                    655:          end loop;
                    656:        end;
                    657:      else
                    658:       -- COMPUTE ALL NEW CELLS AT ONCE :
                    659:        declare
                    660:          res2 : Mixed_Subdivision;
                    661:        begin
                    662:          if index /= 1
                    663:           then Create_Cells(index,n,mix,afs,lifted,nbsucc,nbfail,res2);
                    664:           else Create_CS(n,mix,afs,lifted,nbsucc,nbfail,res2);
                    665:          end if;
                    666:          res := Create(lifted,res2);
                    667:          Shallow_Clear(res2);
                    668:        end;
                    669:     end if;
                    670:     newcells := res;
                    671:   end Compute_New_Cells;
                    672:
                    673: -- BASIC VERSION : WITHOUT OUTPUT GENERICS :
                    674:
                    675:   procedure Dynamic_Lifting
                    676:                 ( n : in natural; mix : in Vector;
                    677:                   points : in Array_of_Lists;
                    678:                   order,inter,conmv : in boolean; maxli : in natural;
                    679:                   mixsub : in out Mixed_Subdivision;
                    680:                   fs : in out Face_Structures;
                    681:                   nbsucc,nbfail : in out Standard_Floating_Vectors.Vector ) is
                    682:
                    683:     rest,inner : Array_of_Lists(points'range);
                    684:     index,newindex : integer;
                    685:     finished : boolean := false;
                    686:     pt : Link_to_Vector;
                    687:     nexli : natural := 1;
                    688:
                    689:   begin
                    690:     Initialize(n,mix,points,mixsub,fs,rest,finished);
                    691:     if not finished
                    692:      then
                    693:        index := First_Non_Empty(rest); newindex := index;
                    694:        while not finished loop  -- ITERATE UNTIL NO MORE POINTS :
                    695:          Next_Point(n,rest,order,newindex,pt);
                    696:          declare
                    697:            point : Link_to_Vector := new vector(pt'first..pt'last+1);
                    698:            newfa : Faces;
                    699:            newcells : Mixed_Subdivision;
                    700:          begin -- LIFT THE POINT CONSERVATIVELY :
                    701:            point(pt'range) := pt.all;
                    702:            point(point'last) := 1;
                    703:            if inter and then Is_In(fs(index),point.all)
                    704:             then
                    705:               Clear(point); Construct(pt,inner(index));
                    706:             else
                    707:               nexli := Conservative_Lifting(mixsub,index,point.all);
                    708:               if (maxli > 0) and then nexli > maxli
                    709:                then Flatten(mixsub); Flatten(fs);
                    710:                     nexli := 1;
                    711:               end if;
                    712:               point(point'last) := nexli;
                    713:              -- COMPUTE NEW FACES AND NEW CELLS :
                    714:               Compute_New_Faces(fs(index),mix(index),n,point,newfa);
                    715:               if not conmv or else not Zero_Contribution(n,fs,point.all,index)
                    716:                then Compute_New_Cells(n,mix,mixsub,index,newfa,fs,
                    717:                                       newcells,nbsucc,nbfail);
                    718:              -- UPDATE THE MIXED SUBDIVISION AND THE FACE STRUCTURES :
                    719:                     Construct(newcells,mixsub);   Shallow_Clear(newcells);
                    720:               end if;
                    721:               Construct(fs(index).f,newfa); Shallow_Clear(newfa);
                    722:            end if;
                    723:          end;
                    724:          index := newindex;
                    725:          finished := (index < rest'first);
                    726:        end loop;
                    727:     end if;
                    728:     if inter  -- lift out the interior points
                    729:      then for i in inner'range loop
                    730:             Constant_Lifting(inner(i),nexli,fs(i).l,fs(i).last);
                    731:             Shallow_Clear(inner(i));
                    732:           end loop;
                    733:     end if;
                    734:   exception
                    735:     when numeric_error    -- probably due to a too high lifting
                    736:        => Flatten(mixsub); Flatten(fs);
                    737:           Dynamic_Lifting(n,mix,rest,order,inter,conmv,maxli,mixsub,fs,
                    738:                           nbsucc,nbfail);
                    739:   end Dynamic_Lifting;
                    740:
                    741: -- EXTENDED VERSIONS : WITH OUTPUT GENERICS :
                    742:
                    743:   procedure Dynamic_Lifting_with_Flat
                    744:                 ( n : in natural; mix : in Vector; points : in Array_of_Lists;
                    745:                   order,inter,conmv : in boolean; maxli : in natural;
                    746:                   mixsub : in out Mixed_Subdivision;
                    747:                   fs : in out Face_Structures;
                    748:                   nbsucc,nbfail : in out Standard_Floating_Vectors.Vector ) is
                    749:
                    750:     rest,inner : Array_of_Lists(points'range);
                    751:     index,newindex : integer;
                    752:     finished : boolean := false;
                    753:     pt : Link_to_Vector;
                    754:     nexli : natural := 1;
                    755:
                    756:   begin
                    757:     Initialize(n,mix,points,mixsub,fs,rest,finished);
                    758:     if not finished
                    759:      then
                    760:        index := First_Non_Empty(rest); newindex := index;
                    761:        while not finished loop -- ITERATE UNTIL NO MORE POINTS :
                    762:          Next_Point(n,rest,order,newindex,pt);
                    763:          declare
                    764:            point : Link_to_Vector := new vector(pt'first..pt'last+1);
                    765:            newfa : Faces;
                    766:            newcells : Mixed_Subdivision;
                    767:          begin -- LIFT THE POINT CONSERVATIVELY :
                    768:            point(pt'range) := pt.all;
                    769:            point(point'last) := 1;
                    770:            if inter and then Is_In(fs(index),point.all)
                    771:             then
                    772:               Clear(point); Construct(pt,inner(index));
                    773:             else
                    774:               nexli := Conservative_Lifting(mixsub,index,point.all);
                    775:               if (maxli > 0) and then nexli > maxli
                    776:                then Before_Flattening(mixsub,fs);
                    777:                     Flatten(mixsub); Flatten(fs);
                    778:                     nexli := 1;
                    779:               end if;
                    780:               point(point'last) := nexli;
                    781:              -- COMPUTE NEW FACES AND NEW CELLS :
                    782:               Compute_New_Faces(fs(index),mix(index),n,point,newfa);
                    783:               if not conmv or else not Zero_Contribution(n,fs,point.all,index)
                    784:                then Compute_New_Cells(n,mix,mixsub,index,newfa,fs,
                    785:                                       newcells,nbsucc,nbfail);
                    786:              -- UPDATE THE MIXED SUBDIVISION AND THE FACE STRUCTURES :
                    787:                     Construct(newcells,mixsub);   Shallow_Clear(newcells);
                    788:               end if;
                    789:               Construct(fs(index).f,newfa); Shallow_Clear(newfa);
                    790:            end if;
                    791:          end;
                    792:          index := newindex;
                    793:          finished := (index < rest'first);
                    794:        end loop;
                    795:     end if;
                    796:     if inter  -- lift out the interior points
                    797:      then for i in inner'range loop
                    798:             Constant_Lifting(inner(i),nexli,fs(i).l,fs(i).last);
                    799:             Shallow_Clear(inner(i));
                    800:           end loop;
                    801:     end if;
                    802:   exception
                    803:     when numeric_error    -- probably due to a too high lifting
                    804:        => Before_Flattening(mixsub,fs);
                    805:           Flatten(mixsub); Flatten(fs);
                    806:           Dynamic_Lifting_with_Flat(n,mix,rest,order,inter,conmv,maxli,mixsub,
                    807:                                     fs,nbsucc,nbfail);
                    808:   end Dynamic_Lifting_with_Flat;
                    809:
                    810:   procedure Dynamic_Lifting_with_New
                    811:                 ( n : in natural; mix : in Vector; points : in Array_of_Lists;
                    812:                   order,inter,conmv : in boolean; maxli : in natural;
                    813:                   mixsub : in out Mixed_Subdivision;
                    814:                   fs : in out Face_Structures;
                    815:                   nbsucc,nbfail : in out Standard_Floating_Vectors.Vector ) is
                    816:
                    817:     rest,inner : Array_of_Lists(points'range);
                    818:     index,newindex : integer;
                    819:     finished : boolean := false;
                    820:     pt : Link_to_Vector;
                    821:     nexli : natural := 1;
                    822:
                    823:   begin
                    824:     Initialize(n,mix,points,mixsub,fs,rest,finished);
                    825:     Process_New_Cells(mixsub,0,Head_Of(fs(fs'last).last).all);
                    826:     if not finished
                    827:      then
                    828:        index := First_Non_Empty(rest); newindex := index;
                    829:        while not finished loop -- ITERATE UNTIL NO MORE POINTS :
                    830:          Next_Point(n,rest,order,newindex,pt);
                    831:          declare
                    832:            point : Link_to_Vector := new vector(pt'first..pt'last+1);
                    833:            newfa : Faces;
                    834:            newcells : Mixed_Subdivision;
                    835:          begin -- LIFT THE POINT CONSERVATIVELY :
                    836:            point(pt'range) := pt.all;
                    837:            point(point'last) := 1;
                    838:            if inter and then Is_In(fs(index),point.all)
                    839:             then
                    840:               Clear(point); Construct(pt,inner(index));
                    841:             else
                    842:               nexli := Conservative_Lifting(mixsub,index,point.all);
                    843:               if (maxli > 0) and then nexli > maxli
                    844:                then Flatten(mixsub); Flatten(fs);
                    845:                     nexli := 1;
                    846:               end if;
                    847:               point(point'last) := nexli;
                    848:              -- COMPUTE NEW FACES AND NEW CELLS :
                    849:               Compute_New_Faces(fs(index),mix(index),n,point,newfa);
                    850:               if not conmv or else not Zero_Contribution(n,fs,point.all,index)
                    851:                then Compute_New_Cells(n,mix,mixsub,index,newfa,fs,newcells,
                    852:                                       nbsucc,nbfail);
                    853:                     Process_New_Cells(newcells,index,point.all);
                    854:              -- UPDATE THE MIXED SUBDIVISION AND THE FACE STRUCTURES :
                    855:                     Construct(newcells,mixsub);   Shallow_Clear(newcells);
                    856:               end if;
                    857:               Construct(fs(index).f,newfa); Shallow_Clear(newfa);
                    858:            end if;
                    859:          end;
                    860:          index := newindex;
                    861:          finished := (index < rest'first);
                    862:        end loop;
                    863:     end if;
                    864:     if inter  -- lift out the interior points
                    865:      then for i in inner'range loop
                    866:             Constant_Lifting(inner(i),nexli,fs(i).l,fs(i).last);
                    867:             Shallow_Clear(inner(i));
                    868:           end loop;
                    869:     end if;
                    870:   exception
                    871:     when numeric_error    -- probably due to a too high lifting
                    872:        => Flatten(mixsub); Flatten(fs);
                    873:           Dynamic_Lifting_with_New(n,mix,rest,order,inter,conmv,maxli,mixsub,fs,
                    874:                                    nbsucc,nbfail);
                    875:   end Dynamic_Lifting_with_New;
                    876:
                    877:   procedure Dynamic_Lifting_with_Flat_and_New
                    878:                 ( n : in natural; mix : in Vector; points : in Array_of_Lists;
                    879:                   order,inter,conmv : in boolean; maxli : in natural;
                    880:                   mixsub : in out Mixed_Subdivision;
                    881:                   fs : in out Face_Structures;
                    882:                   nbsucc,nbfail : in out Standard_Floating_Vectors.Vector ) is
                    883:
                    884:     rest,inner : Array_of_Lists(points'range);
                    885:     index,newindex : integer;
                    886:     finished : boolean := false;
                    887:     pt : Link_to_Vector;
                    888:     nexli : natural := 1;
                    889:
                    890:   begin
                    891:     Initialize(n,mix,points,mixsub,fs,rest,finished);
                    892:     Process_New_Cells(mixsub,0,Head_Of(fs(fs'last).last).all);
                    893:     if not finished
                    894:      then
                    895:        index := First_Non_Empty(rest); newindex := index;
                    896:        while not finished loop -- ITERATE UNTIL NO MORE POINTS
                    897:          Next_Point(n,rest,order,newindex,pt);
                    898:          declare
                    899:            point : Link_to_Vector := new vector(pt'first..pt'last+1);
                    900:            newfa : Faces;
                    901:            newcells : Mixed_Subdivision;
                    902:          begin -- LIFT THE POINT CONSERVATIVELY :
                    903:            point(pt'range) := pt.all;
                    904:            point(point'last) := 1;
                    905:            if inter and then Is_In(fs(index),point.all)
                    906:             then
                    907:               Clear(point); Construct(pt,inner(index));
                    908:             else
                    909:               nexli := Conservative_Lifting(mixsub,index,point.all);
                    910:               if (maxli > 0) and then nexli > maxli
                    911:                then Before_Flattening(mixsub,fs);
                    912:                     Flatten(mixsub); Flatten(fs);
                    913:                     nexli := 1;
                    914:               end if;
                    915:               point(point'last) := nexli;
                    916:              -- COMPUTE NEW FACES AND NEW CELLS :
                    917:               Compute_New_Faces(fs(index),mix(index),n,point,newfa);
                    918:               if not conmv or else not Zero_Contribution(n,fs,point.all,index)
                    919:                then Compute_New_Cells(n,mix,mixsub,index,newfa,fs,newcells,
                    920:                                       nbsucc,nbfail);
                    921:                     Process_New_Cells(newcells,index,point.all);
                    922:              -- UPDATE THE MIXED SUBDIVISION AND THE FACE STRUCTURES :
                    923:                     Construct(newcells,mixsub);   Shallow_Clear(newcells);
                    924:               end if;
                    925:               Construct(fs(index).f,newfa); Shallow_Clear(newfa);
                    926:            end if;
                    927:          end;
                    928:          index := newindex;
                    929:          finished := (index < rest'first);
                    930:        end loop;
                    931:     end if;
                    932:     if inter  -- lift out the interior points
                    933:      then for i in inner'range loop
                    934:             Constant_Lifting(inner(i),nexli,fs(i).l,fs(i).last);
                    935:             Shallow_Clear(inner(i));
                    936:           end loop;
                    937:     end if;
                    938:   exception
                    939:     when numeric_error    -- probably due to a too high lifting
                    940:        => Before_Flattening(mixsub,fs);
                    941:           Flatten(mixsub); Flatten(fs);
                    942:           Dynamic_Lifting_with_Flat_and_New
                    943:               (n,mix,rest,order,inter,conmv,maxli,mixsub,fs,nbsucc,nbfail);
                    944:   end Dynamic_Lifting_with_Flat_and_New;
                    945:
                    946: end Dynamic_Mixed_Subdivisions;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>