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

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

1.1       maekawa     1: with Lists_of_Integer_Vectors;           use Lists_of_Integer_Vectors;
                      2: with Standard_Random_Numbers;            use Standard_Random_Numbers;
                      3:
                      4: --with text_io,Simplices_io;              use text_io,Simplices_io;
                      5: --with Integer_Vectors_io;                use Integer_Vectors_io;
                      6: --with integer_io;                        use integer_io;
                      7:
                      8: package body Triangulations is
                      9:
                     10: -- AUXILIAIRY HASH TABLE FOR Update_One :
                     11:
                     12:   type Matrix_of_Triangulations
                     13:           is array ( integer range <>, integer range <> ) of Triangulation;
                     14:
                     15:   type Hash_Table ( n : natural ) is
                     16:          record
                     17:            weight1,weight2 : Link_to_Vector;
                     18:            data : Matrix_of_Triangulations(0..n,0..n);
                     19:          end record;
                     20:
                     21:   procedure Init ( ht : in out Hash_Table; first,last : in integer ) is
                     22:
                     23:    -- Initializes the hash table with Null_Triangulation.
                     24:    -- Determines the weights for the hash function.
                     25:    -- The numbers first and last determine the length of the weight function.
                     26:
                     27:   begin
                     28:     ht.weight1 := new Vector(first..last);
                     29:     ht.weight2 := new Vector(first..last);
                     30:     for i in first..last loop
                     31:       ht.weight1(i) := Random(-last,last);
                     32:       ht.weight2(i) := Random(-last,last);
                     33:     end loop;
                     34:     ht.weight1(last) := 1;  -- TO AVOID PROBLEMS WITH HIGH LIFTING
                     35:     ht.weight2(last) := 1;
                     36:     for i in ht.data'range(1) loop
                     37:       for j in ht.data'range(2) loop
                     38:         ht.data(i,j) := Null_Triangulation;
                     39:       end loop;
                     40:     end loop;
                     41:   end Init;
                     42:
                     43:   procedure Hash_Function ( ht : in Hash_Table; s : in Simplex;
                     44:                             i,j : out integer ) is
                     45:
                     46:    -- DESCRIPTION :
                     47:    --   Computes the entries in the hash table for the simplex s.
                     48:
                     49:     r1 : constant integer := ht.weight1.all*Vertex(s,1);
                     50:     r2 : constant integer := ht.weight2.all*Vertex(s,2);
                     51:
                     52:   begin
                     53:     i := r1 mod (ht.n + 1);
                     54:     j := r2 mod (ht.n + 1);
                     55:   end Hash_Function;
                     56:
                     57:   procedure Update ( ht : in out Hash_Table; s : in Simplex ) is
                     58:
                     59:    -- DESCRIPTION :
                     60:    --   Updates the hash table with the given simplex s.
                     61:
                     62:     i,j : integer;
                     63:
                     64:   begin
                     65:     Hash_Function(ht,s,i,j);
                     66:     Construct(s,ht.data(i,j));
                     67:   end Update;
                     68:
                     69:   function Is_In ( ht : Hash_Table; s : Simplex ) return boolean is
                     70:
                     71:    -- DESCRIPTION :
                     72:    --   Checks whether the simplex belongs to the hash table.
                     73:
                     74:     i,j : integer;
                     75:
                     76:   begin
                     77:     Hash_Function(ht,s,i,j);
                     78:     return Is_In(ht.data(i,j),s);
                     79:   end Is_In;
                     80:
                     81: --  procedure Write_Distribution ( ht : in Hash_Table ) is
                     82: --
                     83: --   -- DESCRIPTION :
                     84: --   --   Writes the lengths of the lists in ht.
                     85: --
                     86: --  begin
                     87: --    for i in ht.data'range(1) loop
                     88: --      for j in ht.data'range(2) loop
                     89: --        put(Length_Of(ht.data(i,j)),1);  put(' ');
                     90: --      end loop;
                     91: --      new_line;
                     92: --    end loop;
                     93: --  end Write_Distribution;
                     94:
                     95:   procedure Clear ( ht : in out Hash_Table ) is
                     96:
                     97:    -- DESCRIPTION :
                     98:    --   Clears the allocated memory space for the hash table,
                     99:    --   only a shallow copy is performed.
                    100:
                    101:   begin
                    102:     Clear(ht.weight1);
                    103:     Clear(ht.weight2);
                    104:     for i in ht.data'range(1) loop
                    105:       for j in ht.data'range(2) loop
                    106:         Lists_of_Simplices.Clear(Lists_of_Simplices.List(ht.data(i,j)));
                    107:       end loop;
                    108:     end loop;
                    109:   end Clear;
                    110:
                    111: -- CREATORS :
                    112:
                    113:   function Create ( s : Simplex ) return Triangulation is
                    114:
                    115:     res : Triangulation;
                    116:
                    117:   begin
                    118:     Construct(s,res);
                    119:     return res;
                    120:   end Create;
                    121:
                    122:   function Is_Inner ( n : natural; s : Simplex ) return boolean is
                    123:   begin
                    124:     for k in 1..n loop
                    125:       if Neighbor(s,k) = Null_Simplex
                    126:        then return false;
                    127:       end if;
                    128:     end loop;
                    129:     return true;
                    130:   end Is_Inner;
                    131:
                    132:   procedure Update ( t : in out Triangulation; s : in out Simplex;
                    133:                      x : in Link_to_Vector ) is
                    134:
                    135:     pos : vector(0..x'last) := Position(s,x.all);
                    136:
                    137:   begin
                    138:     for k in x'range loop
                    139:       if Neighbor(s,k) = Null_Simplex
                    140:        then if pos(k-1)*pos(pos'last) > 0
                    141:              then Update(s,x,k);
                    142:                   Construct(Neighbor(s,k),t);
                    143:             end if;
                    144:       end if;
                    145:     end loop;
                    146:   end Update;
                    147:
                    148:   procedure Connect_and_Update
                    149:                    ( s : in out Simplex; t : in out Triangulation ) is
                    150:
                    151:    -- DESCRIPTION :
                    152:    --   Connects the simplex with each other simplex in the triangulation
                    153:    --   and adds it to the list t.
                    154:
                    155:     tmp : Triangulation := t;
                    156:
                    157:   begin
                    158:     while not Is_Null(tmp) loop
                    159:       declare
                    160:         s2 : Simplex := Head_Of(tmp);
                    161:       begin
                    162:         Connect(s,s2);
                    163:         --Set_Head(tmp,s2);
                    164:       end;
                    165:       tmp := Tail_Of(tmp);
                    166:     end loop;
                    167:     Construct(s,t);
                    168:   end Connect_and_Update;
                    169:
                    170:   procedure Connect_and_Update
                    171:                    ( t1 : in Triangulation; t2 : in out Triangulation ) is
                    172:
                    173:    -- DESCRIPTION :
                    174:    --   Connects all simplices in t1 properly with each other
                    175:    --   and adds them to the list t2.
                    176:
                    177:     tmp1 : Triangulation := t1;
                    178:     tmp2 : Triangulation;
                    179:     s1,s2 : Simplex;
                    180:
                    181:   begin
                    182:     while not Is_Null(tmp1) loop
                    183:       s1 := Head_Of(tmp1);
                    184:       tmp2 := Tail_Of(tmp1);
                    185:       while not Is_Null(tmp2) loop
                    186:         s2 := Head_Of(tmp2);
                    187:         Connect(s1,s2);
                    188:         tmp2 := Tail_Of(tmp2);
                    189:       end loop;
                    190:       tmp1 := Tail_Of(tmp1);
                    191:       Construct(s1,t2);
                    192:     end loop;
                    193:   end Connect_and_Update;
                    194:
                    195:   procedure Update ( t : in out Triangulation; x : in Link_to_Vector;
                    196:                      newt : out Triangulation ) is
                    197:
                    198:     tmp : Triangulation := t;
                    199:     s : Simplex;
                    200:     nwt : Triangulation; -- for the new simplices that will contain x
                    201:
                    202:   begin
                    203:     while not Is_Null(tmp) loop
                    204:       s := Head_Of(tmp);
                    205:       if not Is_Inner(x'last,s)
                    206:        then Update(nwt,s,x);
                    207:       end if;
                    208:       tmp := Tail_Of(tmp);
                    209:     end loop;
                    210:     Connect_and_Update(nwt,t);
                    211:     newt := nwt;
                    212:   end Update;
                    213:
                    214:   procedure Update ( t : in out Triangulation; x : in Link_to_Vector ) is
                    215:
                    216:     nwt : Triangulation; -- for the new simplices that will contain x
                    217:
                    218:   begin
                    219:     Update(t,x,nwt);
                    220:    -- SHALLOW CLEAR :
                    221:     Lists_of_Simplices.Clear(Lists_of_Simplices.List(nwt));
                    222:   end Update;
                    223:
                    224:   procedure Collect_Vertices
                    225:                 ( s : in Simplex; l : in out List ) is
                    226:
                    227:    -- DESCRIPTION :
                    228:    --   Collects the vertices in s and puts them in the list l.
                    229:    --   Auxiliary routine for Update_One.
                    230:
                    231:     pts : constant VecVec := Vertices(s);
                    232:
                    233:   begin
                    234:     for k in pts'range loop
                    235:       if not Is_In(l,pts(k).all)
                    236:        then declare
                    237:               newpt : Link_to_Vector := new Vector'(pts(k).all);
                    238:             begin
                    239:               Construct(newpt,l);
                    240:             end;
                    241:       end if;
                    242:     end loop;
                    243:   end Collect_Vertices;
                    244:
                    245:   function Has_Vertices_in_List ( s : Simplex; l : List ) return boolean is
                    246:
                    247:    -- DESCRIPTION :
                    248:    --   Returns true if the simplex s has vertices in the list l.
                    249:
                    250:    pts : constant VecVec := Vertices(s);
                    251:
                    252:   begin
                    253:     for k in pts'range loop
                    254:       if Is_In(l,pts(k).all)
                    255:        then return true;
                    256:       end if;
                    257:     end loop;
                    258:     return false;
                    259:   end Has_Vertices_in_List;
                    260:
                    261:   procedure Update_One
                    262:               ( t : in out Triangulation; x : in Link_to_Vector ) is
                    263:
                    264:     s : Simplex := Head_Of(t);
                    265:     news,nei : Simplex;
                    266:     nwt,leaves : Triangulation;
                    267:     root : Hash_Table(2*x'last-1);
                    268:     pos : Vector(0..x'last);
                    269:     border_vertices : List;
                    270:
                    271:     procedure Process_Tree_of_Updates is
                    272:
                    273:      -- DESCRIPTION :
                    274:      --   Constructs a tree of adjencencies which consists of
                    275:      --   connected simplices on the edge of the triangulation.
                    276:
                    277:       tmp,newleaves : Triangulation;
                    278:       si,neisi : Simplex;
                    279:
                    280:     begin
                    281:      -- INITIALIZATION :
                    282:       --Construct(s,root);
                    283:       Init(root,x'first,x'last);
                    284:       Update(root,s);
                    285:       for k in x'range loop
                    286:         declare
                    287:           nei : Simplex := Neighbor(s,k);
                    288:         begin
                    289:           if (nei /= Null_Simplex) and then not Is_Vertex(nei,x.all)
                    290:            then Construct(nei,leaves);
                    291:           end if;
                    292:         end;
                    293:       end loop;
                    294:      -- PERFORM THE UPDATES :
                    295:       loop
                    296:        -- INVARIANT CONDITION :
                    297:        --   the simplices considered have vertices on the border close to x
                    298:         newleaves := Null_Triangulation;
                    299:         tmp := leaves;
                    300:         while not Is_Null(tmp) loop
                    301:           si := Head_Of(tmp);
                    302:          -- UPDATE root TO PREVENT TURNING BACK :
                    303:           Update(root,si);
                    304:          -- COMPUTE NEW SIMPLICES AND LEAVES :
                    305:           if not Is_Inner(x'last,si)
                    306:            then pos := Position(si,x.all);
                    307:                 for k in x'range loop
                    308:                  -- LOOK IN THE DIRECTION TOWARDS x :
                    309:                   if pos(k-1)*pos(pos'last) > 0
                    310:                    then neisi := Neighbor(si,k);
                    311:                         if neisi = Null_Simplex
                    312:                          then Update(si,x,k);         -- NEW SIMPLEX
                    313:                               neisi := Neighbor(si,k);
                    314:                               Construct(neisi,nwt);
                    315:                               Collect_Vertices(neisi,border_vertices);
                    316:                         end if;
                    317:                   end if;
                    318:                 end loop;
                    319:           end if;
                    320:           for l in x'range loop   -- GO FURTHER
                    321:             neisi := Neighbor(si,l);
                    322:             if (neisi /= Null_Simplex)
                    323:               and then not Is_Vertex(neisi,x.all)
                    324:               and then Has_Vertices_in_List(neisi,border_vertices)
                    325:               and then not Is_In(leaves,neisi)
                    326:               and then not Is_In(newleaves,neisi)
                    327:               and then not Is_In(root,neisi)
                    328:              then Construct(neisi,newleaves);
                    329:             end if;
                    330:           end loop;
                    331:           tmp := Tail_Of(tmp);
                    332:         end loop;
                    333:         exit when (newleaves = Null_Triangulation);
                    334:         Lists_of_Simplices.Clear(Lists_of_Simplices.List(leaves));
                    335:         leaves := newleaves;
                    336:       end loop;
                    337:      -- SHALLOW CLEAR :
                    338:      -- Lists_of_Simplices.Clear(Lists_of_Simplices.List(root));
                    339:      -- put_line("Distribution of root : "); Write_Distribution(root);
                    340:       Clear(root);
                    341:       Lists_of_Simplices.Clear(Lists_of_Simplices.List(leaves));
                    342:     end Process_Tree_of_Updates;
                    343:
                    344:   begin
                    345:     nei := s;                 -- USED TO SEE WHETHER s WILL CHANGE
                    346:     pos := Position(s,x.all);
                    347:     Update_One(s,x,pos,news);
                    348:     Construct(news,nwt);
                    349:     Collect_Vertices(news,border_vertices);
                    350:     if s /= nei
                    351:      then pos := Position(s,x.all);  -- BECAUSE s IS CHANGED !!!
                    352:     end if;
                    353:     for k in x'range loop      -- COMPUTE OTHER NEIGHBORS
                    354:       if pos(k-1)*pos(pos'last) > 0
                    355:        then nei := Neighbor(s,k);
                    356:             if nei = Null_Simplex
                    357:              then Update(s,x,k);
                    358:                   nei := Neighbor(s,k);
                    359:                   Construct(nei,nwt);
                    360:                   Collect_Vertices(nei,border_vertices);
                    361:             end if;
                    362:       end if;
                    363:     end loop;
                    364:     Process_Tree_of_Updates;
                    365:     Clear(border_vertices);
                    366:     Connect_and_Update(nwt,t);
                    367:     Lists_of_Simplices.Clear(Lists_of_Simplices.List(nwt));
                    368:   end Update_One;
                    369:
                    370:   procedure Connect ( t : in out Triangulation ) is
                    371:
                    372:     tmp1 : Triangulation := t;
                    373:     tmp2 : Triangulation;
                    374:     s1,s2 : Simplex;
                    375:
                    376:   begin
                    377:     while not Is_Null(tmp1) loop
                    378:       s1 := Head_Of(tmp1);
                    379:       tmp2 := Tail_Of(tmp1);
                    380:       while not Is_Null(tmp2) loop
                    381:         s2 := Head_Of(tmp2);
                    382:         Connect(s1,s2);
                    383:         --Set_Head(tmp2,s2);
                    384:         tmp2 := Tail_Of(tmp2);
                    385:       end loop;
                    386:       --Set_Head(tmp1,s1);
                    387:       tmp1 := Tail_Of(tmp1);
                    388:     end loop;
                    389:   end Connect;
                    390:
                    391: -- THE OPTIMAL DISCRETE CONSERVATIVE LIFTING FUNCTION :
                    392:
                    393: --  procedure Write_Neighbors ( s : in Simplex ) is
                    394: --  begin
                    395: --    put("The normal of simplex s : "); put(Normal(s)); new_line;
                    396: --    put_line(" with vertices : "); put(s);
                    397: --    for k in Normal(s)'range loop
                    398: --      if Neighbor(s,k) /= Null_Simplex
                    399: --       then put("normal of a not null neighbors of s :");
                    400: --            put(Normal(Neighbor(s,k))); new_line;
                    401: --      end if;
                    402: --    end loop;
                    403: --  end Write_Neighbors;
                    404:
                    405: --  procedure Write ( t : in Triangulation ) is
                    406: --
                    407: --    tmp : Triangulation := t;
                    408: --
                    409: --  begin
                    410: --    while not Is_Null(tmp) loop
                    411: --      Write_Neighbors(Head_Of(tmp));
                    412: --      tmp := Tail_Of(tmp);
                    413: --    end loop;
                    414: --  end Write;
                    415:
                    416:   procedure Flatten ( t : in out Triangulation ) is
                    417:
                    418:     tmp : Triangulation := t;
                    419:     s : Simplex;
                    420:
                    421:   -- IMPLEMENTATION REQUIREMENT :
                    422:   --   Cells that are already flattened are grouped at the end of the list.
                    423:
                    424:   begin
                    425:    -- put_line("THE TRIANGULATION BEFORE LIFTING : "); Write(t);
                    426:     while not Is_Null(tmp) loop
                    427:       s := Head_Of(tmp);
                    428:       exit when Is_Flat(s);
                    429:      -- put_line("NEIGHBORS BEFORE FLATTENING : "); Write_Neighbors(s);
                    430:       Flatten(s);
                    431:      -- put_line("NEIGHBORS AFTER FLATTENING : "); Write_Neighbors(s);
                    432:       --Set_Head(tmp,s);
                    433:       tmp := Tail_Of(tmp);
                    434:     end loop;
                    435:    -- put_line("THE TRIANGULATION AFTER LIFTING : "); Write(t);
                    436:   end Flatten;
                    437:
                    438: -- SELECTORS :
                    439:
                    440:   function Is_Vertex ( t : Triangulation; x : Vector ) return boolean is
                    441:
                    442:     tmp : Triangulation := t;
                    443:
                    444:   begin
                    445:     while not Is_Null(tmp) loop
                    446:       if Is_Vertex(Head_Of(tmp),x)
                    447:        then return true;
                    448:       end if;
                    449:       tmp := Tail_Of(tmp);
                    450:     end loop;
                    451:     return false;
                    452:   end Is_Vertex;
                    453:
                    454:   function Vertices ( t : Triangulation ) return List is
                    455:
                    456:    -- DESCRIPTION :
                    457:    --   Returns a list with all vertices in the simplices of t.
                    458:
                    459:     res,res_last : List;
                    460:     tmp : Triangulation := t;
                    461:
                    462:   begin
                    463:     res_last := res;
                    464:     while not Is_Null(tmp) loop
                    465:       declare
                    466:         s : Simplex := Head_Of(tmp);
                    467:         v : constant VecVec := Vertices(s);
                    468:       begin
                    469:         for i in v'range loop
                    470:           if not Is_In(res,v(i))
                    471:            then Append(res,res_last,v(i));
                    472:           end if;
                    473:         end loop;
                    474:       end;
                    475:       tmp := Tail_Of(tmp);
                    476:     end loop;
                    477:     return res;
                    478:   end Vertices;
                    479:
                    480:   function Vertices ( t : Triangulation; x : vector ) return List is
                    481:
                    482:     res,res_last : List;
                    483:     tmp : Triangulation := t;
                    484:
                    485:   begin
                    486:     res_last := res;
                    487:     while not Is_Null(tmp) loop
                    488:       declare
                    489:         s : Simplex := Head_Of(tmp);
                    490:       begin
                    491:         if Is_Vertex(s,x)
                    492:          then
                    493:            declare
                    494:              v : constant VecVec := Vertices(s);
                    495:            begin
                    496:              for i in v'range loop
                    497:                if not Is_In(res,v(i))
                    498:                 then Append(res,res_last,v(i));
                    499:                end if;
                    500:              end loop;
                    501:            end;
                    502:         end if;
                    503:         tmp := Tail_Of(tmp);
                    504:       end;
                    505:     end loop;
                    506:     return res;
                    507:   end Vertices;
                    508:
                    509:   function Vertices ( t : Triangulation ) return VecVec is
                    510:
                    511:     vertri : List := Vertices(t);
                    512:     res : VecVec(1..Length_Of(vertri));
                    513:     tmp : List := vertri;
                    514:
                    515:   begin
                    516:     for i in res'range loop
                    517:       res(i) := Head_Of(tmp);
                    518:       tmp := Tail_Of(tmp);
                    519:     end loop;
                    520:     Shallow_Clear(vertri);
                    521:    -- Lists_of_Link_to_Integer_Vectors.Clear
                    522:    --                    (Lists_of_Link_to_Integer_Vectors.List(vertri));
                    523:     return res;
                    524:   end Vertices;
                    525:
                    526:   function Vertices ( t : Triangulation; x : vector ) return VecVec is
                    527:
                    528:     vertri : List := Vertices(t,x);
                    529:     res : VecVec(1..Length_Of(vertri));
                    530:     tmp : List := vertri;
                    531:
                    532:   begin
                    533:     for i in res'range loop
                    534:       res(i) := Head_Of(tmp);
                    535:       tmp := Tail_Of(tmp);
                    536:     end loop;
                    537:     Shallow_Clear(vertri);
                    538:    -- Lists_of_Link_to_Integer_Vectors.Clear
                    539:    --                    (Lists_of_Link_to_Integer_Vectors.List(vertri));
                    540:     return res;
                    541:   end Vertices;
                    542:
                    543:   function Is_In1 ( t : Triangulation; x : Vector ) return boolean is
                    544:
                    545:     tmp : Triangulation := t;
                    546:
                    547:   begin
                    548:     while not Is_Null(tmp) loop
                    549:       if Is_In(Head_Of(tmp),x)
                    550:        then return true;
                    551:       end if;
                    552:       tmp := Tail_Of(tmp);
                    553:     end loop;
                    554:     return false;
                    555:   end Is_In1;
                    556:
                    557:   function Is_In ( t : Triangulation; x : Vector ) return boolean is
                    558:   begin
                    559:     return Is_In_All(Head_Of(t),x);
                    560:   end Is_In;
                    561:
                    562:   function Is_In ( t : Triangulation; x : Vector ) return Simplex is
                    563:   begin
                    564:     return Is_In_All(Head_Of(t),x);
                    565:   end Is_In;
                    566:
                    567:   function Is_In ( t : Triangulation; s : Simplex ) return boolean is
                    568:
                    569:     tmp : Triangulation := t;
                    570:
                    571:   begin
                    572:    -- put("Length of triangulation : "); put(Length_Of(t),1); new_line;
                    573:     while not Is_Null(tmp) loop
                    574:       if Equal(s,Head_Of(tmp))
                    575:        then return true;
                    576:        else tmp := Tail_Of(tmp);
                    577:       end if;
                    578:     end loop;
                    579:     return false;
                    580:   end Is_In;
                    581:
                    582:   function Volume ( t : Triangulation ) return natural is
                    583:
                    584:     tmp : Triangulation := t;
                    585:     vol : natural := 0;
                    586:
                    587:   begin
                    588:     while not Is_Null(tmp) loop
                    589:       vol := vol + Volume(Head_Of(tmp));
                    590:       tmp := Tail_Of(tmp);
                    591:     end loop;
                    592:     return vol;
                    593:   end Volume;
                    594:
                    595: -- DESTRUCTOR :
                    596:
                    597:   procedure Clear ( t : in out Triangulation ) is
                    598:
                    599:     tmp : Triangulation := t;
                    600:
                    601:   begin
                    602:     while not Is_Null(tmp) loop
                    603:       declare
                    604:         s : Simplex := Head_Of(tmp);
                    605:       begin
                    606:         Clear(s);
                    607:       end;
                    608:       tmp := Tail_Of(tmp);
                    609:     end loop;
                    610:     Lists_of_Simplices.Clear(Lists_of_Simplices.List(t));
                    611:   end Clear;
                    612:
                    613: end Triangulations;

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