[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

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>