Changeset d51d87 in git


Ignore:
Timestamp:
Aug 30, 2013, 7:45:42 PM (10 years ago)
Author:
Oleksandr Motsak <motsak@…>
Branches:
(u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'f875bbaccd0831e36aaed09ff6adeb3eb45aeb94')
Children:
c44f0c47dd0522db3b9d26283ffefec28e6d53aa
Parents:
62e51f3a438d0476a7cc82ebe3df5d93b7a740b0035b6439d8381335d8497466228554322c60d1de
Message:
Merge pull request #354 from mmklee/multi_sw

Multi sw: absolute factorization
Files:
4 added
2 deleted
17 edited
1 moved

Legend:

Unmodified
Added
Removed
  • Singular/LIB/absfact.lib

    r62e51f rd51d87  
    77         Gregoire Lecerf,      lecerf at math.uvsq.fr
    88         Gerhard Pfister,      pfister at mathematik.uni-kl.de
     9         Martin Lee,           mlee at mathematik.uni-kl.de
    910
    1011OVERVIEW:
     
    1617Then a minimal extension field is determined making use of the
    1718Rothstein-Trager partial fraction decomposition algorithm.
     19absFactorizeBCG uses the algorithm of Bertone, Cheze and Galligo for bivariate
     20polynomials and similar ideas as above to reduce to this case.
    1821
    1922REFERENCES:
    2023G. Cheze, G. Lecerf: Lifting and recombination techniques for absolute
    2124                  factorization. Journal of Complexity, 23(3):380-420, 2007.
     25C. Bertone, G. Cheze, and A. Galligo: Modular las vegas algorithms for
     26                  polynomial absolute factorization. J. Symb. Comput.,
     27                  45(12):1280-1295, December 2010
    2228
    2329KEYWORDS: factorization; absolute factorization.
     
    2632PROCEDURES:
    2733  absFactorize();        absolute factorization of poly
    28   absBiFactorize();      absolute factorization of bivariate poly
     34  absFactorizeBCG();     absolute factorization of poly
    2935";
    3036
     
    611617
    612618////////////////////////////////////////////////////////////////////////////////
    613 proc absBiFactorize(poly p, list #)
    614 "USAGE:  absBiFactorize(p [,s]);   p poly, s string
     619proc absFactorizeBCG(poly p, list #)
     620"USAGE:  absFactorizeBCG(p [,s]);   p poly, s string
    615621ASSUME: coefficient field is the field of rational numbers or a
    616622        transcendental extension thereof
     
    637643        no field extension was necessary for the @code{j}th (class of)
    638644        absolute factor(s).
    639 NOTE:   The input polynomial p is assumed to be bivariate or to contain one para-
    640         meter and one variable. All factors are presented denominator- and
    641         content-free. The constant factor (first entry) is chosen such that the
    642         product of all (!) the (denominator- and content-free) absolute factors
    643         of @code{p} equals @code{p / absolute_factors[1][1]}.
     645NOTE:   All factors are presented denominator- and content-free. The constant
     646        factor (first entry) is chosen such that the product of all (!) the
     647        (denominator- and content-free) absolute factors of @code{p} equals
     648        @code{p / absolute_factors[1][1]}.
    644649SEE ALSO: factorize, absPrimdecGTZ, absFactorize
    645 EXAMPLE: example absBiFactorize; shows an example
     650EXAMPLE: example absFactorizeBCG; shows an example
    646651"
    647652{
    648653  int dblevel = printlevel - voice + 2;
    649   dbprint(dblevel,"Entering absfact.lib::absBiFactorize with ",p);
     654  dbprint(dblevel,"Entering absfact.lib::absFactorizeBCG with ",p);
    650655  def MP = basering;
    651656  int i;
    652657  if (char(MP) != 0)
    653658  {
    654     ERROR("// absfact.lib::absBiFactorize is only implemented for "+
     659    ERROR("// absfact.lib::absFactorizeBCG is only implemented for "+
    655660          "characteristic 0");
    656661  }
    657662  if(minpoly!=0)
    658663  {
    659     ERROR("// absfact.lib::absBiFactorize is not implemented for algebraic "
     664    ERROR("// absfact.lib::absFactorizeBCG is not implemented for algebraic "
    660665          +"extensions");
    661666  }
     
    745750  poly p=imap(MP,p);
    746751
    747   if (size (variables (p)) > 2)
    748   {
    749     ERROR("// absfact.lib::absBiFactorize is not implemented for polynomials "
    750           +"with more than 2 variables");
    751   }
    752 
    753752  // special treatment in the homogeneous case, dropping one variable
    754753  // by substituting the first variable by 1
     
    761760  }
    762761
    763   list tmpf=system ("absBiFact", p);
     762  list tmpf=system ("absFact", p);
    764763
    765764  // the homogeneous case, homogenizing the result
     
    824823
    825824  dbprint( printlevel-voice+3,"
    826 // 'absBiFactorize' created a ring, in which a list absolute_factors (the
     825// 'absFactorizeBCG' created a ring, in which a list absolute_factors (the
    827826// absolute factors) is stored.
    828827// To access the list of absolute factors, type (if the name S was assigned
     
    836835  ring R = (0), (x,y), lp;
    837836  poly p = (-7*x^2 + 2*x*y^2 + 6*x + y^4 + 14*y^2 + 47)*(5x2+y2)^3*(x-y)^4;
    838   def S = absBiFactorize(p) ;
     837  def S = absFactorizeBCG(p) ;
    839838  setring(S);
    840839  absolute_factors;
  • Singular/extra.cc

    r62e51f rd51d87  
    36963696      else
    36973697  /*================= absBiFact ======================*/
    3698       if (strcmp(sys_cmd, "absBiFact") == 0)
     3698      if (strcmp(sys_cmd, "absFact") == 0)
    36993699      {
    37003700        if (h!=NULL)
     
    37063706            ideal mipos= NULL;
    37073707            int n= 0;
    3708             ideal f=singclap_absBiFactorize((poly)(h->Data()), mipos, &v, n, currRing);
     3708            ideal f=singclap_absFactorize((poly)(h->Data()), mipos, &v, n, currRing);
    37093709            if (f==NULL) return TRUE;
    37103710            ivTest(v);
  • Singular/misc_ip.cc

    r62e51f rd51d87  
    769769}
    770770
     771/* version strings */
     772#ifdef HAVE_FLINT
     773#ifdef __cplusplus
     774extern "C"
     775{
     776#endif
     777#ifndef __GMP_BITS_PER_MP_LIMB
     778#define __GMP_BITS_PER_MP_LIMB GMP_LIMB_BITS
     779#endif
     780#include <flint/flint.h>
     781#ifdef __cplusplus
     782}
     783#endif
     784#endif
     785
    771786char * versionString()
    772787{
     
    797812#endif
    798813
     814#ifdef HAVE_FACTORY
    799815#ifdef HAVE_FLINT
    800 // #include <NTL/version.h>
    801               StringAppend("FLINT(??){'%s','%s'},", FLINT_CFLAGS, FLINT_LIBS);
    802 #endif
    803    
     816              StringAppend("FLINT(%s){'%s','%s'},",version, FLINT_CFLAGS, FLINT_LIBS);
     817#endif
     818#endif
    804819
    805820#if SIZEOF_VOIDP == 8
  • Tst/Short.lst

    r62e51f rd51d87  
    1 Short/absbifact.tst
     1Short/absfact.tst
    22Short/alexpoly.tst
    33Short/algebralib.tst
  • Tst/Short/absfact.tst

    r62e51f rd51d87  
    1212absolute_factors;
    1313setring R;
    14 def T= absBiFactorize (p);
     14def T= absFactorizeBCG (p);
    1515setring T;
    1616short= 0;
     
    2626absolute_factors;
    2727setring R;
    28 def T= absBiFactorize (p);
     28def T= absFactorizeBCG (p);
    2929setring T;
    3030short= 0;
     
    3636poly p = (5x2+y2);
    3737absFactorize(p,77) ;
    38 absBiFactorize (p,77);
     38absFactorizeBCG (p,77);
    3939
    4040kill R;
     
    4747absolute_factors;
    4848setring R;
    49 def T= absBiFactorize (p);
     49def T= absFactorizeBCG (p);
    5050setring T;
    5151short= 0;
     
    5959absolute_factors;
    6060setring r;
    61 def T= absBiFactorize(p, "s");
     61def T= absFactorizeBCG(p, "s");
    6262setring T;
    6363absolute_factors;
     
    7070absolute_factors;
    7171setring r;
    72 def T= absBiFactorize(p);
     72def T= absFactorizeBCG(p);
    7373setring T;
    7474absolute_factors;
     
    8181absolute_factors;
    8282setring r;
    83 def T= absBiFactorize(p);
     83def T= absFactorizeBCG(p);
    8484setring T;
    8585absolute_factors;
     
    9292absolute_factors;
    9393setring r;
    94 def T= absBiFactorize(p);
     94def T= absFactorizeBCG(p);
    9595setring T;
    9696absolute_factors;
     
    103103absolute_factors;
    104104setring r;
    105 def T= absBiFactorize(p);
     105def T= absFactorizeBCG(p);
    106106setring T;
    107107absolute_factors;
     
    114114absolute_factors;
    115115setring r;
    116 def T= absBiFactorize(p,"s");
     116def T= absFactorizeBCG(p,"s");
    117117setring T;
    118118absolute_factors;
     
    125125absolute_factors;
    126126setring r;
    127 def T= absBiFactorize(p,"s");
     127def T= absFactorizeBCG(p,"s");
    128128setring T;
    129129absolute_factors;
     
    136136absolute_factors;
    137137setring r;
    138 def T= absBiFactorize(p,"s");
     138def T= absFactorizeBCG(p,"s");
    139139setring T;
    140140absolute_factors;
     
    146146absolute_factors;
    147147setring R1;
    148 def T= absBiFactorize(f);
     148def T= absFactorizeBCG(f);
    149149setring T;
    150150absolute_factors;
     
    156156absolute_factors;
    157157setring R3;
    158 def T=absBiFactorize (f3);
     158def T=absFactorizeBCG (f3);
     159setring T;
     160absolute_factors;
     161
     162ring r2=0,(x,y,z,w),dp;
     163poly f=(x2+y2+z2)^2+w4;
     164def S =absFactorize(f);
     165setring(S);
     166absolute_factors;
     167setring r2;
     168def T=absFactorizeBCG (f);
     169setring T;
     170absolute_factors;
     171
     172ring r1=(0,a,b),(x,y),dp;
     173poly p=(a3-a2b+27ab3-27b4)/(a+b5)*x2+(a2+27b3)*y;
     174def S = absFactorize(p);
     175setring(S);
     176absolute_factors;
     177setring r1;
     178def T=absFactorizeBCG (p);
     179setring T;
     180absolute_factors;
     181
     182ring r3=0,(x,y,z,w),dp;
     183poly f=(x2+y2+z2)^4+w8;
     184tst_status();
     185def S =absFactorize(f);
     186tst_status();
     187setring(S);
     188absolute_factors;
     189setring r3;
     190tst_status();
     191def T=absFactorizeBCG (f);
     192tst_status();
     193setring T;
     194absolute_factors;
     195
     196ring R = 0, (x,y,z), dp;
     197poly f = y4+z2-y2*(1-x2);
     198def S = absFactorize(f);
     199setring S;
     200absolute_factors;
     201setring R;
     202def T=absFactorizeBCG (f);
    159203setring T;
    160204absolute_factors;
  • Tst/Short/ok_s.lst

    r62e51f rd51d87  
    11;; Test which should pass shifted exponents
    2 absbifact
     2absfact
    33abusalem
    44alexpoly
  • factory/Makefile.am

    r62e51f rd51d87  
    6363                DegreePattern.cc \
    6464                ExtensionInfo.cc \
     65                facAbsBiFact.cc \
    6566                facAbsFact.cc \
    6667                facAlgExt.cc \
     
    146147                DegreePattern.h \
    147148                ExtensionInfo.h \
     149                facAbsBiFact.h \
    148150                facAbsFact.h \
    149151                facAlgExt.h \
  • factory/cfNewtonPolygon.cc

    r62e51f rd51d87  
    6565bool isLess (int* point1, int* point2)
    6666{
    67   int area= point1[0]*point2[1]- point1[1]*point2[0];
     67  long area= point1[0]*point2[1]- point1[1]*point2[0];
    6868  if (area > 0) return true;
    6969  if (area == 0)
     
    108108bool isConvex (int* point1, int* point2, int* point3)
    109109{
    110   int relArea= (point1[0] - point2[0])*(point3[1] - point2[1]) -
    111                (point1[1] - point2[1])*(point3[0] - point2[0]);
     110  long relArea= (point1[0] - point2[0])*(point3[1] - point2[1]) -
     111                (point1[1] - point2[1])*(point3[0] - point2[0]);
    112112  if (relArea < 0)
    113113    return true;
     
    153153  if (i + 1 <= sizePoints || i == sizePoints)
    154154  {
    155     int relArea=
     155    long relArea=
    156156    (points [i-2][0] - points [i-1][0])*(points [0][1] - points [i-1][1])-
    157157    (points [i-2][1] - points [i-1][1])*(points [0][0] - points [i-1][0]);
     
    11731173
    11741174  if (isRat)
     1175  {
    11751176    ASSERT (bCommonDen (F).isOne(), "poly over Z expected");
     1177  }
    11761178
    11771179  CanonicalForm Fp, N= maxNorm (F);
     
    12501252
    12511253  if (isRat)
     1254  {
    12521255    ASSERT (bCommonDen (F).isOne(), "poly over Z expected");
     1256  }
    12531257
    12541258  Variable x= Variable (1);
  • factory/facAbsFact.cc

    r62e51f rd51d87  
    1616#include "debug.h"
    1717
     18#include "facAbsBiFact.h"
    1819#include "facAbsFact.h"
    19 #include "facBivar.h"
    20 #include "facFqBivar.h"
     20#include "facFqFactorize.h"
     21#include "facFqFactorizeUtil.h"
     22#include "facHensel.h"
     23#include "facSparseHensel.h"
     24#include "facFactorize.h"
    2125#include "cf_reval.h"
    2226#include "cf_primes.h"
    2327#include "cf_algorithm.h"
     28#include "cfModResultant.h"
    2429#ifdef HAVE_FLINT
    2530#include "FLINTconvert.h"
    26 #include <flint/fmpz_poly_factor.h>
    2731#endif
    2832#ifdef HAVE_NTL
     
    3236
    3337#ifdef HAVE_NTL
    34 
    35 TIMING_DEFINE_PRINT(fac_Qa_factorize)
    36 TIMING_DEFINE_PRINT(fac_evalpoint)
    37 
    38 //TODO optimize choice of p -> choose p as large as possible (better than small p since factorization mod p does not require field extension, also less lifting)
    39 int choosePoint (const CanonicalForm& F, int tdegF, CFArray& eval, bool rec)
     38TIMING_DEFINE_PRINT(abs_fac_bi_factorizer)
     39TIMING_DEFINE_PRINT(abs_fac_hensel_lift)
     40TIMING_DEFINE_PRINT(abs_fac_factor_recombination)
     41TIMING_DEFINE_PRINT(abs_fac_shift_to_zero)
     42TIMING_DEFINE_PRINT(abs_fac_precompute_leadcoeff)
     43TIMING_DEFINE_PRINT(abs_fac_evaluation)
     44TIMING_DEFINE_PRINT(abs_fac_recover_factors)
     45TIMING_DEFINE_PRINT(abs_fac_bifactor_total)
     46TIMING_DEFINE_PRINT(abs_fac_luckswang)
     47TIMING_DEFINE_PRINT(abs_fac_lcheuristic)
     48TIMING_DEFINE_PRINT(abs_fac_cleardenom)
     49TIMING_DEFINE_PRINT(abs_fac_compress)
     50
     51/// steps 4)-8) of Algorithm B.7.8. from Greuel, Pfister "A Singular
     52/// Introduction to Commutative Algebra"
     53CFAFList
     54RothsteinTragerResultant (const CanonicalForm& F, const CanonicalForm& w, int s,
     55                          const CFList& evaluation, const Variable& y)
    4056{
    41   REvaluation E1 (1, 1, IntRandom (25));
    42   REvaluation E2 (2, 2, IntRandom (25));
    43   if (rec)
    44   {
    45     E1.nextpoint();
    46     E2.nextpoint();
    47   }
    48   CanonicalForm f, f1, f2, Fp;
    49   int i, p;
    50   eval=CFArray (2);
    51   while (1)
    52   {
    53     f1= E1(F);
    54     if (!f1.isZero() && factorize (f1).length() == 2)
    55     {
    56       Off (SW_RATIONAL);
    57       f= E2(f1);
    58       f2= E2 (F);
    59       if ((!f.isZero()) && (abs(f)>cf_getSmallPrime (cf_getNumSmallPrimes()-1)))
    60       {
    61         for (i= cf_getNumPrimes()-1; i >= 0; i--)
    62         {
    63           if (f % CanonicalForm (cf_getPrime (i)) == 0)
    64           {
    65             p= cf_getPrime(i);
    66             Fp= mod (F,p);
    67             if (totaldegree (Fp) == tdegF &&
    68                 degree (mod (f2,p), 1) == degree (F,1) &&
    69                 degree (mod (f1, p),2) == degree (F,2))
    70             {
    71               eval[0]= E1[1];
    72               eval[1]= E2[2];
    73               return p;
    74             }
    75           }
    76         }
    77       }
    78       else if (!f.isZero())
    79       {
    80         for (i= cf_getNumSmallPrimes()-1; i >= 0; i--)
    81         {
    82           if (f % CanonicalForm (cf_getSmallPrime (i)) == 0)
    83           {
    84             p= cf_getSmallPrime (i);
    85             Fp= mod (F,p);
    86             if (totaldegree (Fp) == tdegF &&
    87                 degree (mod (f2, p),1) == degree (F,1) &&
    88                 degree (mod (f1,p),2) == degree (F,2))
    89             {
    90               eval[0]= E1[1];
    91               eval[1]= E2[2];
    92               return p;
    93             }
    94           }
    95         }
    96       }
    97       E2.nextpoint();
    98       On (SW_RATIONAL);
    99     }
    100     E1.nextpoint();
    101   }
    102   return 0;
     57  CFList terms;
     58  for (CFIterator i= w; i.hasTerms(); i++)
     59    terms.append (i.coeff());
     60
     61  Variable x= Variable (1);
     62  CanonicalForm derivF= deriv (F, x);
     63  CanonicalForm g, geval, derivFeval, Feval, H, res, sqrfPartRes;
     64  CFListIterator iter;
     65
     66  REvaluation E (1, terms.length(), IntRandom (25));
     67
     68  do
     69  {
     70    E.nextpoint();
     71    g= 0;
     72    iter= terms;
     73    for (int i= terms.length(); i >= 1; i--, iter++)
     74      g += E[i]*iter.getItem();
     75
     76    geval= g;
     77    Feval= F;
     78    derivFeval= derivF;
     79    iter= evaluation;
     80    for (int i= F.level(); i >= 2; iter++, i--)
     81    {
     82      Feval= Feval (iter.getItem(), i);
     83      geval= geval (iter.getItem(), i);
     84      derivFeval= derivFeval (iter.getItem(), i);
     85    }
     86
     87    H= y*derivFeval-geval;
     88
     89    if (degree (Feval, x) >= 8 || degree (H, x) >= 8)
     90      res= resultantZ (Feval, H, x);
     91    else
     92      res= resultant (Feval, H, x);
     93
     94    sqrfPartRes= sqrfPart (res); //univariate poly in y
     95  }
     96  while (degree (sqrfPartRes) != s);
     97
     98  Variable beta= rootOf (sqrfPartRes);
     99
     100  CanonicalForm factor= gcd (F, beta*derivF-g);
     101
     102  return CFAFList (CFAFactor (factor, getMipo (beta), 1));
    103103}
    104104
    105 //G is assumed to be bivariate, irreducible over Q, primitive wrt x and y, compressed
    106 CFAFList absFactorizeMain (const CanonicalForm& G)
     105
     106/// Algorithm B.7.8 from Greuel, Pfister "A Singular Introduction to Commutative
     107/// Algebra"
     108CFAFList
     109RothsteinTrager (const CanonicalForm& F, const CFList& factors,
     110                 const Variable& alpha, const CFList& evaluation)
    107111{
    108   CanonicalForm F= bCommonDen (G)*G;
    109   Off (SW_RATIONAL);
    110   F /= icontent (F);
    111   On (SW_RATIONAL);
    112   CFArray eval;
    113   int minTdeg, tdegF= totaldegree (F);
    114   CanonicalForm Fp, smallestFactor;
    115   int p;
    116   CFFList factors;
    117   Variable alpha;
    118   bool rec= false;
    119112  Variable x= Variable (1);
    120   Variable y= Variable (2);
    121   CanonicalForm bufF= F;
    122   CFFListIterator iter;
    123 differentevalpoint:
    124   while (1)
    125   {
    126     TIMING_START (fac_evalpoint);
    127     p= choosePoint (F, tdegF, eval, rec);
    128     TIMING_END_AND_PRINT (fac_evalpoint, "time to find eval point: ");
    129 
    130     setCharacteristic (p);
    131     Fp=F.mapinto();
    132     factors= factorize (Fp);
    133 
    134     if (factors.getFirst().factor().inCoeffDomain())
    135       factors.removeFirst();
    136 
    137     if (factors.length() == 1 && factors.getFirst().exp() == 1)
    138     {
    139       if (absIrredTest (Fp))
    140       {
    141         setCharacteristic(0);
    142         return CFAFList (CFAFactor (G, 1, 1));
    143       }
     113  ASSERT (factors.length() == 2, "expected two factors");
     114  CanonicalForm G, H;
     115  if (totaldegree (factors.getFirst()) > totaldegree (factors.getLast()))
     116  {
     117    H= factors.getLast();
     118    G= factors.getFirst();
     119  }
     120  else
     121  {
     122    H= factors.getFirst();
     123    G= factors.getLast();
     124  }
     125  CanonicalForm derivH= deriv (H, x);
     126  CanonicalForm w= G*derivH;
     127  Variable y= Variable (F.level()+1);
     128  w= replacevar (w, alpha, y);
     129
     130  int s= totaldegree (F)/totaldegree (H);
     131
     132  return RothsteinTragerResultant (F, w, s, evaluation, y);
     133}
     134
     135CFList
     136evalPoints4AbsFact (const CanonicalForm& F, CFList& eval, Evaluation& E,
     137                    int& intervalSize)
     138{
     139  CFList result;
     140  Variable x= Variable (1);
     141
     142  CanonicalForm LCF= LC (F, x);
     143  CFList LCFeval= CFList();
     144
     145  bool found= false;
     146  bool allZero= true;
     147  bool foundZero= false;
     148  CanonicalForm deriv_x, gcd_deriv;
     149  CFFList uniFactors;
     150  CFListIterator iter;
     151  int count= 0;
     152  do
     153  {
     154    count++;
     155    if (count==E.max() - E.min() + 1)
     156    {
     157      count= 1;
     158      intervalSize++;
     159      E= REvaluation (E.min(), E.max(), IntRandom (intervalSize));
     160      E.nextpoint();
     161    }
     162    eval.insert (F);
     163    LCFeval.insert (LCF);
     164    bool bad= false;
     165    for (int i= E.max(); i >= E.min(); i--)
     166    {
     167      eval.insert (eval.getFirst()( E [i], i));
     168      LCFeval.insert (LCFeval.getFirst()( E [i], i));
     169      result.append (E[i]);
     170      if (!E[i].isZero())
     171        allZero= false;
    144172      else
    145       {
    146         setCharacteristic (0);
    147         if (modularIrredTestWithShift (F))
    148         {
    149           return CFAFList (CFAFactor (G, 1, 1));
    150         }
    151         rec= true;
    152         continue;
    153       }
    154     }
    155     iter= factors;
    156     smallestFactor= iter.getItem().factor();
    157     while (smallestFactor.isUnivariate() && iter.hasItem())
    158     {
    159       iter++;
    160       if (!iter.hasItem())
     173        foundZero= true;
     174      if (!allZero && foundZero)
     175      {
     176        result= CFList();
     177        eval= CFList();
     178        LCFeval= CFList();
     179        bad= true;
     180        foundZero= false;
    161181        break;
    162       smallestFactor= iter.getItem().factor();
    163     }
    164 
    165     minTdeg= totaldegree (smallestFactor);
    166     if (iter.hasItem())
    167       iter++;
    168     for (; iter.hasItem(); iter++)
    169     {
    170       if (!iter.getItem().factor().isUnivariate() &&
    171           (totaldegree (iter.getItem().factor()) < minTdeg))
    172       {
    173         smallestFactor= iter.getItem().factor();
    174         minTdeg= totaldegree (smallestFactor);
    175       }
    176     }
    177     if (tdegF % minTdeg == 0)
    178       break;
    179     setCharacteristic(0);
    180     rec=true;
    181   }
    182   CanonicalForm Gp= Fp/smallestFactor;
    183   Gp= Gp /Lc (Gp);
    184 
    185   CanonicalForm Gpy= Gp (eval[0].mapinto(), 1);
    186   CanonicalForm smallestFactorEvaly= smallestFactor (eval[0].mapinto(),1);
    187   CanonicalForm Gpx= Gp (eval[1].mapinto(), 2);
    188   CanonicalForm smallestFactorEvalx= smallestFactor (eval[1].mapinto(),2);
    189 
    190   bool xValid= !(Gpx.inCoeffDomain() || smallestFactorEvalx.inCoeffDomain() ||
    191                !gcd (Gpx, smallestFactorEvalx).inCoeffDomain());
    192   bool yValid= !(Gpy.inCoeffDomain() || smallestFactorEvaly.inCoeffDomain() ||
    193                !gcd (Gpy, smallestFactorEvaly).inCoeffDomain());
    194   if (!xValid && !yValid)
    195   {
    196     rec= true;
    197     setCharacteristic (0);
    198     goto differentevalpoint;
    199   }
    200 
    201   setCharacteristic (0);
    202 
    203   CanonicalForm mipo;
    204 
    205   int loop, i;
    206   if (xValid && yValid)
    207   {
    208     loop= 3;
    209     i=1;
    210   }
    211   else if (xValid)
    212   {
    213     loop= 3;
    214     i=2;
    215   }
    216   else
    217   {
    218     loop= 2;
    219     i=1;
    220   }
    221 
    222   CFArray mipos= CFArray (loop-i);
    223   for (; i < loop; i++)
    224   {
    225     CanonicalForm Fi= F(eval[i-1],i);
    226 
    227     int s= tdegF/minTdeg + 1;
    228     CanonicalForm bound= power (maxNorm (Fi), 2*(s-1));
    229     bound *= power (CanonicalForm (s),s-1);
    230     bound *= power (CanonicalForm (2), ((s-1)*(s-1))/2); //possible int overflow
    231 
    232     CanonicalForm B = p;
    233     long k = 1L;
    234     while ( B < bound ) {
    235       B *= p;
    236       k++;
    237     }
    238 
    239     //TODO take floor (log2(k))
    240     k= k+1;
    241 #ifdef HAVE_FLINT
    242     fmpz_poly_t FLINTFi;
    243     convertFacCF2Fmpz_poly_t (FLINTFi, Fi);
    244     setCharacteristic (p);
    245     nmod_poly_t FLINTFpi, FLINTGpi;
    246     if (i == 2)
    247     {
    248       convertFacCF2nmod_poly_t (FLINTFpi,
    249                                 smallestFactorEvalx/lc (smallestFactorEvalx));
    250       convertFacCF2nmod_poly_t (FLINTGpi, Gpx/lc (Gpx));
    251     }
    252     else
    253     {
    254       convertFacCF2nmod_poly_t (FLINTFpi,
    255                                 smallestFactorEvaly/lc (smallestFactorEvaly));
    256       convertFacCF2nmod_poly_t (FLINTGpi, Gpy/lc (Gpy));
    257     }
    258     nmod_poly_factor_t nmodFactors;
    259     nmod_poly_factor_init (nmodFactors);
    260     nmod_poly_factor_insert (nmodFactors, FLINTFpi, 1L);
    261     nmod_poly_factor_insert (nmodFactors, FLINTGpi, 1L);
    262 
    263     long * link= new long [2];
    264     fmpz_poly_t *v= new fmpz_poly_t[2];
    265     fmpz_poly_t *w= new fmpz_poly_t[2];
    266     fmpz_poly_init(v[0]);
    267     fmpz_poly_init(v[1]);
    268     fmpz_poly_init(w[0]);
    269     fmpz_poly_init(w[1]);
    270 
    271     fmpz_poly_factor_t liftedFactors;
    272     fmpz_poly_factor_init (liftedFactors);
    273     _fmpz_poly_hensel_start_lift (liftedFactors, link, v, w, FLINTFi,
    274                                   nmodFactors, k);
    275 
    276     nmod_poly_factor_clear (nmodFactors);
    277     nmod_poly_clear (FLINTFpi);
    278     nmod_poly_clear (FLINTGpi);
    279 
    280     setCharacteristic(0);
    281     CanonicalForm liftedSmallestFactor=
    282     convertFmpz_poly_t2FacCF ((fmpz_poly_t &)liftedFactors->p[0],x);
    283 
    284     CanonicalForm otherFactor=
    285     convertFmpz_poly_t2FacCF ((fmpz_poly_t &)liftedFactors->p[1],x);
    286     modpk pk= modpk (p, k);
    287 #else
    288     modpk pk= modpk (p, k);
    289     ZZX NTLFi=convertFacCF2NTLZZX (pk (Fi*pk.inverse (lc(Fi))));
    290     setCharacteristic (p);
    291 
    292     if (fac_NTL_char != p)
    293     {
    294       fac_NTL_char= p;
    295       zz_p::init (p);
    296     }
    297     zz_pX NTLFpi, NTLGpi;
    298     if (i == 2)
    299     {
    300       NTLFpi= convertFacCF2NTLzzpX (smallestFactorEvalx/lc (smallestFactorEvalx));
    301       NTLGpi= convertFacCF2NTLzzpX (Gpx/lc (Gpx));
    302     }
    303     else
    304     {
    305       NTLFpi= convertFacCF2NTLzzpX (smallestFactorEvaly/lc (smallestFactorEvaly));
    306       NTLGpi= convertFacCF2NTLzzpX (Gpy/lc (Gpy));
    307     }
    308     vec_zz_pX modFactors;
    309     modFactors.SetLength(2);
    310     modFactors[0]= NTLFpi;
    311     modFactors[1]= NTLGpi;
    312     vec_ZZX liftedFactors;
    313     MultiLift (liftedFactors, modFactors, NTLFi, (long) k);
    314     setCharacteristic(0);
    315     CanonicalForm liftedSmallestFactor=
    316                   convertNTLZZX2CF (liftedFactors[0], x);
    317 
    318     CanonicalForm otherFactor=
    319                   convertNTLZZX2CF (liftedFactors[1], x);
    320 #endif
    321 
    322     Off (SW_SYMMETRIC_FF);
    323     liftedSmallestFactor= pk (liftedSmallestFactor);
    324     if (i == 2)
    325       liftedSmallestFactor= liftedSmallestFactor (eval[0],1);
    326     else
    327       liftedSmallestFactor= liftedSmallestFactor (eval[1],1);
    328 
    329     On (SW_SYMMETRIC_FF);
    330     CFMatrix M= CFMatrix (s, s);
    331     M(s,s)= power (CanonicalForm (p), k);
    332     for (int j= 1; j < s; j++)
    333     {
    334       M (j,j)= 1;
    335       M (j+1,j)= -liftedSmallestFactor;
    336     }
    337 
    338     mat_ZZ NTLM= *convertFacCFMatrix2NTLmat_ZZ (M);
    339 
    340     ZZ det;
    341 
    342     transpose (NTLM, NTLM);
    343     (void) LLL (det, NTLM, 1L, 1L); //use floating point LLL ?
    344     transpose (NTLM, NTLM);
    345     M= *convertNTLmat_ZZ2FacCFMatrix (NTLM);
    346 
    347     mipo= 0;
    348     for (int j= 1; j <= s; j++)
    349       mipo += M (j,1)*power (x,s-j);
    350 
    351     CFFList mipoFactors= factorize (mipo);
    352     mipoFactors.removeFirst();
    353 
    354 #ifdef HAVE_FLINT
    355     fmpz_poly_clear (v[0]);
    356     fmpz_poly_clear (v[1]);
    357     fmpz_poly_clear (w[0]);
    358     fmpz_poly_clear (w[1]);
    359     delete [] v;
    360     delete [] w;
    361     delete [] link;
    362     fmpz_poly_factor_clear (liftedFactors);
    363 #endif
    364 
    365     if (mipoFactors.length() > 1 ||
    366         (mipoFactors.length() == 1 && mipoFactors.getFirst().exp() > 1))
    367     {
    368       if (i+1 >= loop && ((loop-i == 1) || (loop-i==2 && mipos[0].isZero())))
    369       {
    370         rec=true;
    371         goto differentevalpoint;
    372       }
    373     }
    374     else
    375       mipos[loop-i-1]= mipo;
    376   }
    377 
    378   On (SW_RATIONAL);
    379   if (xValid && yValid && !mipos[0].isZero() && !mipos[1].isZero())
    380   {
    381     if (maxNorm (mipos[0]) < maxNorm (mipos[1]))
    382       alpha= rootOf (mipos[0]);
    383     else
    384       alpha= rootOf (mipos[1]);
    385   }
    386   else if (xValid && yValid)
    387   {
    388     if (mipos[0].isZero())
    389       alpha= rootOf (mipos[1]);
    390     else
    391       alpha= rootOf (mipos[0]);
    392   }
    393   else
    394     alpha= rootOf (mipo);
    395 
    396   CanonicalForm F1;
    397   CFFList QaF1Factors;
    398   int wrongMipo= 0;
    399   if (xValid && yValid)
    400   {
    401     if (degree (F,1) > minTdeg)
    402       F1= F (eval[1], 2);
    403     else
    404       F1= F (eval[0], 1);
    405   }
    406   else if (xValid)
    407     F1= F (eval[1], 2);
    408   else
    409     F1= F (eval[0], 1);
    410 
    411   bool swap= false;
    412   if (F1.level() == 2)
    413   {
    414     swap= true;
    415     F1=swapvar (F1, x, y);
    416     F= swapvar (F, x, y);
    417   }
    418 
    419   QaF1Factors= factorize (F1, alpha);
    420   if (QaF1Factors.getFirst().factor().inCoeffDomain())
    421     QaF1Factors.removeFirst();
    422   for (iter= QaF1Factors; iter.hasItem(); iter++)
    423   {
    424     if (degree (iter.getItem().factor()) > minTdeg)
    425       wrongMipo++;
    426   }
    427 
    428   if (wrongMipo == QaF1Factors.length())
    429   {
    430     if (xValid && yValid && !mipos[0].isZero() && !mipos[1].isZero())
    431     {
    432       if (maxNorm (mipos[0]) < maxNorm (mipos[1])) //try the other minpoly
    433         alpha= rootOf (mipos[1]);
    434       else
    435         alpha= rootOf (mipos[0]);
    436     }
    437     else
    438     {
    439       rec= true;
    440       F= bufF;
    441       goto differentevalpoint;
    442     }
    443 
    444     wrongMipo= 0;
    445     QaF1Factors= factorize (F1, alpha);
    446     if (QaF1Factors.getFirst().factor().inCoeffDomain())
    447       QaF1Factors.removeFirst();
    448     for (iter= QaF1Factors; iter.hasItem(); iter++)
    449     {
    450       if (degree (iter.getItem().factor()) > minTdeg)
    451         wrongMipo++;
    452     }
    453     if (wrongMipo == QaF1Factors.length())
    454     {
    455       rec= true;
    456       F= bufF;
    457       goto differentevalpoint;
    458     }
    459   }
    460 
    461   CanonicalForm evaluation;
    462   if (swap)
    463     evaluation= eval[0];
    464   else
    465     evaluation= eval[1];
    466 
    467   F *= bCommonDen (F);
    468   F= F (y + evaluation, y);
    469 
    470   int liftBound= degree (F,y) + 1;
    471 
    472   modpk b= modpk();
    473 
    474   CanonicalForm den= 1;
    475 
    476   mipo= getMipo (alpha);
    477 
    478   CFList uniFactors;
    479   for (iter=QaF1Factors; iter.hasItem(); iter++)
    480     uniFactors.append (iter.getItem().factor());
    481 
    482   F /= Lc (F1);
    483   ZZX NTLmipo= convertFacCF2NTLZZX (mipo);
    484   ZZX NTLLcf= convertFacCF2NTLZZX (Lc (F*bCommonDen (F)));
    485   ZZ NTLf= resultant (NTLmipo, NTLLcf);
    486   ZZ NTLD= discriminant (NTLmipo);
    487   den= abs (convertZZ2CF (NTLD*NTLf));
    488 
    489   // make factors elements of Z(a)[x] disable for modularDiophant
    490   CanonicalForm multiplier= 1;
    491   for (CFListIterator i= uniFactors; i.hasItem(); i++)
    492   {
    493     multiplier *= bCommonDen (i.getItem());
    494     i.getItem()= i.getItem()*bCommonDen(i.getItem());
    495   }
    496   F *= multiplier;
    497   F *= bCommonDen (F);
    498 
    499   Off (SW_RATIONAL);
    500   int ii= 0;
    501   CanonicalForm discMipo= convertZZ2CF (NTLD);
    502   findGoodPrime (bufF*discMipo,ii);
    503   findGoodPrime (F1*discMipo,ii);
    504   findGoodPrime (F*discMipo,ii);
    505 
    506   int pp=cf_getBigPrime(ii);
    507   b = coeffBound( F, pp, mipo );
    508   modpk bb= coeffBound (F1, pp, mipo);
    509   if (bb.getk() > b.getk() ) b=bb;
    510     bb= coeffBound (F, pp, mipo);
    511   if (bb.getk() > b.getk() ) b=bb;
    512 
    513   ExtensionInfo dummy= ExtensionInfo (alpha, false);
    514   DegreePattern degs= DegreePattern (uniFactors);
    515 
    516   bool earlySuccess= false;
    517   CFList earlyFactors;
    518   uniFactors= henselLiftAndEarly
    519               (F, earlySuccess, earlyFactors, degs, liftBound,
    520                uniFactors, dummy, evaluation, b, den);
    521   DEBOUTLN (cerr, "lifted factors= " << uniFactors);
    522 
    523   CanonicalForm MODl= power (y, liftBound);
    524 
    525   On (SW_RATIONAL);
    526   F *= bCommonDen (F);
    527   Off (SW_RATIONAL);
    528 
    529   CFList biFactors;
    530 
    531   biFactors= factorRecombination (uniFactors, F, MODl, degs, evaluation, 1,
    532                                   uniFactors.length()/2, b, den);
    533 
    534   On (SW_RATIONAL);
    535 
    536   if (earlySuccess)
    537     biFactors= Union (earlyFactors, biFactors);
    538   else if (!earlySuccess && degs.getLength() == 1)
    539     biFactors= earlyFactors;
    540 
    541   bool swap2= false;
    542   appendSwapDecompress (biFactors, CFList(), CFList(), swap, swap2, CFMap());
    543   if (isOn (SW_RATIONAL))
    544     normalize (biFactors);
    545 
    546   CFAFList result;
    547   bool found= false;
    548 
    549   for (CFListIterator i= biFactors; i.hasItem(); i++)
    550   {
    551     if (totaldegree (i.getItem()) == minTdeg)
    552     {
    553       result= CFAFList (CFAFactor (i.getItem(), getMipo (alpha), 1));
    554       found= true;
    555       break;
    556     }
    557   }
    558 
    559   if (!found)
    560   {
    561     rec= true;
    562     F= bufF;
    563     goto differentevalpoint;
    564   }
    565 
     182      }
     183      if (degree (eval.getFirst(), i - 1) != degree (F, i - 1))
     184      {
     185        result= CFList();
     186        LCFeval= CFList();
     187        eval= CFList();
     188        bad= true;
     189        break;
     190      }
     191      if ((i != 2) && (degree (LCFeval.getFirst(), i-1) != degree (LCF, i-1)))
     192      {
     193        result= CFList();
     194        LCFeval= CFList();
     195        eval= CFList();
     196        bad= true;
     197        break;
     198      }
     199    }
     200
     201    if (bad)
     202    {
     203      E.nextpoint();
     204      continue;
     205    }
     206
     207    if (degree (eval.getFirst()) != degree (F, 1))
     208    {
     209      result= CFList();
     210      eval= CFList();
     211      LCFeval= CFList();
     212      E.nextpoint();
     213      continue;
     214    }
     215
     216    deriv_x= deriv (eval.getFirst(), x);
     217    gcd_deriv= gcd (eval.getFirst(), deriv_x);
     218    if (degree (gcd_deriv) > 0)
     219    {
     220      result= CFList();
     221      eval= CFList();
     222      LCFeval= CFList();
     223      E.nextpoint();
     224      continue;
     225    }
     226    uniFactors= factorize (eval.getFirst());
     227    if (uniFactors.getFirst().factor().inCoeffDomain())
     228      uniFactors.removeFirst();
     229    if (uniFactors.length() > 1 || uniFactors.getFirst().exp() > 1)
     230    {
     231      result= CFList();
     232      eval= CFList();
     233      LCFeval= CFList();
     234      E.nextpoint();
     235      continue;
     236    }
     237    iter= eval;
     238    iter++;
     239    CanonicalForm contentx= content (iter.getItem(), x);
     240    if (degree (contentx) > 0)
     241    {
     242      result= CFList();
     243      eval= CFList();
     244      LCFeval= CFList();
     245      E.nextpoint();
     246      continue;
     247    }
     248    found= true;
     249  }
     250  while (!found);
     251
     252  if (!eval.isEmpty())
     253    eval.removeFirst();
    566254  return result;
    567255}
    568256
    569 #endif
    570 
    571 #ifdef HAVE_NTL
    572 /// absolute factorization of bivariate poly over Q
    573 ///
    574 /// @return absFactorize returns a list whose entries contain three entities:
    575 ///         an absolute irreducible factor, an irreducible univariate polynomial
    576 ///         that defines the minimal field extension over which the irreducible
    577 ///         factor is defined and the multiplicity of the absolute irreducible
    578 ///         factor
    579 CFAFList absFactorize (const CanonicalForm& G ///<[in] bivariate poly over Q
    580                       )
     257CFAFList absFactorize (const CanonicalForm& G
     258                           )
    581259{
    582   //TODO handle homogeneous input
    583   ASSERT (getNumVars (G) <= 2, "expected bivariate input");
     260  //TODO handle homogeneous input, is already done in LIB interface but still...
    584261  ASSERT (getCharacteristic() == 0, "expected poly over Q");
    585262
    586   CFMap N;
    587   CanonicalForm F= compress (G, N);
     263  CanonicalForm F= G;
     264
     265  CanonicalForm LcF= Lc (F);
    588266  bool isRat= isOn (SW_RATIONAL);
    589267  if (isRat)
     
    595273    On (SW_RATIONAL);
    596274
    597   CanonicalForm contentX= content (F, 1);
    598   CanonicalForm contentY= content (F, 2);
    599   F /= (contentX*contentY);
    600   CFAFList contentXFactors, contentYFactors;
    601   contentXFactors= uniAbsFactorize (contentX);
    602   contentYFactors= uniAbsFactorize (contentY);
    603 
    604   if (contentXFactors.getFirst().factor().inCoeffDomain())
    605     contentXFactors.removeFirst();
    606   if (contentYFactors.getFirst().factor().inCoeffDomain())
    607     contentYFactors.removeFirst();
    608   if (F.inCoeffDomain())
    609   {
    610     CFAFList result;
    611     for (CFAFListIterator i= contentXFactors; i.hasItem(); i++)
    612       result.append (CFAFactor (N (i.getItem().factor()), i.getItem().minpoly(),
    613                                 i.getItem().exp()));
    614     for (CFAFListIterator i= contentYFactors; i.hasItem(); i++)
    615       result.append (CFAFactor (N (i.getItem().factor()),i.getItem().minpoly(),
    616                                 i.getItem().exp()));
    617     normalize (result);
    618     result.insert (CFAFactor (Lc (G), 1, 1));
    619     return result;
    620   }
    621275  CFFList rationalFactors= factorize (F);
    622276
     
    635289  }
    636290
    637   for (CFAFListIterator i= result; i.hasItem(); i++)
    638     i.getItem()= CFAFactor (N (i.getItem().factor()), i.getItem().minpoly(),
    639                             i.getItem().exp());
    640   for (CFAFListIterator i= contentXFactors; i.hasItem(); i++)
    641     result.append (CFAFactor (N(i.getItem().factor()), i.getItem().minpoly(),
    642                               i.getItem().exp()));
    643   for (CFAFListIterator i= contentYFactors; i.hasItem(); i++)
    644     result.append (CFAFactor (N(i.getItem().factor()), i.getItem().minpoly(),
    645                               i.getItem().exp()));
    646   normalize (result);
    647   result.insert (CFAFactor (Lc(G), 1, 1));
     291  if (isRat)
     292    normalize (result);
     293  result.insert (CFAFactor (LcF, 1, 1));
    648294
    649295  return result;
    650296}
     297
     298CFAFList absFactorizeMain (const CanonicalForm& G)
     299{
     300  CanonicalForm F= bCommonDen (G)*G;
     301
     302  Off (SW_RATIONAL);
     303  F /= icontent (F);
     304  On (SW_RATIONAL);
     305
     306  if (F.inCoeffDomain())
     307    return CFAFList (CFAFactor (F, 1, 1));
     308
     309  // compress and find main Variable
     310  CFMap N;
     311  TIMING_START (abs_fac_compress)
     312  CanonicalForm A= myCompress (F, N);
     313  TIMING_END_AND_PRINT (abs_fac_compress,
     314                        "time to compress poly in abs fact: ")
     315
     316  //univariate case
     317  if (F.isUnivariate())
     318  {
     319    CFAFList result;
     320    result= uniAbsFactorize (F);
     321    if (result.getFirst().factor().inCoeffDomain())
     322      result.removeFirst();
     323    return result;
     324  }
     325
     326  //bivariate case
     327  if (A.level() == 2)
     328  {
     329    CFAFList result= absBiFactorizeMain (A);
     330    decompress (result, N);
     331    return result; //needs compressed input
     332  }
     333
     334  Variable x= Variable (1);
     335  Variable y= Variable (2);
     336
     337  CFAFList factors;
     338  A *= bCommonDen (A);
     339  CFList Aeval, list, evaluation, bufEvaluation, bufAeval;
     340  int factorNums= 1;
     341  CFAFList absBiFactors, absBufBiFactors;
     342  CanonicalForm evalPoly;
     343  int lift, bufLift, lengthAeval2= A.level()-2;
     344  CFList* bufAeval2= new CFList [lengthAeval2];
     345  CFList* Aeval2= new CFList [lengthAeval2];
     346  int counter;
     347  int differentSecondVar= 0;
     348  CanonicalForm bufA;
     349
     350  // several bivariate factorizations
     351  TIMING_START (abs_fac_bifactor_total);
     352  int absValue= 2;
     353  REvaluation E (2, A.level(), IntRandom (absValue));
     354  for (int i= 0; i < factorNums; i++)
     355  {
     356    counter= 0;
     357    bufA= A;
     358    bufAeval= CFList();
     359    TIMING_START (abs_fac_evaluation);
     360    bufEvaluation= evalPoints4AbsFact (bufA, bufAeval, E, absValue);
     361    TIMING_END_AND_PRINT (abs_fac_evaluation,
     362                          "time to find evaluation point in abs fact: ");
     363    E.nextpoint();
     364    evalPoly= 0;
     365
     366    TIMING_START (abs_fac_evaluation);
     367    evaluationWRTDifferentSecondVars (bufAeval2, bufEvaluation, A);
     368    TIMING_END_AND_PRINT (abs_fac_evaluation,
     369                          "time to eval wrt diff second vars in abs fact: ");
     370
     371    for (int j= 0; j < lengthAeval2; j++)
     372    {
     373      if (!bufAeval2[j].isEmpty())
     374        counter++;
     375    }
     376
     377    bufLift= degree (A, y) + 1 + degree (LC(A, x), y);
     378
     379    TIMING_START (abs_fac_bi_factorizer);
     380    absBufBiFactors= absBiFactorizeMain (bufAeval.getFirst(), true);
     381    TIMING_END_AND_PRINT (abs_fac_bi_factorizer,
     382                          "time for bivariate factorization in abs fact: ");
     383
     384    if (absBufBiFactors.length() == 1)
     385    {
     386      factors.append (CFAFactor (A, 1, 1));
     387      decompress (factors, N);
     388      if (isOn (SW_RATIONAL))
     389        normalize (factors);
     390      delete [] bufAeval2;
     391      delete [] Aeval2;
     392      return factors;
     393    }
     394
     395    if (i == 0)
     396    {
     397      Aeval= bufAeval;
     398      evaluation= bufEvaluation;
     399      absBiFactors= absBufBiFactors;
     400      lift= bufLift;
     401      for (int j= 0; j < lengthAeval2; j++)
     402        Aeval2 [j]= bufAeval2 [j];
     403      differentSecondVar= counter;
     404    }
     405    else
     406    {
     407      if (absBufBiFactors.length() < absBiFactors.length() ||
     408          ((bufLift < lift) &&
     409          (absBufBiFactors.length() == absBiFactors.length())) ||
     410          counter > differentSecondVar)
     411      {
     412        Aeval= bufAeval;
     413        evaluation= bufEvaluation;
     414        absBiFactors= absBufBiFactors;
     415        lift= bufLift;
     416        for (int j= 0; j < lengthAeval2; j++)
     417          Aeval2 [j]= bufAeval2 [j];
     418        differentSecondVar= counter;
     419      }
     420    }
     421    int k= 0;
     422    for (CFListIterator j= bufEvaluation; j.hasItem(); j++, k++)
     423      evalPoly += j.getItem()*power (x, k);
     424    list.append (evalPoly);
     425  }
     426
     427  delete [] bufAeval2;
     428
     429  CFList rationalFactors;
     430  Variable v= mvar (absBiFactors.getFirst().minpoly());
     431
     432  CFList biFactors;
     433  for (CFAFListIterator iter= absBiFactors; iter.hasItem(); iter++)
     434    biFactors.append (iter.getItem().factor());
     435
     436  sortList (biFactors, x);
     437
     438  int minFactorsLength;
     439  bool irred= false;
     440
     441  TIMING_START (abs_fac_bi_factorizer);
     442  factorizationWRTDifferentSecondVars (A, Aeval2, minFactorsLength, irred, v);
     443  TIMING_END_AND_PRINT (abs_fac_bi_factorizer,
     444         "time for bivariate factorization wrt diff second vars in abs fact: ");
     445
     446  TIMING_END_AND_PRINT (abs_fac_bifactor_total,
     447                        "total time for eval and bivar factors in abs fact: ");
     448  if (irred)
     449  {
     450    factors.append (CFAFactor (A, 1, 1));
     451    decompress (factors, N);
     452    if (isOn (SW_RATIONAL))
     453      normalize (factors);
     454    delete [] Aeval2;
     455    return factors;
     456  }
     457
     458  if (minFactorsLength == 0)
     459    minFactorsLength= biFactors.length();
     460  else if (biFactors.length() > minFactorsLength)
     461    refineBiFactors (A, biFactors, Aeval2, evaluation, minFactorsLength);
     462
     463  bool found= false;
     464  if (differentSecondVar == lengthAeval2)
     465  {
     466    bool zeroOccured= false;
     467    for (CFListIterator iter= evaluation; iter.hasItem(); iter++)
     468    {
     469      if (iter.getItem().isZero())
     470      {
     471        zeroOccured= true;
     472        break;
     473      }
     474    }
     475    if (!zeroOccured)
     476    {
     477      rationalFactors= sparseHeuristic (A, biFactors, Aeval2, evaluation,
     478                                       minFactorsLength);
     479      if (rationalFactors.length() == biFactors.length())
     480      {
     481        for (CFListIterator iter= rationalFactors; iter.hasItem(); iter++)
     482        {
     483          if (totaldegree(iter.getItem())*degree(getMipo(v)) == totaldegree (G))
     484          {
     485            factors= CFAFList (CFAFactor (iter.getItem(), getMipo (v), 1));
     486            found= true;
     487            break;
     488          }
     489        }
     490        // necessary since extension may be too large
     491        if (!found)
     492          factors= RothsteinTrager (A, rationalFactors, v, evaluation);
     493
     494        decompress (factors, N);
     495        normalize (factors);
     496        delete [] Aeval2;
     497        return factors;
     498      }
     499      else
     500        rationalFactors= CFList();
     501      //TODO case where factors.length() > 0
     502    }
     503  }
     504
     505  CFList uniFactors= buildUniFactors (biFactors, evaluation.getLast(), y);
     506
     507  sortByUniFactors (Aeval2, lengthAeval2, uniFactors, evaluation);
     508
     509  CFList * oldAeval= new CFList [lengthAeval2];
     510  for (int i= 0; i < lengthAeval2; i++)
     511    oldAeval[i]= Aeval2[i];
     512
     513  getLeadingCoeffs (A, Aeval2);
     514
     515  CFList biFactorsLCs;
     516  for (CFListIterator i= biFactors; i.hasItem(); i++)
     517    biFactorsLCs.append (LC (i.getItem(), 1));
     518
     519  Variable w;
     520  TIMING_START (abs_fac_precompute_leadcoeff);
     521  CFList leadingCoeffs= precomputeLeadingCoeff (LC (A, 1), biFactorsLCs, x,
     522                                          evaluation, Aeval2, lengthAeval2, w);
     523
     524  if (w.level() != 1)
     525    changeSecondVariable (A, biFactors, evaluation, oldAeval, lengthAeval2,
     526                          uniFactors, w);
     527
     528  CanonicalForm oldA= A;
     529  CFList oldBiFactors= biFactors;
     530
     531  CanonicalForm LCmultiplier= leadingCoeffs.getFirst();
     532  bool LCmultiplierIsConst= LCmultiplier.inCoeffDomain();
     533  leadingCoeffs.removeFirst();
     534
     535  if (!LCmultiplierIsConst)
     536    distributeLCmultiplier (A, leadingCoeffs, biFactors, evaluation,
     537                            LCmultiplier);
     538
     539  //prepare leading coefficients
     540  CFList* leadingCoeffs2= new CFList [lengthAeval2];
     541  prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(), leadingCoeffs,
     542                        biFactors, evaluation);
     543
     544  CFListIterator iter;
     545  CFList bufLeadingCoeffs2= leadingCoeffs2[lengthAeval2-1];
     546  CFList bufBiFactors= biFactors;
     547  bufA= A;
     548  CanonicalForm testVars, bufLCmultiplier= LCmultiplier;
     549  if (!LCmultiplierIsConst)
     550  {
     551    testVars= Variable (2);
     552    for (int i= 0; i < lengthAeval2; i++)
     553    {
     554      if (!oldAeval[i].isEmpty())
     555        testVars *= oldAeval[i].getFirst().mvar();
     556    }
     557  }
     558  TIMING_END_AND_PRINT(abs_fac_precompute_leadcoeff,
     559                       "time to precompute LC in abs fact: ");
     560
     561  TIMING_START (abs_fac_luckswang);
     562  CFList bufFactors= CFList();
     563  bool LCheuristic= false;
     564  if (LucksWangSparseHeuristic (A, biFactors, 2, leadingCoeffs2[lengthAeval2-1],
     565                                rationalFactors))
     566  {
     567    int check= biFactors.length();
     568    int * index= new int [factors.length()];
     569    CFList oldFactors= rationalFactors;
     570    rationalFactors= recoverFactors (A, rationalFactors, index);
     571
     572    if (check == rationalFactors.length())
     573    {
     574      if (w.level() != 1)
     575      {
     576        for (iter= rationalFactors; iter.hasItem(); iter++)
     577          iter.getItem()= swapvar (iter.getItem(), w, y);
     578      }
     579
     580      for (CFListIterator iter= rationalFactors; iter.hasItem(); iter++)
     581      {
     582        if (totaldegree(iter.getItem())*degree (getMipo (v)) == totaldegree (G))
     583        {
     584          factors= CFAFList (CFAFactor (iter.getItem(), getMipo (v), 1));
     585          found=true;
     586          break;
     587        }
     588      }
     589      // necessary since extension may be too large
     590      if (!found)
     591        factors= RothsteinTrager (A, rationalFactors, v, evaluation);
     592
     593      decompress (factors, N);
     594      normalize (factors);
     595      delete [] index;
     596      delete [] Aeval2;
     597      TIMING_END_AND_PRINT (abs_fac_luckswang,
     598                            "time for successful LucksWang in abs fact: ");
     599      return factors;
     600    }
     601    else if (rationalFactors.length() > 0)
     602    {
     603      int oneCount= 0;
     604      CFList l;
     605      for (int i= 0; i < check; i++)
     606      {
     607        if (index[i] == 1)
     608        {
     609          iter=biFactors;
     610          for (int j=1; j <= i-oneCount; j++)
     611            iter++;
     612          iter.remove (1);
     613          for (int j= 0; j < lengthAeval2; j++)
     614          {
     615            l= leadingCoeffs2[j];
     616            iter= l;
     617            for (int k=1; k <= i-oneCount; k++)
     618              iter++;
     619            iter.remove (1);
     620            leadingCoeffs2[j]=l;
     621          }
     622          oneCount++;
     623        }
     624      }
     625      bufFactors= rationalFactors;
     626      rationalFactors= CFList();
     627    }
     628    else if (!LCmultiplierIsConst && rationalFactors.length() == 0)
     629    {
     630      LCheuristic= true;
     631      rationalFactors= oldFactors;
     632      CFList contents, LCs;
     633      bool foundTrueMultiplier= false;
     634      LCHeuristic2 (LCmultiplier,rationalFactors,leadingCoeffs2[lengthAeval2-1],
     635                    contents, LCs, foundTrueMultiplier);
     636      if (foundTrueMultiplier)
     637      {
     638          A= oldA;
     639          leadingCoeffs= leadingCoeffs2[lengthAeval2-1];
     640          for (int i= lengthAeval2-1; i > -1; i--)
     641            leadingCoeffs2[i]= CFList();
     642          prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(),
     643                                leadingCoeffs, biFactors, evaluation);
     644      }
     645      else
     646      {
     647        bool foundMultiplier= false;
     648        LCHeuristic3 (LCmultiplier, rationalFactors, oldBiFactors, contents,
     649                      oldAeval,A,leadingCoeffs2, lengthAeval2, foundMultiplier);
     650        // coming from above: divide out more LCmultiplier if possible
     651        if (foundMultiplier)
     652        {
     653          foundMultiplier= false;
     654          LCHeuristic4 (oldBiFactors, oldAeval, contents, rationalFactors,
     655                        testVars, lengthAeval2, leadingCoeffs2, A, LCmultiplier,
     656                        foundMultiplier);
     657        }
     658        else
     659        {
     660          LCHeuristicCheck (LCs, contents, A, oldA,
     661                            leadingCoeffs2[lengthAeval2-1], foundMultiplier);
     662          if (!foundMultiplier && fdivides (getVars (LCmultiplier), testVars))
     663          {
     664            LCHeuristic (A, LCmultiplier, biFactors, leadingCoeffs2, oldAeval,
     665                         lengthAeval2, evaluation, oldBiFactors);
     666          }
     667        }
     668
     669        // patch everything together again
     670        leadingCoeffs= leadingCoeffs2[lengthAeval2-1];
     671        for (int i= lengthAeval2-1; i > -1; i--)
     672          leadingCoeffs2[i]= CFList();
     673        prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(),leadingCoeffs,
     674                              biFactors, evaluation);
     675      }
     676      rationalFactors= CFList();
     677      if (!fdivides (LC (oldA,1),prod (leadingCoeffs2[lengthAeval2-1])))
     678      {
     679        LCheuristic= false;
     680        A= bufA;
     681        biFactors= bufBiFactors;
     682        leadingCoeffs2[lengthAeval2-1]= bufLeadingCoeffs2;
     683        LCmultiplier= bufLCmultiplier;
     684      }
     685    }
     686    else
     687      rationalFactors= CFList();
     688    delete [] index;
     689  }
     690  TIMING_END_AND_PRINT (abs_fac_luckswang, "time for LucksWang in abs fact: ");
     691
     692  TIMING_START (abs_fac_lcheuristic);
     693  if (!LCheuristic && !LCmultiplierIsConst && bufFactors.isEmpty()
     694      && fdivides (getVars (LCmultiplier), testVars))
     695  {
     696    LCheuristic= true;
     697    LCHeuristic (A, LCmultiplier, biFactors, leadingCoeffs2, oldAeval,
     698                 lengthAeval2, evaluation, oldBiFactors);
     699
     700    leadingCoeffs= leadingCoeffs2[lengthAeval2-1];
     701    for (int i= lengthAeval2-1; i > -1; i--)
     702      leadingCoeffs2[i]= CFList();
     703    prepareLeadingCoeffs (leadingCoeffs2, A, Aeval, A.level(),leadingCoeffs,
     704                          biFactors, evaluation);
     705
     706    if (!fdivides (LC (oldA,1),prod (leadingCoeffs2[lengthAeval2-1])))
     707    {
     708      LCheuristic= false;
     709      A= bufA;
     710      biFactors= bufBiFactors;
     711      leadingCoeffs2[lengthAeval2-1]= bufLeadingCoeffs2;
     712      LCmultiplier= bufLCmultiplier;
     713    }
     714  }
     715  TIMING_END_AND_PRINT (abs_fac_lcheuristic,
     716                        "time for Lc heuristic in abs fact: ");
     717
     718tryAgainWithoutHeu:
     719  //shifting to zero
     720  TIMING_START (abs_fac_shift_to_zero);
     721  CanonicalForm denA= bCommonDen (A);
     722  A *= denA;
     723  A= shift2Zero (A, Aeval, evaluation);
     724  A /= denA;
     725
     726  for (iter= biFactors; iter.hasItem(); iter++)
     727    iter.getItem()= iter.getItem () (y + evaluation.getLast(), y);
     728
     729  for (int i= 0; i < lengthAeval2-1; i++)
     730    leadingCoeffs2[i]= CFList();
     731  for (iter= leadingCoeffs2[lengthAeval2-1]; iter.hasItem(); iter++)
     732  {
     733    iter.getItem()= shift2Zero (iter.getItem(), list, evaluation);
     734    for (int i= A.level() - 4; i > -1; i--)
     735    {
     736      if (i + 1 == lengthAeval2-1)
     737        leadingCoeffs2[i].append (iter.getItem() (0, i + 4));
     738      else
     739        leadingCoeffs2[i].append (leadingCoeffs2[i+1].getLast() (0, i + 4));
     740    }
     741  }
     742  TIMING_END_AND_PRINT (abs_fac_shift_to_zero,
     743                        "time to shift evaluation point to zero in abs fact: ");
     744
     745  CFArray Pi;
     746  CFList diophant;
     747  int* liftBounds= new int [A.level() - 1];
     748  int liftBoundsLength= A.level() - 1;
     749  for (int i= 0; i < liftBoundsLength; i++)
     750    liftBounds [i]= degree (A, i + 2) + 1;
     751
     752  Aeval.removeFirst();
     753  bool noOneToOne= false;
     754
     755  TIMING_START (abs_fac_cleardenom);
     756  CFList commonDenominators;
     757  for (iter=biFactors; iter.hasItem(); iter++)
     758    commonDenominators.append (bCommonDen (iter.getItem()));
     759  CanonicalForm tmp1, tmp2, tmp3=1;
     760  CFListIterator iter2;
     761  for (int i= 0; i < lengthAeval2; i++)
     762  {
     763    iter2= commonDenominators;
     764    for (iter= leadingCoeffs2[i]; iter.hasItem(); iter++, iter2++)
     765    {
     766      tmp1= bCommonDen (iter.getItem());
     767      Off (SW_RATIONAL);
     768      iter2.getItem()= lcm (iter2.getItem(), tmp1);
     769      On (SW_RATIONAL);
     770    }
     771  }
     772  tmp1= prod (commonDenominators);
     773  for (iter= Aeval; iter.hasItem(); iter++)
     774  {
     775    tmp2= bCommonDen (iter.getItem()/denA);
     776    Off (SW_RATIONAL);
     777    tmp3= lcm (tmp2,tmp3);
     778    On (SW_RATIONAL);
     779  }
     780  CanonicalForm multiplier;
     781  multiplier= tmp3/tmp1;
     782  iter2= commonDenominators;
     783  for (iter=biFactors; iter.hasItem(); iter++, iter2++)
     784    iter.getItem() *= iter2.getItem()*multiplier;
     785
     786  for (iter= Aeval; iter.hasItem(); iter++)
     787    iter.getItem() *= tmp3*power (multiplier, biFactors.length() - 1)/denA;
     788
     789  for (int i= 0; i < lengthAeval2; i++)
     790  {
     791    iter2= commonDenominators;
     792    for (iter= leadingCoeffs2[i]; iter.hasItem(); iter++, iter2++)
     793      iter.getItem() *= iter2.getItem()*multiplier;
     794  }
     795
     796  TIMING_END_AND_PRINT (abs_fac_cleardenom,
     797                        "time to clear denominators in abs fact: ");
     798
     799  TIMING_START (abs_fac_hensel_lift);
     800  rationalFactors= nonMonicHenselLift (Aeval, biFactors,leadingCoeffs2,diophant,
     801                               Pi, liftBounds, liftBoundsLength, noOneToOne);
     802  TIMING_END_AND_PRINT (abs_fac_hensel_lift,
     803                        "time for non monic hensel lifting in abs fact: ");
     804
     805  if (!noOneToOne)
     806  {
     807    int check= rationalFactors.length();
     808    A= oldA;
     809    TIMING_START (abs_fac_recover_factors);
     810    rationalFactors= recoverFactors (A, rationalFactors, evaluation);
     811    TIMING_END_AND_PRINT (abs_fac_recover_factors,
     812                          "time to recover factors in abs fact: ");
     813    if (check != rationalFactors.length())
     814      noOneToOne= true;
     815    else
     816      rationalFactors= Union (rationalFactors, bufFactors);
     817  }
     818  if (noOneToOne)
     819  {
     820    if (!LCmultiplierIsConst && LCheuristic)
     821    {
     822      A= bufA;
     823      biFactors= bufBiFactors;
     824      leadingCoeffs2[lengthAeval2-1]= bufLeadingCoeffs2;
     825      delete [] liftBounds;
     826      LCheuristic= false;
     827      goto tryAgainWithoutHeu;
     828      //something probably went wrong in the heuristic
     829    }
     830
     831    A= shift2Zero (oldA, Aeval, evaluation);
     832    biFactors= oldBiFactors;
     833    for (iter= biFactors; iter.hasItem(); iter++)
     834      iter.getItem()= iter.getItem () (y + evaluation.getLast(), y);
     835    CanonicalForm LCA= LC (Aeval.getFirst(), 1);
     836    CanonicalForm yToLift= power (y, lift);
     837    CFListIterator i= biFactors;
     838    lift= degree (i.getItem(), 2) + degree (LC (i.getItem(), 1)) + 1;
     839    i++;
     840
     841    for (; i.hasItem(); i++)
     842      lift= tmax (lift, degree (i.getItem(), 2)+degree (LC (i.getItem(), 1))+1);
     843
     844    lift= tmax (degree (Aeval.getFirst() , 2) + 1, lift);
     845
     846    i= biFactors;
     847    yToLift= power (y, lift);
     848    CanonicalForm dummy;
     849    for (; i.hasItem(); i++)
     850    {
     851      LCA= LC (i.getItem(), 1);
     852      extgcd (LCA, yToLift, LCA, dummy);
     853      i.getItem()= mod (i.getItem()*LCA, yToLift);
     854    }
     855
     856    liftBoundsLength= F.level() - 1;
     857    liftBounds= liftingBounds (A, lift);
     858
     859    CFList MOD;
     860    bool earlySuccess;
     861    CFList earlyFactors;
     862    ExtensionInfo info= ExtensionInfo (false);
     863    CFList liftedFactors;
     864    TIMING_START (abs_fac_hensel_lift);
     865    liftedFactors= henselLiftAndEarly
     866                   (A, MOD, liftBounds, earlySuccess, earlyFactors,
     867                    Aeval, biFactors, evaluation, info);
     868    TIMING_END_AND_PRINT (abs_fac_hensel_lift,
     869                          "time for hensel lifting in abs fact: ");
     870
     871    TIMING_START (abs_fac_factor_recombination);
     872    rationalFactors= factorRecombination (A, liftedFactors, MOD);
     873    TIMING_END_AND_PRINT (abs_fac_factor_recombination,
     874                          "time for factor recombination in abs fact: ");
     875
     876    if (earlySuccess)
     877      rationalFactors= Union (rationalFactors, earlyFactors);
     878
     879    for (CFListIterator i= rationalFactors; i.hasItem(); i++)
     880    {
     881      int kk= Aeval.getLast().level();
     882      for (CFListIterator j= evaluation; j.hasItem(); j++, kk--)
     883      {
     884        if (i.getItem().level() < kk)
     885          continue;
     886       i.getItem()= i.getItem() (Variable (kk) - j.getItem(), kk);
     887      }
     888    }
     889  }
     890
     891  if (w.level() != 1)
     892  {
     893    for (CFListIterator iter= rationalFactors; iter.hasItem(); iter++)
     894      iter.getItem()= swapvar (iter.getItem(), w, y);
     895  }
     896
     897  for (CFListIterator iter= rationalFactors; iter.hasItem(); iter++)
     898  {
     899    if (totaldegree (iter.getItem())*degree (getMipo (v)) == totaldegree (G))
     900    {
     901      factors= CFAFList (CFAFactor (iter.getItem(), getMipo (v), 1));
     902      found= true;
     903      break;
     904    }
     905  }
     906
     907  // necessary since extension may be too large
     908  if (!found)
     909    factors= RothsteinTrager (A, rationalFactors, v, evaluation);
     910
     911  decompress (factors, N);
     912  if (isOn (SW_RATIONAL))
     913    normalize (factors);
     914
     915  delete [] leadingCoeffs2;
     916  delete [] oldAeval;
     917  delete [] Aeval2;
     918  delete[] liftBounds;
     919
     920  return factors;
     921}
     922
    651923#endif
    652 
    653 
  • factory/facAbsFact.h

    r62e51f rd51d87  
    44/** @file facAbsFact.h
    55 *
    6  * bivariate absolute factorization over Q described in "Modular Las Vegas
    7  * Algorithms for Polynomial Absolute Factorization" by Bertone, ChÚze, Galligo
     6 * absolute multivariate factorization over Q
    87 *
    98 * @author Martin Lee
     
    1514#define FAC_ABS_FACT_H
    1615
    17 #include "cf_assert.h"
    18 
    19 #include "cf_algorithm.h"
    20 #include "cf_map.h"
     16#include "facAbsBiFact.h"
    2117
    2218#ifdef HAVE_NTL
    23 /// main absolute factorization routine, expects bivariate poly which is
    24 /// primitive wrt. any of its variables and irreducible over Q
    25 ///
    26 /// @return absFactorizeMain returns a list whose entries contain three entities:
    27 ///         an absolute irreducible factor, an irreducible univariate polynomial
    28 ///         that defines the minimal field extension over which the irreducible
    29 ///         factor is defined and the multiplicity of the absolute irreducible
    30 ///         factor
    31 CFAFList absFactorizeMain (const CanonicalForm& F ///<[in] s.a.
    32                           );
     19CFAFList absFactorizeMain (const CanonicalForm& F);
    3320#endif
    3421
    35 /// normalize factors, i.e. make factors monic
    36 static inline
    37 void normalize (CFAFList & L)
    38 {
    39   for (CFAFListIterator i= L; i.hasItem(); i++)
    40     i.getItem()= CFAFactor (i.getItem().factor()/Lc (i.getItem().factor()),
    41                             i.getItem().minpoly(), i.getItem().exp());
    42 }
    43 
    44 /// univariate absolute factorization over Q
    45 ///
    46 /// @return uniAbsFactorize returns a list whose entries contain three entities:
    47 ///         an absolute irreducible factor, an irreducible univariate polynomial
    48 ///         that defines the minimal field extension over which the irreducible
    49 ///         factor is defined and the multiplicity of the absolute irreducible
    50 ///         factor
    51 static inline
    52 CFAFList uniAbsFactorize (const CanonicalForm& F ///<[in] univariate poly over Q
    53                          )
    54 {
    55   CFFList rationalFactors= factorize (F);
    56   CFFListIterator i= rationalFactors;
    57   i++;
    58   Variable alpha;
    59   CFAFList result;
    60   CFFList QaFactors;
    61   CFFListIterator iter;
    62   for (; i.hasItem(); i++)
    63   {
    64     if (degree (i.getItem().factor()) == 1)
    65     {
    66       result.append (CFAFactor (i.getItem().factor(), 1, i.getItem().exp()));
    67       continue;
    68     }
    69     alpha= rootOf (i.getItem().factor());
    70     QaFactors= factorize (i.getItem().factor(), alpha);
    71     iter= QaFactors;
    72     if (iter.getItem().factor().inCoeffDomain())
    73       iter++;
    74     for (;iter.hasItem(); iter++)
    75     {
    76       if (degree (iter.getItem().factor()) == 1)
    77       {
    78         result.append (CFAFactor (iter.getItem().factor(), getMipo (alpha),
    79                                   i.getItem().exp()));
    80         break;
    81       }
    82     }
    83   }
    84   result.insert (CFAFactor (rationalFactors.getFirst().factor(), 1, 1));
    85   return result;
    86 }
    87 
    8822/*BEGINPUBLIC*/
    89 
    9023#ifdef HAVE_NTL
    91 CFAFList absFactorize (const CanonicalForm& G);
     24CFAFList absFactorize (const CanonicalForm& G ///<[in] poly over Q
     25                      );
    9226#endif
    93 
    9427/*ENDPUBLIC*/
    9528
     29
    9630#endif
  • factory/facFactorize.cc

    r62e51f rd51d87  
    5252  Variable x= Variable (1);
    5353
     54  CanonicalForm LCF=LC (F,x);
     55  CFList LCFeval;
     56
    5457  bool found= false;
    5558  bool allZero= true;
     
    6063  {
    6164    eval.insert (F);
     65    LCFeval.insert (LCF);
    6266    bool bad= false;
    6367    for (int i= E.max(); i >= E.min(); i--)
    6468    {
    6569      eval.insert (eval.getFirst()( E [i], i));
     70      LCFeval.insert (LCFeval.getFirst() (E [i], i));
    6671      result.append (E[i]);
    6772      if (!E[i].isZero())
     
    7378        result= CFList();
    7479        eval= CFList();
     80        LCFeval= CFList();
    7581        bad= true;
    7682        foundZero= false;
     
    8187        result= CFList();
    8288        eval= CFList();
     89        LCFeval= CFList();
    8390        bad= true;
    8491        break;
    8592      }
     93      if ((i != 2) && (degree (LCFeval.getFirst(), i-1) != degree (LCF, i-1)))
     94      {
     95        result= CFList();
     96        eval= CFList();
     97        LCFeval= CFList();
     98        bad= true;
     99        break;
     100      }
    86101    }
    87102
     
    96111      result= CFList();
    97112      eval= CFList();
     113      LCFeval= CFList();
    98114      E.nextpoint();
    99115      continue;
     
    106122      result= CFList();
    107123      eval= CFList();
     124      LCFeval= CFList();
    108125      E.nextpoint();
    109126      continue;
     
    116133      result= CFList();
    117134      eval= CFList();
     135      LCFeval= CFList();
    118136      E.nextpoint();
    119137      continue;
     
    769787  }
    770788
    771   swap (factors, 0, 0, x);
    772789  append (factors, contentAFactors);
    773790  decompress (factors, N);
  • factory/facFactorize.h

    r62e51f rd51d87  
    2222TIMING_DEFINE_PRINT (fac_squarefree)
    2323TIMING_DEFINE_PRINT (fac_factor_squarefree)
     24
     25/// Factorization of A wrt. to different second vars
     26void
     27factorizationWRTDifferentSecondVars (
     28                          const CanonicalForm& A, ///<[in] poly
     29                          CFList*& Aeval,         ///<[in,out] A evaluated wrt.
     30                                                  ///< different second vars
     31                                                  ///< returns bivariate factors
     32                          int& minFactorsLength,  ///<[in,out] minimal length of
     33                                                  ///< bivariate factors
     34                          bool& irred,            ///<[in,out] Is A irreducible?
     35                          const Variable& w       ///<[in] alg. variable
     36                                    );
    2437
    2538/// Factorization over Q (a)
  • factory/facFqBivarUtil.cc

    r62e51f rd51d87  
    5858}
    5959
     60void decompress (CFAFList& factors, const CFMap& N)
     61{
     62  for (CFAFListIterator i= factors; i.hasItem(); i++)
     63    i.getItem()= CFAFactor (N (i.getItem().factor()), i.getItem().minpoly(),
     64                            i.getItem().exp());
     65}
     66
    6067void appendSwapDecompress (CFList& factors1, const CFList& factors2,
    6168                           const CFList& factors3, const bool swap1,
     
    464471  logDeriv= mulMod2 (q, deriv (G, y), xToL);
    465472  TIMING_END_AND_PRINT (fac_log_deriv_mul, "time to multiply in logderiv1: ");
     473
     474  if (degree (logDeriv, x) == 0)
     475  {
     476    Q= q;
     477    return CFArray();
     478  }
    466479
    467480  int j= degree (logDeriv, y) + 1;
     
    543556  TIMING_END_AND_PRINT (fac_log_deriv_mul, "time for mul in logderiv2: ");
    544557
     558  if (degree (logDeriv, x) == 0)
     559  {
     560    Q= q;
     561    return CFArray();
     562  }
     563
    545564  int j= degree (logDeriv,y) + 1;
    546565  CFArray result= CFArray (j);
     
    726745  maxX= minX;
    727746  maxY= minY;
     747  int indZero= 0;
    728748  for (int i= 1; i < sizeOfNewtonPolygon; i++)
    729749  {
     750    if (newtonPolyg[i][1] == 0)
     751    {
     752      if (newtonPolyg[indZero][1] == 0)
     753      {
     754        if (newtonPolyg[indZero][0] < newtonPolyg[i][0])
     755          indZero= i;
     756      }
     757      else
     758        indZero= i;
     759    }
    730760    if (minX > newtonPolyg [i] [0])
    731761      minX= newtonPolyg [i] [0];
     
    738768  }
    739769
    740   int k= maxX;
     770  int slopeNum, slopeDen, constTerm;
     771  bool negativeSlope=false;
     772  if (indZero != sizeOfNewtonPolygon - 1)
     773  {
     774    slopeNum= newtonPolyg[indZero+1][0]-newtonPolyg[indZero][0];
     775    slopeDen= newtonPolyg[indZero+1][1];
     776    constTerm= newtonPolyg[indZero][0];
     777  }
     778  else
     779  {
     780    slopeNum= newtonPolyg[0][0]-newtonPolyg[indZero][0];
     781    slopeDen= newtonPolyg[0][1];
     782    constTerm= newtonPolyg[indZero][0];
     783  }
     784  if (slopeNum < 0)
     785  {
     786    slopeNum= -slopeNum;
     787    negativeSlope= true;
     788  }
     789  int k= 0;
    741790  for (int i= 0; i < n; i++)
    742791  {
     792    if (((indZero+1) < sizeOfNewtonPolygon && (i+1) > newtonPolyg[indZero+1][1])
     793        || ((indZero+1) >= sizeOfNewtonPolygon && (i+1) > newtonPolyg[0][1]))
     794    {
     795      if (indZero + 1 != sizeOfNewtonPolygon)
     796        indZero++;
     797      else
     798        indZero= 0;
     799      if (indZero != sizeOfNewtonPolygon - 1)
     800      {
     801        slopeNum= newtonPolyg[indZero+1][0]-newtonPolyg[indZero][0];
     802        slopeDen= newtonPolyg[indZero+1][1]-newtonPolyg[indZero][1];
     803        constTerm= newtonPolyg[indZero][0];
     804      }
     805      else
     806      {
     807        slopeNum= newtonPolyg[0][0]-newtonPolyg[indZero][0];
     808        slopeDen= newtonPolyg[0][1]-newtonPolyg[indZero][1];
     809        constTerm= newtonPolyg[indZero][0];
     810      }
     811      if (slopeNum < 0)
     812      {
     813        negativeSlope= true;
     814        slopeNum= - slopeNum;
     815        k= (int) -(((long) slopeNum*((i+1)-newtonPolyg[indZero][1])+slopeDen-1)/
     816                   slopeDen) + constTerm;
     817      }
     818      else
     819        k= (int) (((long) slopeNum*((i+1)-newtonPolyg[indZero][1])) / slopeDen)
     820                  + constTerm;
     821    }
     822    else
     823    {
     824      if (negativeSlope)
     825        k= (int) -(((long) slopeNum*((i+1)-newtonPolyg[indZero][1])+slopeDen-1)/
     826                   slopeDen) + constTerm;
     827      else
     828        k= (int) ((long) slopeNum*((i+1)-newtonPolyg[indZero][1])) / slopeDen
     829                  + constTerm;
     830    }
    743831    if (i + 1 > maxY || i + 1 < minY)
    744832    {
     
    749837    point [0]= k;
    750838    point [1]= i + 1;
    751     while (!isInPolygon (newtonPolyg, sizeOfNewtonPolygon, point) && k > 0)
    752     {
    753       k--;
    754       point [0]= k;
    755     }
     839    if (!isInPolygon (newtonPolyg, sizeOfNewtonPolygon, point) && k > 0)
     840      k= 0;
    756841    result [i]= k;
    757     k= maxX;
    758842    delete [] point;
    759843  }
     844
     845  for (int i= 0; i < sizeOfNewtonPolygon; i++)
     846    delete [] newtonPolyg[i];
     847  delete [] newtonPolyg;
    760848
    761849  return result;
     
    811899  maxX= minX;
    812900  maxY= minY;
     901  int indZero= 0;
    813902  for (int i= 1; i < sizeOfNewtonPolygon; i++)
    814903  {
     904    if (newtonPolyg[i][0] == 0)
     905    {
     906      if (newtonPolyg[indZero][0] == 0)
     907      {
     908        if (newtonPolyg[indZero][1] < newtonPolyg[i][1])
     909          indZero= i;
     910      }
     911      else
     912        indZero= i;
     913    }
    815914    if (minX > newtonPolyg [i] [0])
    816915      minX= newtonPolyg [i] [0];
     
    823922  }
    824923
    825   int k= maxY;
     924  int slopeNum, slopeDen, constTerm;
     925  bool negativeSlope=false;
     926  if (indZero != sizeOfNewtonPolygon - 1)
     927  {
     928    slopeNum= newtonPolyg[indZero+1][1]-newtonPolyg[indZero][1];
     929    slopeDen= newtonPolyg[indZero+1][0];
     930    constTerm= newtonPolyg[indZero][1];
     931  }
     932  else
     933  {
     934    slopeNum= newtonPolyg[0][1]-newtonPolyg[indZero][1];
     935    slopeDen= newtonPolyg[0][0];
     936    constTerm= newtonPolyg[indZero][1];
     937  }
     938  if (slopeNum < 0)
     939  {
     940    slopeNum= -slopeNum;
     941    negativeSlope= true;
     942  }
     943  int k= 0;
    826944  for (int i= 0; i < n; i++)
    827945  {
     946    if (((indZero+1) < sizeOfNewtonPolygon && (i+1) > newtonPolyg[indZero+1][0])
     947        || ((indZero+1) >= sizeOfNewtonPolygon && (i+1) > newtonPolyg[0][0]))
     948    {
     949      if (indZero + 1 != sizeOfNewtonPolygon)
     950        indZero++;
     951      else
     952        indZero= 0;
     953      if (indZero != sizeOfNewtonPolygon - 1)
     954      {
     955        slopeNum= newtonPolyg[indZero+1][1]-newtonPolyg[indZero][1];
     956        slopeDen= newtonPolyg[indZero+1][0]-newtonPolyg[indZero][0];
     957        constTerm= newtonPolyg[indZero][1];
     958      }
     959      else
     960      {
     961        slopeNum= newtonPolyg[0][1]-newtonPolyg[indZero][1];
     962        slopeDen= newtonPolyg[0][0]-newtonPolyg[indZero][0];
     963        constTerm= newtonPolyg[indZero][1];
     964      }
     965      if (slopeNum < 0)
     966      {
     967        negativeSlope= true;
     968        slopeNum= - slopeNum;
     969        k= (int) -(((long) slopeNum*((i+1)-newtonPolyg[indZero][0])+slopeDen-1)/
     970                   slopeDen) + constTerm;
     971      }
     972      else
     973        k= (int) (((long) slopeNum*((i+1)-newtonPolyg[indZero][0])) / slopeDen)
     974                  + constTerm;
     975    }
     976    else
     977    {
     978      if (negativeSlope)
     979        k= (int) -(((long) slopeNum*((i+1)-newtonPolyg[indZero][0])+slopeDen-1)/
     980                   slopeDen) + constTerm;
     981      else
     982        k= (int) ((long) slopeNum*((i+1)-newtonPolyg[indZero][0])) / slopeDen
     983                  + constTerm;
     984    }
    828985    if (i + 1 > maxX || i + 1 < minX)
    829986    {
     
    834991    point [0]= i + 1;
    835992    point [1]= k;
    836     while (!isInPolygon (newtonPolyg, sizeOfNewtonPolygon, point) && k > 0)
    837     {
    838       k--;
    839       point [1]= k;
    840     }
     993    if (!isInPolygon (newtonPolyg, sizeOfNewtonPolygon, point) && k > 0)
     994      k= 0;
    841995    result [i]= k;
    842     k= maxY;
    843996    delete [] point;
    844997  }
     998
     999  for (int i= 0; i < sizeOfNewtonPolygon; i++)
     1000    delete [] newtonPolyg[i];
     1001  delete [] newtonPolyg;
    8451002
    8461003  return result;
  • factory/facFqBivarUtil.h

    r62e51f rd51d87  
    3838                );
    3939
     40/// as above
     41void decompress (CFAFList& factors, ///< [in,out] a list of factors
     42                 const CFMap& N    ///< [in] a map
     43                );
     44
    4045/// first swap Variables in @a factors1 if necessary, then append @a factors2
    4146/// and @a factors3 on @a factors1 and finally decompress @a factors1
     
    6873                                                 ///< Fq if we are not over some
    6974                                                 ///< GF
    70                     const int k,                 ///< some int k such that k 
     75                    const int k,                 ///< some int k such that k
    7176                                                 ///< divides l if we are not
    7277                                                 ///< over some Fq
     
    189194///         Variable (2)^l
    190195CFArray
    191 logarithmicDerivative (const CanonicalForm& F,   ///< [in] bivariate poly 
     196logarithmicDerivative (const CanonicalForm& F,   ///< [in] bivariate poly
    192197                                                 ///< truncated at Variable(2)^l
    193198                       const CanonicalForm& G,   ///< [in] a factor of F
     
    199204                      );
    200205
    201 /// compute bounds for logarithmic derivative as described in K. Belabas, 
    202 /// M. van Hoeij, J. KlÃŒners, and A. Steel, Factoring polynomials over global 
     206/// compute bounds for logarithmic derivative as described in K. Belabas,
     207/// M. van Hoeij, J. KlÃŒners, and A. Steel, Factoring polynomials over global
    203208/// fields
    204209///
     
    225230/// @return coefficients of \f$ x^i \f$ for \f$i\geq k\f$
    226231/// @sa {getCoeffs (const CanonicalForm&, const int, const Variable&),
    227 /// getCoeffs (const CanonicalForm&, const int, const int, const int, 
     232/// getCoeffs (const CanonicalForm&, const int, const int, const int,
    228233/// const Variable&, const CanonicalForm&, const mat_zz_p&)}
    229234CFArray
     
    237242/// @return coefficients of \f$ x^i \f$ for \f$i\geq k\f$
    238243/// @sa {getCoeffs (const CanonicalForm&, const int),
    239 /// getCoeffs (const CanonicalForm&, const int, const int, const int, 
     244/// getCoeffs (const CanonicalForm&, const int, const int, const int,
    240245/// const Variable&, const CanonicalForm&, const mat_zz_p&)}
    241246CFArray
    242 getCoeffs (const CanonicalForm& F,///< [in] compressed bivariate poly over 
     247getCoeffs (const CanonicalForm& F,///< [in] compressed bivariate poly over
    243248                                  ///< F_p(alpha)
    244249           const int k,           ///< [in] some int
     
    281286/// substitute x^d by x in F
    282287void
    283 subst (const CanonicalForm& F, ///< [in] a polynomial 
     288subst (const CanonicalForm& F, ///< [in] a polynomial
    284289       CanonicalForm& A,       ///< [in,out] returns F with x^d replaced by x
    285290       const int d,            ///< d > 1 such that a substitution x^d -> x
     
    299304/// reverse a substitution x^d->x
    300305void
    301 reverseSubst (CFList& L,        ///< [in,out] a list of polys, returns the 
     306reverseSubst (CFList& L,        ///< [in,out] a list of polys, returns the
    302307                                ///< given list with x replaced by x^d
    303308              const int d,      ///< [in] an integer > 0
  • factory/facFqFactorize.cc

    r62e51f rd51d87  
    88 *
    99 * ABSTRACT: "Efficient Multivariate Factorization over Finite Fields" by
    10  * L. Bernardin & M. Monagon. Precomputation of leading coefficients is 
     10 * L. Bernardin & M. Monagon. Precomputation of leading coefficients is
    1111 * described in "Sparse Hensel lifting" by E. Kaltofen
    1212 *
     
    743743  int k= F.level() - 1;
    744744  Variable x= Variable (1);
     745  CanonicalForm LCF=LC (F, x);
     746  CFList LCFeval;
     747
    745748  CFList result;
    746749  FFRandom genFF;
     
    818821    int l= F.level();
    819822    eval.insert (F);
     823    LCFeval.insert (LCF);
    820824    bool bad= false;
    821825    for (CFListIterator i= result; i.hasItem(); i++, l--)
    822826    {
    823827      eval.insert (eval.getFirst()(i.getItem(), l));
     828      LCFeval.insert (LCFeval.getFirst()(i.getItem(), l));
    824829      if (degree (eval.getFirst(), l - 1) != degree (F, l - 1))
    825830      {
     
    828833        result= CFList();
    829834        eval= CFList();
     835        LCFeval= CFList();
     836        bad= true;
     837        break;
     838      }
     839      if ((l != 2) && (degree (LCFeval.getFirst(), l-1) != degree (LCF, l-1)))
     840      {
     841        if (!find (list, random))
     842          list.append (random);
     843        result= CFList();
     844        eval= CFList();
     845        LCFeval= CFList();
    830846        bad= true;
    831847        break;
     
    841857        list.append (random);
    842858      result= CFList();
     859      LCFeval= CFList();
    843860      eval= CFList();
    844861      continue;
     
    852869        list.append (random);
    853870      result= CFList();
     871      LCFeval= CFList();
    854872      eval= CFList();
    855873      continue;
     
    863881        list.append (random);
    864882      result= CFList();
     883      LCFeval= CFList();
    865884      eval= CFList();
    866885      continue;
     
    20142033    }
    20152034    s++;
    2016     if (T.length() < 2*s || T.length() == s) 
     2035    if (T.length() < 2*s || T.length() == s)
    20172036    {
    20182037      delete [] v;
     
    36383657#endif
    36393658/* HAVE_NTL */
    3640 
  • factory/facFqFactorize.h

    r62e51f rd51d87  
    472472/// polynomial has main variable Variable (1), is squarefree and its degree
    473473/// coincides with degree(F) and the bivariate one is primitive wrt.
    474 /// Variable(1), and successively evaluated polynomials have the same degree in 
    475 /// their main variable as F has, fails if there are no valid evaluation points, 
     474/// Variable(1), and successively evaluated polynomials have the same degree in
     475/// their main variable as F has, fails if there are no valid evaluation points,
    476476/// eval contains the intermediate evaluated polynomials.
    477477///
     
    527527/// A.
    528528///
    529 /// @return @a lcmContent returns the LCM of the contents of @a A wrt to each 
     529/// @return @a lcmContent returns the LCM of the contents of @a A wrt to each
    530530///         variable occuring in @a A.
    531531CanonicalForm
    532 lcmContent (const CanonicalForm& A, ///< [in] a compressed multivariate poly 
     532lcmContent (const CanonicalForm& A, ///< [in] a compressed multivariate poly
    533533            CFList& contentAi       ///< [in,out] an empty list, returns a list
    534                                     ///< of the contents of @a A wrt to each 
     534                                    ///< of the contents of @a A wrt to each
    535535                                    ///< variable occuring in @a A starting from
    536536                                    ///< @a A.mvar().
    537537           );
    538538
    539 /// compress a polynomial s.t. \f$ deg_{x_{i}} (F) >= deg_{x_{i+1}} (F) \f$ and 
     539/// compress a polynomial s.t. \f$ deg_{x_{i}} (F) >= deg_{x_{i+1}} (F) \f$ and
    540540/// no gaps between the variables occur
    541541///
    542542/// @return a compressed poly with the above properties
    543543CanonicalForm myCompress (const CanonicalForm& F, ///< [in] a poly
    544                           CFMap& N                ///< [in,out] a map to 
     544                          CFMap& N                ///< [in,out] a map to
    545545                                                  ///< decompress
    546546                         );
     
    579579/// plug in evalPoint for y in a list of polys
    580580///
    581 /// @return returns a list of the evaluated polys, these evaluated polys are 
     581/// @return returns a list of the evaluated polys, these evaluated polys are
    582582/// made monic
    583583CFList
     
    607607
    608608/// normalize precomputed leading coefficients such that leading coefficients
    609 /// evaluated at @a evaluation in K^(n-2) equal the leading coeffs wrt 
     609/// evaluated at @a evaluation in K^(n-2) equal the leading coeffs wrt
    610610/// Variable(1) of bivariate factors and change @a A and @a Aeval accordingly
    611611void
     
    641641distributeContent (
    642642          const CFList& L,                        ///<[in] list of polys, first
    643                                                   ///< entry the content to be 
     643                                                  ///< entry the content to be
    644644                                                  ///< distributed
    645           const CFList* differentSecondVarFactors,///<[in] factorization wrt 
     645          const CFList* differentSecondVarFactors,///<[in] factorization wrt
    646646                                                  ///< different second vars
    647           int length                              ///<[in] length of 
     647          int length                              ///<[in] length of
    648648                                                  ///<differentSecondVarFactors
    649649                  );
     
    659659/// computes a list l of length length(LCFFactors)+1 of polynomials such that
    660660/// prod (l)=LCF, note that the first entry of l may be non constant. Intended
    661 /// to be used to precompute coefficients of a polynomial f from its bivariate 
     661/// to be used to precompute coefficients of a polynomial f from its bivariate
    662662/// factorizations.
    663663///
     
    795795#endif
    796796/* FAC_FQ_FACTORIZE_H */
    797 
  • libpolys/polys/clapsing.cc

    r62e51f rd51d87  
    16951695}
    16961696
    1697 ideal singclap_absBiFactorize ( poly f, ideal & mipos, intvec ** exps, int & numFactors, const ring r)
     1697ideal singclap_absFactorize ( poly f, ideal & mipos, intvec ** exps, int & numFactors, const ring r)
    16981698{
    16991699  p_Test(f, r);
     
    17141714  CanonicalForm F( convSingTrPFactoryP( f, r) );
    17151715
    1716   if (getNumVars (F) > 2)
    1717   {
    1718     WerrorS( feNotImplemented );
    1719     return res;
    1720   }
     1716  bool isRat= isOn (SW_RATIONAL);
     1717  if (!isRat)
     1718    On (SW_RATIONAL);
     1719
    17211720  CFAFList absFactors= absFactorize (F);
    17221721
     
    17401739    iter++;
    17411740  }
    1742   bool isRat= isOn (SW_RATIONAL);
    1743   if (!isRat)
    1744     On (SW_RATIONAL);
    17451741  for (; iter.hasItem(); iter++, i++)
    17461742  {
  • libpolys/polys/clapsing.h

    r62e51f rd51d87  
    5858intvec* singntl_LLL(intvec* A, const ring r);
    5959
    60 ideal singclap_absBiFactorize ( poly f, ideal & mipos, intvec ** exps, int & n, const ring r);
     60ideal singclap_absFactorize ( poly f, ideal & mipos, intvec ** exps, int & n, const ring r);
    6161#  endif
    6262# endif
Note: See TracChangeset for help on using the changeset viewer.