[493c477] | 1 | /* emacs edit mode for this file is -*- C++ -*- */ |
---|
[b1326b] | 2 | /* $Id: cf_factor.cc,v 1.20 2003-08-28 11:54:32 Singular Exp $ */ |
---|
[1a776f] | 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 | // |
---|
[989079] | 10 | // Header file: cf_algorithm.h |
---|
| 11 | // |
---|
[1a776f] | 12 | //}}} |
---|
[2dd068] | 13 | |
---|
[ab4548f] | 14 | #include <config.h> |
---|
| 15 | |
---|
[2dd068] | 16 | #include "cf_gmp.h" |
---|
| 17 | |
---|
| 18 | #include "assert.h" |
---|
[8d9226] | 19 | |
---|
[2dd068] | 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" |
---|
[d6c703] | 28 | #include "cf_algorithm.h" |
---|
[2dd068] | 29 | |
---|
[a99e31] | 30 | #include "int_int.h" |
---|
[cd86ac] | 31 | #ifdef HAVE_NTL |
---|
[a99e31] | 32 | #include "NTLconvert.h" |
---|
| 33 | #endif |
---|
| 34 | |
---|
| 35 | int getExp(); /* cf_char.cc */ |
---|
| 36 | |
---|
[2dd068] | 37 | static bool isUnivariateBaseDomain( const CanonicalForm & f ) |
---|
| 38 | { |
---|
| 39 | CFIterator i = f; |
---|
| 40 | bool ok = i.coeff().inBaseDomain(); |
---|
| 41 | i++; |
---|
| 42 | while ( i.hasTerms() && ( ok = ok && i.coeff().inBaseDomain() ) ) i++; |
---|
| 43 | return ok; |
---|
| 44 | } |
---|
| 45 | |
---|
[28ffaa] | 46 | void find_exp(const CanonicalForm & f, int * exp_f) |
---|
| 47 | { |
---|
| 48 | if ( ! f.inCoeffDomain() ) |
---|
| 49 | { |
---|
| 50 | int e=f.level(); |
---|
| 51 | CFIterator i = f; |
---|
[7af0e48] | 52 | if (e>=0) |
---|
| 53 | { |
---|
| 54 | if (i.exp() > exp_f[e]) exp_f[e]=i.exp(); |
---|
| 55 | } |
---|
[28ffaa] | 56 | for (; i.hasTerms(); i++ ) |
---|
| 57 | { |
---|
| 58 | find_exp(i.coeff(), exp_f); |
---|
| 59 | } |
---|
| 60 | } |
---|
| 61 | } |
---|
| 62 | |
---|
| 63 | int find_mvar(const CanonicalForm & f) |
---|
| 64 | { |
---|
| 65 | int mv=f.level(); |
---|
| 66 | int *exp_f=new int[mv+1]; |
---|
| 67 | int i; |
---|
| 68 | for(i=mv;i>0;i--) exp_f[i]=0; |
---|
| 69 | find_exp(f,exp_f); |
---|
| 70 | for(i=mv;i>0;i--) |
---|
| 71 | { |
---|
| 72 | if ((exp_f[i]>0) && (exp_f[i]<exp_f[mv])) |
---|
| 73 | { |
---|
| 74 | mv=i; |
---|
| 75 | } |
---|
| 76 | } |
---|
| 77 | delete[] exp_f; |
---|
| 78 | return mv; |
---|
| 79 | } |
---|
| 80 | |
---|
[7af0e48] | 81 | #if 0 |
---|
| 82 | void out_cf(char *s1,const CanonicalForm &f,char *s2) |
---|
| 83 | { |
---|
| 84 | printf("%s",s1); |
---|
| 85 | if (f==0) printf("+0"); |
---|
[b1476d0] | 86 | //else if (! f.inCoeffDomain() ) |
---|
| 87 | else if (! f.inBaseDomain() ) |
---|
[7af0e48] | 88 | { |
---|
| 89 | int l = f.level(); |
---|
| 90 | for ( CFIterator i = f; i.hasTerms(); i++ ) |
---|
| 91 | { |
---|
| 92 | int e=i.exp(); |
---|
[b1476d0] | 93 | if (i.coeff().isOne()) |
---|
| 94 | { |
---|
| 95 | printf("+"); |
---|
[cd86ac] | 96 | if (e==0) printf("1"); |
---|
| 97 | else |
---|
| 98 | { |
---|
| 99 | printf("v(%d)",l); |
---|
| 100 | if (e!=1) printf("^%d",e); |
---|
[b1476d0] | 101 | } |
---|
[cd86ac] | 102 | } |
---|
[b1476d0] | 103 | else |
---|
| 104 | { |
---|
| 105 | out_cf("+(",i.coeff(),")"); |
---|
| 106 | if (e!=0) |
---|
[cd86ac] | 107 | { |
---|
| 108 | printf("*v(%d)",l); |
---|
| 109 | if (e!=1) printf("^%d",e); |
---|
| 110 | } |
---|
| 111 | } |
---|
[7af0e48] | 112 | } |
---|
| 113 | } |
---|
| 114 | else |
---|
| 115 | { |
---|
| 116 | if ( f.isImm() ) |
---|
| 117 | { |
---|
[b1476d0] | 118 | printf("+%d",f.intval()); |
---|
[7af0e48] | 119 | } |
---|
[b1476d0] | 120 | else printf("+..."); |
---|
| 121 | //if (f.inZ()) printf("(Z)"); |
---|
| 122 | //else if (f.inQ()) printf("(Q)"); |
---|
| 123 | //else if (f.inFF()) printf("(FF)"); |
---|
| 124 | //else if (f.inPP()) printf("(PP)"); |
---|
| 125 | //else if (f.inGF()) printf("(PP)"); |
---|
| 126 | //else |
---|
| 127 | if (f.inExtension()) printf("E(%d)",f.level()); |
---|
[7af0e48] | 128 | } |
---|
| 129 | printf("%s",s2); |
---|
| 130 | } |
---|
| 131 | void out_cff(CFFList &L) |
---|
| 132 | { |
---|
| 133 | int n = L.length(); |
---|
| 134 | CFFListIterator J=L; |
---|
| 135 | int j=0; |
---|
| 136 | for ( ; J.hasItem(); J++, j++ ) |
---|
| 137 | { |
---|
| 138 | printf("F%d",j);out_cf(":",J.getItem().factor()," ^ "); |
---|
| 139 | printf("%d\n", J.getItem().exp()); |
---|
| 140 | } |
---|
| 141 | } |
---|
| 142 | void test_cff(CFFList &L,const CanonicalForm & f) |
---|
| 143 | { |
---|
| 144 | int n = L.length(); |
---|
| 145 | CFFListIterator J=L; |
---|
| 146 | CanonicalForm t=1; |
---|
| 147 | int j=0; |
---|
| 148 | if (!(L.getFirst().factor().inCoeffDomain())) |
---|
| 149 | printf("first entry is not const\n"); |
---|
| 150 | for ( ; J.hasItem(); J++, j++ ) |
---|
| 151 | { |
---|
| 152 | CanonicalForm tt=J.getItem().factor(); |
---|
| 153 | if (tt.inCoeffDomain() && (j!=0)) |
---|
| 154 | printf("other entry is const\n"); |
---|
| 155 | j=J.getItem().exp(); |
---|
| 156 | while(j>0) { t*=tt; j--; } |
---|
| 157 | } |
---|
| 158 | if ((f-t)!=0) { printf("problem:\n");out_cf("factor:",f," has problems\n");} |
---|
| 159 | } |
---|
| 160 | #endif |
---|
| 161 | |
---|
| 162 | static bool isPurePoly(const CanonicalForm & f) |
---|
| 163 | { |
---|
| 164 | if (f.level()<=0) return false; |
---|
| 165 | for (CFIterator i=f;i.hasTerms();i++) |
---|
| 166 | { |
---|
| 167 | if (!(i.coeff().inBaseDomain())) return false; |
---|
| 168 | } |
---|
| 169 | return true; |
---|
| 170 | } |
---|
| 171 | |
---|
[cd86ac] | 172 | static bool isPurePoly(const CanonicalForm & f, const Variable alpha) |
---|
| 173 | { |
---|
| 174 | if (f.level()<=0) return (f.mvar() == alpha); |
---|
| 175 | for (CFIterator i=f;i.hasTerms();i++) |
---|
| 176 | { |
---|
| 177 | if (!(i.coeff().inBaseDomain())) |
---|
| 178 | { |
---|
| 179 | if (f.mvar() != alpha) return false; |
---|
| 180 | } |
---|
| 181 | } |
---|
| 182 | return true; |
---|
| 183 | } |
---|
| 184 | |
---|
[989079] | 185 | CFFList factorize ( const CanonicalForm & f, bool issqrfree ) |
---|
[2dd068] | 186 | { |
---|
[a99e31] | 187 | if ( f.inCoeffDomain() ) |
---|
[7af0e48] | 188 | return CFFList( f ); |
---|
[cae0b6] | 189 | //out_cf("factorize:",f,"==================================\n"); |
---|
[a99e31] | 190 | int mv=f.level(); |
---|
[cae0b6] | 191 | int org_v=mv; |
---|
[a99e31] | 192 | if (! f.isUnivariate() ) |
---|
| 193 | { |
---|
| 194 | mv=find_mvar(f); |
---|
[ec989c] | 195 | if ( getCharacteristic() == 0 ) |
---|
[a99e31] | 196 | { |
---|
[cae0b6] | 197 | if (mv!=f.level()) |
---|
| 198 | { |
---|
| 199 | swapvar(f,Variable(mv),f.mvar()); |
---|
| 200 | } |
---|
| 201 | } |
---|
| 202 | else |
---|
| 203 | { |
---|
| 204 | if (mv!=1) |
---|
| 205 | { |
---|
| 206 | swapvar(f,Variable(mv),Variable(1)); |
---|
| 207 | org_v=1; |
---|
| 208 | } |
---|
[a99e31] | 209 | } |
---|
| 210 | } |
---|
| 211 | CFFList F; |
---|
[7af0e48] | 212 | if ( getCharacteristic() > 0 ) |
---|
[a99e31] | 213 | { |
---|
| 214 | ASSERT( f.isUnivariate(), "multivariate factorization not implemented" ); |
---|
[7af0e48] | 215 | #ifdef HAVE_NTL |
---|
| 216 | if (isOn(SW_USE_NTL) && (isPurePoly(f))) |
---|
| 217 | { |
---|
[a99e31] | 218 | // USE NTL |
---|
| 219 | if (getCharacteristic()!=2) |
---|
| 220 | { |
---|
[7af0e48] | 221 | // set remainder |
---|
[a99e31] | 222 | ZZ r; |
---|
[7af0e48] | 223 | r=getCharacteristic(); |
---|
[a99e31] | 224 | ZZ_pContext ccc(r); |
---|
| 225 | ccc.restore(); |
---|
[7af0e48] | 226 | ZZ_p::init(r); |
---|
[a99e31] | 227 | // convert to NTL |
---|
[7af0e48] | 228 | ZZ_pX f1=convertFacCF2NTLZZpX(f); |
---|
[a99e31] | 229 | ZZ_p leadcoeff = LeadCoeff(f1); |
---|
| 230 | //make monic |
---|
| 231 | f1=f1 / LeadCoeff(f1); |
---|
| 232 | |
---|
| 233 | // factorize |
---|
| 234 | vec_pair_ZZ_pX_long factors; |
---|
| 235 | CanZass(factors,f1); |
---|
[7af0e48] | 236 | |
---|
[a99e31] | 237 | // convert back to factory |
---|
| 238 | F=convertNTLvec_pair_ZZpX_long2FacCFFList(factors,leadcoeff,f.mvar()); |
---|
[7af0e48] | 239 | //test_cff(F,f); |
---|
[a99e31] | 240 | } |
---|
| 241 | else |
---|
| 242 | { |
---|
| 243 | // Specialcase characteristic==2 |
---|
[7af0e48] | 244 | ZZ r;r=2; |
---|
| 245 | ZZ_p::init(r); |
---|
| 246 | |
---|
[a99e31] | 247 | // remainder is 2 --> nothing to set |
---|
[7af0e48] | 248 | |
---|
[a99e31] | 249 | // convert to NTL using the faster conversion routine for characteristic 2 |
---|
| 250 | GF2X f1=convertFacCF2NTLGF2X(f); |
---|
| 251 | // no make monic necessary in GF2 |
---|
| 252 | //factorize |
---|
| 253 | vec_pair_GF2X_long factors; |
---|
| 254 | CanZass(factors,f1); |
---|
[7af0e48] | 255 | |
---|
[a99e31] | 256 | // convert back to factory again using the faster conversion routine for vectors over GF2X |
---|
[7af0e48] | 257 | F=convertNTLvec_pair_GF2X_long2FacCFFList(factors,LeadCoeff(f1),f.mvar()); |
---|
[a99e31] | 258 | } |
---|
| 259 | } |
---|
| 260 | else |
---|
| 261 | #endif |
---|
| 262 | { // Use Factory without NTL |
---|
| 263 | if ( isOn( SW_BERLEKAMP ) ) |
---|
| 264 | F=FpFactorizeUnivariateB( f, issqrfree ); |
---|
[7af0e48] | 265 | else |
---|
[a99e31] | 266 | F=FpFactorizeUnivariateCZ( f, issqrfree, 0, Variable(), Variable() ); |
---|
[7af0e48] | 267 | } |
---|
[a99e31] | 268 | } |
---|
| 269 | else |
---|
| 270 | { |
---|
| 271 | CanonicalForm cd = bCommonDen( f ); |
---|
| 272 | CanonicalForm fz = f * cd; |
---|
| 273 | bool on_rational = isOn(SW_RATIONAL); |
---|
| 274 | Off(SW_RATIONAL); |
---|
| 275 | if ( f.isUnivariate() ) |
---|
| 276 | { |
---|
[7af0e48] | 277 | #ifdef HAVE_NTL |
---|
| 278 | if ((isOn(SW_USE_NTL)) && (isPurePoly(f))) |
---|
| 279 | { |
---|
[a99e31] | 280 | //USE NTL |
---|
[7af0e48] | 281 | CanonicalForm ic=icontent(fz); |
---|
| 282 | fz/=ic; |
---|
[a99e31] | 283 | ZZ c; |
---|
| 284 | vec_pair_ZZX_long factors; |
---|
| 285 | //factorize the converted polynomial |
---|
[7af0e48] | 286 | factor(c,factors,convertFacCF2NTLZZX(fz)); |
---|
| 287 | |
---|
[a99e31] | 288 | //convert the result back to Factory |
---|
| 289 | F=convertNTLvec_pair_ZZX_long2FacCFFList(factors,c,fz.mvar()); |
---|
[7af0e48] | 290 | if ( ! ic.isOne() ) |
---|
| 291 | { |
---|
| 292 | if ( F.getFirst().factor().inCoeffDomain() ) |
---|
| 293 | { |
---|
| 294 | CFFactor new_first( F.getFirst().factor() * ic ); |
---|
| 295 | F.removeFirst(); |
---|
| 296 | F.insert( new_first ); |
---|
| 297 | } |
---|
| 298 | else |
---|
| 299 | F.insert( CFFactor( ic ) ); |
---|
| 300 | } |
---|
[cd86ac] | 301 | else |
---|
| 302 | { |
---|
[cae0b6] | 303 | if ( !F.getFirst().factor().inCoeffDomain() ) |
---|
| 304 | { |
---|
| 305 | CFFactor new_first( 1 ); |
---|
| 306 | F.insert( new_first ); |
---|
| 307 | } |
---|
[cd86ac] | 308 | } |
---|
[cae0b6] | 309 | //if ( F.getFirst().factor().isOne() ) |
---|
| 310 | //{ |
---|
| 311 | // F.removeFirst(); |
---|
| 312 | //} |
---|
[cd86ac] | 313 | //printf("NTL:\n");out_cff(F); |
---|
| 314 | //F=ZFactorizeUnivariate( fz, issqrfree ); |
---|
| 315 | //printf("fac.:\n");out_cff(F); |
---|
[a99e31] | 316 | } |
---|
| 317 | else |
---|
| 318 | #endif |
---|
[7af0e48] | 319 | { |
---|
[a99e31] | 320 | //Use Factory without NTL |
---|
| 321 | F = ZFactorizeUnivariate( fz, issqrfree ); |
---|
| 322 | } |
---|
| 323 | } |
---|
| 324 | else |
---|
| 325 | F = ZFactorizeMultivariate( fz, issqrfree ); |
---|
| 326 | |
---|
| 327 | if ( on_rational ) |
---|
| 328 | On(SW_RATIONAL); |
---|
| 329 | if ( ! cd.isOne() ) |
---|
| 330 | { |
---|
| 331 | if ( F.getFirst().factor().inCoeffDomain() ) |
---|
| 332 | { |
---|
| 333 | CFFactor new_first( F.getFirst().factor() / cd ); |
---|
| 334 | F.removeFirst(); |
---|
| 335 | F.insert( new_first ); |
---|
| 336 | } |
---|
| 337 | else |
---|
| 338 | { |
---|
| 339 | F.insert( CFFactor( 1/cd ) ); |
---|
| 340 | } |
---|
[2dd068] | 341 | } |
---|
[7af0e48] | 342 | } |
---|
[a99e31] | 343 | |
---|
[cae0b6] | 344 | if ((mv!=org_v) && (! f.isUnivariate() )) |
---|
[a99e31] | 345 | { |
---|
| 346 | CFFListIterator J=F; |
---|
| 347 | for ( ; J.hasItem(); J++) |
---|
| 348 | { |
---|
[cae0b6] | 349 | swapvar(J.getItem().factor(),Variable(mv),Variable(org_v)); |
---|
[2dd068] | 350 | } |
---|
[cae0b6] | 351 | swapvar(f,Variable(mv),Variable(org_v)); |
---|
[a99e31] | 352 | } |
---|
[cae0b6] | 353 | //out_cff(F); |
---|
[a99e31] | 354 | return F; |
---|
[2dd068] | 355 | } |
---|
[cae0b6] | 356 | |
---|
[6acb298] | 357 | #ifdef HAVE_NTL |
---|
[b1476d0] | 358 | CanonicalForm fntl ( const CanonicalForm & f, int j ) |
---|
| 359 | { |
---|
| 360 | ZZX f1=convertFacCF2NTLZZX(f); |
---|
| 361 | return convertZZ2CF(coeff(f1,j)); |
---|
[cd86ac] | 362 | } |
---|
[6acb298] | 363 | #endif |
---|
[2dd068] | 364 | |
---|
| 365 | CFFList factorize ( const CanonicalForm & f, const Variable & alpha ) |
---|
| 366 | { |
---|
[cd86ac] | 367 | //out_cf("factorize:",f,"==================================\n"); |
---|
| 368 | //out_cf("mipo:",getMipo(alpha),"\n"); |
---|
| 369 | CFFList F; |
---|
| 370 | ASSERT( alpha.level() < 0, "not an algebraic extension" ); |
---|
| 371 | ASSERT( f.isUnivariate(), "multivariate factorization not implemented" ); |
---|
| 372 | ASSERT( getCharacteristic() > 0, "char 0 factorization not implemented" ); |
---|
| 373 | #ifdef HAVE_NTL |
---|
| 374 | //if (isOn(SW_USE_NTL)) |
---|
[b1326b] | 375 | if (isOn(SW_USE_NTL) /*&& (isPurePoly(f,alpha))*/) |
---|
[cd86ac] | 376 | { |
---|
| 377 | //USE NTL |
---|
| 378 | if (getCharacteristic()!=2) |
---|
[a99e31] | 379 | { |
---|
[cd86ac] | 380 | // First all cases with characteristic !=2 |
---|
| 381 | // set remainder |
---|
| 382 | ZZ r; |
---|
| 383 | r=getCharacteristic(); |
---|
| 384 | ZZ_pContext ccc(r); |
---|
| 385 | ccc.restore(); |
---|
[7af0e48] | 386 | |
---|
[cd86ac] | 387 | // set minimal polynomial in NTL |
---|
| 388 | ZZ_pX minPo=convertFacCF2NTLZZpX(getMipo(alpha)); |
---|
| 389 | ZZ_pEContext c(minPo); |
---|
[b1476d0] | 390 | |
---|
[cd86ac] | 391 | c.restore(); |
---|
[a99e31] | 392 | |
---|
[cd86ac] | 393 | // convert to NTL |
---|
| 394 | ZZ_pEX f1=convertFacCF2NTLZZ_pEX(f,minPo); |
---|
[7af0e48] | 395 | |
---|
[cd86ac] | 396 | //make monic |
---|
| 397 | ZZ_pE leadcoeff= LeadCoeff(f1); |
---|
| 398 | f1=f1 / leadcoeff; |
---|
[a99e31] | 399 | |
---|
[cd86ac] | 400 | // factorize using NTL |
---|
| 401 | vec_pair_ZZ_pEX_long factors; |
---|
| 402 | CanZass(factors,f1); |
---|
[a99e31] | 403 | |
---|
[cd86ac] | 404 | // return converted result |
---|
| 405 | F=convertNTLvec_pair_ZZpEX_long2FacCFFList(factors,leadcoeff,f.mvar(),alpha); |
---|
| 406 | } |
---|
| 407 | else |
---|
| 408 | { |
---|
| 409 | // special case : GF2 |
---|
[a99e31] | 410 | |
---|
[cd86ac] | 411 | // remainder is two ==> nothing to do |
---|
[b1326b] | 412 | // set remainder |
---|
| 413 | ZZ r; |
---|
| 414 | r=getCharacteristic(); |
---|
| 415 | ZZ_pContext ccc(r); |
---|
| 416 | ccc.restore(); |
---|
[7af0e48] | 417 | |
---|
[cd86ac] | 418 | // set minimal polynomial in NTL using the optimized conversion routines for characteristic 2 |
---|
| 419 | GF2X minPo=convertFacCF2NTLGF2X(getMipo(alpha,f.mvar())); |
---|
| 420 | GF2EContext c(minPo); |
---|
| 421 | c.restore(); |
---|
[7af0e48] | 422 | |
---|
[cd86ac] | 423 | // convert to NTL again using the faster conversion routines |
---|
[b1326b] | 424 | GF2EX f1; |
---|
| 425 | if (isPurePoly(f)) |
---|
| 426 | { |
---|
| 427 | GF2X f_tmp=convertFacCF2NTLGF2X(f); |
---|
| 428 | f1=to_GF2EX(f_tmp); |
---|
| 429 | } |
---|
| 430 | else |
---|
| 431 | { |
---|
| 432 | f1=convertFacCF2NTLGF2EX(f,minPo); |
---|
| 433 | } |
---|
[7af0e48] | 434 | |
---|
[b1326b] | 435 | // make monic (in Z/2(a)) |
---|
| 436 | GF2E f1_coef=LeadCoeff(f1); |
---|
| 437 | MakeMonic(f1); |
---|
[a99e31] | 438 | |
---|
[cd86ac] | 439 | // factorize using NTL |
---|
| 440 | vec_pair_GF2EX_long factors; |
---|
| 441 | CanZass(factors,f1); |
---|
[7af0e48] | 442 | |
---|
[cd86ac] | 443 | // return converted result |
---|
[b1326b] | 444 | F=convertNTLvec_pair_GF2EX_long2FacCFFList(factors,f1_coef,f.mvar(),alpha); |
---|
[a99e31] | 445 | } |
---|
[cd86ac] | 446 | |
---|
| 447 | } |
---|
| 448 | else |
---|
| 449 | #endif |
---|
| 450 | { |
---|
| 451 | F=FpFactorizeUnivariateCZ( f, false, 1, alpha, Variable() ); |
---|
| 452 | } |
---|
| 453 | return F; |
---|
[2dd068] | 454 | } |
---|
| 455 | |
---|
[989079] | 456 | CFFList sqrFree ( const CanonicalForm & f, bool sort ) |
---|
[2dd068] | 457 | { |
---|
| 458 | // ASSERT( f.isUnivariate(), "multivariate factorization not implemented" ); |
---|
[87e1de] | 459 | CFFList result; |
---|
| 460 | |
---|
[2dd068] | 461 | if ( getCharacteristic() == 0 ) |
---|
[7af0e48] | 462 | result = sqrFreeZ( f ); |
---|
[2dd068] | 463 | else |
---|
[7af0e48] | 464 | result = sqrFreeFp( f ); |
---|
[87e1de] | 465 | |
---|
| 466 | return ( sort ? sortCFFList( result ) : result ); |
---|
| 467 | } |
---|
| 468 | |
---|
[2dd068] | 469 | bool isSqrFree ( const CanonicalForm & f ) |
---|
| 470 | { |
---|
| 471 | // ASSERT( f.isUnivariate(), "multivariate factorization not implemented" ); |
---|
| 472 | if ( getCharacteristic() == 0 ) |
---|
[7af0e48] | 473 | return isSqrFreeZ( f ); |
---|
[2dd068] | 474 | else |
---|
[7af0e48] | 475 | return isSqrFreeFp( f ); |
---|
[2dd068] | 476 | } |
---|
[a99e31] | 477 | |
---|