Annotation of OpenXM_contrib/PHC/Ada/Root_Counts/Implift/mixed_homotopy_continuation.adb, Revision 1.1
1.1 ! maekawa 1: with Standard_Floating_Numbers; use Standard_Floating_Numbers;
! 2: with Standard_Complex_Numbers; use Standard_Complex_Numbers;
! 3: with Standard_Complex_Numbers_Polar; use Standard_Complex_Numbers_Polar;
! 4: with Standard_Random_Numbers; use Standard_Random_Numbers;
! 5: with Standard_Integer_Vectors;
! 6: with Standard_Integer_Vectors_io; use Standard_Integer_Vectors_io;
! 7: with Standard_Complex_Vectors;
! 8: with Standard_Complex_Norms_Equals; use Standard_Complex_Norms_Equals;
! 9: with Standard_Complex_Matrices; use Standard_Complex_Matrices;
! 10: with Standard_Complex_Polynomials;
! 11: with Standard_Complex_Laur_Polys; use Standard_Complex_Laur_Polys;
! 12: with Standard_Complex_Poly_Systems; use Standard_Complex_Poly_Systems;
! 13: with Standard_Complex_Poly_Functions; use Standard_Complex_Poly_Functions;
! 14: with Standard_Complex_Poly_SysFun; use Standard_Complex_Poly_SysFun;
! 15: with Standard_Complex_Jaco_Matrices; use Standard_Complex_Jaco_Matrices;
! 16: with Standard_Poly_Laur_Convertors; use Standard_Poly_Laur_Convertors;
! 17: with Standard_Laur_Poly_Convertors; use Standard_Laur_Poly_Convertors;
! 18: with Lists_of_Integer_Vectors; use Lists_of_Integer_Vectors;
! 19: with Integer_Support_Functions; use Integer_Support_Functions;
! 20: with Arrays_of_Integer_Vector_Lists; use Arrays_of_Integer_Vector_Lists;
! 21: with Increment_and_Fix_Continuation; use Increment_and_Fix_Continuation;
! 22: with Standard_Root_Refiners; use Standard_Root_Refiners;
! 23: with Integer_Vectors_Utilities; use Integer_Vectors_Utilities;
! 24: with Lists_of_Vectors_Utilities; use Lists_of_Vectors_Utilities;
! 25: with Arrays_of_Lists_Utilities; use Arrays_of_Lists_Utilities;
! 26: with Transformations; use Transformations;
! 27: with Transforming_Solutions; use Transforming_Solutions;
! 28: with Transforming_Laurent_Systems; use Transforming_Laurent_Systems;
! 29: with Transforming_Integer_Vector_Lists; use Transforming_Integer_Vector_Lists;
! 30: with Power_Lists; use Power_Lists;
! 31: with Volumes;
! 32: with Durand_Kerner;
! 33:
! 34: package body Mixed_Homotopy_Continuation is
! 35:
! 36: -- INVARIANT CONDITION :
! 37: -- The procedures and functions in this package `mirror' corresponding
! 38: -- routines in the package Volumes.
! 39:
! 40: -- AUXILIARIES :
! 41:
! 42: type bar is array ( integer range <> ) of boolean;
! 43:
! 44: function Interchange2 ( p : Laur_Sys; index : integer ) return Laur_Sys is
! 45:
! 46: -- DESCRIPTION :
! 47: -- Returns a polynomial system where the first equation is interchanged
! 48: -- with the equation given by the index.
! 49:
! 50: res : Laur_Sys(p'range);
! 51:
! 52: begin
! 53: if index = p'first
! 54: then res := p;
! 55: else res(res'first) := p(index);
! 56: res(index) := p(p'first);
! 57: res(res'first+1..index-1) := p(p'first+1..index-1);
! 58: res(index+1..res'last) := p(index+1..p'last);
! 59: end if;
! 60: return res;
! 61: end Interchange2;
! 62:
! 63: procedure Interchange2 ( adl : in out Array_of_Lists; index : integer ) is
! 64:
! 65: -- DESCRIPTION :
! 66: -- Interchanges the first list with the list given by the index.
! 67:
! 68: tmp : List;
! 69:
! 70: begin
! 71: if index /= adl'first
! 72: then tmp := adl(adl'first);
! 73: adl(adl'first) := adl(index);
! 74: adl(index) := tmp;
! 75: end if;
! 76: end Interchange2;
! 77:
! 78: function Permute ( perm : Standard_Integer_Vectors.Vector; p : Laur_Sys )
! 79: return laur_Sys is
! 80:
! 81: -- DESCRIPTION :
! 82: -- Returns a permuted polynomial system.
! 83:
! 84: res : Laur_Sys(p'range);
! 85:
! 86: begin
! 87: for i in p'range loop
! 88: res(i) := p(perm(i));
! 89: end loop;
! 90: return res;
! 91: end Permute;
! 92:
! 93: function Initial_Degrees ( p : Poly ) return Degrees is
! 94:
! 95: -- DESCRIPTION :
! 96: -- Returns the initial degrees of the polynomial p.
! 97:
! 98: init : Degrees;
! 99:
! 100: procedure Init_Term ( t : in Term; cont : out boolean ) is
! 101: begin
! 102: init := new Standard_Integer_Vectors.Vector'(t.dg.all);
! 103: cont := false;
! 104: end Init_Term;
! 105: procedure Initial_Term is new Visiting_Iterator (Init_Term);
! 106:
! 107: begin
! 108: Initial_Term(p);
! 109: return init;
! 110: end Initial_Degrees;
! 111:
! 112: procedure Binomial ( p : in Poly;
! 113: d : out Standard_Integer_Vectors.Link_to_Vector;
! 114: k : in out integer; c : in out Complex_Number ) is
! 115:
! 116: -- DESCRIPTION :
! 117: -- p consists of two terms, this procedure gets the degrees d and
! 118: -- the constant c of the binomial equation.
! 119:
! 120: first : boolean := true;
! 121: dd : Degrees;
! 122:
! 123: procedure Scan_Term ( t : in Term; cont : out boolean ) is
! 124: begin
! 125: if first
! 126: then dd := new Standard_Integer_Vectors.Vector'(t.dg.all);
! 127: c := t.cf;
! 128: first := false;
! 129: else k := dd'first - 1;
! 130: for i in dd'range loop
! 131: dd(i) := dd(i) - t.dg(i);
! 132: if k < dd'first and then dd(i) /= 0
! 133: then k := i;
! 134: end if;
! 135: end loop;
! 136: c := -t.cf/c;
! 137: end if;
! 138: cont := true;
! 139: end Scan_Term;
! 140: procedure Scan_Terms is new Visiting_Iterator (Scan_Term);
! 141:
! 142: begin
! 143: Scan_Terms(p);
! 144: d := new Standard_Integer_Vectors.Vector'(dd.all);
! 145: Standard_Integer_Vectors.Clear(Standard_Integer_Vectors.Link_to_Vector(dd));
! 146: end Binomial;
! 147:
! 148: procedure Normalize ( p : in Laur_Sys; dl : in out List;
! 149: wp : in out Laur_Sys; shifted : out boolean ) is
! 150:
! 151: -- DESCRIPTION :
! 152: -- Makes sure that the first element of dl contains all zeroes.
! 153:
! 154: -- REQUIRED :
! 155: -- The list dl is not empty.
! 156:
! 157: -- ON ENTRY :
! 158: -- p a Laurent polynomial system;
! 159: -- dl the power list of p(p'first).
! 160:
! 161: -- ON RETURN :
! 162: -- dl the first element of contains all zeroes,
! 163: -- therefore dl has been shifted;
! 164: -- wp a Laurent polynomial system where
! 165: -- dl is the power list of wp(wp'first);
! 166: -- shifted is true if dl has been shifted.
! 167:
! 168: use Standard_Integer_Vectors;
! 169:
! 170: first : Link_to_Vector := Head_Of(dl);
! 171: nullvec : Vector(first'range) := (first'range => 0);
! 172: shiftvec : Link_to_Vector;
! 173:
! 174: begin
! 175: if not Is_In(dl,nullvec)
! 176: then shiftvec := Graded_Max(dl);
! 177: Shift(dl,shiftvec);
! 178: Clear(shiftvec);
! 179: Copy(p,wp);
! 180: for i in p'range loop
! 181: Shift(wp(i));
! 182: end loop;
! 183: else wp := p;
! 184: shifted := false;
! 185: end if;
! 186: Move_to_Front(dl,nullvec);
! 187: end Normalize;
! 188:
! 189: function Evaluate ( p : Poly; x : Complex_Number; k : integer )
! 190: return Poly is
! 191:
! 192: -- DESCRIPTION :
! 193: -- This function returns a polynomial where the kth unknown has
! 194: -- been replaced by x.
! 195: -- It is important to use this function as the term order in p
! 196: -- must remain the same!
! 197:
! 198: res : Poly;
! 199:
! 200: procedure Evaluate_Term ( t : in out Term; cont : out boolean ) is
! 201:
! 202: fac : Complex_Number;
! 203: pow : natural;
! 204:
! 205: begin
! 206: if t.dg(k) < 0
! 207: then fac := Create(1.0)/x;
! 208: pow := -t.dg(k);
! 209: else fac := x;
! 210: pow := t.dg(k);
! 211: end if;
! 212: for i in 1..pow loop
! 213: t.cf := t.cf * fac;
! 214: end loop;
! 215: declare
! 216: tmp : constant Standard_Integer_Vectors.Vector := t.dg.all;
! 217: begin
! 218: Clear(t);
! 219: t.dg := new Standard_Integer_Vectors.Vector'(Reduce(tmp,k));
! 220: end;
! 221: cont := true;
! 222: end Evaluate_Term;
! 223: procedure Evaluate_Terms is new Changing_Iterator (Evaluate_Term);
! 224:
! 225: begin
! 226: Copy(p,res);
! 227: Evaluate_Terms(res);
! 228: return res;
! 229: end Evaluate;
! 230:
! 231: function Re_Arrange ( p : poly ) return Poly is
! 232:
! 233: -- DESCRIPTION :
! 234: -- Returns a polynomial whose terms are sorted
! 235: -- in graded lexicographical ordening.
! 236:
! 237: res : Poly := Null_Poly;
! 238:
! 239: procedure Re_Arrange_Term ( t : in Term; cont : out boolean ) is
! 240: begin
! 241: Add(res,t);
! 242: cont := true;
! 243: end Re_Arrange_Term;
! 244: procedure Re_Arrange_Terms is new Visiting_Iterator (Re_Arrange_Term);
! 245:
! 246: begin
! 247: Re_Arrange_Terms(p);
! 248: return res;
! 249: end Re_Arrange;
! 250:
! 251: function Substitute ( p : Poly; v : Standard_Complex_Vectors.Vector;
! 252: k : integer ) return Poly is
! 253:
! 254: -- DESCRIPTION :
! 255: -- Substitutes the values in v into the polynomial p,
! 256: -- starting at the last unknowns of p.
! 257:
! 258: init : Degrees := Initial_Degrees(p);
! 259: index : integer := init'last;
! 260: res,tmp : Poly;
! 261:
! 262: begin
! 263: if index = k
! 264: then index := index - 1;
! 265: res := Evaluate(p,v(v'last),index);
! 266: else res := Evaluate(p,v(v'last),index);
! 267: end if;
! 268: for i in reverse v'first..(v'last-1) loop
! 269: index := index - 1;
! 270: if index = k
! 271: then index := index - 1;
! 272: end if;
! 273: tmp := Evaluate(res,v(i),index);
! 274: Clear(res); Copy(tmp,res); Clear(tmp);
! 275: end loop;
! 276: Standard_Integer_Vectors.Clear
! 277: (Standard_Integer_Vectors.Link_to_Vector(init));
! 278: return res;
! 279: end Substitute;
! 280:
! 281: procedure Refine_and_Concat
! 282: ( p : in Laur_Sys;
! 283: newsols,sols,sols_last : in out Solution_List ) is
! 284:
! 285: -- DESCRIPTION :
! 286: -- This procedure refines the solutions of a given
! 287: -- polynomial system and adds them to the solution list.
! 288: -- This can be very useful for eliminating rounding errors
! 289: -- after transformating the solutions.
! 290:
! 291: pp : Poly_Sys(p'range) := Laurent_to_Polynomial_System(p);
! 292: numb : natural := 0;
! 293:
! 294: begin
! 295: Silent_Root_Refiner(pp,newsols,10.0**(-12),10.0**(-12),10.0**(-8),numb,5);
! 296: Concat(sols,sols_last,newsols);
! 297: Clear(pp); Shallow_Clear(newsols);
! 298: end Refine_and_Concat;
! 299:
! 300: procedure Refine_and_Concat
! 301: ( file : in file_type; p : in Laur_Sys;
! 302: newsols,sols,sols_last : in out Solution_List ) is
! 303:
! 304: -- DESCRIPTION :
! 305: -- This procedure refines the solutions of a given
! 306: -- polynomial system and adds them to the solution list.
! 307: -- This can be very useful for eliminating rounding errors
! 308: -- after transformating the solutions.
! 309:
! 310: pp : Poly_Sys(p'range) := Laurent_to_Polynomial_System(p);
! 311: numb : natural := 0;
! 312:
! 313: begin
! 314: Reporting_Root_Refiner
! 315: (file,pp,newsols,10.0**(-12),10.0**(-12),10.0**(-8),numb,5,false);
! 316: Concat(sols,sols_last,newsols);
! 317: Clear(pp); Shallow_Clear(newsols);
! 318: end Refine_and_Concat;
! 319:
! 320: procedure Write_Direction
! 321: ( file : in file_type;
! 322: v : in Standard_Integer_Vectors.Link_to_Vector ) is
! 323: begin
! 324: put(file,"++++ considering direction "); put(file,v);
! 325: put_line(file," ++++");
! 326: end Write_Direction;
! 327:
! 328: -- INTERMEDIATE LAYER :
! 329:
! 330: procedure Mixed_Continue
! 331: ( file : in file_type; p : in Laur_Sys;
! 332: k : in integer; m : in Standard_Integer_Vectors.Vector;
! 333: sols : in out Solution_List ) is
! 334:
! 335: -- DESCRIPTION :
! 336: -- This continuation routine computes a part of the solution list
! 337: -- of a Laurent polynomial system.
! 338:
! 339: -- ON ENTRY :
! 340: -- file a file where the intermediate results are written;
! 341: -- p the transformed Laurent polynomial system to be solved;
! 342: -- k the index;
! 343: -- m m(k) = p1(v), m(k/=l) = Maximal_Degree(p(l),k);
! 344: -- sols the start solutions.
! 345:
! 346: -- ON RETURN :
! 347: -- sols the computed solutions.
! 348:
! 349: h : Laur_Sys(p'range);
! 350: hp : Poly_Sys(h'range);
! 351: hpe : Eval_Poly_Sys(hp'range);
! 352: j : Jaco_Mat(p'range,p'first..p'last+1);
! 353: je : Eval_Jaco_Mat(j'range(1),j'range(2));
! 354:
! 355: function Construct_Homotopy
! 356: ( p : Laur_Sys; k : integer;
! 357: m : Standard_Integer_Vectors.Vector ) return Laur_Sys is
! 358:
! 359: res : Laur_Sys(p'range);
! 360: ran : Complex_Number;
! 361: re : boolean;
! 362: zeroes : Degrees := new Standard_Integer_Vectors.Vector'(p'range => 0);
! 363:
! 364: function Construct_First_Polynomial
! 365: ( pp : Poly; max : integer ) return Poly is
! 366:
! 367: r : Poly := Null_Poly;
! 368:
! 369: procedure Construct_Term ( t : in Term; cont : out boolean ) is
! 370:
! 371: rt : Term;
! 372:
! 373: begin
! 374: rt.cf := t.cf;
! 375: rt.dg := new Standard_Integer_Vectors.Vector(t.dg'first..t.dg'last+1);
! 376: rt.dg(t.dg'range) := t.dg.all;
! 377: rt.dg(k) := -t.dg(k) + max;
! 378: if Equal(t.dg,zeroes)
! 379: then rt.dg(rt.dg'last) := 0;
! 380: re := ( IMAG_PART(rt.cf) + 1.0 = 1.0 );
! 381: else rt.dg(rt.dg'last) := rt.dg(k);
! 382: end if;
! 383: Add(r,rt);
! 384: Clear(rt);
! 385: cont := true;
! 386: end Construct_Term;
! 387: procedure Construct_Terms is new Visiting_Iterator(Construct_Term);
! 388:
! 389: begin
! 390: Construct_Terms(pp);
! 391: Standard_Integer_Vectors.Clear
! 392: (Standard_Integer_Vectors.Link_to_Vector(zeroes));
! 393: return r;
! 394: end Construct_First_Polynomial;
! 395:
! 396: function Construct_Polynomial ( pp : Poly; max : integer ) return Poly is
! 397:
! 398: r : Poly := Null_Poly;
! 399:
! 400: procedure Construct_Term ( t : in Term; cont : out boolean ) is
! 401:
! 402: rt : Term;
! 403:
! 404: begin
! 405: rt.cf := t.cf;
! 406: rt.dg := new Standard_Integer_Vectors.Vector(t.dg'first..t.dg'last+1);
! 407: rt.dg(t.dg'range) := t.dg.all;
! 408: rt.dg(k) := -t.dg(k) + max;
! 409: rt.dg(rt.dg'last) := rt.dg(k);
! 410: Add(r,rt);
! 411: Clear(rt);
! 412: cont := true;
! 413: end Construct_Term;
! 414: procedure Construct_Terms is new Visiting_Iterator(Construct_Term);
! 415:
! 416: begin
! 417: Construct_Terms(pp);
! 418: return r;
! 419: end Construct_Polynomial;
! 420:
! 421: begin
! 422: res(res'first) := Construct_First_Polynomial(p(p'first),m(m'first));
! 423: for i in p'first+1..p'last loop
! 424: res(i) := Construct_Polynomial(p(i),m(i));
! 425: end loop;
! 426: if re
! 427: then for i in res'range loop
! 428: ran := Random;
! 429: Mul(res(i),ran);
! 430: end loop;
! 431: end if;
! 432: return res;
! 433: end Construct_Homotopy;
! 434:
! 435: function To_Be_Removed ( flag : in natural ) return boolean is
! 436: begin
! 437: return ( flag /= 1 );
! 438: end To_Be_Removed;
! 439: procedure Extract_Regular_Solutions is
! 440: new Standard_Complex_Solutions.Delete(To_Be_Removed);
! 441:
! 442: begin
! 443: h := Construct_Homotopy(p,k,m); -- CONSTRUCTION OF HOMOTOPY
! 444: hp := Laurent_to_Polynomial_System(h);
! 445: hpe := Create(hp);
! 446: j := Create(hp);
! 447: je := Create(j);
! 448: declare -- CONTINUATION
! 449:
! 450: use Standard_Complex_Vectors;
! 451:
! 452: function Eval ( x : Vector; t : Complex_Number ) return Vector is
! 453:
! 454: xt : Vector(x'first..x'last+1);
! 455:
! 456: begin
! 457: xt(x'range) := x;
! 458: xt(xt'last) := t;
! 459: return Eval(hpe,xt);
! 460: end Eval;
! 461:
! 462: function dHt ( x : Vector; t : Complex_Number ) return Vector is
! 463:
! 464: xt : Vector(x'first..x'last+1);
! 465: res : Vector(p'range);
! 466:
! 467: begin
! 468: xt(x'range) := x;
! 469: xt(xt'last) := t;
! 470: for i in res'range loop
! 471: res(i) := Eval(je(i,xt'last),xt);
! 472: end loop;
! 473: return res;
! 474: end dHt;
! 475:
! 476: function dHx ( x : Vector; t : Complex_Number ) return Matrix is
! 477:
! 478: xt : Vector(x'first..x'last+1);
! 479: m : Matrix(x'range,x'range);
! 480:
! 481: begin
! 482: xt(x'range) := x;
! 483: xt(xt'last) := t;
! 484: for i in m'range(1) loop
! 485: for j in m'range(1) loop
! 486: m(i,j) := Eval(je(i,j),xt);
! 487: end loop;
! 488: end loop;
! 489: return m;
! 490: end dHx;
! 491:
! 492: procedure Invert ( k : in integer; sols : in out Solution_List ) is
! 493:
! 494: -- DESCRIPTION :
! 495: -- For all solutions s in sols : s.v(k) := 1/s.v(k).
! 496:
! 497: tmp : Solution_List := sols;
! 498:
! 499: begin
! 500: while not Is_Null(tmp) loop
! 501: declare
! 502: l : Link_to_Solution := Head_Of(tmp);
! 503: begin
! 504: l.v(k) := Create(1.0)/l.v(k);
! 505: l.t := Create(0.0);
! 506: end;
! 507: tmp := Tail_Of(tmp);
! 508: end loop;
! 509: end Invert;
! 510:
! 511: procedure Cont is new Reporting_Continue(Max_Norm,Eval,dHt,dHx);
! 512:
! 513: begin
! 514: Invert(k,sols);
! 515: Cont(file,sols,false);
! 516: Invert(k,sols);
! 517: Extract_Regular_Solutions(sols);
! 518: end;
! 519: Clear(h); Clear(hp); Clear(hpe); Clear(j); Clear(je);
! 520: end Mixed_Continue;
! 521:
! 522: -- THE SOLVERS :
! 523:
! 524: function One_Unknown_Solve ( p : Poly )
! 525: return Standard_Complex_Vectors.Vector is
! 526:
! 527: -- DESCRIPTION :
! 528: -- Returns the solution vector of p, a polynomial in one unknown.
! 529: -- p will be solved by using the method of Durand-Kerner.
! 530:
! 531: p1 : Poly := Re_Arrange(p);
! 532: init : Degrees := Initial_Degrees(p1);
! 533: index : integer := init'first;
! 534: min : integer := -Minimal_Degree(p1,index);
! 535: pv : Standard_Complex_Vectors.Vector(0..Degree(p1)+min);
! 536: z,res : Standard_Complex_Vectors.Vector(1..pv'last);
! 537: maxsteps : constant natural := 10;
! 538: eps : constant double_float := 10.0**(-10);
! 539: nb : integer := pv'last + 1;
! 540:
! 541: procedure Store_Coeff ( t : in Term; cont : out boolean ) is
! 542: begin
! 543: nb := nb - 1;
! 544: if t.dg(index) = (nb - min)
! 545: then pv(nb) := t.cf;
! 546: else for i in reverse nb..(t.dg(index)+min+1) loop
! 547: pv(i) := Create(0.0);
! 548: end loop;
! 549: nb := t.dg(index) + min;
! 550: pv(nb) := t.cf;
! 551: end if;
! 552: cont := true;
! 553: end Store_Coeff;
! 554: procedure Polynomial_To_Vector is new Visiting_Iterator (Store_Coeff);
! 555:
! 556: procedure Write ( step : in natural;
! 557: z,res : in Standard_Complex_Vectors.Vector ) is
! 558: begin
! 559: null; -- no output desired during the iterations
! 560: end Write;
! 561: procedure DuKe is new Durand_Kerner (Write);
! 562:
! 563: begin
! 564: for i in pv'range loop -- initialize coefficient vector
! 565: pv(i) := Create(0.0);
! 566: end loop;
! 567: Standard_Integer_Vectors.Clear
! 568: (Standard_Integer_Vectors.Link_to_Vector(init));
! 569: Polynomial_To_Vector(p1);
! 570: Clear(p1);
! 571: for i in z'range loop
! 572: z(i) := Random;
! 573: res(i) := z(i);
! 574: end loop;
! 575: DuKe(pv,z,res,maxsteps,eps,nb);
! 576: return z;
! 577: end One_Unknown_Solve;
! 578:
! 579: procedure One_Unknown_Solve ( p : in Poly; sols : in out Solution_List ) is
! 580:
! 581: -- DESCRIPTION :
! 582: -- If p is a polynomial in one unknown,
! 583: -- p can be solved efficiently by the application of Durand-Kerner.
! 584:
! 585: init : Degrees := Initial_Degrees(p);
! 586:
! 587: function Make_Solutions ( x : in Standard_Complex_Vectors.Vector )
! 588: return Solution_List is
! 589:
! 590: res,res_last : Solution_List;
! 591: s : Solution(1);
! 592:
! 593: begin
! 594: s.m := 1;
! 595: s.t := Create(0.0);
! 596: for i in x'range loop
! 597: s.v(init'first) := x(i);
! 598: Append(res,res_last,s);
! 599: end loop;
! 600: return res;
! 601: end Make_Solutions;
! 602:
! 603: begin
! 604: sols := Make_Solutions(One_Unknown_Solve(p));
! 605: Standard_Integer_Vectors.Clear
! 606: (Standard_Integer_Vectors.Link_to_Vector(init));
! 607: end One_Unknown_Solve;
! 608:
! 609: procedure Two_Terms_Solve
! 610: ( file : in file_type; p : in Laur_Sys;
! 611: tv : in Tree_of_Vectors; bkk : out natural;
! 612: sols : in out Solution_List ) is
! 613:
! 614: -- DESCRIPTION :
! 615: -- The first polynomial of p consists of two terms.
! 616: -- A binomial system can be solved efficiently by
! 617: -- transforming and using de Moivre's rule.
! 618:
! 619: d : Standard_Integer_Vectors.Link_to_Vector;
! 620: c : Complex_Number := Create(0.0);
! 621: k : natural := 0;
! 622: sols_last : Solution_List;
! 623:
! 624: begin
! 625: -- put_line(file,"Applying Two_Terms_Solve on "); Write(file,p);
! 626: Binomial(p(p'first),d,k,c);
! 627: if k < d'first
! 628: then bkk := 0;
! 629: Standard_Integer_Vectors.Clear(d); return;
! 630: elsif ( c + Create(1.0) = Create(1.0) )
! 631: then bkk := 0;
! 632: Standard_Integer_Vectors.Clear(d); return;
! 633: elsif d(k) < 0
! 634: then Standard_Integer_Vectors.Min(d);
! 635: c := Create(1.0)/c;
! 636: end if;
! 637: declare
! 638: t : Transfo := Rotate(d,k);
! 639: tmp_bkk : natural := 0;
! 640: begin
! 641: Apply(t,d);
! 642: declare
! 643: v : Standard_Complex_Vectors.Vector(1..d(k));
! 644: tmp : Poly;
! 645: rtp : Laur_Sys(p'first..(p'last-1));
! 646: rtp_bkk : natural;
! 647: rtp_sols : Solution_List;
! 648: begin
! 649: for i in v'range loop
! 650: v(i) := Root(c,d(k),i);
! 651: for j in rtp'range loop
! 652: tmp := Transform(t,p(j+1));
! 653: rtp(j) := Evaluate(tmp,v(i),k);
! 654: Clear(tmp);
! 655: end loop;
! 656: Solve(file,rtp,tv,rtp_bkk,rtp_sols);
! 657: Clear(rtp);
! 658: tmp_bkk := tmp_bkk + rtp_bkk;
! 659: Insert(v(i),k,rtp_sols);
! 660: Transform(t,rtp_sols);
! 661: --Concat(sols,sols_last,rtp_sols);
! 662: Refine_and_Concat(file,p,rtp_sols,sols,sols_last);
! 663: end loop;
! 664: end;
! 665: Clear(t);
! 666: bkk := tmp_bkk;
! 667: end;
! 668: -- end if;
! 669: Standard_Integer_Vectors.Clear(d);
! 670: -- put_line(file,"The solutions found : "); put(file,sols);
! 671: end Two_Terms_Solve;
! 672:
! 673: function Project_on_First_and_Solve
! 674: ( p : Poly; k : integer; sols : Solution_List )
! 675: return Solution_List is
! 676:
! 677: -- ON ENTRY :
! 678: -- p a Laurent polynomial in n unknowns x1,..,xk,..,xn;
! 679: -- sols contains values for x1,..,xn, except xk.
! 680:
! 681: -- ON RETURN :
! 682: -- a solution list for p, obtained after substition of the values
! 683: -- for x1,..,xn into the polynomial p.
! 684:
! 685: tmp,res,res_last : Solution_List;
! 686: init : Degrees := Initial_Degrees(p);
! 687:
! 688: begin
! 689: -- put_line(file,"Calling Project_on_First_and_Solve");
! 690: -- put_line(file," with polynomial : ");
! 691: -- put(file,Laurent_Polynomial_to_Polynomial(p)); new_line(file);
! 692: tmp := sols;
! 693: while not Is_Null(tmp) loop
! 694: declare
! 695: p1 : Poly := Substitute(p,Head_Of(tmp).v,k);
! 696: sols1 : Solution_List;
! 697: begin
! 698: -- put(file,"k : "); put(file,k,1); new_line(file);
! 699: -- put(file,"v : "); put(file,Head_Of(tmp).v,3,3,3); new_line(file);
! 700: -- put_line(file,"After substitution : "); Write(file,p1);
! 701: if Number_of_Terms(p1) < 2
! 702: then null;
! 703: elsif Number_of_Terms(p1) = 2
! 704: then
! 705: declare
! 706: d : Standard_Integer_Vectors.Link_to_Vector;
! 707: l : natural := 0;
! 708: c : Complex_Number := Create(0.0);
! 709: begin
! 710: Binomial(p1,d,l,c);
! 711: if l < init'first
! 712: then null;
! 713: elsif ( c + Create(1.0) = Create(1.0) )
! 714: then null;
! 715: else
! 716: if d(l) < 0
! 717: then d(l) := -d(l); c := Create(1.0)/c;
! 718: end if;
! 719: declare
! 720: v : Standard_Complex_Vectors.Vector(1..d(l));
! 721: begin
! 722: for i in v'range loop
! 723: v(i) := Root(c,d(l),i);
! 724: end loop;
! 725: sols1 := Insert(v,k,Head_Of(tmp).all);
! 726: -- put_line(file,"Sols1 after Binomial :");
! 727: -- put(file,sols1);
! 728: Concat(res,res_last,sols1);
! 729: Shallow_Clear(sols1);
! 730: end;
! 731: end if;
! 732: Standard_Integer_Vectors.Clear(d);
! 733: end;
! 734: else
! 735: sols1 := Insert(One_Unknown_Solve(p1),k,Head_Of(tmp).all);
! 736: Concat(res,res_last,sols1);
! 737: -- put_line(file,"Sols1 :"); put(file,sols1);
! 738: Shallow_Clear(sols1);
! 739: end if;
! 740: Clear(p1);
! 741: end;
! 742: tmp := Tail_Of(tmp);
! 743: end loop;
! 744: Standard_Integer_Vectors.Clear
! 745: (Standard_Integer_Vectors.Link_to_Vector(init));
! 746: return res;
! 747: end Project_on_First_and_Solve;
! 748:
! 749: procedure Project_and_Solve
! 750: ( file : in file_type; p : in Laur_Sys; k : in integer;
! 751: m : in out Standard_Integer_Vectors.Vector;
! 752: nd : in node; bkk : out natural;
! 753: sols : in out Solution_List ) is
! 754:
! 755: -- DESCRIPTION :
! 756: -- Solves the projected start system of p along a direction v.
! 757:
! 758: -- ON ENTRY :
! 759: -- file a file to write intermediate results on;
! 760: -- p a Laurent polynomial system;
! 761: -- k entry in the degrees of p;
! 762: -- m m(m'first) equals Maximal_Support(p(p'first),v) > 0;
! 763: -- nd a node in the tree of useful directions.
! 764:
! 765: -- ON RETURN :
! 766: -- m m(m'first+1..m'last) contains the maximal degrees
! 767: -- of the last n-1 equations of p in xk;
! 768: -- bkk the BKK bound of the projected system;
! 769: -- sols the solutions of the projected system.
! 770:
! 771: g_v : Laur_Sys(p'first..(p'last-1));
! 772: bkk_g_v : natural;
! 773: sols_g_v : Solution_List;
! 774:
! 775: begin
! 776: -- put_line(file,"Applying Project_and_Solve on"); Write(file,p);
! 777: for i in g_v'range loop
! 778: m(i+1) := Maximal_Degree(p(i+1),k);
! 779: g_v(i) := Face(k,m(i+1),p(i+1));
! 780: Reduce(k,g_v(i));
! 781: end loop;
! 782: if (nd.ltv = null) or else Is_Null(nd.ltv.all)
! 783: then Solve(file,g_v,bkk_g_v,sols_g_v);
! 784: else Solve(file,g_v,nd.ltv.all,bkk_g_v,sols_g_v);
! 785: end if;
! 786: -- put(file,"After Solve (without tv) bkk_g_v = "); put(file,bkk_g_v,1);
! 787: -- new_line(file);
! 788: declare
! 789: p0 : Poly := Re_Arrange(p(p'first));
! 790: p1 : Poly := Face(k,m(m'first),p0);
! 791: cnst : Term;
! 792: begin
! 793: cnst.dg := new Standard_Integer_Vectors.Vector'(p'range => 0);
! 794: if Coeff(p1,cnst.dg) = Create(0.0)
! 795: then cnst.cf := Coeff(p0,cnst.dg);
! 796: Add(p1,cnst);
! 797: end if;
! 798: Standard_Integer_Vectors.Clear
! 799: (Standard_Integer_Vectors.Link_to_Vector(cnst.dg));
! 800: Clear(p0);
! 801: sols := Project_on_First_and_Solve(p1,k,sols_g_v);
! 802: -- sols := Project_on_First_and_Solve(file,p1,k,sols_g_v);
! 803: Set_Continuation_Parameter(sols,Create(0.0));
! 804: Clear(p1);
! 805: end;
! 806: bkk := m(m'first)*bkk_g_v;
! 807: Clear(sols_g_v);
! 808: Clear(g_v);
! 809: -- put_line(file,"The solutions found : "); put(file,sols);
! 810: end Project_and_Solve;
! 811:
! 812: procedure Unmixed_Solve
! 813: ( file : in file_type; p : in Laur_Sys; dl : in List;
! 814: tv : in Tree_of_Vectors;
! 815: bkk : out natural; sols : in out Solution_List ) is
! 816:
! 817: -- DESCRIPTION :
! 818: -- Solves a Laurent polynomial system where all polytopes are the same.
! 819:
! 820: -- ON ENTRY :
! 821: -- file a file to write intermediate results on;
! 822: -- p a Laurent polynomial system;
! 823: -- dl the list of powers for p;
! 824: -- tv the tree of degrees containing the useful directions.
! 825:
! 826: -- ON RETURN :
! 827: -- bkk the bkk bound;
! 828: -- sols the list of solutions.
! 829:
! 830: sols_last : Solution_List;
! 831: tmp_bkk : natural := 0;
! 832: tmp : Tree_of_Vectors := tv;
! 833:
! 834: begin
! 835: tmp_bkk := 0;
! 836: tmp := tv;
! 837: while not Is_Null(tmp) loop
! 838: declare
! 839: nd : node := Head_Of(tmp);
! 840: v : Standard_Integer_Vectors.Link_to_Vector := nd.d;
! 841: i : integer := Pivot(v);
! 842: pv : integer := Maximal_Support(dl,v.all);
! 843: t : Transfo := Build_Transfo(v,i);
! 844: tp : Laur_Sys(p'range) := Transform(t,p);
! 845: bkk_tp : natural;
! 846: sols_tp : Solution_List;
! 847: max : Standard_Integer_Vectors.Vector(p'range);
! 848: begin
! 849: Write_Direction(file,v);
! 850: max(max'first) := pv;
! 851: -- if (nd.ltv = null) or else Is_Null(nd.ltv.all)
! 852: -- then Projected_Solve(file,tp,i,max,bkk_tp,sols_tp);
! 853: -- else Projected_Solve
! 854: -- (file,tp,i,max,nd.ltv.all,bkk_tp,sols_tp);
! 855: -- end if;
! 856: Project_and_Solve(file,tp,i,max,nd,bkk_tp,sols_tp);
! 857: Mixed_Continue(file,tp,i,max,sols_tp);
! 858: tmp_bkk := tmp_bkk + bkk_tp;
! 859: Transform(t,sols_tp);
! 860: --Concat(sols,sols_last,sols_tp);
! 861: Refine_and_Concat(file,p,sols_tp,sols,sols_last);
! 862: Clear(t); Clear(tp);
! 863: end;
! 864: tmp := Tail_Of(tmp);
! 865: end loop;
! 866: bkk := tmp_bkk;
! 867: end Unmixed_Solve;
! 868:
! 869: procedure Unmixed_Solve
! 870: ( file : in file_type; p : in Laur_Sys; dl : in List;
! 871: bkk : out natural; sols : in out Solution_List ) is
! 872:
! 873: tv : Tree_of_Vectors;
! 874:
! 875: begin
! 876: Volumes.Volume(p'last,dl,tv,bkk);
! 877: Unmixed_Solve(file,p,dl,tv,bkk,sols);
! 878: Clear(tv);
! 879: end Unmixed_Solve;
! 880:
! 881: procedure Mixed_Solve
! 882: ( file : in file_type; p : in Laur_Sys;
! 883: adl : in out Array_of_Lists; tv : in Tree_of_Vectors;
! 884: bkk : out natural; sols : in out Solution_List ) is
! 885:
! 886: -- DESCRIPTION :
! 887: -- Computes the solutions of the Laurent polynomial system p,
! 888: -- where p has more than one equation.
! 889:
! 890: -- NOTE :
! 891: -- This procedure mirrors the procedure Minkowski_Sum in the body
! 892: -- of the package Volumes.
! 893:
! 894: tmp_bkk,len : natural;
! 895: tmp : Tree_of_Vectors;
! 896: index : integer := Index2(adl);
! 897: wp : Laur_Sys(p'range);
! 898: sols_last : Solution_List;
! 899: shifted : boolean;
! 900: perm,mix : Standard_Integer_Vectors.Link_to_Vector;
! 901:
! 902: begin
! 903: Interchange2(adl,index);
! 904: len := Length_Of(adl(adl'first));
! 905: -- put_line(file,"Applying Mixed_Solve on"); Write(file,p);
! 906: if len = 2
! 907: then wp := Interchange2(p,index);
! 908: Two_Terms_Solve(file,wp,tv,bkk,sols);
! 909: else
! 910: if len > 2
! 911: then -- INITIALIZATION :
! 912: Mixture(adl,perm,mix);
! 913: wp := Permute(perm.all,p);
! 914: declare
! 915: zeroes : Degrees
! 916: := new Standard_Integer_Vectors.Vector'(p'range => 0);
! 917: tmpwpi : Poly;
! 918: begin
! 919: if Coeff(wp(wp'first),zeroes) = Create(0.0)
! 920: then shifted := true;
! 921: -- wp(wp'first) := Shift(p(p'first));
! 922: Copy(p(index),tmpwpi); wp(wp'first) := tmpwpi;
! 923: Shift(wp(wp'first));
! 924: else shifted := false;
! 925: end if;
! 926: Standard_Integer_Vectors.Clear
! 927: (Standard_Integer_Vectors.Link_to_Vector(zeroes));
! 928: end;
! 929: -- MIXED HOMOTOPY CONTINUATION :
! 930: tmp_bkk := 0;
! 931: tmp := tv;
! 932: while not Is_Null(tmp) loop
! 933: declare
! 934: nd : node := Head_Of(tmp);
! 935: v : Standard_Integer_Vectors.Link_to_Vector := nd.d;
! 936: k : integer := Pivot(v);
! 937: pv : integer := Maximal_Support(wp(wp'first),v);
! 938: t : Transfo := Build_Transfo(v,k);
! 939: twp : Laur_Sys(wp'range) := Transform(t,wp);
! 940: bkk_twp : natural;
! 941: sols_twp : Solution_List;
! 942: m : Standard_Integer_Vectors.Vector(wp'range);
! 943: begin
! 944: Write_Direction(file,v);
! 945: m(m'first) := pv;
! 946: -- if (nd.ltv = null) or else Is_Null(nd.ltv.all)
! 947: -- then Projected_Solve(file,twp,k,m,bkk_twp,sols_twp);
! 948: -- else Projected_Solve
! 949: -- (file,twp,k,m,nd.ltv.all,bkk_twp,sols_twp);
! 950: -- end if;
! 951: Project_and_Solve(file,twp,k,m,nd,bkk_twp,sols_twp);
! 952: Mixed_Continue(file,twp,k,m,sols_twp);
! 953: tmp_bkk := tmp_bkk + bkk_twp;
! 954: Transform(t,sols_twp);
! 955: --Concat(sols,sols_last,sols_twp);
! 956: Refine_and_Concat(file,wp,sols_twp,sols,sols_last);
! 957: Clear(t); Clear(twp);
! 958: end;
! 959: tmp := Tail_Of(tmp);
! 960: end loop;
! 961: bkk := tmp_bkk;
! 962: Standard_Integer_Vectors.Clear(perm);
! 963: Standard_Integer_Vectors.Clear(mix);
! 964: if shifted
! 965: then Clear(wp(wp'first));
! 966: end if;
! 967: else -- len < 2
! 968: bkk := 0;
! 969: end if;
! 970: end if;
! 971: end Mixed_Solve;
! 972:
! 973: procedure Mixed_Solve
! 974: ( file : in file_type; p : in Laur_Sys;
! 975: adl : in out Array_of_Lists; bkk : out natural;
! 976: sols : in out Solution_List ) is
! 977:
! 978: tv : Tree_of_Vectors;
! 979:
! 980: begin
! 981: Volumes.Mixed_Volume(adl'last,adl,tv,bkk);
! 982: Mixed_Solve(file,p,adl,tv,bkk,sols);
! 983: Clear(tv);
! 984: end Mixed_Solve;
! 985:
! 986: procedure Solve ( file : in file_type; p : in Laur_Sys;
! 987: bkk : out natural; sols : in out Solution_List ) is
! 988:
! 989: al : Array_of_Lists(p'range) := Create(p);
! 990: tv : Tree_of_Vectors;
! 991:
! 992: begin
! 993: Volumes.Mixed_Volume(p'last,al,tv,bkk);
! 994: Solve(file,p,tv,bkk,sols);
! 995: Deep_Clear(al); Clear(tv);
! 996: end Solve;
! 997:
! 998: procedure Solve ( file : in file_type; p : in Laur_Sys;
! 999: tv : in Tree_of_Vectors; bkk : out natural;
! 1000: sols : in out Solution_List ) is
! 1001:
! 1002: -- NOTE :
! 1003: -- This procedure mirrors the procedure Volumes.Mixed_Volume,
! 1004: -- with a tree of useful directions on entry.
! 1005:
! 1006: begin
! 1007: if p'first = p'last
! 1008: then One_Unknown_Solve(p(p'first),sols);
! 1009: bkk := Length_Of(sols);
! 1010: else --if Is_Fewnomial_System(p)
! 1011: -- then
! 1012: -- declare
! 1013: -- fail : boolean;
! 1014: -- begin
! 1015: -- Fewnomials.Solve(p,sols,fail);
! 1016: -- if fail
! 1017: -- then bkk := 0; Clear(sols);
! 1018: -- else bkk := Length_Of(sols);
! 1019: -- end if;
! 1020: -- end;
! 1021: -- else
! 1022: declare
! 1023: adl : Array_of_Lists(p'range) := Create(p);
! 1024: begin
! 1025: if All_Equal(adl)
! 1026: then
! 1027: for i in (adl'first+1)..adl'last loop
! 1028: Deep_Clear(adl(i));
! 1029: end loop;
! 1030: declare
! 1031: wp : Laur_Sys(p'range);
! 1032: shifted : boolean;
! 1033: begin
! 1034: Normalize(p,adl(adl'first),wp,shifted);
! 1035: if Is_Null(tv)
! 1036: then Unmixed_Solve(file,wp,adl(adl'first),bkk,sols);
! 1037: else Unmixed_Solve(file,wp,adl(adl'first),tv,bkk,sols);
! 1038: end if;
! 1039: if shifted
! 1040: then Clear(wp);
! 1041: end if;
! 1042: end;
! 1043: elsif Is_Null(tv)
! 1044: then Mixed_Solve(file,p,adl,bkk,sols);
! 1045: else Mixed_Solve(file,p,adl,tv,bkk,sols);
! 1046: end if;
! 1047: end;
! 1048: end if;
! 1049: end Solve;
! 1050:
! 1051: end Mixed_Homotopy_Continuation;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>