source: git/factory/cf_factor.cc @ 77f483

spielwiese
Last change on this file since 77f483 was 77f483, checked in by Hans Schönemann <hannes@…>, 18 years ago
*hannes: fixed rational coeffs in factorize git-svn-id: file:///usr/local/Singular/svn/trunk@8405 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 11.0 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: cf_factor.cc,v 1.24 2005-06-28 14:39:52 Singular Exp $ */
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
30#include "int_int.h"
31#ifdef HAVE_NTL
32#include "NTLconvert.h"
33#endif
34
35int getExp(); /* cf_char.cc */
36
37static 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
46void find_exp(const CanonicalForm & f, int * exp_f)
47{
48  if ( ! f.inCoeffDomain() )
49  {
50    int e=f.level();
51    CFIterator i = f;
52    if (e>=0)
53    {
54      if (i.exp() > exp_f[e]) exp_f[e]=i.exp();
55    }
56    for (; i.hasTerms(); i++ )
57    {
58      find_exp(i.coeff(), exp_f);
59    }
60  }
61}
62
63int 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
81#if 0
82void out_cf(char *s1,const CanonicalForm &f,char *s2)
83{
84  printf("%s",s1);
85  if (f==0) printf("+0");
86  //else if (! f.inCoeffDomain() )
87  else if (! f.inBaseDomain() )
88  {
89    int l = f.level();
90    for ( CFIterator i = f; i.hasTerms(); i++ )
91    {
92      int e=i.exp();
93      if (i.coeff().isOne())
94      {
95        printf("+");
96        if (e==0) printf("1");
97        else
98        {
99          printf("v(%d)",l);
100          if (e!=1) printf("^%d",e);
101        }
102      }
103      else
104      {
105        out_cf("+(",i.coeff(),")");
106        if (e!=0)
107        {
108          printf("*v(%d)",l);
109          if (e!=1) printf("^%d",e);
110        }
111      }
112    }
113  }
114  else
115  {
116    if ( f.isImm() )
117    {
118      printf("+%d",f.intval());
119    }
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());
128  }
129  printf("%s",s2);
130}
131void 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}
142void 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
162bool 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
172CFFList factorize ( const CanonicalForm & f, bool issqrfree )
173{
174  if ( f.inCoeffDomain() )
175        return CFFList( f );
176  //out_cf("factorize:",f,"==================================\n");
177  int mv=f.level();
178  int org_v=mv;
179  if (! f.isUnivariate() )
180  {
181    mv=find_mvar(f);
182    if ( getCharacteristic() == 0 )
183    {
184      if (mv!=f.level())
185      {
186        swapvar(f,Variable(mv),f.mvar());
187      }
188    }
189    else
190    {
191      if (mv!=1)
192      {
193        swapvar(f,Variable(mv),Variable(1));
194        org_v=1;
195      }
196    }
197  }
198  CFFList F;
199  if ( getCharacteristic() > 0 )
200  {
201    ASSERT( f.isUnivariate(), "multivariate factorization not implemented" );
202    #ifdef HAVE_NTL
203    if (isOn(SW_USE_NTL) && (isPurePoly(f)))
204    {
205      // USE NTL
206      if (getCharacteristic()!=2)
207      {
208        // set remainder
209        #ifdef NTL_ZZ
210        ZZ r;
211        r=getCharacteristic();
212        ZZ_pContext ccc(r);
213        #else
214        zz_pContext ccc(getCharacteristic());
215        #endif
216        ccc.restore();
217        #ifdef NTL_ZZ
218        ZZ_p::init(r);
219        #else
220        zz_p::init(getCharacteristic());
221        #endif
222        // convert to NTL
223        #ifdef NTL_ZZ
224        ZZ_pX f1=convertFacCF2NTLZZpX(f);
225        ZZ_p leadcoeff = LeadCoeff(f1);
226        #else
227        zz_pX f1=convertFacCF2NTLzzpX(f);
228        zz_p leadcoeff = LeadCoeff(f1);
229        #endif
230        //make monic
231        f1=f1 / LeadCoeff(f1);
232
233        // factorize
234        #ifdef NTL_ZZ
235        vec_pair_ZZ_pX_long factors;
236        #else
237        vec_pair_zz_pX_long factors;
238        #endif
239        CanZass(factors,f1);
240
241        // convert back to factory
242        #ifdef NTL_ZZ
243        F=convertNTLvec_pair_ZZpX_long2FacCFFList(factors,leadcoeff,f.mvar());
244        #else
245        F=convertNTLvec_pair_zzpX_long2FacCFFList(factors,leadcoeff,f.mvar());
246        #endif
247        //test_cff(F,f);
248      }
249      else
250      {
251        // Specialcase characteristic==2
252        ZZ r;r=2;
253        ZZ_p::init(r);
254
255        // remainder is 2 --> nothing to set
256
257        // convert to NTL using the faster conversion routine for characteristic 2
258        GF2X f1=convertFacCF2NTLGF2X(f);
259        // no make monic necessary in GF2
260        //factorize
261        vec_pair_GF2X_long factors;
262        CanZass(factors,f1);
263
264        // convert back to factory again using the faster conversion routine for vectors over GF2X
265        F=convertNTLvec_pair_GF2X_long2FacCFFList(factors,LeadCoeff(f1),f.mvar());
266      }
267    }
268    else
269    #endif
270    {  // Use Factory without NTL
271      if ( isOn( SW_BERLEKAMP ) )
272         F=FpFactorizeUnivariateB( f, issqrfree );
273      else
274        F=FpFactorizeUnivariateCZ( f, issqrfree, 0, Variable(), Variable() );
275    }
276  }
277  else
278  {
279    bool on_rational = isOn(SW_RATIONAL);
280    On(SW_RATIONAL);
281    CanonicalForm cd = bCommonDen( f );
282    CanonicalForm fz = f * cd;
283    Off(SW_RATIONAL);
284    if ( f.isUnivariate() )
285    {
286      #ifdef HAVE_NTL
287      if ((isOn(SW_USE_NTL)) && (isPurePoly(f)))
288      {
289        //USE NTL
290        CanonicalForm ic=icontent(fz);
291        fz/=ic;
292        ZZ c;
293        vec_pair_ZZX_long factors;
294        //factorize the converted polynomial
295        factor(c,factors,convertFacCF2NTLZZX(fz));
296
297        //convert the result back to Factory
298        F=convertNTLvec_pair_ZZX_long2FacCFFList(factors,c,fz.mvar());
299        if ( ! ic.isOne() )
300        {
301          if ( F.getFirst().factor().inCoeffDomain() )
302          {
303            CFFactor new_first( F.getFirst().factor() * ic );
304            F.removeFirst();
305            F.insert( new_first );
306          }
307          else
308            F.insert( CFFactor( ic ) );
309        }
310        else
311        {
312          if ( !F.getFirst().factor().inCoeffDomain() )
313          {
314            CFFactor new_first( 1 );
315            F.insert( new_first );
316          }
317        }
318        //if ( F.getFirst().factor().isOne() )
319        //{
320        //  F.removeFirst();
321        //}
322        //printf("NTL:\n");out_cff(F);
323        //F=ZFactorizeUnivariate( fz, issqrfree );
324        //printf("fac.:\n");out_cff(F);
325      }
326      else
327      #endif
328      {
329        //Use Factory without NTL
330        F = ZFactorizeUnivariate( fz, issqrfree );
331      }
332    }
333    else
334      F = ZFactorizeMultivariate( fz, issqrfree );
335
336    if ( on_rational )
337      On(SW_RATIONAL);
338    if ( ! cd.isOne() )
339    {
340      if ( F.getFirst().factor().inCoeffDomain() )
341      {
342        CFFactor new_first( F.getFirst().factor() / cd );
343        F.removeFirst();
344        F.insert( new_first );
345      }
346      else
347      {
348        F.insert( CFFactor( 1/cd ) );
349      }
350    }
351  }
352
353  if ((mv!=org_v) && (! f.isUnivariate() ))
354  {
355    CFFListIterator J=F;
356    for ( ; J.hasItem(); J++)
357    {
358      swapvar(J.getItem().factor(),Variable(mv),Variable(org_v));
359    }
360    swapvar(f,Variable(mv),Variable(org_v));
361  }
362  //out_cff(F);
363  return F;
364}
365
366#ifdef HAVE_NTL
367CanonicalForm fntl ( const CanonicalForm & f, int j )
368{
369  ZZX f1=convertFacCF2NTLZZX(f);
370  return convertZZ2CF(coeff(f1,j));
371}
372#endif
373
374CFFList factorize ( const CanonicalForm & f, const Variable & alpha )
375{
376  //out_cf("factorize:",f,"==================================\n");
377  //out_cf("mipo:",getMipo(alpha),"\n");
378  CFFList F;
379  ASSERT( alpha.level() < 0, "not an algebraic extension" );
380  ASSERT( f.isUnivariate(), "multivariate factorization not implemented" );
381  ASSERT( getCharacteristic() > 0, "char 0 factorization not implemented" );
382  #ifdef HAVE_NTL
383  if  (isOn(SW_USE_NTL))
384  {
385    //USE NTL
386    if (getCharacteristic()!=2)
387    {
388      // First all cases with characteristic !=2
389      // set remainder
390      ZZ r;
391      r=getCharacteristic();
392      ZZ_pContext ccc(r);
393      ccc.restore();
394
395      // set minimal polynomial in NTL
396      ZZ_pX minPo=convertFacCF2NTLZZpX(getMipo(alpha));
397      ZZ_pEContext c(minPo);
398
399      c.restore();
400
401      // convert to NTL
402      ZZ_pEX f1=convertFacCF2NTLZZ_pEX(f,minPo);
403
404      //make monic
405      ZZ_pE leadcoeff= LeadCoeff(f1);
406      f1=f1 / leadcoeff;
407
408      // factorize using NTL
409      vec_pair_ZZ_pEX_long factors;
410      CanZass(factors,f1);
411
412      // return converted result
413      F=convertNTLvec_pair_ZZpEX_long2FacCFFList(factors,leadcoeff,f.mvar(),alpha);
414    }
415    else
416    {
417      // special case : GF2
418
419      // remainder is two ==> nothing to do
420      // set remainder
421      ZZ r;
422      r=getCharacteristic();
423      ZZ_pContext ccc(r);
424      ccc.restore();
425
426      // set minimal polynomial in NTL using the optimized conversion routines for characteristic 2
427      GF2X minPo=convertFacCF2NTLGF2X(getMipo(alpha,f.mvar()));
428      GF2EContext c(minPo);
429      c.restore();
430
431      // convert to NTL again using the faster conversion routines
432      GF2EX f1;
433      if (isPurePoly(f))
434      {
435        GF2X f_tmp=convertFacCF2NTLGF2X(f);
436        f1=to_GF2EX(f_tmp);
437      }
438      else
439      {
440        f1=convertFacCF2NTLGF2EX(f,minPo);
441      }
442
443      // make monic (in Z/2(a))
444      GF2E f1_coef=LeadCoeff(f1);
445      MakeMonic(f1);
446
447      // factorize using NTL
448      vec_pair_GF2EX_long factors;
449      CanZass(factors,f1);
450
451      // return converted result
452      F=convertNTLvec_pair_GF2EX_long2FacCFFList(factors,f1_coef,f.mvar(),alpha);
453    }
454
455  }
456  else
457  #endif
458  {
459    F=FpFactorizeUnivariateCZ( f, false, 1, alpha, Variable() );
460  }
461  return F;
462}
463
464CFFList sqrFree ( const CanonicalForm & f, bool sort )
465{
466//    ASSERT( f.isUnivariate(), "multivariate factorization not implemented" );
467    CFFList result;
468
469    if ( getCharacteristic() == 0 )
470        result = sqrFreeZ( f );
471    else
472        result = sqrFreeFp( f );
473
474    return ( sort ? sortCFFList( result ) : result );
475}
476
477bool isSqrFree ( const CanonicalForm & f )
478{
479//    ASSERT( f.isUnivariate(), "multivariate factorization not implemented" );
480    if ( getCharacteristic() == 0 )
481        return isSqrFreeZ( f );
482    else
483        return isSqrFreeFp( f );
484}
485
Note: See TracBrowser for help on using the repository browser.