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

Annotation of OpenXM_contrib/PHC/Ada/Root_Counts/Stalift/floating_pruning_methods.adb, Revision 1.1.1.1

1.1       maekawa     1: with Standard_Natural_Vectors;
                      2: with Standard_Floating_Matrices;         use Standard_Floating_Matrices;
                      3: with Standard_Floating_Linear_Solvers;   use Standard_Floating_Linear_Solvers;
                      4: with Floating_Linear_Inequalities;       use Floating_Linear_Inequalities;
                      5: with Lists_of_Floating_Vectors;          use Lists_of_Floating_Vectors;
                      6:
                      7: package body Floating_Pruning_Methods is
                      8:
                      9: -- GENERAL AUXILIARIES :
                     10:
                     11:   procedure Normalize ( v : in out Standard_Floating_Vectors.Vector ) is
                     12:
                     13:   -- DESCRIPTION : Divides every entry by v(v'last).
                     14:
                     15:   begin
                     16:     for i in v'range loop
                     17:       v(i) := v(i)/v(v'last);
                     18:     end loop;
                     19:   end Normalize;
                     20:
                     21:   function Convert ( fa : Face_Array ) return Array_of_Lists is
                     22:
                     23:   -- DESCRIPTION :
                     24:   --   Converts the array of faces into an array of lists by
                     25:   --   converting the first element of each list of faces.
                     26:
                     27:     res : Array_of_Lists(fa'range);
                     28:
                     29:   begin
                     30:     for k in fa'range loop
                     31:       res(k) := Shallow_Create(fa(k).all);
                     32:     end loop;
                     33:     return res;
                     34:   end Convert;
                     35:
                     36: -- AUXILIARIES FOR THE PRUNING ALGORITHMS :
                     37:
                     38:   procedure Initialize ( n : in natural; mat : out Matrix;
                     39:                          ipvt : out Standard_Natural_Vectors.Vector ) is
                     40:
                     41:   -- DESCRIPTION :
                     42:   --   Initializes an n*(n+1) matrix with zeroes and the pivoting vector
                     43:   --   with the entries 1..n.
                     44:
                     45:   begin
                     46:     for i in 1..n loop
                     47:       for j in 1..n+1 loop
                     48:         mat(i,j) := 0.0;
                     49:       end loop;
                     50:     end loop;
                     51:     for i in 1..n loop
                     52:       ipvt(i) := i;
                     53:     end loop;
                     54:   end Initialize;
                     55:
                     56:   function Number_of_Inequalities
                     57:               ( mix : Vector; lifted : Array_of_Lists ) return natural is
                     58:
                     59:   -- DESCRIPTION :
                     60:   --   Returns the maximal number of inequalities for pruning.
                     61:
                     62:     res : natural := 0;
                     63:
                     64:   begin
                     65:     for k in lifted'range loop
                     66:       res := res + Length_Of(lifted(k)) - mix(k) - 1;
                     67:     end loop;
                     68:     return res;
                     69:   end Number_of_Inequalities;
                     70:
                     71:   procedure Ordered_Inequalities ( k : in natural; mat : in out Matrix ) is
                     72:
                     73:   -- DESCRIPTION :
                     74:   --   Defines k inequalities mat(k,k) - mat(k+1,k) >= 0.
                     75:
                     76:   begin
                     77:     for i in mat'first(1)..k loop
                     78:       for j in mat'range(2) loop
                     79:         mat(i,j) := 0.0;
                     80:       end loop;
                     81:       mat(i,i) := 1.0; mat(i,i+1) := -1.0;
                     82:     end loop;
                     83:   end Ordered_Inequalities;
                     84:
                     85:   procedure Check_and_Update
                     86:                 ( mic : in Face_Array; lifted : in Array_of_Lists;
                     87:                   m : in Matrix; ipvt : in Standard_Natural_Vectors.Vector;
                     88:                   tol : in double_float;
                     89:                   mixsub,mixsub_last : in out Mixed_Subdivision ) is
                     90:
                     91:   -- DESCRIPTION :
                     92:   --   Computes the normal to the points in pts, by solving the
                     93:   --   linear system defined by m and ipvt.
                     94:   --   If the computed normal is an inner normal w.r.t. the lifted points,
                     95:   --   then the mixed subdivision will be updated with a new cell.
                     96:
                     97:     use Standard_Floating_Vectors;
                     98:     v : Standard_Floating_Vectors.Vector(m'range(2)) := Solve(m,tol,ipvt);
                     99:     pts : Array_of_Lists(mic'range);
                    100:
                    101:   begin
                    102:     if abs(v(v'last)) > tol
                    103:      then Normalize(v);
                    104:           if v(v'last) < 0.0
                    105:            then Min(v);
                    106:           end if;
                    107:          -- pts := Convert(mic);
                    108:          -- Update(pts,v,mixsub,mixsub_last);
                    109:           declare
                    110:             cell : Mixed_Cell;
                    111:           begin
                    112:             cell.nor := new Standard_Floating_Vectors.Vector'(v);
                    113:             cell.pts := new Array_of_Lists'(Convert(mic));
                    114:             cell.sub := null;
                    115:             Append(mixsub,mixsub_last,cell);
                    116:           end;
                    117:     end if;
                    118:   end Check_and_Update;
                    119:
                    120:   procedure Create_Equalities
                    121:                 ( n : in natural; f : in Face; mat,ineq : in Matrix;
                    122:                   tol : in double_float;
                    123:                   ipvt : in Standard_Natural_Vectors.Vector;
                    124:                   row,rowineq : in natural;
                    125:                   newmat,newineq : in out Matrix;
                    126:                   newipvt : in out Standard_Natural_Vectors.Vector;
                    127:                   newrow,newrowineq : in out natural; fail : out boolean ) is
                    128:
                    129:   -- DESCRIPTION :
                    130:   --   Creates new equalities and uses them to eliminate unknowns in the
                    131:   --   matrices of equalities and inequalities.  Failure is reported when
                    132:   --   a zero row is encountered.  On entry, all new* variables must be
                    133:   --   initialized with the corresponding *-ones.
                    134:
                    135:     shi : Standard_Floating_Vectors.Vector(1..n+1) := f(f'first).all;
                    136:     fl : boolean := false;
                    137:     pivot : natural;
                    138:
                    139:   begin
                    140:     for i in f'first+1..f'last loop
                    141:       newrow := newrow + 1;
                    142:       for j in f(i)'range loop
                    143:         newmat(newrow,j) := f(i)(j) - shi(j);
                    144:       end loop;
                    145:       Switch(newipvt,newrow,newmat);
                    146:       Upper_Triangulate(newrow,newmat,tol,newipvt,pivot);
                    147:       fl := (pivot = 0);
                    148:       exit when fl;
                    149:       Switch(newrow,pivot,ineq'first,rowineq,newineq);
                    150:     end loop;
                    151:     fail := fl;
                    152:   end Create_Equalities;
                    153:
                    154:   procedure Complementary_Slackness
                    155:                   ( tableau : in out matrix;
                    156:                     tol : in double_float; feasible : out boolean ) is
                    157:
                    158:     lastcol : constant integer := tableau'last(2)-1;
                    159:     rhs,sol : Standard_Floating_Vectors.Vector(tableau'range(1));
                    160:     columns : Vector(sol'range);
                    161:
                    162:   begin
                    163:     for i in rhs'range loop
                    164:       rhs(i) := double_float(tableau(i,tableau'last(2)));
                    165:     end loop;
                    166:     Complementary_Slackness(tableau,lastcol,rhs,tol,sol,columns,feasible);
                    167:   end Complementary_Slackness;
                    168:
                    169:   function Check_Feasibility ( k,m,n : natural; ineq : Matrix;
                    170:                                tol : double_float ) return boolean is
                    171:
                    172:   -- DESCRIPTION :
                    173:   --   Returns true if -v(n+1) > 0 can be derived, false otherwise.
                    174:
                    175:   -- ON ENTRY :
                    176:   --   k      current unknown that has been eliminated,
                    177:   --           for all i <= k : ineq(l,i) = 0, for l in ineq'first..m;
                    178:   --   m      number of inequalities;
                    179:   --   n      dimension;
                    180:   --   ineq   matrix of inequalities.
                    181:
                    182:     tableau : Matrix(1..n-k+1,1..m+1);
                    183:     feasi : boolean;
                    184:
                    185:   begin
                    186:     if m = 0
                    187:      then feasi := false;
                    188:      else for i in k+1..n+1 loop
                    189:             for j in 1..m loop
                    190:               tableau(i-k,j) := ineq(j,i);
                    191:             end loop;
                    192:             tableau(i-k,m+1) := 0.0;
                    193:           end loop;
                    194:           tableau(n-k+1,m+1) := -1.0;
                    195:           Complementary_Slackness(tableau,tol,feasi);
                    196:     end if;
                    197:     return feasi;
                    198:   end Check_Feasibility;
                    199:
                    200:   procedure Update_Inequalities
                    201:                ( k,rowmat1,rowmat2,n : in natural;
                    202:                  mat : in Matrix; ipvt : in Standard_Natural_Vectors.Vector;
                    203:                  tol : in double_float;
                    204:                  rowineq : in out natural; ineq : in out Matrix;
                    205:                  lifted : in Array_of_Lists; mic : in out Face_Array ) is
                    206:
                    207:   -- DESCRIPTION :
                    208:   --   The inequalities will be updated w.r.t. the equality
                    209:   --   constraints on the inner normal.
                    210:
                    211:     tmp : List;
                    212:     pt,shi : Standard_Floating_Vectors.Link_to_Vector;
                    213:
                    214:   begin
                    215:     for i in ineq'first..rowineq loop      -- update the old inequalities
                    216:       for j in rowmat1..rowmat2 loop
                    217:         Upper_Triangulate(j,mat,tol,i,ineq);
                    218:       end loop;
                    219:     end loop;
                    220:     shi := mic(k)(mic(k)'first);
                    221:     tmp := lifted(k);                      -- make new inequalities
                    222:     while not Is_Null(tmp) loop
                    223:       pt := Head_Of(tmp);
                    224:       if not Is_In(mic(k),pt.all)
                    225:        then rowineq := rowineq + 1;
                    226:             for j in pt'range loop
                    227:               ineq(rowineq,j) := pt(j) - shi(j);
                    228:             end loop;
                    229:             Switch(ipvt,rowineq,ineq);
                    230:             for i in 1..rowmat2 loop
                    231:               Upper_Triangulate(i,mat,tol,rowineq,ineq);
                    232:             end loop;
                    233:       end if;
                    234:       tmp := Tail_Of(tmp);
                    235:     end loop;
                    236:   end Update_Inequalities;
                    237:
                    238: -- CONSTRUCTION WITH PRUNING :
                    239:
                    240:   procedure Gen1_Create
                    241:                ( n : in natural; mix : in Vector; fa : in Array_of_Faces;
                    242:                  lifted : in Array_of_Lists; tol : in double_float;
                    243:                  nbsucc,nbfail : in out Standard_Floating_Vectors.Vector;
                    244:                  mixsub : out Mixed_Subdivision ) is
                    245:
                    246:     res,res_last : Mixed_Subdivision;
                    247:     accu : Face_Array(fa'range);
                    248:     ma : Matrix(1..n,1..n+1);
                    249:     ipvt : Standard_Natural_Vectors.Vector(1..n);
                    250:     ineqrows : natural;
                    251:
                    252:     procedure Compute_Mixed_Cells
                    253:                  ( k,row : in natural; mat : in Matrix;
                    254:                    ipvt : in Standard_Natural_Vectors.Vector;
                    255:                    rowineq : in natural; ineq : in Matrix;
                    256:                    mic : in out Face_Array; continue : out boolean );
                    257:
                    258:     -- DESCRIPTION :
                    259:     --   Backtrack recursive procedure to enumerate face-face combinations.
                    260:
                    261:     -- ON ENTRY :
                    262:     --   k         index for current point set;
                    263:     --   row       number of rows already in the matrix;
                    264:     --   mat       matrix which determines the inner normal;
                    265:     --   ipvt      contains the pivoting information;
                    266:     --   rowineq   number of inequality constraints already in ineq;
                    267:     --   ineq      matrix for the inequality constraints on the
                    268:     --             inner normal v, of type <.,v> >= 0;
                    269:     --   mic       contains the current selected faces, up to k-1.
                    270:
                    271:     -- ON RETURN :
                    272:     --   mic       updated selected faces.
                    273:     --   continue  indicates whether to continue the creation or not.
                    274:
                    275:     procedure Process_Inequalities
                    276:                  ( k,rowmat1,rowmat2 : in natural;
                    277:                    mat : in Matrix; ipvt : in Standard_Natural_Vectors.Vector;
                    278:                    rowineq : in out natural; ineq : in out Matrix;
                    279:                    mic : in out Face_Array; cont : out boolean ) is
                    280:
                    281:     -- DESCRIPTION :
                    282:     --   Updates inequalities and checks feasibility before proceeding.
                    283:
                    284:       fl : boolean := false;
                    285:       tmp : List;
                    286:       pt,shi : Link_to_Vector;
                    287:
                    288:     begin
                    289:       Update_Inequalities(k,rowmat1,rowmat2,n,mat,ipvt,tol,rowineq,ineq,
                    290:                           lifted,mic);
                    291:       if Check_Feasibility(rowmat2,rowineq,n,ineq,tol)
                    292:        then nbfail(k) := nbfail(k) + 1.0;
                    293:             cont := true;
                    294:        else nbsucc(k) := nbsucc(k) + 1.0;
                    295:             Compute_Mixed_Cells(k+1,rowmat2,mat,ipvt,rowineq,ineq,mic,cont);
                    296:       end if;
                    297:     end Process_Inequalities;
                    298:
                    299:     procedure Compute_Mixed_Cells
                    300:                  ( k,row : in natural; mat : in Matrix;
                    301:                    ipvt : in Standard_Natural_Vectors.Vector;
                    302:                    rowineq : in natural; ineq : in Matrix;
                    303:                    mic : in out Face_Array; continue : out boolean ) is
                    304:
                    305:       old : Mixed_Subdivision := res_last;
                    306:       cont : boolean := true;
                    307:       tmpfa : Faces;
                    308:
                    309:     begin
                    310:       if k > mic'last
                    311:        then Check_and_Update(mic,lifted,mat,ipvt,tol,res,res_last);
                    312:             if old /= res_last
                    313:              then Process(Head_Of(res_last),continue);
                    314:              else continue := true;
                    315:             end if;
                    316:        else tmpfa := fa(k);
                    317:             while not Is_Null(tmpfa) loop  -- enumerate faces of kth polytope
                    318:               mic(k) := Head_Of(tmpfa);
                    319:               declare                                 -- update the matrices
                    320:                 fl : boolean;
                    321:                 newipvt : Standard_Natural_Vectors.Vector(ipvt'range) := ipvt;
                    322:                 newmat : Matrix(mat'range(1),mat'range(2)) := mat;
                    323:                 newineq : Matrix(ineq'range(1),ineq'range(2)) := ineq;
                    324:                 newrow : natural := row;
                    325:                 newrowineq : natural := rowineq;
                    326:               begin
                    327:                 Create_Equalities
                    328:                    (n,mic(k),mat,ineq,tol,ipvt,row,rowineq,newmat,newineq,
                    329:                     newipvt,newrow,newrowineq,fl);
                    330:                 if fl
                    331:                  then nbfail(k) := nbfail(k) + 1.0;
                    332:                  else Process_Inequalities(k,row+1,newrow,newmat,newipvt,
                    333:                                            newrowineq,newineq,mic,cont);
                    334:                 end if;
                    335:               end;
                    336:               tmpfa := Tail_Of(tmpfa);
                    337:               exit when not cont;
                    338:             end loop;
                    339:             continue := cont;
                    340:       end if;
                    341:     end Compute_Mixed_Cells;
                    342:
                    343:   begin
                    344:     Initialize(n,ma,ipvt);
                    345:     ineqrows := Number_of_Inequalities(mix,lifted);
                    346:     declare
                    347:       ineq : matrix(1..ineqrows,1..n+1);
                    348:       cont : boolean;
                    349:     begin
                    350:       ineq(1,1) := 0.0;
                    351:       Compute_Mixed_Cells(accu'first,0,ma,ipvt,0,ineq,accu,cont);
                    352:     end;
                    353:     mixsub := res;
                    354:   end Gen1_Create;
                    355:
                    356:   procedure Create
                    357:               ( n : in natural; mix : in Vector; fa : in Array_of_Faces;
                    358:                 lifted : in Array_of_Lists; tol : in double_float;
                    359:                 nbsucc,nbfail : in out Standard_Floating_Vectors.Vector;
                    360:                mixsub : out Mixed_Subdivision ) is
                    361:
                    362:     res,res_last : Mixed_Subdivision;
                    363:     accu : Face_Array(fa'range);
                    364:     ma : Matrix(1..n,1..n+1);
                    365:     ipvt : Standard_Natural_Vectors.Vector(1..n);
                    366:     ineqrows : natural;
                    367:
                    368:     procedure Compute_Mixed_Cells
                    369:                  ( k,row : in natural; mat : in Matrix;
                    370:                    ipvt : in Standard_Natural_Vectors.Vector;
                    371:                    rowineq : in natural; ineq : in Matrix;
                    372:                    mic : in out Face_Array );
                    373:
                    374:     -- DESCRIPTION :
                    375:     --   Backtrack recursive procedure to enumerate face-face combinations.
                    376:
                    377:     -- ON ENTRY :
                    378:     --   k         index for current point set;
                    379:     --   row       number of rows already in the matrix;
                    380:     --   mat       matrix which determines the inner normal;
                    381:     --   ipvt      contains the pivoting information;
                    382:     --   rowineq   number of inequality constraints already in ineq;
                    383:     --   ineq      matrix for the inequality constraints on the
                    384:     --             inner normal v, of type <.,v> >= 0;
                    385:     --   mic       contains the current selected faces, up to k-1.
                    386:
                    387:     -- ON RETURN :
                    388:     --   mic       updated selected faces.
                    389:
                    390:     procedure Process_Inequalities
                    391:                  ( k,rowmat1,rowmat2 : in natural;
                    392:                    mat : in Matrix; ipvt : in Standard_Natural_Vectors.Vector;
                    393:                    rowineq : in out natural; ineq : in out matrix;
                    394:                    mic : in out Face_Array) is
                    395:
                    396:     -- DESCRIPTION :
                    397:     --   Updates inequalities and checks feasibility before proceeding.
                    398:
                    399:       tmp : List;
                    400:       pt,shi : Link_to_Vector;
                    401:
                    402:     begin
                    403:       Update_Inequalities(k,rowmat1,rowmat2,n,mat,ipvt,tol,rowineq,ineq,
                    404:                           lifted,mic);
                    405:       if Check_Feasibility(rowmat2,rowineq,n,ineq,tol)
                    406:        then nbfail(k) := nbfail(k) + 1.0;
                    407:        else nbsucc(k) := nbsucc(k) + 1.0;
                    408:             Compute_Mixed_Cells(k+1,rowmat2,mat,ipvt,rowineq,ineq,mic);
                    409:       end if;
                    410:     end Process_Inequalities;
                    411:
                    412:     procedure Compute_Mixed_Cells
                    413:                  ( k,row : in natural; mat : in Matrix;
                    414:                    ipvt : in Standard_Natural_Vectors.Vector;
                    415:                    rowineq : in natural; ineq : in Matrix;
                    416:                    mic : in out Face_Array ) is
                    417:
                    418:       tmpfa : Faces;
                    419:
                    420:     begin
                    421:       if k > mic'last
                    422:        then Check_and_Update(mic,lifted,mat,ipvt,tol,res,res_last);
                    423:        else tmpfa := fa(k);
                    424:             while not Is_Null(tmpfa) loop  -- enumerate faces of kth polytope
                    425:               mic(k) := Head_Of(tmpfa);
                    426:               declare                                      -- update matrices
                    427:                 fl : boolean;
                    428:                 newipvt : Standard_Natural_Vectors.Vector(ipvt'range) := ipvt;
                    429:                 newmat : Matrix(mat'range(1),mat'range(2)) := mat;
                    430:                 newineq : Matrix(ineq'range(1),ineq'range(2)) := ineq;
                    431:                 newrow : natural := row;
                    432:                 newrowineq : natural := rowineq;
                    433:               begin
                    434:                 Create_Equalities
                    435:                     (n,mic(k),mat,ineq,tol,ipvt,row,rowineq,newmat,newineq,
                    436:                      newipvt,newrow,newrowineq,fl);
                    437:                 if fl
                    438:                  then nbfail(k) := nbfail(k) + 1.0;
                    439:                  else Process_Inequalities
                    440:                         (k,row+1,newrow,newmat,newipvt,newrowineq,newineq,mic);
                    441:                 end if;
                    442:               end;
                    443:               tmpfa := Tail_Of(tmpfa);
                    444:             end loop;
                    445:       end if;
                    446:     end Compute_Mixed_Cells;
                    447:
                    448:   begin
                    449:     Initialize(n,ma,ipvt);
                    450:     ineqrows := Number_of_Inequalities(mix,lifted);
                    451:     declare
                    452:       ineq : Matrix(1..ineqrows,1..n+1);
                    453:     begin
                    454:       ineq(1,1) := 0.0;
                    455:       Compute_Mixed_Cells(accu'first,0,ma,ipvt,0,ineq,accu);
                    456:     end;
                    457:     mixsub := res;
                    458:   end Create;
                    459:
                    460: end Floating_Pruning_Methods;

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