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

Annotation of OpenXM_contrib/PHC/Ada/Math_Lib/Supports/floating_linear_inequalities.adb, Revision 1.1

1.1     ! maekawa     1: with Standard_Mathematical_Functions;    use Standard_Mathematical_Functions;
        !             2: with Givens_Rotations;                   use Givens_Rotations;
        !             3:
        !             4: package body Floating_Linear_Inequalities is
        !             5:
        !             6: -- USAGE OF LP :
        !             7:
        !             8:   procedure Is_In_Cone ( tab : in out Matrix; lastcol : in integer;
        !             9:                          rhs : in out Standard_Floating_Vectors.Vector;
        !            10:                          tol : in double_float;
        !            11:                          solution : out Standard_Floating_Vectors.Vector;
        !            12:                          columns : out Standard_Integer_Vectors.Vector;
        !            13:                          feasible : out boolean ) is
        !            14:
        !            15:   -- ALGORITHM:
        !            16:   --   The following linear program will be solved:
        !            17:   --
        !            18:   --    min u_1 + .. + u_n
        !            19:   --
        !            20:   --        l_1*p_1i + l_2*p_2i + .. + l_m*p_mi + u_i*q_i = q_i   i=1,2,..,n
        !            21:   --
        !            22:   --  to determine whether q belongs to the cone spanned by the
        !            23:   --  vectors p_1,p_2,..,p_m.
        !            24:   --  If all u_i are zero and all constraints are satisfied,
        !            25:   --  then q belongs to the cone spanned by the vectors.
        !            26:
        !            27:   -- CONSTANTS :
        !            28:
        !            29:     n  : constant natural := rhs'last;
        !            30:     m  : constant natural := 2*n;             -- number of constraints
        !            31:     nb : constant natural := lastcol+n;       -- number of unknowns
        !            32:
        !            33:   -- VARIABLES :
        !            34:
        !            35:     mat : matrix(0..m,0..nb);
        !            36:     sol : Standard_Floating_Vectors.Vector(1..nb) := (1..nb => 0.0);
        !            37:     bas : Standard_Integer_Vectors.Vector(1..m) := (1..m => 0);
        !            38:     slk : Standard_Integer_Vectors.Vector(1..nb) := (1..nb => 0);
        !            39:
        !            40:     cnt : natural;
        !            41:     s : double_float;
        !            42:
        !            43:   begin
        !            44:
        !            45:    -- INITIALIZATION OF THE TARGET :
        !            46:
        !            47:     for i in 0..(nb-n) loop
        !            48:       mat(0,i) := 0.0;              -- sum of the lambda's
        !            49:     end loop;
        !            50:     for i in (nb-n+1)..nb loop
        !            51:       mat(0,i) := -1.0;             -- sum of the mu's
        !            52:     end loop;
        !            53:
        !            54:    -- INITIALIZATION OF THE CONSTRAINTS :
        !            55:
        !            56:     for i in 1..n loop
        !            57:       for j in (nb-n+1)..nb loop
        !            58:         if i /= j-nb+n
        !            59:          then mat(i,j)   := 0.0;
        !            60:               mat(i+n,j) := 0.0;
        !            61:         end if;
        !            62:       end loop;
        !            63:     end loop;
        !            64:
        !            65:     for j in tab'first(2)..lastcol loop
        !            66:       for i in tab'range(1) loop
        !            67:         mat(i,j)   := -tab(i,j);
        !            68:         mat(i+n,j) :=  tab(i,j);
        !            69:       end loop;
        !            70:     end loop;
        !            71:
        !            72:     for i in rhs'range loop
        !            73:       mat(i,0)   := -rhs(i);
        !            74:       mat(i+n,0) :=  rhs(i);
        !            75:       mat(i,i+nb-n)   := -rhs(i);
        !            76:       mat(i+n,i+nb-n) :=  rhs(i);
        !            77:     end loop;
        !            78:
        !            79:   -- SOLVE THE LINEAR PROGRAM :
        !            80:
        !            81:    -- New_Tableau.Init_Basis(nb,bas,slk);
        !            82:    -- Dual_Simplex(mat,sol,bas,slk,tol,false);
        !            83:
        !            84:   -- RETURN AND CHECK THE SOLUTION :
        !            85:
        !            86:     cnt := 0;
        !            87:     for i in tab'first(2)..lastcol loop
        !            88:       if abs(sol(i)) > tol
        !            89:        then cnt := cnt + 1;
        !            90:             solution(cnt) := sol(i);
        !            91:             columns(cnt) := i;
        !            92:       end if;
        !            93:     end loop;
        !            94:
        !            95:     s := 0.0;
        !            96:     for i in (nb-n+1)..nb loop
        !            97:       s := s + sol(i);
        !            98:     end loop;
        !            99:     if abs(s) > tol
        !           100:      then feasible := false; return;
        !           101:     end if;
        !           102:     feasible := true;
        !           103:
        !           104:   end Is_In_Cone;
        !           105:
        !           106: -- AUXILIARIES :
        !           107:
        !           108:   function Index_of_Maximum ( v : Standard_Floating_Vectors.Vector;
        !           109:                               lst : integer ) return integer is
        !           110:
        !           111:   -- DESCRIPTION :
        !           112:   --   Returns the index in the vector v(v'first..lst) for which the maximum
        !           113:   --   is obtained.
        !           114:
        !           115:     res : integer := v'first;
        !           116:     max : double_float := v(res);
        !           117:
        !           118:   begin
        !           119:     for i in v'first+1..lst loop
        !           120:       if v(i) > max
        !           121:        then max := v(i); res := i;
        !           122:       end if;
        !           123:     end loop;
        !           124:     return res;
        !           125:   end Index_of_Maximum;
        !           126:
        !           127:   function Norm ( v : Standard_Floating_Vectors.Vector ) return double_float is
        !           128:
        !           129:   -- DESCRIPTION :
        !           130:   --   Returns the 2-norm of the vector.
        !           131:
        !           132:     res : double_float := 0.0;
        !           133:
        !           134:   begin
        !           135:     for j in v'range loop
        !           136:       res := res + v(j)*v(j);
        !           137:     end loop;
        !           138:     if res + 1.0 = 1.0
        !           139:      then return 0.0;
        !           140:      else return SQRT(res);
        !           141:     end if;
        !           142:   end Norm;
        !           143:
        !           144:   function Norm ( v : Standard_Floating_Vectors.vector;
        !           145:                   frst : integer ) return double_float is
        !           146:
        !           147:   -- DESCRIPTION :
        !           148:   --   Returns the 2-norm of the vector v(frst..v'last).
        !           149:
        !           150:     res : double_float := 0.0;
        !           151:
        !           152:   begin
        !           153:     for j in frst..v'last loop
        !           154:       res := res + v(j)*v(j);
        !           155:     end loop;
        !           156:     if res + 1.0 = 1.0
        !           157:      then return 0.0;
        !           158:      else return SQRT(res);
        !           159:     end if;
        !           160:   end Norm;
        !           161:
        !           162:   procedure Scale ( v : in out Standard_Floating_Vectors.vector ) is
        !           163:
        !           164:   -- DESCRIPTION :
        !           165:   --   Returns the normed vector, i.e. v/Norm(v).
        !           166:
        !           167:     nrm : double_float := Norm(v);
        !           168:
        !           169:   begin
        !           170:     if nrm + 1.0 /= 1.0
        !           171:      then for i in v'range loop
        !           172:             v(i) := v(i)/nrm;
        !           173:           end loop;
        !           174:     end if;
        !           175:   end Scale;
        !           176:
        !           177:   function Norm ( mat : matrix; i : integer ) return double_float is
        !           178:
        !           179:   -- DESCRIPTION :
        !           180:   --   Returns the 2-norm of the ith column in the matrix.
        !           181:
        !           182:     res : double_float := 0.0;
        !           183:
        !           184:   begin
        !           185:     for j in mat'range(1) loop
        !           186:       res := res + mat(j,i)*mat(j,i);
        !           187:     end loop;
        !           188:     if res + 1.0 = 1.0
        !           189:      then return 0.0;
        !           190:      else return SQRT(res);
        !           191:     end if;
        !           192:   end Norm;
        !           193:
        !           194:   procedure Scale ( mat : in out matrix; lastcolumn : in integer ) is
        !           195:
        !           196:   -- DESCRIPTION :
        !           197:   --   Scales the columns in the matrix, by dividing by their norm.
        !           198:
        !           199:     nrm : double_float;
        !           200:
        !           201:   begin
        !           202:     for i in mat'first(2)..lastcolumn loop
        !           203:       nrm := Norm(mat,i);
        !           204:       if nrm + 1.0 /= 1.0
        !           205:        then for j in mat'range(1) loop
        !           206:               mat(j,i) := mat(j,i)/nrm;
        !           207:             end loop;
        !           208:       end if;
        !           209:     end loop;
        !           210:   end Scale;
        !           211:
        !           212:   function Inner_Product ( mat : Matrix; i : integer;
        !           213:                            v : Standard_Floating_Vectors.Vector )
        !           214:                          return double_float is
        !           215:   -- DESCRIPTION :
        !           216:   --   Computes the inner product of the given vector v and the vector
        !           217:   --   in the ith column of the matrix.
        !           218:
        !           219:     res : double_float := 0.0;
        !           220:
        !           221:   begin
        !           222:     for k in mat'range(1) loop
        !           223:       res := res + mat(k,i)*v(k);
        !           224:     end loop;
        !           225:     return res;
        !           226:   end Inner_Product;
        !           227:
        !           228:   function Maximal_Product ( mat : matrix; i : integer;
        !           229:                              v : Standard_Floating_Vectors.Vector;
        !           230:                              frst : integer ) return integer is
        !           231:   -- DESCRIPTION :
        !           232:   --   Returns the index in v(frst..v'last) for which mat(index,i)*v(index)
        !           233:   --   becomes maximal.
        !           234:
        !           235:     res : integer := frst;
        !           236:     max : double_float := mat(res,i)*v(res);
        !           237:     tmp : double_float;
        !           238:
        !           239:   begin
        !           240:     for j in frst+1..v'last loop
        !           241:       tmp := mat(j,i)*v(j);
        !           242:       if tmp > max
        !           243:        then max := tmp; res := j;
        !           244:       end if;
        !           245:     end loop;
        !           246:     return res;
        !           247:   end Maximal_Product;
        !           248:
        !           249:   function Inner_Product ( mat : Matrix; i,j : integer ) return double_float is
        !           250:
        !           251:   -- DESCRIPTION :
        !           252:   --   Computes the inner product of the vectors in the columns i and j
        !           253:   --   of the matrix.
        !           254:
        !           255:     res : double_float := 0.0;
        !           256:
        !           257:   begin
        !           258:     for k in mat'range(1) loop
        !           259:       res := res + mat(k,i)*mat(k,j);
        !           260:     end loop;
        !           261:     return res;
        !           262:   end Inner_Product;
        !           263:
        !           264:   function Inner_Products ( mat : matrix; lastcol : integer;
        !           265:                             v : Standard_Floating_Vectors.Vector )
        !           266:                           return Standard_Floating_Vectors.Vector is
        !           267:
        !           268:   -- DESCRIPTION :
        !           269:   --   Returns a vector with all inner products of the given vector
        !           270:   --   and the column vectors of the matrix.
        !           271:
        !           272:     res : Standard_Floating_Vectors.Vector(mat'first(2)..lastcol);
        !           273:
        !           274:   begin
        !           275:     for i in res'range loop
        !           276:       res(i) := Inner_Product(mat,i,v);
        !           277:     end loop;
        !           278:     return res;
        !           279:   end Inner_Products;
        !           280:
        !           281:   function Positive ( v : Standard_Floating_Vectors.Vector;
        !           282:                       lst : integer; tol : double_float )
        !           283:                     return boolean is
        !           284:   -- DESCRIPTION :
        !           285:   --   Returns true if all elements in v(v'first..lst) are >= 0.
        !           286:
        !           287:   begin
        !           288:     for i in v'first..lst loop
        !           289:       if abs(v(i)) > tol and then (v(i) < 0.0)
        !           290:        then return false;
        !           291:       end if;
        !           292:     end loop;
        !           293:     return true;
        !           294:   end Positive;
        !           295:
        !           296:   function Positive
        !           297:                ( mat : matrix; rhs : Standard_Floating_Vectors.Vector;
        !           298:                  ind,col : integer;
        !           299:                  solind : double_float; tol : double_float ) return boolean is
        !           300:
        !           301:   -- DESCRIPTION :
        !           302:   --   The given matrix is upper triangular up to the column indicated
        !           303:   --   by ind.  This function returns true when by replacing column ind
        !           304:   --   by column col, a positive solution would be obtained.
        !           305:   --   The number solind is sol(ind) in the solution vector.
        !           306:
        !           307:     sol : Standard_Floating_Vectors.Vector(1..ind) := (1..ind => 0.0);
        !           308:
        !           309:   begin
        !           310:     sol(ind) := solind;
        !           311:     for i in reverse mat'first(1)..(ind-1) loop
        !           312:       for j in i+1..(ind-1) loop
        !           313:         sol(i) := sol(i) + mat(i,j)*sol(j);
        !           314:       end loop;
        !           315:       sol(i) := sol(i) + mat(i,col)*sol(ind);
        !           316:       sol(i) := (rhs(i) - sol(i))/mat(i,i);
        !           317:       if (abs(sol(i)) > tol) and then (sol(i) < 0.0)
        !           318:        then --put_line("The solution before returning false : ");
        !           319:             --put(sol,3,3,3); new_line;
        !           320:             return false;
        !           321:       end if;
        !           322:     end loop;
        !           323:     --put_line("The solution before returning true : ");
        !           324:     --put(sol,3,3,3); new_line;
        !           325:     return true;
        !           326:   end Positive;
        !           327:
        !           328:   function Positive_Diagonal
        !           329:                ( mat : Matrix; rhs : Standard_Floating_Vectors.Vector;
        !           330:                  ind,col : integer;
        !           331:                  solind : double_float; tol : double_float ) return boolean is
        !           332:
        !           333:   -- DESCRIPTION :
        !           334:   --   The given matrix is diagonal up to the column indicated
        !           335:   --   by ind.  This function returns true when by replacing column ind
        !           336:   --   by column col, a positive solution would be obtained.
        !           337:   --   The number solind is sol(ind) in the solution vector.
        !           338:
        !           339:     sol : Standard_Floating_Vectors.Vector(1..ind) := (1..ind => 0.0);
        !           340:
        !           341:   begin
        !           342:     sol(ind) := solind;
        !           343:     for i in reverse mat'first(1)..(ind-1) loop
        !           344:       sol(i) := (rhs(i) - mat(i,col)*sol(ind))/mat(i,i);
        !           345:       if (abs(sol(i)) > tol) and then (sol(i) < 0.0)
        !           346:        then --put_line("The solution before returning false : ");
        !           347:             --put(sol,3,3,3); new_line;
        !           348:             return false;
        !           349:       end if;
        !           350:     end loop;
        !           351:     --put_line("The solution before returning true : ");
        !           352:     --put(sol,3,3,3); new_line;
        !           353:     return true;
        !           354:   end Positive_Diagonal;
        !           355:
        !           356: -- PIVOTING PROCEDURES :
        !           357:
        !           358:   procedure Interchange ( v : in out Standard_Floating_Vectors.Vector;
        !           359:                           i,j : in integer ) is
        !           360:
        !           361:   -- DESCRIPTION :
        !           362:   --   The entries v(i) and v(j) are interchanged.
        !           363:
        !           364:     temp : double_float;
        !           365:
        !           366:   begin
        !           367:     temp := v(i); v(i) := v(j); v(j) := temp;
        !           368:   end Interchange;
        !           369:
        !           370:   procedure Interchange_Columns ( mat : in out matrix; i,j : in integer ) is
        !           371:
        !           372:   -- DESCRIPTION :
        !           373:   --   The columns i and j of the given matrix are interchanged.
        !           374:
        !           375:     temp : double_float;
        !           376:
        !           377:   begin
        !           378:     for k in mat'range(1) loop
        !           379:       temp := mat(k,i); mat(k,i) := mat(k,j); mat(k,j) := temp;
        !           380:     end loop;
        !           381:   end Interchange_Columns;
        !           382:
        !           383:   procedure Interchange_Rows
        !           384:                  ( mat : in out Matrix; lastcol : in integer;
        !           385:                    v : in out Standard_Floating_Vectors.Vector;
        !           386:                    i,j : in integer ) is
        !           387:
        !           388:   -- DESCRIPTION :
        !           389:   --   The rows i and j of the given matrix and vector are interchanged.
        !           390:
        !           391:     temp : double_float;
        !           392:
        !           393:   begin
        !           394:     for k in mat'first(2)..lastcol loop
        !           395:       temp := mat(i,k); mat(i,k) := mat(j,k); mat(j,k) := temp;
        !           396:     end loop;
        !           397:     temp := v(i); v(i) := v(j); v(j) := temp;
        !           398:   end Interchange_Rows;
        !           399:
        !           400:   procedure Rotate ( mat : in out Matrix; lastcol,i : in integer;
        !           401:                      v : in out Standard_Floating_Vectors.Vector;
        !           402:                      tol : in double_float ) is
        !           403:
        !           404:   -- DESCRIPTION :
        !           405:   --   Performs Givens rotations on the matrix and vector such that
        !           406:   --   mat(j,i) = 0, for all j > i.
        !           407:
        !           408:   -- NOTE :
        !           409:   --   A diagonalization procedure constructs an orthonormal basis
        !           410:   --   and does not preserve the angles between the vectors.
        !           411:
        !           412:     cosi,sine : double_float;
        !           413:
        !           414:   begin
        !           415:     for j in i+1..mat'last(1) loop
        !           416:       if abs(mat(j,i)) > tol
        !           417:        then Givens_Factors(mat,i,j,cosi,sine);
        !           418:             Givens_Rotation(mat,lastcol,i,j,cosi,sine);
        !           419:             Givens_Rotation(v,i,j,cosi,sine);
        !           420:       end if;
        !           421:     end loop;
        !           422:   end Rotate;
        !           423:
        !           424:   procedure Upper_Triangulate ( mat : in out Matrix; lastcol,i : in integer;
        !           425:                                 v : in out Standard_Floating_Vectors.Vector;
        !           426:                                 tol : in double_float ) is
        !           427:
        !           428:   -- DESCRIPTION :
        !           429:   --   Makes the upper diagonal elements of the ith colume zero:
        !           430:   --   mat(j,i) = 0, for all j /= i.
        !           431:
        !           432:     fac : double_float;
        !           433:
        !           434:   begin
        !           435:     for j in mat'first(1)..(i-1) loop
        !           436:       if (abs(mat(j,i)) > tol)
        !           437:        then fac := mat(j,i)/mat(i,i);
        !           438:             for k in i..lastcol loop
        !           439:               mat(j,k) := mat(j,k) - fac*mat(i,k);
        !           440:             end loop;
        !           441:       end if;
        !           442:     end loop;
        !           443:   end Upper_Triangulate;
        !           444:
        !           445: -- INITIALIZE : COMPUTE CLOSEST VECTOR TO RHS
        !           446:
        !           447:   procedure Initialize
        !           448:               ( tableau : in out Matrix; lastcol : in integer;
        !           449:                 rhs,sol : in out Standard_Floating_Vectors.Vector;
        !           450:                 tol : in double_float;
        !           451:                 columns : in out Standard_Integer_Vectors.Vector;
        !           452:                 cosines : out Standard_Floating_Vectors.Vector;
        !           453:                 feasible : out boolean ) is
        !           454:
        !           455:   -- DESCRIPTION :
        !           456:   --   Scales the tableau and right hand side by dividing by its norm.
        !           457:   --   Then computes the vector of cosines.
        !           458:   --   If no vector with positive cosine with the right hand side vector
        !           459:   --   can be found, then the problem is not feasible, otherwise,
        !           460:   --   the vector with largest positive cosine will be the first column.
        !           461:   --   At last, this first column will be transformed to the unit vector,
        !           462:   --   by means of Givens rotations.
        !           463:   --   Then the first solution component equals the first component of
        !           464:   --   the transformed right hand side vector.
        !           465:
        !           466:     ips : Standard_Floating_Vectors.Vector(tableau'first(2)..lastcol);
        !           467:     index : integer;
        !           468:
        !           469:   begin
        !           470:     Scale(tableau,lastcol); Scale(rhs);
        !           471:    -- put_line("The tableau after scaling : "); put(tableau,3,3,3);
        !           472:    -- put_line(" with scaled right hand side : "); put(rhs,3,3,3); new_line;
        !           473:     ips := Inner_Products(tableau,lastcol,rhs);
        !           474:     index := Index_of_Maximum(ips,lastcol);
        !           475:     if (abs(ips(index)) < tol) or else (ips(index) < 0.0)
        !           476:      then if index <= rhs'last
        !           477:            then feasible := (abs(rhs(index)) < tol);
        !           478:            else feasible := false;
        !           479:           end if;
        !           480:      else feasible := true;
        !           481:           columns(columns'first) := index;
        !           482:           columns(index) := columns'first;
        !           483:           Interchange_Columns(tableau,tableau'first(2),index);
        !           484:           Interchange(ips,tableau'first(2),index);
        !           485:           index := Maximal_Product(tableau,tableau'first(2),rhs,rhs'first);
        !           486:           if index /= tableau'first(2)
        !           487:            then Interchange_Rows(tableau,lastcol,rhs,tableau'first(2),index);
        !           488:           end if;
        !           489:           Rotate(tableau,lastcol,tableau'first(2),rhs,tol);
        !           490:          -- Upper_Triangulate(tableau,lastcol,tableau'first(2),rhs,tol);
        !           491:           sol(sol'first) := rhs(rhs'first);
        !           492:     end if;
        !           493:     cosines := ips;
        !           494:    -- put_line("At the end of Initialize : ");
        !           495:    -- put(" cosines : "); put(ips,3,3,3); new_line;
        !           496:    -- put_line("The tableau : "); put(tableau,3,3,3);
        !           497:    -- put_line(" with right hand side : "); put(rhs,3,3,3); new_line;
        !           498:    -- put(" and last column "); put(lastcol,1); new_line;
        !           499:   end Initialize;
        !           500:
        !           501:   procedure Initialize
        !           502:               ( tableau : in out Matrix; lastcol : in integer;
        !           503:                 rhs,sol : in out Standard_Floating_Vectors.Vector;
        !           504:                 tol : in double_float;
        !           505:                 columns : in out Standard_Integer_Vectors.Vector;
        !           506:                 feasible : out boolean ) is
        !           507:
        !           508:   -- DESCRIPTION :
        !           509:   --   Scales the tableau and right hand side by dividing by its norm.
        !           510:   --   Then computes the vector of cosines.
        !           511:   --   If no vector with positive cosine with the right hand side vector
        !           512:   --   can be found, then the problem is not feasible, otherwise,
        !           513:   --   the vector with largest positive cosine will be the first column.
        !           514:   --   At last, this first column will be transformed to the unit vector,
        !           515:   --   by means of Givens rotations.
        !           516:   --   Then the first solution component equals the first component of
        !           517:   --   the transformed right hand side vector.
        !           518:
        !           519:     ips : Standard_Floating_Vectors.Vector(tableau'first(2)..lastcol);
        !           520:     index : integer;
        !           521:
        !           522:   begin
        !           523:     Scale(tableau,lastcol); Scale(rhs);
        !           524:    -- put_line("The tableau after scaling : "); put(tableau,3,3,3);
        !           525:    -- put_line(" with scaled right hand side : "); put(rhs,3,3,3); new_line;
        !           526:     ips := Inner_Products(tableau,lastcol,rhs);
        !           527:     index := Index_of_Maximum(ips,lastcol);
        !           528:     if (abs(ips(index)) < tol) or else (ips(index) < 0.0)
        !           529:      then if index <= rhs'last
        !           530:            then feasible := (abs(rhs(index)) < tol);
        !           531:            else feasible := false;
        !           532:           end if;
        !           533:      else feasible := true;
        !           534:           columns(columns'first) := index;
        !           535:           columns(index) := columns'first;
        !           536:           Interchange_Columns(tableau,tableau'first(2),index);
        !           537:           index := Maximal_Product(tableau,tableau'first(2),rhs,rhs'first);
        !           538:           if index /= tableau'first(2)
        !           539:            then Interchange_Rows(tableau,lastcol,rhs,tableau'first(2),index);
        !           540:           end if;
        !           541:           Rotate(tableau,lastcol,tableau'first(2),rhs,tol);
        !           542:          -- Upper_Triangulate(tableau,lastcol,tableau'first(2),rhs,tol);
        !           543:           sol(sol'first) := rhs(rhs'first);
        !           544:     end if;
        !           545:    -- put_line("At the end of Initialize : ");
        !           546:    -- put_line("The tableau : "); put(tableau,3,3,3);
        !           547:    -- put_line(" with right hand side : "); put(rhs,3,3,3); new_line;
        !           548:    -- put(" and last column "); put(lastcol,1); new_line;
        !           549:   end Initialize;
        !           550:
        !           551: -- PERFORM THE NEXT STEPS :
        !           552:
        !           553:   procedure Select_Column
        !           554:                   ( mat : in Matrix; lastcol : in integer;
        !           555:                     rhs,cosines : in Standard_Floating_Vectors.Vector;
        !           556:                     index : in integer;
        !           557:                     tol : in double_float; row,col : out integer ) is
        !           558:   -- DESCRIPTION :
        !           559:   --   Selects a column col with in matrix for which
        !           560:   --    1) the cosine is maximal and
        !           561:   --    2) row = Maximal_Product(mat,col,rhs,index), with mat(row,col) > 0.0
        !           562:   --   If the resulting column is smaller than index, then no such column
        !           563:   --   has been found.
        !           564:
        !           565:     cl : integer := index;
        !           566:     maxcos,prod : double_float;
        !           567:     rw : integer := Maximal_Product(mat,cl,rhs,index);
        !           568:     mp : integer;
        !           569:
        !           570:   begin
        !           571:    -- put_line("The tableau when Select_Column :"); put(mat,3,3,3);
        !           572:    -- put_line(" with right hand side : "); put(rhs,3,3,3); new_line;
        !           573:    -- put_line("and vector of cosines : "); put(cosines,3,3,3); new_line;
        !           574:    -- put("The index : "); put(index,1); new_line;
        !           575:     prod := mat(rw,cl)*rhs(rw);
        !           576:     if prod > tol
        !           577:       and then Positive(mat,rhs,index,cl,rhs(rw)/mat(rw,cl),tol)
        !           578:               -- Positive_Diagonal(mat,rhs,index,cl,rhs(rw)/mat(rw,cl),tol)
        !           579:      then maxcos := cosines(cl);
        !           580:      else maxcos := -2.0;
        !           581:     end if;
        !           582:     for i in index+1..lastcol loop
        !           583:       mp := Maximal_Product(mat,i,rhs,index);
        !           584:      -- put("mp : "); put(mp,1); put(" when testing "); put(i,1);
        !           585:      -- put_line("th column");
        !           586:       prod := mat(mp,i)*rhs(mp);
        !           587:       if prod > tol and then cosines(i) > maxcos
        !           588:        then if Positive(mat,rhs,index,i,rhs(mp)/mat(mp,i),tol)
        !           589:               -- Positive_Diagonal(mat,rhs,index,i,rhs(mp)/mat(mp,i),tol)
        !           590:              then cl := i; rw := mp; maxcos := cosines(i);
        !           591:             end if;
        !           592:       end if;
        !           593:     end loop;
        !           594:    -- put("maximal cosine : "); put(maxcos,3,3,3); new_line;
        !           595:     if maxcos >= -1.0
        !           596:      then col := cl; row := rw;
        !           597:          -- put("column : "); put(cl,1);
        !           598:          -- put(" and row : "); put(rw,1); new_line;
        !           599:      else col := index-1; row := index-1;
        !           600:          -- put("column : "); put(index-1,1);
        !           601:          -- put(" and row : "); put(index-1,1); new_line;
        !           602:     end if;
        !           603:   end Select_Column;
        !           604:
        !           605:   procedure Select_Column
        !           606:                   ( mat : in Matrix; lastcol : in integer;
        !           607:                     rhs : in Standard_Floating_Vectors.Vector;
        !           608:                     index,column : in integer;
        !           609:                     tol : in double_float; row,col : out integer ) is
        !           610:   -- DESCRIPTION :
        !           611:   --   Selects first column col with in matrix for which
        !           612:   --    row = Maximal_Product(mat,col,rhs,index), with mat(row,col) > 0.0.
        !           613:   --   If the resulting column is smaller than index, then no such column
        !           614:   --   has been found.
        !           615:
        !           616:     cl : integer := index-1;
        !           617:     prod : double_float;
        !           618:     rw,mp : integer;
        !           619:
        !           620:   begin
        !           621:    -- put_line("The tableau when Select_Column :"); put(mat,3,3,3);
        !           622:    -- put_line(" with right hand side : "); put(rhs,3,3,3); new_line;
        !           623:    -- put("The index : "); put(index,1); new_line;
        !           624:     for i in column..lastcol loop
        !           625:       mp := Maximal_Product(mat,i,rhs,index);
        !           626:      -- put("mp : "); put(mp,1); put(" when testing "); put(i,1);
        !           627:      -- put_line("th column");
        !           628:       prod := mat(mp,i)*rhs(mp);
        !           629:       if prod > tol
        !           630:         and then Positive(mat,rhs,index,i,rhs(mp)/mat(mp,i),tol)
        !           631:                 -- Positive_Diagonal(mat,rhs,index,i,rhs(mp)/mat(mp,i),tol)
        !           632:        then cl := i; rw := mp;
        !           633:       end if;
        !           634:       exit when (cl >= index);
        !           635:     end loop;
        !           636:     if cl >= index
        !           637:      then col := cl; row := rw;
        !           638:          -- put("column : "); put(cl,1);
        !           639:          -- put(" and row : "); put(rw,1); new_line;
        !           640:      else col := index-1; row := index-1;
        !           641:          -- put("column : "); put(index-1,1);
        !           642:          -- put(" and row : "); put(index-1,1); new_line;
        !           643:     end if;
        !           644:   end Select_Column;
        !           645:
        !           646:   procedure Next ( tableau : in out Matrix; lastcol : in integer;
        !           647:                    rhs,sol,cosines : in out Standard_Floating_Vectors.Vector;
        !           648:                    pivots : in out Standard_Integer_Vectors.Vector;
        !           649:                    tol : in double_float;
        !           650:                    index : in integer; feasi : in out boolean ) is
        !           651:
        !           652:   -- DESCRIPTION :
        !           653:   --   Selects one new column out of the tableau.
        !           654:
        !           655:   -- ON ENTRY :
        !           656:   --   tableau     upper triangular up to the row and column index-1;
        !           657:   --   lastcol     index of the last column of interest in the tableau;
        !           658:   --   rhs         right hand side vector;
        !           659:   --   sol         solution vector for the components 1..index;
        !           660:   --   cosines     vector of cosines;
        !           661:   --   pivots      vector of column interchangements;
        !           662:   --   tol         tolerance to decide whether a number equals zero;
        !           663:   --   index       indicator of the current step;
        !           664:   --   feasi       must be true on entry.
        !           665:
        !           666:   -- ON RETURN :
        !           667:   --   tableau     upper triangular up to the row and column index,
        !           668:   --               under the condition that feasi remains true;
        !           669:   --   rhs         transformed right hand side vector;
        !           670:   --   sol         new solution, with additional meaningful component
        !           671:   --               sol(index);
        !           672:   --   cosines     eventually permuted vector of cosines:
        !           673:   --               cosines(index) is the cosine of the (new) column,
        !           674:   --               indicated by index, and the right hand side vector;
        !           675:   --   pivots      updated vector of column interchangements;
        !           676:   --   feasi       if true, then a new column which yields a positive
        !           677:   --               contribution of the right hand side vector has been
        !           678:   --               found, if this was not the case, then feasi is false;
        !           679:
        !           680:     col,row,tmp : integer;
        !           681:
        !           682:   begin
        !           683:     Select_Column(tableau,lastcol,rhs,cosines,index,tol,row,col);
        !           684:     if col < index
        !           685:      then feasi := false;
        !           686:      else feasi := true;
        !           687:           if col /= index
        !           688:            then tmp := pivots(col); pivots(col) := pivots(index);
        !           689:                 pivots(index) := tmp;
        !           690:                 Interchange_Columns(tableau,col,index);
        !           691:                 Interchange(cosines,col,index);
        !           692:           end if;
        !           693:           if row /= index
        !           694:            then Interchange_Rows(tableau,lastcol,rhs,row,index);
        !           695:           end if;
        !           696:           Rotate(tableau,lastcol,index,rhs,tol);
        !           697:          -- Upper_Triangulate(tableau,lastcol,index,rhs,tol);
        !           698:          -- Solve(tableau,rhs,tol,index,sol);  -- only needed at end
        !           699:          -- feasi := Positive(sol,index,tol);  -- double check...
        !           700:     end if;
        !           701:   end Next;
        !           702:
        !           703:   procedure Next ( tableau : in out Matrix; lastcol : in integer;
        !           704:                    rhs,sol : in out Standard_Floating_Vectors.Vector;
        !           705:                    pivots : in out Standard_Integer_Vectors.Vector;
        !           706:                    tol : in double_float;
        !           707:                    index : in integer; rank : out integer;
        !           708:                    feasi : in out boolean ) is
        !           709:
        !           710:   -- DESCRIPTION :
        !           711:   --   Lexicographic enumeration of the candidates, stops when a feasible
        !           712:   --   solution is encountered.
        !           713:
        !           714:   -- ON ENTRY :
        !           715:   --   tableau     upper triangular up to the row and column index-1;
        !           716:   --   lastcol     index of the last column of interest in the tableau;
        !           717:   --   rhs         right hand side vector;
        !           718:   --   sol         solution vector for the components 1..index;
        !           719:   --   pivots      vector of column interchangements;
        !           720:   --   tol         tolerance to decide whether a number equals zero;
        !           721:   --   index       indicator of the current step;
        !           722:   --   feasi       must be true on entry.
        !           723:
        !           724:   -- ON RETURN :
        !           725:   --   tableau     upper triangular up to the row and column index,
        !           726:   --               under the condition that feasi remains true;
        !           727:   --   rhs         transformed right hand side vector;
        !           728:   --   sol         new solution, with additional meaningful component
        !           729:   --               sol(index);
        !           730:   --   pivots      updated vector of column interchangements;
        !           731:   --   rank        rank of the current tableau;
        !           732:   --   feasi       if true, then a new column which yields a positive
        !           733:   --               contribution of the right hand side vector has been
        !           734:   --               found, if this was not the case, then feasi is false;
        !           735:
        !           736:     column,col,row,tmp : integer;
        !           737:     stop : boolean := false;
        !           738:
        !           739:   begin
        !           740:     column := index;
        !           741:     loop
        !           742:       Select_Column(tableau,lastcol,rhs,index,column,tol,row,col);
        !           743:       if col < column
        !           744:        then feasi := false; stop := true;
        !           745:        else
        !           746:          feasi := true;
        !           747:          if col /= index
        !           748:           then tmp := pivots(col); pivots(col) := pivots(index);
        !           749:                pivots(index) := tmp;
        !           750:                Interchange_Columns(tableau,col,index);
        !           751:          end if;
        !           752:          if row /= index
        !           753:           then Interchange_Rows(tableau,lastcol,rhs,row,index);
        !           754:          end if;
        !           755:          Rotate(tableau,lastcol,index,rhs,tol);
        !           756:         -- Upper_Triangulate(tableau,lastcol,index,rhs,tol);
        !           757:          if (index = lastcol) or else (index = tableau'last(1))
        !           758:                               or else (Norm(rhs,index+1) < tol)
        !           759:           then stop := true; rank := index;
        !           760:           else
        !           761:             Next(tableau,lastcol,rhs,sol,pivots,tol,index+1,rank,feasi);
        !           762:             if feasi
        !           763:              then stop := true;
        !           764:              else column := col+1;
        !           765:             end if;
        !           766:          end if;
        !           767:       end if;
        !           768:       exit when stop;
        !           769:     end loop;
        !           770:   end Next;
        !           771:
        !           772:   procedure Complementary_Slackness
        !           773:                  ( tableau : in out matrix;
        !           774:                    rhs : in out Standard_Floating_Vectors.Vector;
        !           775:                    tol : in double_float;
        !           776:                    solution : out Standard_Floating_Vectors.Vector;
        !           777:                    columns : out Standard_Integer_Vectors.Vector;
        !           778:                    feasible : out boolean ) is
        !           779:   begin
        !           780:     Complementary_Slackness
        !           781:        (tableau,tableau'last(2),rhs,tol,solution,columns,feasible);
        !           782:   end Complementary_Slackness;
        !           783:
        !           784:   procedure Complementary_Slackness1
        !           785:                  ( tableau : in out Matrix; lastcol : in integer;
        !           786:                    rhs : in out Standard_Floating_Vectors.Vector;
        !           787:                    tol : in double_float;
        !           788:                    solution : out Standard_Floating_Vectors.Vector;
        !           789:                    columns : out Standard_Integer_Vectors.Vector;
        !           790:                    feasible : out boolean ) is
        !           791:
        !           792:   -- NOTE :
        !           793:   --   This version is a straigth forward search and finds not always
        !           794:   --   the feasible solution.
        !           795:
        !           796:     feasi : boolean;
        !           797:     pivots : Standard_Integer_Vectors.Vector(tableau'first(2)..lastcol);
        !           798:     cosis : Standard_Floating_Vectors.Vector(tableau'first(2)..lastcol);
        !           799:     sol : Standard_Floating_Vectors.Vector(rhs'range) := (rhs'range => 0.0);
        !           800:     rank : integer;
        !           801:
        !           802:   begin
        !           803:     for i in pivots'range loop  -- initialize vector of pivots
        !           804:       pivots(i) := i;
        !           805:     end loop;
        !           806:     Initialize(tableau,lastcol,rhs,sol,tol,pivots,cosis,feasi);
        !           807:     if feasi
        !           808:      then
        !           809:        if Norm(rhs,rhs'first+1) > tol  -- check whether residual > 0
        !           810:         then
        !           811:           if tableau'first(1)+1 > lastcol
        !           812:            then feasi := false;
        !           813:            else
        !           814:              rank := 1;
        !           815:              for i in tableau'first(1)+1..tableau'last(1) loop
        !           816:                Next(tableau,lastcol,rhs,sol,cosis,pivots,tol,i,feasi);
        !           817:                exit when not feasi;
        !           818:                exit when (i = lastcol);
        !           819:                rank := rank + 1;
        !           820:                exit when (Norm(rhs,i+1) < tol);
        !           821:              end loop;
        !           822:              if feasi
        !           823:               then Solve(tableau,rhs,tol,rank,sol);
        !           824:              end if;
        !           825:           end if;
        !           826:        end if;
        !           827:        if feasi and then (tableau'last(1) > lastcol)
        !           828:         then feasi := (Norm(rhs,lastcol+1) < tol);
        !           829:        end if;
        !           830:        if feasi and then (Norm(sol) < tol)
        !           831:         then feasi := (Norm(rhs) < tol);
        !           832:        end if;
        !           833:        solution := sol;
        !           834:        if tableau'last(1) <= lastcol
        !           835:         then
        !           836:           for i in tableau'range(1) loop
        !           837:             columns(i) := pivots(i);
        !           838:           end loop;
        !           839:         else
        !           840:           for i in tableau'first(2)..lastcol loop
        !           841:             columns(i) := pivots(i);
        !           842:           end loop;
        !           843:        end if;
        !           844:     end if;
        !           845:     feasible := feasi;
        !           846:   end Complementary_Slackness1;
        !           847:
        !           848:   procedure Complementary_Slackness
        !           849:                  ( tableau : in out Matrix; lastcol : in integer;
        !           850:                    rhs : in out Standard_Floating_Vectors.Vector;
        !           851:                    tol : in double_float;
        !           852:                    solution : out Standard_Floating_Vectors.Vector;
        !           853:                    columns : out Standard_Integer_Vectors.Vector;
        !           854:                    feasible : out boolean ) is
        !           855:
        !           856:   -- NOTE :
        !           857:   --   This version enumerates in a lexicographic order all candidates
        !           858:   --   for entering the basis and stops when a feasible solution has been
        !           859:   --   found.
        !           860:
        !           861:     feasi : boolean;
        !           862:     pivots : Standard_Integer_Vectors.Vector(tableau'first(2)..lastcol);
        !           863:     sol : Standard_Floating_Vectors.Vector(rhs'range) := (rhs'range => 0.0);
        !           864:     ind,rank : integer;
        !           865:
        !           866:   begin
        !           867:     for i in pivots'range loop  -- initialize vector of pivots
        !           868:       pivots(i) := i;
        !           869:     end loop;
        !           870:     Initialize(tableau,lastcol,rhs,sol,tol,pivots,feasi);
        !           871:     if feasi
        !           872:      then
        !           873:        if Norm(rhs,rhs'first+1) > tol  -- check whether residual > 0
        !           874:         then
        !           875:           if tableau'first(1)+1 > lastcol
        !           876:            then feasi := false;
        !           877:            else
        !           878:              ind := tableau'first(1)+1;
        !           879:              Next(tableau,lastcol,rhs,sol,pivots,tol,ind,rank,feasi);
        !           880:              if feasi
        !           881:               then Solve(tableau,rhs,tol,rank,sol);
        !           882:              end if;
        !           883:           end if;
        !           884:        end if;
        !           885:        if feasi and then (tableau'last(1) > lastcol)
        !           886:         then feasi := (Norm(rhs,lastcol+1) < tol);
        !           887:        end if;
        !           888:        if feasi and then (Norm(sol) < tol)
        !           889:         then feasi := (Norm(rhs) < tol);
        !           890:        end if;
        !           891:        solution := sol;
        !           892:        if tableau'last(1) <= lastcol
        !           893:         then
        !           894:           for i in tableau'range(1) loop
        !           895:             columns(i) := pivots(i);
        !           896:           end loop;
        !           897:         else
        !           898:           for i in tableau'first(2)..lastcol loop
        !           899:             columns(i) := pivots(i);
        !           900:           end loop;
        !           901:        end if;
        !           902:     end if;
        !           903:     feasible := feasi;
        !           904:   end Complementary_Slackness;
        !           905:
        !           906:   procedure Complementary_Slackness2
        !           907:                  ( tableau : in out Matrix; lastcol : in integer;
        !           908:                    rhs : in out Standard_Floating_Vectors.Vector;
        !           909:                    tol : in double_float;
        !           910:                    solution : out Standard_Floating_Vectors.Vector;
        !           911:                    columns : out Standard_Integer_Vectors.Vector;
        !           912:                    feasible : out boolean ) is
        !           913:
        !           914:   -- NOTE :
        !           915:   --   This version explicitly uses linear programming.
        !           916:
        !           917:   begin
        !           918:     Is_In_Cone(tableau,lastcol,rhs,tol,solution,columns,feasible);
        !           919:   end Complementary_Slackness2;
        !           920:
        !           921: end Floating_Linear_Inequalities;

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