source: git/factory/cf_factor.cc @ f5d2647

spielwiese
Last change on this file since f5d2647 was 142afd, checked in by Martin Lee <martinlee84@…>, 11 years ago
deleted more unnecessary stuff using NTL in non-word size case in univariate factorization
  • Property mode set to 100644
File size: 19.1 KB
RevLine 
[362fc67]1/* emacs edit mode for this file is -*- C++ -*- */
[1a776f]2
3//{{{ docu
4//
5// cf_factor.cc - factorization and square free algorithms.
6//
7// Used by: fac_multivar.cc, fac_univar.cc, cf_irred.cc
8//
[989079]9// Header file: cf_algorithm.h
10//
[1a776f]11//}}}
[2dd068]12
[16f511]13#ifdef HAVE_CONFIG_H
[e4fe2b]14#include "config.h"
[16f511]15#endif /* HAVE_CONFIG_H */
[ab4548f]16
[650f2d8]17#include "cf_assert.h"
[8d9226]18
[2dd068]19#include "cf_defs.h"
20#include "canonicalform.h"
21#include "cf_iter.h"
22#include "fac_berlekamp.h"
23#include "fac_cantzass.h"
24#include "fac_univar.h"
25#include "fac_multivar.h"
26#include "fac_sqrfree.h"
[d6c703]27#include "cf_algorithm.h"
[7bf145]28#include "facFqFactorize.h"
[f78374]29#include "facFqSquarefree.h"
[afd067]30#include "cf_map.h"
[7bf145]31#include "algext.h"
[59a7ca1]32#include "facAlgExt.h"
[fcf7587]33#include "facFactorize.h"
34#include "singext.h"
[a43cca]35#include "cf_util.h"
[2dd068]36
[a99e31]37#include "int_int.h"
[cd86ac]38#ifdef HAVE_NTL
[a99e31]39#include "NTLconvert.h"
40#endif
41
[ee668e]42#include <factory/cf_gmp.h>
[ae3775]43#ifdef HAVE_FLINT
44#include "FLINTconvert.h"
45#endif
[daa556]46
[a99e31]47int getExp(); /* cf_char.cc */
48
[01e8874]49//static bool isUnivariateBaseDomain( const CanonicalForm & f )
50//{
51//    CFIterator i = f;
52//    bool ok = i.coeff().inBaseDomain();
53//    i++;
54//    while ( i.hasTerms() && ( ok = ok && i.coeff().inBaseDomain() ) ) i++;
55//    return ok;
56//}
[2dd068]57
[28ffaa]58void find_exp(const CanonicalForm & f, int * exp_f)
59{
60  if ( ! f.inCoeffDomain() )
61  {
62    int e=f.level();
63    CFIterator i = f;
[7af0e48]64    if (e>=0)
65    {
66      if (i.exp() > exp_f[e]) exp_f[e]=i.exp();
67    }
[28ffaa]68    for (; i.hasTerms(); i++ )
69    {
70      find_exp(i.coeff(), exp_f);
71    }
72  }
73}
74
75int find_mvar(const CanonicalForm & f)
76{
77  int mv=f.level();
78  int *exp_f=new int[mv+1];
79  int i;
80  for(i=mv;i>0;i--) exp_f[i]=0;
81  find_exp(f,exp_f);
82  for(i=mv;i>0;i--)
83  {
84    if ((exp_f[i]>0) && (exp_f[i]<exp_f[mv]))
85    {
86      mv=i;
87    }
88  }
89  delete[] exp_f;
90  return mv;
91}
92
[8710ff0]93#if 1
[6f62c3]94//#ifndef NOSTREAMIO
[27bb97f]95void out_cf(const char *s1,const CanonicalForm &f,const char *s2)
[7af0e48]96{
97  printf("%s",s1);
[1e6de6]98  if (f.isZero()) printf("+0");
[b1476d0]99  //else if (! f.inCoeffDomain() )
100  else if (! f.inBaseDomain() )
[7af0e48]101  {
102    int l = f.level();
103    for ( CFIterator i = f; i.hasTerms(); i++ )
104    {
105      int e=i.exp();
[b1476d0]106      if (i.coeff().isOne())
107      {
108        printf("+");
[cd86ac]109        if (e==0) printf("1");
110        else
111        {
112          printf("v(%d)",l);
113          if (e!=1) printf("^%d",e);
[b1476d0]114        }
[cd86ac]115      }
[b1476d0]116      else
117      {
118        out_cf("+(",i.coeff(),")");
119        if (e!=0)
[cd86ac]120        {
121          printf("*v(%d)",l);
122          if (e!=1) printf("^%d",e);
123        }
124      }
[7af0e48]125    }
126  }
127  else
128  {
129    if ( f.isImm() )
130    {
[903f87]131      if (CFFactory::gettype()==GaloisFieldDomain)
132      {
[8e4601]133         long a= imm2int (f.getval());
[903f87]134         if ( a == gf_q )
[8e4601]135           printf ("+%ld", a);
136         else  if ( a == 0L )
[903f87]137           printf ("+1");
[8e4601]138         else  if ( a == 1L )
[903f87]139           printf ("+%c",gf_name);
140         else
141         {
142           printf ("+%c",gf_name);
[8e4601]143           printf ("^%ld",a);
[903f87]144         }
145      }
146      else
147        printf("+%ld",f.intval());
[7af0e48]148    }
[3fd1ff]149    else
150    {
[6f62c3]151    #ifdef NOSTREAMIO
[3fd1ff]152      if (f.inZ())
153      {
[6d4f42]154        mpz_t m;
[806c18]155        gmp_numerator(f,m);
[6d4f42]156        char * str = new char[mpz_sizeinbase( m, 10 ) + 2];
157        str = mpz_get_str( str, 10, m );
[3fd1ff]158        printf("%s",str);
159        delete[] str;
[806c18]160        mpz_clear(m);
[3fd1ff]161      }
162      else if (f.inQ())
163      {
[6d4f42]164        mpz_t m;
[806c18]165        gmp_numerator(f,m);
[6d4f42]166        char * str = new char[mpz_sizeinbase( m, 10 ) + 2];
167        str = mpz_get_str( str, 10, m );
[3fd1ff]168        printf("%s/",str);
169        delete[] str;
[806c18]170        mpz_clear(m);
[6d4f42]171        gmp_denominator(f,m);
172        str = new char[mpz_sizeinbase( m, 10 ) + 2];
173        str = mpz_get_str( str, 10, m );
[3fd1ff]174        printf("%s",str);
175        delete[] str;
[806c18]176        mpz_clear(m);
[3fd1ff]177      }
[6f62c3]178    #else
[a1ab2a]179       std::cout << f;
[6f62c3]180    #endif
[3fd1ff]181    }
[b1476d0]182    //if (f.inZ()) printf("(Z)");
183    //else if (f.inQ()) printf("(Q)");
184    //else if (f.inFF()) printf("(FF)");
185    //else if (f.inPP()) printf("(PP)");
186    //else if (f.inGF()) printf("(PP)");
187    //else
188    if (f.inExtension()) printf("E(%d)",f.level());
[7af0e48]189  }
190  printf("%s",s2);
191}
192void out_cff(CFFList &L)
193{
[01e8874]194  //int n = L.length();
[7af0e48]195  CFFListIterator J=L;
196  int j=0;
197  for ( ; J.hasItem(); J++, j++ )
198  {
199    printf("F%d",j);out_cf(":",J.getItem().factor()," ^ ");
200    printf("%d\n", J.getItem().exp());
201  }
202}
203void test_cff(CFFList &L,const CanonicalForm & f)
204{
[01e8874]205  //int n = L.length();
[7af0e48]206  CFFListIterator J=L;
207  CanonicalForm t=1;
208  int j=0;
209  if (!(L.getFirst().factor().inCoeffDomain()))
210    printf("first entry is not const\n");
211  for ( ; J.hasItem(); J++, j++ )
212  {
213    CanonicalForm tt=J.getItem().factor();
214    if (tt.inCoeffDomain() && (j!=0))
215      printf("other entry is const\n");
216    j=J.getItem().exp();
217    while(j>0) { t*=tt; j--; }
218  }
[ceaa04]219  if (!(f-t).isZero()) { printf("problem:\n");out_cf("factor:",f," has problems\n");}
[7af0e48]220}
[6f62c3]221//#endif
[c6eecb]222#endif
[7af0e48]223
[6f62c3]224bool isPurePoly_m(const CanonicalForm & f)
225{
226  if (f.inBaseDomain()) return true;
227  if (f.level()<0) return false;
228  for (CFIterator i=f;i.hasTerms();i++)
229  {
230    if (!isPurePoly_m(i.coeff())) return false;
231  }
232  return true;
233}
[034eec]234bool isPurePoly(const CanonicalForm & f)
[7af0e48]235{
236  if (f.level()<=0) return false;
237  for (CFIterator i=f;i.hasTerms();i++)
238  {
239    if (!(i.coeff().inBaseDomain())) return false;
240  }
241  return true;
242}
243
[6f62c3]244
[dad0bc5]245///////////////////////////////////////////////////////////////
246// get_max_degree_Variable returns Variable with             //
247// highest degree. We assume f is *not* a constant!          //
248///////////////////////////////////////////////////////////////
249Variable
250get_max_degree_Variable(const CanonicalForm & f)
251{
252  ASSERT( ( ! f.inCoeffDomain() ), "no constants" );
253  int max=0, maxlevel=0, n=level(f);
254  for ( int i=1; i<=n; i++ )
255  {
256    if (degree(f,Variable(i)) >= max)
257    {
258      max= degree(f,Variable(i)); maxlevel= i;
259    }
260  }
261  return Variable(maxlevel);
262}
263
264///////////////////////////////////////////////////////////////
265// get_Terms: Split the polynomial in the containing terms.  //
266// getTerms: the real work is done here.                     //
267///////////////////////////////////////////////////////////////
268void
269getTerms( const CanonicalForm & f, const CanonicalForm & t, CFList & result )
270{
271  if ( getNumVars(f) == 0 ) result.append(f*t);
272  else{
273    Variable x(level(f));
274    for ( CFIterator i=f; i.hasTerms(); i++ )
275      getTerms( i.coeff(), t*power(x,i.exp()), result);
276  }
277}
278CFList
279get_Terms( const CanonicalForm & f ){
280  CFList result,dummy,dummy2;
281  CFIterator i;
282  CFListIterator j;
283
284  if ( getNumVars(f) == 0 ) result.append(f);
285  else{
286    Variable _x(level(f));
287    for ( i=f; i.hasTerms(); i++ ){
288      getTerms(i.coeff(), 1, dummy);
289      for ( j=dummy; j.hasItem(); j++ )
290        result.append(j.getItem() * power(_x, i.exp()));
291
292      dummy= dummy2; // have to initalize new
293    }
294  }
295  return result;
296}
297
298
299///////////////////////////////////////////////////////////////
300// homogenize homogenizes f with Variable x                  //
301///////////////////////////////////////////////////////////////
302
303CanonicalForm
304homogenize( const CanonicalForm & f, const Variable & x)
305{
306#if 0
307  int maxdeg=totaldegree(f), deg;
308  CFIterator i;
[faa6c6]309  CanonicalForm elem, result(0);
[3fd1ff]310
[dad0bc5]311  for (i=f; i.hasTerms(); i++)
312  {
313    elem= i.coeff()*power(f.mvar(),i.exp());
314    deg = totaldegree(elem);
315    if ( deg < maxdeg )
316      result += elem * power(x,maxdeg-deg);
[3fd1ff]317    else
[dad0bc5]318      result+=elem;
319  }
320  return result;
321#else
322  CFList Newlist, Termlist= get_Terms(f);
323  int maxdeg=totaldegree(f), deg;
324  CFListIterator i;
[faa6c6]325  CanonicalForm elem, result(0);
[dad0bc5]326
[a38d45]327  for (i=Termlist; i.hasItem(); i++)
328  {
[dad0bc5]329    elem= i.getItem();
330    deg = totaldegree(elem);
331    if ( deg < maxdeg )
332      Newlist.append(elem * power(x,maxdeg-deg));
333    else
334      Newlist.append(elem);
335  }
336  for (i=Newlist; i.hasItem(); i++) // rebuild
337    result += i.getItem();
338
339  return result;
340#endif
341}
342
[a38d45]343CanonicalForm
344homogenize( const CanonicalForm & f, const Variable & x, const Variable & v1, const Variable & v2)
345{
346#if 0
347  int maxdeg=totaldegree(f), deg;
348  CFIterator i;
349  CanonicalForm elem, result(0);
[3fd1ff]350
[a38d45]351  for (i=f; i.hasTerms(); i++)
352  {
353    elem= i.coeff()*power(f.mvar(),i.exp());
354    deg = totaldegree(elem);
355    if ( deg < maxdeg )
356      result += elem * power(x,maxdeg-deg);
[3fd1ff]357    else
[a38d45]358      result+=elem;
359  }
360  return result;
361#else
362  CFList Newlist, Termlist= get_Terms(f);
363  int maxdeg=totaldegree(f), deg;
364  CFListIterator i;
365  CanonicalForm elem, result(0);
366
367  for (i=Termlist; i.hasItem(); i++)
368  {
369    elem= i.getItem();
370    deg = totaldegree(elem,v1,v2);
371    if ( deg < maxdeg )
372      Newlist.append(elem * power(x,maxdeg-deg));
373    else
374      Newlist.append(elem);
375  }
376  for (i=Newlist; i.hasItem(); i++) // rebuild
377    result += i.getItem();
378
379  return result;
380#endif
381}
382
[fbbb08]383int singular_homog_flag=1;
384
[0cb22ad]385int cmpCF( const CFFactor & f, const CFFactor & g )
[dad0bc5]386{
387  if (f.exp() > g.exp()) return 1;
388  if (f.exp() < g.exp()) return 0;
389  if (f.factor() > g.factor()) return 1;
390  return 0;
391}
392
[989079]393CFFList factorize ( const CanonicalForm & f, bool issqrfree )
[2dd068]394{
[a99e31]395  if ( f.inCoeffDomain() )
[7af0e48]396        return CFFList( f );
[dad0bc5]397  //out_cf("factorize:",f,"==================================\n");
[a99e31]398  if (! f.isUnivariate() )
399  {
[dad0bc5]400    if ( singular_homog_flag && f.isHomogeneous())
401    {
402      Variable xn = get_max_degree_Variable(f);
403      int d_xn = degree(f,xn);
404      CFMap n;
405      CanonicalForm F = compress(f(1,xn),n);
406      CFFList Intermediatelist;
407      Intermediatelist = factorize(F);
408      CFFList Homoglist;
409      CFFListIterator j;
410      for ( j=Intermediatelist; j.hasItem(); j++ )
411      {
412        Homoglist.append(
413            CFFactor( n(j.getItem().factor()), j.getItem().exp()) );
414      }
415      CFFList Unhomoglist;
416      CanonicalForm unhomogelem;
417      for ( j=Homoglist; j.hasItem(); j++ )
418      {
419        unhomogelem= homogenize(j.getItem().factor(),xn);
420        Unhomoglist.append(CFFactor(unhomogelem,j.getItem().exp()));
421        d_xn -= (degree(unhomogelem,xn)*j.getItem().exp());
422      }
423      if ( d_xn != 0 ) // have to append xn^(d_xn)
[3fd1ff]424        Unhomoglist.append(CFFactor(CanonicalForm(xn),d_xn));
425      if(isOn(SW_USE_NTL_SORT)) Unhomoglist.sort(cmpCF);
[dad0bc5]426      return Unhomoglist;
427    }
[a99e31]428  }
429  CFFList F;
[7af0e48]430  if ( getCharacteristic() > 0 )
[a99e31]431  {
[7bf145]432    if (f.isUnivariate())
[7af0e48]433    {
[7cb5590]434#ifdef HAVE_NTL
[0dff6bc]435#ifdef HAVE_FLINT
436      if (degree (f) < 300)
437      {
438        nmod_poly_t f1;
439        convertFacCF2nmod_poly_t (f1, f);
440        nmod_poly_factor_t result;
441        nmod_poly_factor_init (result);
442        mp_limb_t leadingCoeff= nmod_poly_factor (result, f1);
443        F= convertFLINTnmod_poly_factor2FacCFFList (result, leadingCoeff, f.mvar());
444        nmod_poly_factor_clear (result);
445        nmod_poly_clear (f1);
446      }
447      else
448#endif
[7bf145]449      if (isOn(SW_USE_NTL) && (isPurePoly(f)))
[a99e31]450      {
[34ceab]451        // USE NTL
452        if (getCharacteristic()!=2)
453        {
[14212fa]454          if (fac_NTL_char != getCharacteristic())
[34ceab]455          {
[14212fa]456            fac_NTL_char = getCharacteristic();
[142afd]457            zz_p::init(getCharacteristic());
[34ceab]458          }
[142afd]459
460          // convert to NTL
461          zz_pX f1=convertFacCF2NTLzzpX(f);
462          zz_p leadcoeff = LeadCoeff(f1);
463
464          //make monic
465          f1=f1 / LeadCoeff(f1);
466          // factorize
467          vec_pair_zz_pX_long factors;
468          CanZass(factors,f1);
469
470          F=convertNTLvec_pair_zzpX_long2FacCFFList(factors,leadcoeff,f.mvar());
[34ceab]471          //test_cff(F,f);
472        }
[3b77086]473        else /*getCharacteristic()==2*/
[34ceab]474        {
475          // Specialcase characteristic==2
[14212fa]476          if (fac_NTL_char != 2)
[34ceab]477          {
[14212fa]478            fac_NTL_char = 2;
[34ceab]479            zz_p::init(2);
480          }
481          // convert to NTL using the faster conversion routine for characteristic 2
482          GF2X f1=convertFacCF2NTLGF2X(f);
483          // no make monic necessary in GF2
484          //factorize
485          vec_pair_GF2X_long factors;
486          CanZass(factors,f1);
487
488          // convert back to factory again using the faster conversion routine for vectors over GF2X
489          F=convertNTLvec_pair_GF2X_long2FacCFFList(factors,LeadCoeff(f1),f.mvar());
490        }
[a99e31]491      }
492      else
[7cb5590]493#endif //HAVE_NTL
[7bf145]494      {  // Use Factory without NTL
[34ceab]495        if ( isOn( SW_BERLEKAMP ) )
496          F=FpFactorizeUnivariateB( f, issqrfree );
497        else
498          F=FpFactorizeUnivariateCZ( f, issqrfree, 0, Variable(), Variable() );
[a99e31]499      }
500    }
501    else
[7bf145]502    {
503      #ifdef HAVE_NTL
504      if (issqrfree)
505      {
506        CFList factors;
507        Variable alpha;
508        if (CFFactory::gettype() == GaloisFieldDomain)
509          factors= GFSqrfFactorize (f);
510        else if (hasFirstAlgVar (f, alpha))
511          factors= FqSqrfFactorize (f, alpha);
512        else
513          factors= FpSqrfFactorize (f);
514        for (CFListIterator i= factors; i.hasItem(); i++)
515          F.append (CFFactor (i.getItem(), 1));
516      }
[e89e56]517      else
[7bf145]518      {
519        Variable alpha;
520        if (CFFactory::gettype() == GaloisFieldDomain)
521          F= GFFactorize (f);
522        else if (hasFirstAlgVar (f, alpha))
523          F= FqFactorize (f, alpha);
524        else
[34ceab]525          F= FpFactorize (f);
[7bf145]526      }
527      #else
528      ASSERT( f.isUnivariate(), "multivariate factorization not implemented" );
[a43cca]529      factoryError ("multivariate factorization not implemented");
530      return CFFList (CFFactor (f, 1));
[7bf145]531      #endif
[7af0e48]532    }
[a99e31]533  }
[e89e56]534  else
[a99e31]535  {
[77f483]536    bool on_rational = isOn(SW_RATIONAL);
537    On(SW_RATIONAL);
[a99e31]538    CanonicalForm cd = bCommonDen( f );
539    CanonicalForm fz = f * cd;
540    Off(SW_RATIONAL);
541    if ( f.isUnivariate() )
542    {
[7af0e48]543      #ifdef HAVE_NTL
544      if ((isOn(SW_USE_NTL)) && (isPurePoly(f)))
545      {
[a99e31]546        //USE NTL
[7af0e48]547        CanonicalForm ic=icontent(fz);
548        fz/=ic;
[a99e31]549        ZZ c;
550        vec_pair_ZZX_long factors;
551        //factorize the converted polynomial
[7af0e48]552        factor(c,factors,convertFacCF2NTLZZX(fz));
553
[a99e31]554        //convert the result back to Factory
555        F=convertNTLvec_pair_ZZX_long2FacCFFList(factors,c,fz.mvar());
[7af0e48]556        if ( ! ic.isOne() )
557        {
558          if ( F.getFirst().factor().inCoeffDomain() )
559          {
560            CFFactor new_first( F.getFirst().factor() * ic );
561            F.removeFirst();
562            F.insert( new_first );
563          }
564          else
565            F.insert( CFFactor( ic ) );
566        }
[cd86ac]567        else
568        {
[cae0b6]569          if ( !F.getFirst().factor().inCoeffDomain() )
570          {
571            CFFactor new_first( 1 );
572            F.insert( new_first );
573          }
[cd86ac]574        }
[cae0b6]575        //if ( F.getFirst().factor().isOne() )
576        //{
577        //  F.removeFirst();
578        //}
[cd86ac]579        //printf("NTL:\n");out_cff(F);
580        //F=ZFactorizeUnivariate( fz, issqrfree );
581        //printf("fac.:\n");out_cff(F);
[a99e31]582      }
[a43cca]583      #else
[7af0e48]584      {
[a99e31]585        //Use Factory without NTL
[a43cca]586        //F = ZFactorizeUnivariate( fz, issqrfree );
587        factoryError ("univariate factorization over Z not implemented"); 
588        return CFFList (CFFactor (f, 1));
[a99e31]589      }
[a43cca]590      #endif
[a99e31]591    }
592    else
[afd067]593    {
[a43cca]594      #ifdef HAVE_NTL
[88408d0]595      On (SW_RATIONAL);
596      if (issqrfree)
597      {
598        CFList factors;
[530295]599        factors= ratSqrfFactorize (fz);
[88408d0]600        for (CFListIterator i= factors; i.hasItem(); i++)
601          F.append (CFFactor (i.getItem(), 1));
602      }
603      else
[530295]604        F = ratFactorize (fz);
[88408d0]605      Off (SW_RATIONAL);
[a43cca]606      #else
607      factoryError ("multivariate factorization not implemented");
608      return CFFList (CFFactor (f, 1));
609      #endif
[afd067]610    }
[a99e31]611
612    if ( on_rational )
613      On(SW_RATIONAL);
614    if ( ! cd.isOne() )
615    {
616      if ( F.getFirst().factor().inCoeffDomain() )
617      {
618        CFFactor new_first( F.getFirst().factor() / cd );
619        F.removeFirst();
620        F.insert( new_first );
621      }
622      else
623      {
624        F.insert( CFFactor( 1/cd ) );
625      }
[2dd068]626    }
[7af0e48]627  }
[a99e31]628
[cae0b6]629  //out_cff(F);
[3fd1ff]630  if(isOn(SW_USE_NTL_SORT)) F.sort(cmpCF);
[a99e31]631  return F;
[2dd068]632}
[cae0b6]633
[6acb298]634#ifdef HAVE_NTL
[b1476d0]635CanonicalForm fntl ( const CanonicalForm & f, int j )
636{
637  ZZX f1=convertFacCF2NTLZZX(f);
638  return convertZZ2CF(coeff(f1,j));
[cd86ac]639}
[6acb298]640#endif
[2dd068]641
642CFFList factorize ( const CanonicalForm & f, const Variable & alpha )
643{
[fcf7587]644  if ( f.inCoeffDomain() )
645    return CFFList( f );
[cd86ac]646  //out_cf("factorize:",f,"==================================\n");
647  //out_cf("mipo:",getMipo(alpha),"\n");
648  CFFList F;
649  ASSERT( alpha.level() < 0, "not an algebraic extension" );
[34ceab]650  int ch=getCharacteristic();
651  if (f.isUnivariate()&& (ch>0))
[cd86ac]652  {
[7bf145]653    #ifdef HAVE_NTL
654    if  (isOn(SW_USE_NTL))
[cd86ac]655    {
[7bf145]656      //USE NTL
[34ceab]657      if (ch>2)
[b1326b]658      {
[34ceab]659        // First all cases with characteristic !=2
660        // set remainder
[14212fa]661        if (fac_NTL_char != getCharacteristic())
[34ceab]662        {
[14212fa]663          fac_NTL_char = getCharacteristic();
[34ceab]664          zz_p::init(getCharacteristic());
665        }
666
667        // set minimal polynomial in NTL
668        zz_pX minPo=convertFacCF2NTLzzpX(getMipo(alpha));
[142afd]669        zz_pE::init (minPo);
[34ceab]670
671        // convert to NTL
672        zz_pEX f1=convertFacCF2NTLzz_pEX(f,minPo);
673        zz_pE leadcoeff= LeadCoeff(f1);
674
675        //make monic
676        f1=f1 / leadcoeff;
677
678        // factorize using NTL
679        vec_pair_zz_pEX_long factors;
680        CanZass(factors,f1);
681
682        // return converted result
683        F=convertNTLvec_pair_zzpEX_long2FacCFFList(factors,leadcoeff,f.mvar(),alpha);
684      }
685      else if (/*getCharacteristic()*/ch==2)
686      {
687        // special case : GF2
688
689        // remainder is two ==> nothing to do
690
691        // set minimal polynomial in NTL using the optimized conversion routines for characteristic 2
692        GF2X minPo=convertFacCF2NTLGF2X(getMipo(alpha,f.mvar()));
[142afd]693        GF2E::init (minPo);
[34ceab]694
695        // convert to NTL again using the faster conversion routines
696        GF2EX f1;
697        if (isPurePoly(f))
698        {
699          GF2X f_tmp=convertFacCF2NTLGF2X(f);
700          f1=to_GF2EX(f_tmp);
701        }
702        else
703        {
704          f1=convertFacCF2NTLGF2EX(f,minPo);
705        }
706
707        // make monic (in Z/2(a))
708        GF2E f1_coef=LeadCoeff(f1);
709        MakeMonic(f1);
710
711        // factorize using NTL
712        vec_pair_GF2EX_long factors;
713        CanZass(factors,f1);
714
715        // return converted result
716        F=convertNTLvec_pair_GF2EX_long2FacCFFList(factors,f1_coef,f.mvar(),alpha);
[b1326b]717      }
718      else
719      {
720      }
[a99e31]721    }
[7bf145]722    else
723    #endif
724    {
725      F=FpFactorizeUnivariateCZ( f, false, 1, alpha, Variable() );
726    }
[cd86ac]727  }
[34ceab]728  else if (ch>0)
[cd86ac]729  {
[7bf145]730    #ifdef HAVE_NTL
731    F= FqFactorize (f, alpha);
732    #else
733    ASSERT( f.isUnivariate(), "multivariate factorization not implemented" );
[a43cca]734    factoryError ("multivariate factorization not implemented");
735    return CFFList (CFFactor (f, 1));
[7bf145]736    #endif
[34ceab]737
738  }
[fcf7587]739  else if (f.isUnivariate() && (ch == 0)) // Q(a)[x]
[59a7ca1]740  {
741    F= AlgExtFactorize (f, alpha);
742  }
743  else //Q(a)[x1,...,xn]
[34ceab]744  {
[d990001]745#ifdef HAVE_NTL
[fcf7587]746    F= ratFactorize (f, alpha);
[d990001]747#else
748    ASSERT( f.isUnivariate(), "multivariate factorization not implemented" );
[a43cca]749    factoryError ("multivariate factorization not implemented");
750    return CFFList (CFFactor (f, 1));
[d990001]751#endif
[cd86ac]752  }
[c58765]753  if(isOn(SW_USE_NTL_SORT)) F.sort(cmpCF);
[cd86ac]754  return F;
[2dd068]755}
756
[f78374]757CFFList sqrFree ( const CanonicalForm & f, bool sort )
[2dd068]758{
[e89e56]759//    ASSERT( f.isUnivariate(), "multivariate factorization not implemented" );
[87e1de]760    CFFList result;
761
[2dd068]762    if ( getCharacteristic() == 0 )
[e89e56]763        result = sqrFreeZ( f );
[2dd068]764    else
[f78374]765    {
766        Variable alpha;
767        if (hasFirstAlgVar (f, alpha))
768          result = FqSqrf( f, alpha );
769        else
770          result= FpSqrf (f);
771    }
772    if (sort)
773    {
774      CFFactor buf= result.getFirst();
775      result.removeFirst();
776      result= sortCFFList (result);
777      result.insert (buf);
778    }
[e89e56]779    return result;
[87e1de]780}
781
[e89e56]782bool isSqrFree ( const CanonicalForm & f )
[2dd068]783{
[e89e56]784//    ASSERT( f.isUnivariate(), "multivariate factorization not implemented" );
785    if ( getCharacteristic() == 0 )
786        return isSqrFreeZ( f );
[2dd068]787    else
[e89e56]788        return isSqrFreeFp( f );
[2dd068]789}
[a99e31]790
Note: See TracBrowser for help on using the repository browser.