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>