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

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>