source: git/factory/facAbsBiFact.cc @ c13ebd

spielwiese
Last change on this file since c13ebd was c13ebd, checked in by Hans Schoenemann <hannes@…>, 3 years ago
factory: discriminant from FLINT
  • Property mode set to 100644
File size: 21.0 KB
Line 
1/*****************************************************************************\
2 * Computer Algebra System SINGULAR
3\*****************************************************************************/
4/** @file facAbsBiFact.cc
5 *
6 * @author Martin Lee
7 *
8 **/
9/*****************************************************************************/
10
11
12#include "config.h"
13
14
15#include "timing.h"
16#include "debug.h"
17
18#include "facAbsBiFact.h"
19#include "facBivar.h"
20#include "facFqBivar.h"
21#include "cf_reval.h"
22#include "cf_primes.h"
23#include "cf_algorithm.h"
24#ifdef HAVE_FLINT
25#include "FLINTconvert.h"
26#include <flint/fmpz_poly_factor.h>
27#endif
28#ifdef HAVE_NTL
29#include "NTLconvert.h"
30#include <NTL/LLL.h>
31#endif
32
33#if defined(HAVE_NTL) || defined(HAVE_FLINT)
34TIMING_DEFINE_PRINT(fac_Qa_factorize)
35TIMING_DEFINE_PRINT(fac_evalpoint)
36
37CFAFList uniAbsFactorize (const CanonicalForm& F, bool full)
38{
39  CFAFList result;
40  if (degree (F) == 1)
41  {
42    bool isRat= isOn (SW_RATIONAL);
43    On (SW_RATIONAL);
44    result= CFAFList (CFAFactor (F/Lc(F), 1, 1));
45    result.insert (CFAFactor (Lc (F), 1, 1));
46    if (!isRat)
47      Off (SW_RATIONAL);
48    return result;
49  }
50  CanonicalForm LcF= 1;
51  Variable alpha;
52  CFFList QaFactors;
53  CFFListIterator iter;
54  alpha= rootOf (F);
55  QaFactors= factorize (F, alpha);
56  iter= QaFactors;
57  if (iter.getItem().factor().inCoeffDomain())
58  {
59    LcF = iter.getItem().factor();
60    iter++;
61  }
62  for (;iter.hasItem(); iter++)
63  {
64    if (full)
65      result.append (CFAFactor (iter.getItem().factor(), getMipo (alpha),
66                                iter.getItem().exp()));
67    if (!full && degree (iter.getItem().factor()) == 1)
68    {
69      result.append (CFAFactor (iter.getItem().factor(), getMipo (alpha),
70                                iter.getItem().exp()));
71      break;
72    }
73  }
74  result.insert (CFAFactor (LcF, 1, 1));
75  return result;
76}
77
78//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)
79int
80choosePoint (const CanonicalForm& F, int tdegF, CFArray& eval, bool rec,
81             int absValue)
82{
83  REvaluation E1 (1, 1, IntRandom (absValue));
84  REvaluation E2 (2, 2, IntRandom (absValue));
85  if (rec)
86  {
87    E1.nextpoint();
88    E2.nextpoint();
89  }
90
91  CanonicalForm f, f1, f2, Fp;
92  int i, p;
93  CFFList f1Factors, f2Factors;
94  CFFListIterator iter;
95  int count= 0;
96  while (1)
97  {
98    count++;
99    f1= E1 (F);
100    if (!f1.isZero() && degree (f1) == degree (F,2))
101    {
102      f1Factors= factorize (f1);
103      if (f1Factors.getFirst().factor().inCoeffDomain())
104        f1Factors.removeFirst();
105      if (f1Factors.length() == 1 && f1Factors.getFirst().exp() == 1)
106      {
107        f= E2(f1);
108        f2= E2 (F);
109        f2Factors= factorize (f2);
110        Off (SW_RATIONAL);
111        if (f2Factors.getFirst().factor().inCoeffDomain())
112          f2Factors.removeFirst();
113        if (f2Factors.length() == 1 && f2Factors.getFirst().exp() == 1)
114        {
115          #ifdef HAVE_FLINT
116          // init
117          fmpz_t FLINTD1,FLINTD2;
118          fmpz_init(FLINTD1);
119          fmpz_init(FLINTD2);
120          fmpz_poly_t FLINTf1;
121          fmpz_poly_t FLINTf2;
122          // conversion
123          convertFacCF2Fmpz_poly_t(FLINTf1,f1);
124          convertFacCF2Fmpz_poly_t(FLINTf2,f2);
125          // discriminant
126          fmpz_poly_discriminant(FLINTD1,FLINTf1);
127          fmpz_poly_discriminant(FLINTD2,FLINTf2);
128          // conversion
129          CanonicalForm D1= convertFmpz2CF(FLINTD1);
130          CanonicalForm D2= convertFmpz2CF(FLINTD2);
131          // clean up
132          fmpz_poly_clear(FLINTf1);
133          fmpz_poly_clear(FLINTf2);
134          fmpz_clear(FLINTD1);
135          fmpz_clear(FLINTD2);
136          #elif defined(HAVE_NTL)
137          ZZX NTLf1= convertFacCF2NTLZZX (f1);
138          ZZX NTLf2= convertFacCF2NTLZZX (f2);
139          ZZ NTLD1= discriminant (NTLf1);
140          ZZ NTLD2= discriminant (NTLf2);
141          CanonicalForm D1= convertZZ2CF (NTLD1);
142          CanonicalForm D2= convertZZ2CF (NTLD2);
143          #endif
144          if ((!f.isZero()) &&
145              (abs(f)>cf_getSmallPrime (cf_getNumSmallPrimes()-1)))
146          {
147            for (i= cf_getNumPrimes()-1; i >= 0; i--)
148            {
149              if (f % CanonicalForm (cf_getPrime (i)) == 0)
150              {
151                p= cf_getPrime(i);
152                Fp= mod (F,p);
153                if (totaldegree (Fp) == tdegF &&
154                    degree (mod (f2,p), 1) == degree (F,1) &&
155                    degree (mod (f1, p),2) == degree (F,2))
156                {
157                  if (mod (D1, p) != 0 && mod (D2, p) != 0)
158                  {
159                    eval[0]= E1[1];
160                    eval[1]= E2[2];
161                    return p;
162                  }
163                }
164              }
165            }
166          }
167          else if (!f.isZero())
168          {
169            for (i= cf_getNumSmallPrimes()-1; i >= 0; i--)
170            {
171              if (f % CanonicalForm (cf_getSmallPrime (i)) == 0)
172              {
173                p= cf_getSmallPrime (i);
174                Fp= mod (F,p);
175                if (totaldegree (Fp) == tdegF &&
176                    degree (mod (f2, p),1) == degree (F,1) &&
177                    degree (mod (f1,p),2) == degree (F,2))
178                {
179                  if (mod (D1, p) != 0 && mod (D2, p) != 0)
180                  {
181                    eval[0]= E1[1];
182                    eval[1]= E2[2];
183                    return p;
184                  }
185                }
186              }
187            }
188          }
189        }
190        E2.nextpoint();
191        On (SW_RATIONAL);
192      }
193    }
194    E1.nextpoint();
195    if (count == 2)
196    {
197      count= 0;
198      absValue++;
199      E1=REvaluation (1, 1, IntRandom (absValue));
200      E2=REvaluation (2, 2, IntRandom (absValue));
201      E1.nextpoint();
202      E2.nextpoint();
203    }
204  }
205  return 0;
206}
207
208#ifdef HAVE_NTL
209//G is assumed to be bivariate, irreducible over Q, primitive wrt x and y, compressed
210CFAFList absBiFactorizeMain (const CanonicalForm& G, bool full)
211{
212  CanonicalForm F= bCommonDen (G)*G;
213  bool isRat= isOn (SW_RATIONAL);
214  Off (SW_RATIONAL);
215  F /= icontent (F);
216  On (SW_RATIONAL);
217
218  mpz_t * M=new mpz_t [4];
219  mpz_init (M[0]);
220  mpz_init (M[1]);
221  mpz_init (M[2]);
222  mpz_init (M[3]);
223
224  mpz_t * S=new mpz_t [2];
225  mpz_init (S[0]);
226  mpz_init (S[1]);
227
228  F= compress (F, M, S);
229
230  if (F.isUnivariate())
231  {
232    if (degree (F) == 1)
233    {
234      mpz_clear (M[0]);
235      mpz_clear (M[1]);
236      mpz_clear (M[2]);
237      mpz_clear (M[3]);
238      delete [] M;
239
240      mpz_clear (S[0]);
241      mpz_clear (S[1]);
242      delete [] S;
243      if (!isRat)
244        Off (SW_RATIONAL);
245      return CFAFList (CFAFactor (G, 1, 1));
246    }
247    CFAFList result= uniAbsFactorize (F, full);
248    if (result.getFirst().factor().inCoeffDomain())
249      result.removeFirst();
250    for (CFAFListIterator iter=result; iter.hasItem(); iter++)
251      iter.getItem()= CFAFactor (decompress (iter.getItem().factor(), M, S),
252                                 iter.getItem().minpoly(),iter.getItem().exp());
253    mpz_clear (M[0]);
254    mpz_clear (M[1]);
255    mpz_clear (M[2]);
256    mpz_clear (M[3]);
257    delete [] M;
258
259    mpz_clear (S[0]);
260    mpz_clear (S[1]);
261    delete [] S;
262    if (!isRat)
263      Off (SW_RATIONAL);
264    return result;
265  }
266
267  if (degree (F, 1) == 1 || degree (F, 2) == 1)
268  {
269    mpz_clear (M[0]);
270    mpz_clear (M[1]);
271    mpz_clear (M[2]);
272    mpz_clear (M[3]);
273    delete [] M;
274
275    mpz_clear (S[0]);
276    mpz_clear (S[1]);
277    delete [] S;
278    if (!isRat)
279      Off (SW_RATIONAL);
280    return CFAFList (CFAFactor (G, 1, 1));
281  }
282  int minTdeg, tdegF= totaldegree (F);
283  CanonicalForm Fp, smallestFactor;
284  int p;
285  CFFList factors;
286  Variable alpha;
287  bool rec= false;
288  Variable x= Variable (1);
289  Variable y= Variable (2);
290  CanonicalForm bufF= F;
291  CFFListIterator iter;
292  CFArray eval= CFArray (2);
293  int absValue= 1;
294differentevalpoint:
295  while (1)
296  {
297    TIMING_START (fac_evalpoint);
298    p= choosePoint (F, tdegF, eval, rec, absValue);
299    TIMING_END_AND_PRINT (fac_evalpoint, "time to find eval point: ");
300
301    //after here isOn (SW_RATIONAL)==false
302    setCharacteristic (p);
303    Fp=F.mapinto();
304    factors= factorize (Fp);
305
306    if (factors.getFirst().factor().inCoeffDomain())
307      factors.removeFirst();
308
309    if (factors.length() == 1 && factors.getFirst().exp() == 1)
310    {
311      if (absIrredTest (Fp))
312      {
313        if (isRat)
314          On (SW_RATIONAL);
315        setCharacteristic(0);
316        mpz_clear (M[0]);
317        mpz_clear (M[1]);
318        mpz_clear (M[2]);
319        mpz_clear (M[3]);
320        delete [] M;
321
322        mpz_clear (S[0]);
323        mpz_clear (S[1]);
324        delete [] S;
325        return CFAFList (CFAFactor (G, 1, 1));
326      }
327      else
328      {
329        setCharacteristic (0);
330        if (modularIrredTestWithShift (F))
331        {
332          if (isRat)
333            On (SW_RATIONAL);
334          mpz_clear (M[0]);
335          mpz_clear (M[1]);
336          mpz_clear (M[2]);
337          mpz_clear (M[3]);
338          delete [] M;
339
340          mpz_clear (S[0]);
341          mpz_clear (S[1]);
342          delete [] S;
343          return CFAFList (CFAFactor (G, 1, 1));
344        }
345        rec= true;
346        continue;
347      }
348    }
349    iter= factors;
350    smallestFactor= iter.getItem().factor();
351    while (smallestFactor.isUnivariate() && iter.hasItem())
352    {
353      iter++;
354      if (!iter.hasItem())
355        break;
356      smallestFactor= iter.getItem().factor();
357    }
358
359    minTdeg= totaldegree (smallestFactor);
360    if (iter.hasItem())
361      iter++;
362    for (; iter.hasItem(); iter++)
363    {
364      if (!iter.getItem().factor().isUnivariate() &&
365          (totaldegree (iter.getItem().factor()) < minTdeg))
366      {
367        smallestFactor= iter.getItem().factor();
368        minTdeg= totaldegree (smallestFactor);
369      }
370    }
371    if (tdegF % minTdeg == 0)
372      break;
373    setCharacteristic(0);
374    rec=true;
375  }
376  CanonicalForm Gp= Fp/smallestFactor;
377  Gp= Gp /Lc (Gp);
378
379  CanonicalForm Gpy= Gp (eval[0].mapinto(), 1);
380  CanonicalForm smallestFactorEvaly= smallestFactor (eval[0].mapinto(),1);
381  CanonicalForm Gpx= Gp (eval[1].mapinto(), 2);
382  CanonicalForm smallestFactorEvalx= smallestFactor (eval[1].mapinto(),2);
383
384  bool xValid= !(Gpx.inCoeffDomain() || smallestFactorEvalx.inCoeffDomain() ||
385               !gcd (Gpx, smallestFactorEvalx).inCoeffDomain());
386  bool yValid= !(Gpy.inCoeffDomain() || smallestFactorEvaly.inCoeffDomain() ||
387               !gcd (Gpy, smallestFactorEvaly).inCoeffDomain());
388  if (!xValid || !yValid)
389  {
390    rec= true;
391    setCharacteristic (0);
392    goto differentevalpoint;
393  }
394
395  setCharacteristic (0);
396
397  CanonicalForm mipo;
398
399  CFArray mipos= CFArray (2);
400  CFFList mipoFactors;
401  for (int i= 1; i < 3; i++)
402  {
403    CanonicalForm Fi= F(eval[i-1],i);
404
405    int s= tdegF/minTdeg + 1;
406    CanonicalForm bound= power (maxNorm (Fi), 2*(s-1));
407    bound *= power (CanonicalForm (s),s-1);
408    bound *= power (CanonicalForm (2), ((s-1)*(s-1))/2); //possible int overflow
409
410    CanonicalForm B = p;
411    long k = 1L;
412    while ( B < bound ) {
413      B *= p;
414      k++;
415    }
416
417    //TODO take floor (log2(k))
418    k= k+1;
419#ifdef HAVE_FLINT
420    fmpz_poly_t FLINTFi;
421    convertFacCF2Fmpz_poly_t (FLINTFi, Fi);
422    setCharacteristic (p);
423    nmod_poly_t FLINTFpi, FLINTGpi;
424    if (i == 2)
425    {
426      convertFacCF2nmod_poly_t (FLINTFpi,
427                                smallestFactorEvalx/lc (smallestFactorEvalx));
428      convertFacCF2nmod_poly_t (FLINTGpi, Gpx/lc (Gpx));
429    }
430    else
431    {
432      convertFacCF2nmod_poly_t (FLINTFpi,
433                                smallestFactorEvaly/lc (smallestFactorEvaly));
434      convertFacCF2nmod_poly_t (FLINTGpi, Gpy/lc (Gpy));
435    }
436    nmod_poly_factor_t nmodFactors;
437    nmod_poly_factor_init (nmodFactors);
438    nmod_poly_factor_insert (nmodFactors, FLINTFpi, 1L);
439    nmod_poly_factor_insert (nmodFactors, FLINTGpi, 1L);
440
441    // the following fix is due to interface changes from  FLINT 2.3 -> FLINT 2.4
442#   ifndef slong
443#          define slong long
444#   endif
445
446    slong * link= new slong [2];
447    fmpz_poly_t *v= new fmpz_poly_t[2];
448    fmpz_poly_t *w= new fmpz_poly_t[2];
449    fmpz_poly_init(v[0]);
450    fmpz_poly_init(v[1]);
451    fmpz_poly_init(w[0]);
452    fmpz_poly_init(w[1]);
453
454    fmpz_poly_factor_t liftedFactors;
455    fmpz_poly_factor_init (liftedFactors);
456    _fmpz_poly_hensel_start_lift (liftedFactors, link, v, w, FLINTFi,
457                                  nmodFactors, k);
458
459    nmod_poly_factor_clear (nmodFactors);
460    nmod_poly_clear (FLINTFpi);
461    nmod_poly_clear (FLINTGpi);
462
463    setCharacteristic(0);
464    CanonicalForm liftedSmallestFactor=
465    convertFmpz_poly_t2FacCF ((fmpz_poly_t &)liftedFactors->p[0],x);
466
467    CanonicalForm otherFactor=
468    convertFmpz_poly_t2FacCF ((fmpz_poly_t &)liftedFactors->p[1],x);
469    modpk pk= modpk (p, k);
470#else
471    modpk pk= modpk (p, k);
472    ZZX NTLFi=convertFacCF2NTLZZX (pk (Fi*pk.inverse (lc(Fi))));
473    setCharacteristic (p);
474
475    if (fac_NTL_char != p)
476    {
477      fac_NTL_char= p;
478      zz_p::init (p);
479    }
480    zz_pX NTLFpi, NTLGpi;
481    if (i == 2)
482    {
483      NTLFpi=convertFacCF2NTLzzpX (smallestFactorEvalx/lc(smallestFactorEvalx));
484      NTLGpi=convertFacCF2NTLzzpX (Gpx/lc (Gpx));
485    }
486    else
487    {
488      NTLFpi=convertFacCF2NTLzzpX (smallestFactorEvaly/lc(smallestFactorEvaly));
489      NTLGpi=convertFacCF2NTLzzpX (Gpy/lc (Gpy));
490    }
491    vec_zz_pX modFactors;
492    modFactors.SetLength(2);
493    modFactors[0]= NTLFpi;
494    modFactors[1]= NTLGpi;
495    vec_ZZX liftedFactors;
496    MultiLift (liftedFactors, modFactors, NTLFi, (long) k);
497    setCharacteristic(0);
498    CanonicalForm liftedSmallestFactor=
499                  convertNTLZZX2CF (liftedFactors[0], x);
500
501    CanonicalForm otherFactor=
502                  convertNTLZZX2CF (liftedFactors[1], x);
503#endif
504
505    Off (SW_SYMMETRIC_FF);
506    liftedSmallestFactor= pk (liftedSmallestFactor);
507    if (i == 2)
508      liftedSmallestFactor= liftedSmallestFactor (eval[0],1);
509    else
510      liftedSmallestFactor= liftedSmallestFactor (eval[1],1);
511
512    On (SW_SYMMETRIC_FF);
513    CFMatrix *M= new CFMatrix (s, s);
514    (*M)(s,s)= power (CanonicalForm (p), k);
515    for (int j= 1; j < s; j++)
516    {
517      (*M) (j,j)= 1;
518      (*M) (j+1,j)= -liftedSmallestFactor;
519    }
520
521    mat_ZZ * NTLM= convertFacCFMatrix2NTLmat_ZZ (*M);
522
523    ZZ det;
524
525    transpose (*NTLM, *NTLM);
526    (void) LLL (det, *NTLM, 1L, 1L); //use floating point LLL ?
527    transpose (*NTLM, *NTLM);
528    delete M;
529    M= convertNTLmat_ZZ2FacCFMatrix (*NTLM);
530    delete NTLM;
531
532    mipo= 0;
533    for (int j= 1; j <= s; j++)
534      mipo += (*M) (j,1)*power (x,s-j);
535
536    delete M;
537    mipoFactors= factorize (mipo);
538    if (mipoFactors.getFirst().factor().inCoeffDomain())
539      mipoFactors.removeFirst();
540
541#ifdef HAVE_FLINT
542    fmpz_poly_clear (v[0]);
543    fmpz_poly_clear (v[1]);
544    fmpz_poly_clear (w[0]);
545    fmpz_poly_clear (w[1]);
546    delete [] v;
547    delete [] w;
548    delete [] link;
549    fmpz_poly_factor_clear (liftedFactors);
550#endif
551
552    if (mipoFactors.length() > 1 ||
553        (mipoFactors.length() == 1 && mipoFactors.getFirst().exp() > 1) ||
554         mipo.inCoeffDomain())
555    {
556        rec=true;
557        goto differentevalpoint;
558    }
559    else
560      mipos[i-1]= mipo;
561  }
562
563  if (degree (mipos[0]) != degree (mipos[1]))
564  {
565    rec=true;
566    goto differentevalpoint;
567  }
568
569  On (SW_RATIONAL);
570  if (maxNorm (mipos[0]) < maxNorm (mipos[1]))
571    alpha= rootOf (mipos[0]);
572  else
573    alpha= rootOf (mipos[1]);
574
575  int wrongMipo= 0;
576
577  Variable beta;
578  if (maxNorm (mipos[0]) < maxNorm (mipos[1]))
579  {
580    mipoFactors= factorize (mipos[1], alpha);
581    if (mipoFactors.getFirst().factor().inCoeffDomain())
582      mipoFactors.removeFirst();
583    for (iter= mipoFactors; iter.hasItem(); iter++)
584    {
585      if (degree (iter.getItem().factor()) > 1)
586        wrongMipo++;
587    }
588    if (wrongMipo == mipoFactors.length())
589    {
590      rec=true;
591      goto differentevalpoint;
592    }
593    wrongMipo= 0;
594    beta= rootOf (mipos[1]);
595    mipoFactors= factorize (mipos[0], beta);
596    if (mipoFactors.getFirst().factor().inCoeffDomain())
597      mipoFactors.removeFirst();
598    for (iter= mipoFactors; iter.hasItem(); iter++)
599    {
600      if (degree (iter.getItem().factor()) > 1)
601        wrongMipo++;
602    }
603    if (wrongMipo == mipoFactors.length())
604    {
605      rec=true;
606      goto differentevalpoint;
607    }
608  }
609  else
610  {
611    mipoFactors= factorize (mipos[0], alpha);
612    if (mipoFactors.getFirst().factor().inCoeffDomain())
613      mipoFactors.removeFirst();
614    for (iter= mipoFactors; iter.hasItem(); iter++)
615    {
616      if (degree (iter.getItem().factor()) > 1)
617        wrongMipo++;
618    }
619    if (wrongMipo == mipoFactors.length())
620    {
621      rec=true;
622      goto differentevalpoint;
623    }
624    wrongMipo= 0;
625    beta= rootOf (mipos[0]);
626    mipoFactors= factorize (mipos[1], beta);
627    if (mipoFactors.getFirst().factor().inCoeffDomain())
628      mipoFactors.removeFirst();
629    for (iter= mipoFactors; iter.hasItem(); iter++)
630    {
631      if (degree (iter.getItem().factor()) > 1)
632        wrongMipo++;
633    }
634    if (wrongMipo == mipoFactors.length())
635    {
636      rec=true;
637      goto differentevalpoint;
638    }
639  }
640
641
642  CanonicalForm F1;
643  if (degree (F,1) > minTdeg)
644    F1= F (eval[1], 2);
645  else
646    F1= F (eval[0], 1);
647
648  CFFList QaF1Factors;
649  bool swap= false;
650  if (F1.level() == 2)
651  {
652    swap= true;
653    F1=swapvar (F1, x, y);
654    F= swapvar (F, x, y);
655  }
656
657  wrongMipo= 0;
658  QaF1Factors= factorize (F1, alpha);
659  if (QaF1Factors.getFirst().factor().inCoeffDomain())
660    QaF1Factors.removeFirst();
661  for (iter= QaF1Factors; iter.hasItem(); iter++)
662  {
663    if (degree (iter.getItem().factor()) > minTdeg)
664      wrongMipo++;
665  }
666
667  if (wrongMipo == QaF1Factors.length())
668  {
669    rec= true;
670    F= bufF;
671    goto differentevalpoint;
672  }
673
674  CanonicalForm evaluation;
675  if (swap)
676    evaluation= eval[0];
677  else
678    evaluation= eval[1];
679
680  F *= bCommonDen (F);
681  F= F (y + evaluation, y);
682
683  int liftBound= degree (F,y) + 1;
684
685  modpk b= modpk();
686
687  CanonicalForm den= 1;
688
689  mipo= getMipo (alpha);
690
691  CFList uniFactors;
692  for (iter=QaF1Factors; iter.hasItem(); iter++)
693    uniFactors.append (iter.getItem().factor());
694
695  F /= Lc (F1);
696  #ifdef HAVE_FLINT
697  // init
698  fmpz_t FLINTf,FLINTD;
699  fmpz_init(FLINTf);
700  fmpz_init(FLINTD);
701  fmpz_poly_t FLINTmipo;
702  fmpz_poly_t FLINTLcf;
703  //conversion
704  convertFacCF2Fmpz_poly_t(FLINTmipo,mipo);
705  convertFacCF2Fmpz_poly_t(FLINTLcf,Lc (F*bCommonDen (F)));
706  // resultant, discriminant
707  fmpz_poly_resultant(FLINTf,FLINTmipo,FLINTLcf);
708  fmpz_poly_discriminant(FLINTD,FLINTmipo);
709  fmpz_mul(FLINTf,FLINTD,FLINTf);
710  den= abs (convertFmpz2CF(FLINTf));
711  // clean up
712  fmpz_clear(FLINTf);
713   // FLINTD is used below
714  fmpz_poly_clear(FLINTLcf);
715  fmpz_poly_clear(FLINTmipo);
716  #elif defined(HAVE_NTL)
717  ZZX NTLmipo= convertFacCF2NTLZZX (mipo);
718  ZZX NTLLcf= convertFacCF2NTLZZX (Lc (F*bCommonDen (F)));
719  ZZ NTLf= resultant (NTLmipo, NTLLcf);
720  ZZ NTLD= discriminant (NTLmipo);
721  den= abs (convertZZ2CF (NTLD*NTLf));
722  #endif
723
724  // make factors elements of Z(a)[x] disable for modularDiophant
725  CanonicalForm multiplier= 1;
726  for (CFListIterator i= uniFactors; i.hasItem(); i++)
727  {
728    multiplier *= bCommonDen (i.getItem());
729    i.getItem()= i.getItem()*bCommonDen(i.getItem());
730  }
731  F *= multiplier;
732  F *= bCommonDen (F);
733
734  Off (SW_RATIONAL);
735  int ii= 0;
736  #ifdef HAVE_FLINT
737  CanonicalForm discMipo= convertFmpz2CF(FLINTD);
738  fmpz_clear(FLINTD);
739  #elif defined(HAVE_NTL)
740  CanonicalForm discMipo= convertZZ2CF (NTLD);
741  #endif
742  findGoodPrime (bufF*discMipo,ii);
743  findGoodPrime (F1*discMipo,ii);
744  findGoodPrime (F*discMipo,ii);
745
746  int pp=cf_getBigPrime(ii);
747  b = coeffBound( F, pp, mipo );
748  modpk bb= coeffBound (F1, pp, mipo);
749  if (bb.getk() > b.getk() ) b=bb;
750    bb= coeffBound (F, pp, mipo);
751  if (bb.getk() > b.getk() ) b=bb;
752
753  ExtensionInfo dummy= ExtensionInfo (alpha, false);
754  DegreePattern degs= DegreePattern (uniFactors);
755
756  bool earlySuccess= false;
757  CFList earlyFactors;
758  uniFactors= henselLiftAndEarly
759              (F, earlySuccess, earlyFactors, degs, liftBound,
760               uniFactors, dummy, evaluation, b, den);
761
762  DEBOUTLN (cerr, "lifted factors= " << uniFactors);
763
764  CanonicalForm MODl= power (y, liftBound);
765
766  On (SW_RATIONAL);
767  F *= bCommonDen (F);
768  Off (SW_RATIONAL);
769
770  CFList biFactors;
771
772  biFactors= factorRecombination (uniFactors, F, MODl, degs, evaluation, 1,
773                                  uniFactors.length()/2, b, den);
774
775  On (SW_RATIONAL);
776
777  if (earlySuccess)
778    biFactors= Union (earlyFactors, biFactors);
779  else if (!earlySuccess && degs.getLength() == 1)
780    biFactors= earlyFactors;
781
782  bool swap2= false;
783  appendSwapDecompress (biFactors, CFList(), CFList(), swap, swap2, CFMap());
784  if (isOn (SW_RATIONAL))
785    normalize (biFactors);
786
787  CFAFList result;
788  bool found= false;
789
790  for (CFListIterator i= biFactors; i.hasItem(); i++)
791  {
792    if (full)
793      result.append (CFAFactor (decompress (i.getItem(), M, S),
794                                getMipo (alpha), 1));
795
796    if (totaldegree (i.getItem()) == minTdeg)
797    {
798      if (!full)
799        result= CFAFList (CFAFactor (decompress (i.getItem(), M, S),
800                                     getMipo (alpha), 1));
801      found= true;
802
803      if (!full)
804        break;
805    }
806  }
807
808  if (!found)
809  {
810    rec= true;
811    F= bufF;
812    goto differentevalpoint;
813  }
814
815  if (isRat)
816    On (SW_RATIONAL);
817  else
818    Off (SW_RATIONAL);
819
820  mpz_clear (M[0]);
821  mpz_clear (M[1]);
822  mpz_clear (M[2]);
823  mpz_clear (M[3]);
824  delete [] M;
825
826  mpz_clear (S[0]);
827  mpz_clear (S[1]);
828  delete [] S;
829
830  return result;
831}
832#endif
833#endif
Note: See TracBrowser for help on using the repository browser.