Annotation of OpenXM_contrib/PHC/Ada/Root_Counts/Implift/vertices.adb, Revision 1.1
1.1 ! maekawa 1: with Standard_Floating_Numbers; use Standard_Floating_Numbers;
! 2: with Standard_Integer_VecVecs; use Standard_Integer_VecVecs;
! 3: with Standard_Floating_Matrices; use Standard_Floating_Matrices;
! 4: with Dictionaries;
! 5: with Linear_Programming; use Linear_Programming;
! 6: with Integer_Face_Enumerators; use Integer_Face_Enumerators;
! 7:
! 8: with Integer_Vectors_Utilities; use Integer_Vectors_Utilities;
! 9: with Lists_of_Vectors_Utilities; use Lists_of_Vectors_Utilities;
! 10: with Transformations; use Transformations;
! 11: with Transforming_Integer_Vector_Lists; use Transforming_Integer_Vector_Lists;
! 12:
! 13: package body Vertices is
! 14:
! 15: function Is_In_Hull ( point : Standard_Integer_Vectors.Vector; l : List )
! 16: return boolean is
! 17:
! 18: fpt : Standard_Floating_Vectors.Vector(point'range);
! 19:
! 20: begin
! 21: for i in point'range loop
! 22: fpt(i) := double_float(point(i));
! 23: end loop;
! 24: return Is_In_Hull(fpt,l);
! 25: end Is_In_Hull;
! 26:
! 27: function Is_In_Hull ( point : Standard_Floating_Vectors.Vector; l : List )
! 28: return boolean is
! 29:
! 30: -- ALGORITHM:
! 31: -- The following linear program will be solved:
! 32: --
! 33: -- min u_0 + u_1 + .. + u_n
! 34: --
! 35: -- l_1*p_1i + l_2*p_2i + .. + l_m*p_mi + u_i*q_i = q_i i=1,2,..,n
! 36: --
! 37: -- l_1 + l_2 + .. + l_m + u_0 = 1
! 38: --
! 39: -- to determine whether q belongs to the convex hull spanned by the
! 40: -- vectors p_1,p_2,..,p_m.
! 41: -- If all u_i are zero and all constraints are satisfied,
! 42: -- then q belongs to the convex hull.
! 43:
! 44: -- CONSTANTS :
! 45:
! 46: n : constant natural := point'last;
! 47: m : constant natural := 2*n+2; -- number of constraints
! 48: nb : constant natural := Length_Of(l)+n+1; -- number of unknowns
! 49: eps : constant double_float := 10.0**(-10);
! 50:
! 51: -- VARIABLES :
! 52:
! 53: dic : matrix(0..m,0..nb);
! 54: sol : Standard_Floating_Vectors.vector(1..nb);
! 55: inbas : Standard_Integer_Vectors.Vector(1..m) := (1..m => 0);
! 56: outbas : Standard_Integer_Vectors.Vector(1..nb) := (1..nb => 0);
! 57: nit : natural := 0;
! 58: feasi : boolean;
! 59:
! 60: tmp : List;
! 61: pt : Link_to_Vector;
! 62: s : double_float;
! 63:
! 64: begin
! 65:
! 66: -- INITIALIZATION OF target :
! 67:
! 68: for i in 0..(nb-n-1) loop
! 69: dic(0,i) := 0.0; -- sum of the lambda's
! 70: end loop;
! 71: for i in (nb-n)..nb loop
! 72: dic(0,i) := -1.0; -- sum of the mu's
! 73: end loop;
! 74:
! 75: -- INITIALIZATION OF dic :
! 76:
! 77: for i in 0..(nb-n) loop
! 78: dic(m-1,i) := 1.0; -- sum of the lambda's + mu_0
! 79: dic(m,i) := -1.0;
! 80: end loop;
! 81: for i in (nb-n+1)..nb loop
! 82: dic(m-1,i) := 0.0;
! 83: dic(m,i) := 0.0;
! 84: end loop;
! 85: for i in 1..n loop
! 86: for j in (nb-n)..nb loop
! 87: if i /= j-nb+n
! 88: then dic(i,j) := 0.0;
! 89: dic(i+n,j) := 0.0;
! 90: end if;
! 91: end loop;
! 92: end loop;
! 93:
! 94: tmp := l;
! 95: for j in 1..(nb-n-1) loop
! 96: pt := Head_Of(tmp);
! 97: for i in pt'range loop
! 98: dic(i,j) := double_float(pt(i));
! 99: dic(i+n,j) := -double_float(pt(i));
! 100: end loop;
! 101: tmp := Tail_Of(tmp);
! 102: end loop;
! 103:
! 104: for i in point'range loop
! 105: dic(i,0) := point(i);
! 106: dic(i+n,0) := -point(i);
! 107: dic(i,i+nb-n) := point(i);
! 108: dic(i+n,i+nb-n) := -point(i);
! 109: end loop;
! 110:
! 111: -- SOLVE THE LINEAR PROGRAM :
! 112:
! 113: Dictionaries.Init_Basis(inbas,outbas);
! 114: Dual_Simplex(dic,eps,inbas,outbas,nit,feasi);
! 115: if not feasi
! 116: then return false;
! 117: else
! 118: sol := Dictionaries.Primal_Solution(dic,inbas,outbas);
! 119:
! 120: -- CHECK THE SOLUTION :
! 121:
! 122: s := 0.0;
! 123: for i in 1..(nb-n-1) loop
! 124: s := s + sol(i);
! 125: end loop;
! 126: if abs(s - 1.0) > eps
! 127: then return false;
! 128: end if;
! 129: s := 0.0;
! 130: for i in (nb-n)..nb loop
! 131: s := s + sol(i);
! 132: end loop;
! 133: if abs(s) > eps
! 134: then return false;
! 135: end if;
! 136:
! 137: return true;
! 138:
! 139: end if;
! 140:
! 141: end Is_In_Hull;
! 142:
! 143: function Vertex_Points ( l : List ) return List is
! 144:
! 145: result,result_last : List;
! 146: tmp,rest,origrest,rest_last : List;
! 147: pt : Link_to_Vector;
! 148:
! 149: begin
! 150: if Is_Null(l) or else Is_Null(Tail_Of(l))
! 151: then return l;
! 152: else Copy(Tail_Of(l),rest);
! 153: origrest := rest;
! 154: rest_last := rest;
! 155: while not Is_Null(Tail_Of(rest_last)) loop
! 156: rest_last := Tail_Of(rest_last);
! 157: end loop;
! 158: tmp := l;
! 159: for i in 1..Length_Of(l) loop
! 160: pt := Head_Of(tmp);
! 161: if not Is_In_Hull(pt.all,rest)
! 162: then Append(result,result_last,pt.all);
! 163: Append(rest,rest_last,pt.all);
! 164: end if;
! 165: rest := Tail_Of(rest);
! 166: tmp := Tail_Of(tmp);
! 167: end loop;
! 168: Clear(origrest);
! 169: return result;
! 170: end if;
! 171: end Vertex_Points;
! 172:
! 173: function Vertex_Points1 ( l : List ) return List is
! 174:
! 175: len : constant natural := Length_Of(l);
! 176: pts : VecVec(1..len) := Shallow_Create(l);
! 177: result,result_last : List;
! 178:
! 179: procedure Collect_Vertex ( i : in integer; cont : out boolean ) is
! 180: begin
! 181: Append(result,result_last,pts(i).all);
! 182: cont := true;
! 183: end Collect_Vertex;
! 184: procedure Enum_Vertices is new Enumerate_Vertices(Collect_Vertex);
! 185:
! 186: begin
! 187: Enum_Vertices(pts);
! 188: return result;
! 189: end Vertex_Points1;
! 190:
! 191: procedure Add ( pt : Link_to_Vector; l : in out List ) is
! 192:
! 193: -- DESCRIPTION :
! 194: -- Constructs the point to the list, but without sharing.
! 195:
! 196: newpt : Link_to_Vector := new Vector'(pt.all);
! 197:
! 198: begin
! 199: Construct(newpt,l);
! 200: end Add;
! 201:
! 202: function Extremal_Points ( l : List; v : Link_to_Vector ) return List is
! 203:
! 204: min,max,sp : integer;
! 205: tmp,res : List;
! 206: minpt,maxpt,pt : Link_to_Vector;
! 207:
! 208: begin
! 209: if Length_Of(l) <= 1
! 210: then Copy(l,res);
! 211: else pt := Head_Of(l);
! 212: min := pt*v; max := min;
! 213: minpt := pt; maxpt := pt;
! 214: tmp := Tail_Of(l);
! 215: while not Is_Null(tmp) loop
! 216: pt := Head_Of(tmp);
! 217: sp := pt*v;
! 218: if sp > max
! 219: then max := sp; maxpt := pt;
! 220: elsif sp < min
! 221: then min := sp; minpt := pt;
! 222: end if;
! 223: tmp := Tail_Of(tmp);
! 224: end loop;
! 225: Add(minpt,res);
! 226: if min /= max
! 227: then Add(maxpt,res);
! 228: end if;
! 229: end if;
! 230: return res;
! 231: end Extremal_Points;
! 232:
! 233: function Extremal_Points ( k,n : natural; exl,l : List ) return List is
! 234:
! 235: res,tmp,nres : List;
! 236: iv : VecVec(1..k);
! 237: v : Link_to_Vector := new Vector(1..n);
! 238: sp : integer;
! 239: pt : Link_to_Vector;
! 240: done : boolean;
! 241:
! 242: begin
! 243: tmp := exl;
! 244: for j in iv'range loop
! 245: iv(j) := Head_Of(tmp);
! 246: tmp := Tail_Of(tmp);
! 247: end loop;
! 248: v := Compute_Normal(iv);
! 249: sp := Head_Of(exl)*v;
! 250: nres := Extremal_Points(l,v);
! 251: tmp := nres;
! 252: res := exl;
! 253: done := false;
! 254: while not done and not Is_Null(tmp) loop
! 255: pt := Head_Of(tmp);
! 256: if pt*v /= sp
! 257: then Add(pt,res);
! 258: done := true;
! 259: else tmp := Tail_Of(tmp);
! 260: end if;
! 261: end loop;
! 262: Clear(v);
! 263: return res;
! 264: end Extremal_Points;
! 265:
! 266: function Max_Extremal_Points ( k,n : natural; exl,l : List ) return List is
! 267:
! 268: res,tmp,nres : List;
! 269: iv : VecVec(1..k);
! 270: v : Link_to_Vector := new Vector(1..n);
! 271: sp : integer;
! 272: pt : Link_to_Vector;
! 273: done : boolean;
! 274:
! 275: begin
! 276: tmp := exl;
! 277: for j in iv'range loop
! 278: iv(j) := Head_Of(tmp);
! 279: tmp := Tail_Of(tmp);
! 280: end loop;
! 281: v := Compute_Normal(iv);
! 282: sp := Head_Of(exl)*v;
! 283: nres := Extremal_Points(l,v);
! 284: --put("The computed normal : "); put(v); new_line;
! 285: --put("The inner product : "); put(sp,1); new_line;
! 286: --put_line("The list of extremal points :"); put(nres);
! 287: tmp := nres;
! 288: Copy(exl,res);
! 289: done := false;
! 290: while not done and not Is_Null(tmp) loop
! 291: pt := Head_Of(tmp);
! 292: if pt*v /= sp
! 293: then Add(pt,res);
! 294: done := true;
! 295: else tmp := Tail_Of(tmp);
! 296: end if;
! 297: end loop;
! 298: Clear(nres);
! 299: if not done
! 300: then -- for all points x in l : <x,v> = sp
! 301: if n >= 2
! 302: then declare
! 303: i : integer := Pivot(v);
! 304: t,invt : Transfo;
! 305: texl,tl,tres : List;
! 306: begin
! 307: if i <= v'last
! 308: then t := Build_Transfo(v,i);
! 309: invt := Invert(t);
! 310: texl := Transform_and_Reduce(t,i,exl);
! 311: tl := Transform_and_Reduce(t,i,l);
! 312: tres := Max_Extremal_Points(k,n-1,texl,tl);
! 313: --put("The normal : "); put(v); new_line;
! 314: --put_line("The list of points : "); put(l);
! 315: --put_line("The list of extremal points :"); put(exl);
! 316: --put_line("The transformed list of points : "); put(tl);
! 317: --put_line("The transformed list of extremal points : ");
! 318: --put(texl);
! 319: --put_line("The computed transformed extremal points : ");
! 320: --put(tres);
! 321: --put("k : "); put(k,1); new_line;
! 322: Clear(t); Clear(texl); Clear(tl);
! 323: if Length_Of(tres) = k+1
! 324: then res := Insert_and_Transform(tres,i,sp,invt);
! 325: else Copy(exl,res);
! 326: end if;
! 327: --put_line("The computed extremal points : "); put(res);
! 328: Clear(tres); --responsible for segmentation violation...
! 329: Clear(invt);
! 330: else Copy(exl,res);
! 331: end if;
! 332: end;
! 333: else Copy(exl,res);
! 334: end if;
! 335: end if;
! 336: Clear(v);
! 337: --put_line("The new list of extremal points : "); put(res);
! 338: return res;
! 339: end Max_Extremal_Points;
! 340:
! 341: function Extremal_Points ( n : natural; l : List ) return List is
! 342:
! 343: res : List;
! 344: nor : Link_to_Vector := new Vector'(1..n => 1);
! 345: k : natural;
! 346:
! 347: begin
! 348: res := Extremal_Points(l,nor);
! 349: Clear(nor);
! 350: if Length_Of(res) < 2
! 351: then return res;
! 352: else k := 2;
! 353: while k < n+1 loop
! 354: res := Extremal_Points(k,n,res,l);
! 355: exit when Length_Of(res) = k;
! 356: k := k+1;
! 357: end loop;
! 358: return res;
! 359: end if;
! 360: end Extremal_Points;
! 361:
! 362: function Two_Extremal_Points ( n : natural; l : List ) return List is
! 363:
! 364: -- DESCRIPTION :
! 365: -- Computes two extremal points of the list l.
! 366:
! 367: res,tmp : List;
! 368: pt,minpt,maxpt : Link_to_Vector;
! 369: min,max : integer;
! 370:
! 371: begin
! 372: if Length_Of(l) <= 2
! 373: then Copy(l,res);
! 374: else for i in 1..n loop
! 375: pt := Head_Of(l);
! 376: max := pt(i); min := max;
! 377: maxpt := pt; minpt := pt;
! 378: tmp := Tail_Of(l);
! 379: while not Is_Null(tmp) loop
! 380: pt := Head_Of(tmp);
! 381: if pt(i) < min
! 382: then min := pt(i); minpt := pt;
! 383: elsif pt(i) > max
! 384: then max := pt(i); maxpt := pt;
! 385: end if;
! 386: tmp := Tail_Of(tmp);
! 387: end loop;
! 388: if Is_Null(res)
! 389: then Add(minpt,res);
! 390: if min /= max
! 391: then Add(maxpt,res);
! 392: end if;
! 393: else pt := Head_Of(res);
! 394: if pt.all /= minpt.all
! 395: then Add(minpt,res);
! 396: elsif pt.all /= maxpt.all
! 397: then Add(maxpt,res);
! 398: end if;
! 399: end if;
! 400: exit when (Length_Of(res) = 2);
! 401: end loop;
! 402: end if;
! 403: return res;
! 404: end Two_Extremal_Points;
! 405:
! 406: function Max_Extremal_Points ( n : natural; l : List ) return List is
! 407:
! 408: res,wl,wres,newres : List;
! 409: k : natural;
! 410: nullvec,shiftvec : Link_to_Vector;
! 411: -- shifted : boolean;
! 412:
! 413: begin
! 414: if Length_Of(l) <= 2
! 415: then Copy(l,res);
! 416: else res := Two_Extremal_Points(n,l);
! 417: k := Length_Of(res);
! 418: if k = 2
! 419: then --nullvec := new Vector'(1..n => 0);
! 420: --if Is_In(nullvec,res)
! 421: -- then Copy(l,wl);
! 422: -- Copy(res,wres);
! 423: -- shifted := false;
! 424: -- else shiftvec := Head_Of(res);
! 425: -- wl := Shift(shiftvec,l);
! 426: -- wres := Shift(shiftvec,res);
! 427: -- shifted := true;
! 428: --end if;
! 429: --Clear(nullvec);
! 430: Copy(res,wres);
! 431: while k < n+1 loop
! 432: newres := Max_Extremal_Points(k,n,wres,l);
! 433: Copy(newres,wres);
! 434: exit when Length_Of(wres) = k;
! 435: k := k+1;
! 436: end loop;
! 437: res := wres;
! 438: -- Clear(res);
! 439: -- if shifted
! 440: -- then Min_Vector(shiftvec);
! 441: -- res := Shift(shiftvec,wres);
! 442: -- Clear(wres);
! 443: -- else Copy(wres,res);
! 444: -- end if;
! 445: -- Clear(wl);
! 446: end if;
! 447: end if;
! 448: return res;
! 449: end Max_Extremal_Points;
! 450:
! 451: end Vertices;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>