[BACK]Return to reduction_of_polynomial_systems.adb CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / PHC / Ada / Homotopy

Annotation of OpenXM_contrib/PHC/Ada/Homotopy/reduction_of_polynomial_systems.adb, Revision 1.1.1.1

1.1       maekawa     1: --with text_io,integer_io;                 use text_io,integer_io;
                      2: with Standard_Floating_Numbers;          use Standard_Floating_Numbers;
                      3: with Standard_Complex_Numbers;           use Standard_Complex_Numbers;
                      4: with Standard_Natural_Vectors;
                      5: with Standard_Complex_Matrices;          use Standard_Complex_Matrices;
                      6: with Standard_Complex_Linear_Solvers;    use Standard_Complex_Linear_Solvers;
                      7: with Standard_Complex_Polynomials;       use Standard_Complex_Polynomials;
                      8: with Reduction_of_Polynomials;           use Reduction_of_Polynomials;
                      9:
                     10: package body Reduction_of_Polynomial_Systems is
                     11:
                     12: -- AUXALIARY DATA FOR LINEAR REDUCTION :
                     13:
                     14:   mach_eps : constant double_float := 10.0**(-13);
                     15:
                     16:   type Degrees_Array is array(positive range <>) of Degrees;
                     17:   type Terms_Array   is array(positive range <>) of Term;
                     18:   type Boolean_Array is array(positive range <>) of boolean;
                     19:
                     20: -- AUXILIARY PROCEDURES FOR LINEAR REDUCTION :
                     21:
                     22:   procedure Pop_First_Term ( p : in out Poly; t : in out Term ) is
                     23:
                     24:   -- DESCRIPTION :
                     25:   --   The term on return is the leading term of p.
                     26:   --   This term is removed from p.
                     27:
                     28:     procedure First_Term ( tt : in Term; continue : out boolean ) is
                     29:     begin
                     30:       Copy(tt,t);
                     31:       continue := false;
                     32:     end First_Term;
                     33:     procedure Get_First_Term is new Visiting_Iterator(First_Term);
                     34:
                     35:   begin
                     36:     t.cf := Create(0.0);
                     37:     Get_First_Term(p);
                     38:     if t.cf /= Create(0.0)
                     39:      then Sub(p,t);
                     40:     end if;
                     41:   end Pop_First_Term;
                     42:
                     43:   procedure Leading_Terms ( p : in out Poly_Sys; ta : in out Terms_Array ) is
                     44:
                     45:   -- DESCRIPTION :
                     46:   --   Puts the leading terms of the polynomials in p in the array ta.
                     47:   --   The leading terms are removed afterwards.
                     48:
                     49:   begin
                     50:     for i in p'range loop
                     51:       Clear(ta(i));
                     52:       Pop_First_Term(p(i),ta(i));
                     53:     end loop;
                     54:   end Leading_Terms;
                     55:
                     56:   procedure Find_Max ( ta : in Terms_Array; index : in out Boolean_Array;
                     57:                        stop : in out boolean ) is
                     58:
                     59:     res : Degrees := new Standard_Natural_Vectors.Vector'(ta(1).dg'range => 0);
                     60:
                     61:   begin
                     62:     stop := true;
                     63:     for i in ta'range loop
                     64:       if ta(i).cf /= Create(0.0)
                     65:        then if ta(i).dg > res
                     66:              then res.all := Standard_Natural_Vectors.Vector(ta(i).dg.all);
                     67:                   index(1..(i-1)) := (1..(i-1) => false);
                     68:                   index(i) := true;
                     69:                   stop := false;
                     70:              elsif Equal(ta(i).dg,res)
                     71:                  then index(i) := true;
                     72:                       stop := false;
                     73:             end if;
                     74:       end if;
                     75:     end loop;
                     76:     Standard_Natural_Vectors.Clear
                     77:       (Standard_Natural_Vectors.Link_to_Vector(res));
                     78:   end Find_Max;
                     79:
                     80:   procedure Update ( p : in out Poly_Sys; n : in natural;
                     81:                      ta : in out Terms_Array; da : in out Degrees_Array;
                     82:                      nda,cnt : in out natural; mat : in out Matrix;
                     83:                      stop : in out boolean ) is
                     84:
                     85:     index : natural;
                     86:     is_max : Boolean_Array(1..n) := (1..n => false);
                     87:
                     88:   begin
                     89:     Find_Max(ta,is_max,stop);
                     90:     if not stop
                     91:      then
                     92:       -- Get the next Degrees for in the Degrees_Array
                     93:        for i in is_max'range loop
                     94:          if is_max(i)
                     95:           then index := i;  exit;
                     96:          end if;
                     97:        end loop;
                     98:        nda := nda + 1;
                     99:        Standard_Natural_Vectors.Copy
                    100:          (Standard_Natural_Vectors.Link_to_Vector(ta(index).dg),
                    101:           Standard_Natural_Vectors.Link_to_Vector(da(nda)));
                    102:       -- Fill in the matrix and update the window :
                    103:        for i in is_max'range loop
                    104:          if is_max(i)
                    105:           then mat(i,nda) := ta(i).cf;
                    106:                Pop_First_Term(p(i),ta(i));
                    107:                cnt := cnt+1;
                    108:           else mat(i,nda) := Create(0.0);
                    109:          end if;
                    110:        end loop;
                    111:     end if;
                    112:   end Update;
                    113:
                    114:   procedure Coefficient_Matrix
                    115:                 ( p : in Poly_Sys; mat : in out Matrix;
                    116:                   da : in out Degrees_Array; nda : in out natural;
                    117:                   diagonal : in out boolean ) is
                    118:
                    119:   -- DESCRIPTION :
                    120:   --   Constructs the coefficient matrix of the polynomial system.
                    121:   --   Stops when the system is diagonal.
                    122:
                    123:   -- REQUIRED :
                    124:   --   mat'range(1) = p'range, mat'range(2) = 1..Sum_Number_of_Terms(p),
                    125:   --   da'range = mat'range(2).
                    126:
                    127:   -- ON ENTRY :
                    128:   --   p          a polynomial system.
                    129:
                    130:   -- ON RETURN :
                    131:   --   mat        coefficient matrix, up to column nda filled up;
                    132:   --   da         da(1..nda) collects the different terms in the system;
                    133:   --   nda        number of different terms;
                    134:   --   diagonal   true if the leading terms are all different.
                    135:
                    136:     work : Poly_Sys(p'range);
                    137:     stop : boolean := false;
                    138:     Window : Terms_Array(p'range);
                    139:     cnt : natural := 0;
                    140:
                    141:   begin
                    142:     Copy(p,work);
                    143:     Leading_Terms(work,Window);
                    144:     diagonal := false;
                    145:     while not stop and not diagonal loop
                    146:       Update(work,p'last,Window,da,nda,cnt,mat,stop);
                    147:       if (cnt = p'last) and then (cnt = nda)
                    148:        then diagonal := true;
                    149:       end if;
                    150:       exit when diagonal;
                    151:     end loop;
                    152:     Clear(work);
                    153:   end Coefficient_Matrix;
                    154:
                    155:   procedure Coefficient_Matrix
                    156:                 ( p : in Poly_Sys; mat : in out Matrix;
                    157:                   da : in out Degrees_Array; nda : in out natural ) is
                    158:
                    159:   -- DESCRIPTION :
                    160:   --   Constructs the coefficient matrix of the polynomial system.
                    161:
                    162:   -- REQUIRED :
                    163:   --   mat'range(1) = p'range, mat'range(2) = 1..Sum_Number_of_Terms(p),
                    164:   --   da'range = mat'range(2).
                    165:
                    166:   -- ON ENTRY :
                    167:   --   p          a polynomial system.
                    168:
                    169:   -- ON RETURN :
                    170:   --   mat        coefficient matrix, up to column nda filled up;
                    171:   --   da         da(1..nda) collects the different terms in the system;
                    172:   --   nda        number of different terms.
                    173:
                    174:     work : Poly_Sys(p'range);
                    175:     stop : boolean := false;
                    176:     Window : Terms_Array(p'range);
                    177:     cnt : natural := 0;
                    178:
                    179:   begin
                    180:     Copy(p,work);
                    181:     Leading_Terms(work,Window);
                    182:     while not stop loop
                    183:       Update(work,p'last,Window,da,nda,cnt,mat,stop);
                    184:     end loop;
                    185:     Clear(work);
                    186:   end Coefficient_Matrix;
                    187:
                    188:   procedure Make_Polynomial_System
                    189:                     ( p : in out Poly_Sys; mat : in Matrix;
                    190:                       da : in Degrees_Array; nda : in natural;
                    191:                       inconsistent,infinite : out boolean ) is
                    192:
                    193:     t : Term;
                    194:     n : natural := p'length;
                    195:
                    196:   begin
                    197:     inconsistent := false;
                    198:     infinite := false;
                    199:     Clear(p);
                    200:     for i in p'range loop
                    201:       p(i) := Null_Poly;
                    202:       for j in 1..nda loop
                    203:         if AbsVal(mat(i,j)) > mach_eps
                    204:          then t.dg := new Standard_Natural_Vectors.Vector'(da(j).all);
                    205:               t.cf := mat(i,j);
                    206:               Add(p(i),t);
                    207:               Clear(t);
                    208:         end if;
                    209:       end loop;
                    210:       if p(i) = Null_Poly
                    211:        then infinite := true;
                    212:        elsif Degree(p(i)) = 0
                    213:            then inconsistent := true;
                    214:       end if;
                    215:     end loop;
                    216:   end Make_Polynomial_System;
                    217:
                    218:   function Sum_Number_of_Terms ( p : Poly_Sys ) return natural is
                    219:
                    220:   -- DESCRIPTION :
                    221:   --   Returns the sum of the number of terms of every polynomial in p.
                    222:
                    223:     sum : natural := 0;
                    224:
                    225:   begin
                    226:     for i in p'range loop
                    227:       sum := sum + Number_of_Terms(p(i));
                    228:     end loop;
                    229:     return sum;
                    230:   end Sum_Number_of_Terms;
                    231:
                    232: -- TARGET ROUTINES FOR LINEAR REDUCTION :
                    233:
                    234:   procedure Reduce ( p : in out Poly_Sys;
                    235:                      diagonal,inconsistent,infinite : in out boolean ) is
                    236:
                    237:     n : natural := p'length;
                    238:     cp : Poly_Sys(p'range);
                    239:     max_terms : constant natural := Sum_Number_of_Terms(p);
                    240:     columns : Degrees_Array(1..max_terms);
                    241:     numb_columns : natural := 0;
                    242:     mat : Matrix(p'range,1..max_terms);
                    243:
                    244:   begin
                    245:     Coefficient_Matrix(p,mat,columns,numb_columns,diagonal);
                    246:     if diagonal
                    247:      then inconsistent := false;
                    248:           infinite := false;
                    249:      else declare
                    250:             coeffmat : Matrix(p'range,1..numb_columns);
                    251:           begin
                    252:             for i in coeffmat'range(1) loop
                    253:               for j in coeffmat'range(2) loop
                    254:                 coeffmat(i,j) := mat(i,j);
                    255:               end loop;
                    256:             end loop;
                    257:             Triangulate(coeffmat,n,numb_Columns);
                    258:             Make_Polynomial_System(p,coeffmat,columns,numb_columns,
                    259:                                    inconsistent,infinite);
                    260:             for i in 1..numb_Columns loop
                    261:               Standard_Natural_Vectors.Clear
                    262:                 (Standard_Natural_Vectors.Link_to_Vector(Columns(i)));
                    263:             end loop;
                    264:           end;
                    265:     end if;
                    266:   end Reduce;
                    267:
                    268:   procedure Sparse_Reduce ( p : in out Poly_Sys;
                    269:                             inconsistent,infinite : in out boolean ) is
                    270:
                    271:     n : natural := p'length;
                    272:     max_terms : constant natural := Sum_Number_of_Terms(p);
                    273:     columns : Degrees_Array(1..max_terms);
                    274:     numb_columns : natural := 0;
                    275:     mat : Matrix(1..n,1..max_terms);
                    276:
                    277:   begin
                    278:     Coefficient_Matrix(p,mat,columns,numb_columns);
                    279:     declare
                    280:       coeffmat : Matrix(p'range,1..numb_columns);
                    281:     begin
                    282:       for i in coeffmat'range(1) loop
                    283:         for j in coeffmat'range(2) loop
                    284:           coeffmat(i,j) := mat(i,j);
                    285:         end loop;
                    286:       end loop;
                    287:       Diagonalize(coeffmat,n,numb_Columns);
                    288:       Make_Polynomial_System(p,coeffmat,columns,numb_columns,
                    289:                              inconsistent,infinite);
                    290:       for i in 1..numb_Columns loop
                    291:         Standard_Natural_Vectors.Clear
                    292:           (Standard_Natural_Vectors.Link_to_Vector(columns(i)));
                    293:       end loop;
                    294:     end;
                    295:   end Sparse_Reduce;
                    296:
                    297: -- NONLINEAR REDUCTION :
                    298:
                    299:   function Total_Degree ( p : Poly_Sys ) return natural is
                    300:
                    301:     d : natural := 1;
                    302:     tmp : integer;
                    303:
                    304:   begin
                    305:     for i in p'range loop
                    306:       tmp := Degree(p(i));
                    307:       if tmp >= 0
                    308:        then d := d * tmp;
                    309:       end if;
                    310:     end loop;
                    311:     return d;
                    312:   end Total_Degree;
                    313:
                    314:   function LEQ ( d1,d2 : Degrees ) return boolean is
                    315:
                    316:   -- DESCRIPTION :
                    317:   --   Returns true if all degrees of d1 are lower than
                    318:   --   or equal to the degrees of d2
                    319:
                    320:   begin
                    321:     for i in d1'range loop
                    322:       if d1(i) > d2(i)
                    323:        then return false;
                    324:       end if;
                    325:     end loop;
                    326:     return true;
                    327:   end LEQ;
                    328:
                    329:   function Leading_Term ( p : Poly ) return Term is
                    330:
                    331:   -- DESCRIPTION :
                    332:   --   Returns the leading term of the polynomial p.
                    333:
                    334:     tf : Term;
                    335:
                    336:     procedure First_Term (t : in Term; continue : out boolean) is
                    337:     begin
                    338:       Copy(t,tf);
                    339:       continue := false;
                    340:     end First_Term;
                    341:     procedure Get_First_Term is new Visiting_Iterator (First_Term);
                    342:   begin
                    343:     Get_First_Term(p);
                    344:     return tf;
                    345:   end Leading_Term;
                    346:
                    347:   function Can_Be_Eliminated ( p : Poly_Sys; j : natural ) return boolean is
                    348:
                    349:   -- DESCRIPTION :
                    350:   --   returns true if the degree of the j-th unknown in each equation
                    351:   --   is zero.
                    352:
                    353:   begin
                    354:     for i in p'range loop
                    355:       if Degree(p(i),j) > 0
                    356:        then return false;
                    357:       end if;
                    358:     end loop;
                    359:     return true;
                    360:   end Can_Be_Eliminated;
                    361:
                    362:   procedure Shift_Null_Polynomial ( p : in out Poly_Sys ) is
                    363:
                    364:   -- DESCRIPTION :
                    365:   --   The null polynomial in the system p will be shifted down
                    366:   --   towards the end.
                    367:
                    368:   begin
                    369:     for i in p'range loop
                    370:       if p(i) = Null_Poly
                    371:        then for j in i..(p'last-1) loop
                    372:               Copy(p(j+1),p(j));
                    373:               Clear(p(j+1));
                    374:             end loop;
                    375:       end if;
                    376:     end loop;
                    377:   end Shift_Null_Polynomial;
                    378:
                    379:   procedure Eliminate ( p : in out Poly; j : in natural ) is
                    380:
                    381:   -- DESCRIPTION :
                    382:   --   The j-th unknown will be eliminated out of the polynomial p
                    383:
                    384:     n : natural := Number_Of_Unknowns(p);
                    385:
                    386:     procedure Eliminate_Term (t : in out Term; continue : out boolean) is
                    387:
                    388:       d : Degrees := new Standard_Natural_Vectors.Vector(1..(n-1));
                    389:
                    390:     begin
                    391:       for i in 1..(j-1) loop
                    392:         d(i) := t.dg(i);
                    393:       end loop;
                    394:       for i in j..(n-1) loop
                    395:         d(i) := t.dg(i+1);
                    396:       end loop;
                    397:       Clear(t);
                    398:       t.dg := d;
                    399:       continue := true;
                    400:     end Eliminate_Term;
                    401:     procedure Eliminate_Terms is new Changing_Iterator(Eliminate_Term);
                    402:
                    403:   begin
                    404:     Eliminate_Terms(p);
                    405:   end Eliminate;
                    406:
                    407:   procedure Eliminate ( p : in out Poly_Sys; j : in natural ) is
                    408:
                    409:   -- DESCRIPTION :
                    410:   --   The j-th unknown will be eliminated out of each equation.
                    411:
                    412:   begin
                    413:     for i in p'range loop
                    414:       Eliminate(p(i),j);
                    415:     end loop;
                    416:   end Eliminate;
                    417:
                    418:   procedure Replace ( p : in out Poly_Sys; pp : in Poly; i : in natural ) is
                    419:
                    420:   -- DESCRIPTION :
                    421:   --   This procedure replaces the i-th polynomial in the system p
                    422:   --   by the polynomial pp.  If pp is a null polynomial then the procedure
                    423:   --   tries to eliminate an unknown, in order to have as much equations
                    424:   --   as there are unknowns.
                    425:
                    426:     tmp : natural;
                    427:
                    428:   begin
                    429:     if (pp = Null_Poly) or else (Number_Of_Unknowns(pp) = 0)
                    430:      then -- try to eliminate an unknown
                    431:           tmp := Number_Of_Unknowns(p(1));
                    432:           Clear(p(i)); p(i) := Null_Poly;
                    433:           for j in reverse 1..Number_Of_Unknowns(p(1)) loop
                    434:             if Can_Be_Eliminated(p,j)
                    435:              then Eliminate(p,j);
                    436:             end if;
                    437:           end loop;
                    438:           Shift_Null_Polynomial(p);
                    439:      else Clear(p(i)); Copy(pp,p(i));
                    440:     end if;
                    441:   end Replace;
                    442:
                    443:   function red ( p,b1,b2 : Poly ) return Poly is
                    444:
                    445:     Rpb1 : Poly := Rpoly(p,b1);
                    446:
                    447:   begin
                    448:     if Number_Of_Unknowns(Rpb1) = 0
                    449:      then return Null_Poly;
                    450:      else declare
                    451:             Rpb2 : Poly := Rpoly(Rpb1,b2);
                    452:           begin
                    453:             Clear(Rpb1);
                    454:             return Rpb2;
                    455:           end;
                    456:     end if;
                    457:   end red;
                    458:
                    459:   function Reduce ( p,b1,b2 : Poly ) return Poly is
                    460:
                    461:   -- DESCRIPTION :
                    462:   --   returns p mod < b1,b2 >
                    463:
                    464:     temp : Poly := red(p,b1,b2);
                    465:   begin
                    466:     if Number_Of_Unknowns(temp) = 0
                    467:      then return Null_Poly;
                    468:      else Clear(temp);
                    469:           return red(p,b2,b1);
                    470:     end if;
                    471:   end Reduce;
                    472:
                    473:   function Simple_Criterium ( p1,p2 : Poly ) return boolean is
                    474:
                    475:   -- DESCRIPTION :
                    476:   --   returns true if lcm(in(p1),in(p2)) = in(p1), if in(p2) | in(p1).
                    477:
                    478:     lt1,lt2 : Term;
                    479:     res : boolean;
                    480:
                    481:   begin
                    482:     lt1 := Leading_Term(p1);
                    483:     lt2 := Leading_Term(p2);
                    484:     res := LEQ(lt2.dg,lt1.dg);
                    485:     Clear(lt1); Clear(lt2);
                    486:     return res;
                    487:   end Simple_Criterium;
                    488:
                    489:   procedure Rpoly_Criterium ( p,b1,b2 : in Poly; cnt : in out natural;
                    490:                               res : out boolean ) is
                    491:
                    492:   -- DESCRIPTION :
                    493:   --   Applies the R-polynomial criterium and counts the number of
                    494:   --   R-polynomials computed.
                    495:
                    496:     Rpb1 : Poly := Rpoly(p,b1);
                    497:     Rpb2 : Poly;
                    498:
                    499:   begin
                    500:     cnt := cnt + 1;
                    501:     if Number_Of_Unknowns(Rpb1) = 0
                    502:      then res := true;
                    503:      else Rpb2 := Rpoly(Rpb1,b2);
                    504:           cnt := cnt + 1;
                    505:           Clear(Rpb1);
                    506:           if Number_of_Unknowns(Rpb2) = 0
                    507:            then res := true;
                    508:            else Clear(Rpb2);
                    509:                 Rpb2 := Rpoly(p,b2);
                    510:                 cnt := cnt + 1;
                    511:                 if Number_of_Unknowns(Rpb2) = 0
                    512:                  then res := true;
                    513:                  else Rpb1 := Rpoly(Rpb2,b1);
                    514:                       cnt := cnt + 1;
                    515:                       Clear(Rpb2);
                    516:                       if Number_of_Unknowns(Rpb1) = 0
                    517:                        then res := true;
                    518:                        else res := false;
                    519:                             Clear(Rpb1);
                    520:                       end if;
                    521:                 end if;
                    522:           end if;
                    523:     end if;
                    524:   end Rpoly_Criterium;
                    525:
                    526:   function Criterium ( p,q,s : Poly ) return boolean is
                    527:
                    528:   -- DESCRIPTION :
                    529:   --   returns true if p may be replaced by s.
                    530:
                    531:   begin
                    532:     if Simple_Criterium(p,q)
                    533:      then return true;
                    534:      else declare
                    535:             temp : Poly := Reduce(p,q,s);
                    536:             res : boolean := (Number_Of_Unknowns(temp) = 0);
                    537:           begin
                    538:             Clear(temp);
                    539:             return res;
                    540:           end;
                    541:     end if;
                    542:   end Criterium;
                    543:
                    544:   procedure Criterium ( p,q,s : in Poly; cnt : in out natural;
                    545:                         res : out boolean ) is
                    546:
                    547:   -- DESCRIPTION :
                    548:   --   returns true if p may be replaced by s.
                    549:
                    550:   begin
                    551:     if Simple_Criterium(p,q)
                    552:      then res := true;
                    553:      else Rpoly_Criterium(p,q,s,cnt,res);
                    554:     end if;
                    555:   end Criterium;
                    556:
                    557:   procedure Reduce ( p : in Poly_Sys; res : in out Poly_Sys;
                    558:                      cnt_eq : in out natural; max_eq : in natural;
                    559:                      cnt_sp : in out natural; max_sp : in natural;
                    560:                      cnt_rp : in out natural; max_rp : in natural ) is
                    561:
                    562:     S : Poly;
                    563:     n : natural := p'last - p'first + 1;
                    564:     dS,dpi,dpj : integer;
                    565:     ok : boolean;
                    566:
                    567:     procedure try ( i,dpi : in natural ) is
                    568:
                    569:     -- DESCRIPTION : try to replace p_i by S
                    570:
                    571:       p_red : Poly_Sys(1..n);
                    572:
                    573:     begin
                    574:       if cnt_eq > max_eq then return; end if;
                    575:       if cnt_sp > max_sp then return; end if;
                    576:       Clear(p_red); Copy(p,p_red);
                    577:       Replace(p_red,S,i);
                    578:      -- put("replaced polynomial p("); put(i,1); put_line(").");
                    579:       if dS = 0
                    580:        then return;
                    581:        elsif Total_Degree(p_red) < Total_Degree(res)
                    582:            then Copy(p_red,res);
                    583:                 Reduce(p_red,res,cnt_eq,max_eq,cnt_sp,max_sp,cnt_rp,max_rp);
                    584:            elsif cnt_eq <= max_eq
                    585:                then cnt_eq := cnt_eq + 1;
                    586:                     Reduce(p_red,res,
                    587:                            cnt_eq,max_eq,cnt_sp,max_sp,cnt_rp,max_rp);
                    588:       end if;
                    589:       Clear(p_red);
                    590:     end try;
                    591:
                    592:   begin
                    593:     if cnt_eq > max_eq then return; end if;
                    594:     if cnt_sp > max_sp then return; end if;
                    595:     if cnt_rp > max_rp then return; end if;
                    596:     for i in 1..n loop
                    597:       for j in (i+1)..n loop
                    598:         if (p(i) /= Null_Poly) and (p(j) /= Null_Poly)
                    599:          then
                    600:            Clear(S); S := Spoly(p(i),p(j));
                    601:            cnt_sp := cnt_sp + 1;
                    602:            dS  := Degree(S); dpi := Degree(p(i)); dpj := Degree(p(j));
                    603:           -- put("S-polynomial of p("); put(i,1); put(") and p(");
                    604:           --   put(j,1); put_line(") computed.");
                    605:            if dS <= dpi and then dpi > dpj
                    606:              and then Criterium(p(i),p(j),S)
                    607:             then try(i,dpi);
                    608:             elsif dS <= dpj and then dpi < dpj
                    609:                  and then Criterium(p(j),p(i),S)
                    610:                 then try(j,dpj);
                    611:                 else -- dpi = dpj
                    612:                   if dS <= dpi
                    613:                    then Criterium(p(i),p(j),S,cnt_rp,ok);
                    614:                         if ok then try(i,dpi); end if;
                    615:                   end if;
                    616:                   if dS <= dpj
                    617:                    then Criterium(p(j),p(i),S,cnt_rp,ok);
                    618:                         if ok then try(j,dpj); end if;
                    619:                   end if;
                    620:            end if;
                    621:            Clear(S);
                    622:         end if;
                    623:         exit when (dS = 0);
                    624:       end loop;
                    625:     end loop;
                    626:   end Reduce;
                    627:
                    628:   procedure Sparse_Reduce ( p : in Poly_Sys; res : in out Poly_Sys;
                    629:                             cnt_eq : in out natural; max_eq : in natural ) is
                    630:
                    631:     S : Poly;
                    632:     n : natural := p'last - p'first + 1;
                    633:     dS,dpi,dpj : integer;
                    634:
                    635:     procedure try ( i,dpi : in natural ) is
                    636:
                    637:     -- DESCRIPTION : try to replace p_i by S
                    638:
                    639:       p_red : Poly_Sys(1..n);
                    640:       inconsistent,infinite : boolean := false;
                    641:     begin
                    642:       if cnt_eq > max_eq then return; end if;
                    643:       Clear(p_red); Copy(p,p_red);
                    644:       Replace(p_red,S,i);
                    645:       if dS /= 0
                    646:        then Sparse_Reduce(p_red,inconsistent,infinite);
                    647:       end if;
                    648:       if dS = 0 or inconsistent
                    649:        then cnt_eq := max_eq + 1;
                    650:             return;
                    651:        elsif Total_Degree(p_red) < Total_Degree(res)
                    652:            then Copy(p_red,res);
                    653:                 Sparse_Reduce(p_red,res,cnt_eq,max_eq);
                    654:            else cnt_eq := cnt_eq + 1;
                    655:                 Sparse_Reduce(p_red,res,cnt_eq,max_eq);
                    656:       end if;
                    657:       Clear(p_red);
                    658:     end try;
                    659:
                    660:   begin
                    661:     if cnt_eq > max_eq then return; end if;
                    662:     for i in 1..n loop
                    663:       for j in (i+1)..n loop
                    664:         if (p(i) /= Null_Poly) and (p(j) /= Null_Poly)
                    665:          then
                    666:
                    667:               Clear(S); S := Spoly(p(i),p(j));
                    668:
                    669:               dS  := Degree(S);
                    670:               dpi := Degree(p(i));
                    671:               dpj := Degree(p(j));
                    672:
                    673:               if dS <= dpi and then dpi > dpj
                    674:                 and then Criterium(p(i),p(j),S)
                    675:                then try(i,dpi);
                    676:                elsif dS <= dpj and then dpi < dpj
                    677:                     and then Criterium(p(j),p(i),S)
                    678:                    then try(j,dpj);
                    679:                   else -- dpi = dpj
                    680:                       if dS <= dpi
                    681:                        and then Criterium(p(i),p(j),S) then try(i,dpi); end if;
                    682:                       if dS <= dpj
                    683:                        and then Criterium(p(j),p(i),S) then try(j,dpj); end if;
                    684:               end if;
                    685:
                    686:               Clear(S);
                    687:
                    688:         end if;
                    689:       end loop;
                    690:     end loop;
                    691:   end Sparse_Reduce;
                    692:
                    693: end Reduction_of_Polynomial_Systems;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>