source: git/factory/cf_factor.cc @ ad443e

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