source: git/factory/cfUnivarGcd.cc @ 4a7a45

spielwiese
Last change on this file since 4a7a45 was f4365f, checked in by Martin Lee <martinlee84@…>, 10 years ago
fix: compilation without NTL
  • Property mode set to 100644
File size: 8.1 KB
Line 
1#include "config.h"
2
3#include "debug.h"
4
5#include "cf_algorithm.h"
6#include "templates/ftmpl_functions.h"
7#include "cf_primes.h"
8#include "cfGcdUtil.h"
9
10#ifdef HAVE_NTL
11#include "NTLconvert.h"
12#endif
13
14#ifdef HAVE_FLINT
15#include "FLINTconvert.h"
16#endif
17
18#ifdef HAVE_NTL
19#ifndef HAVE_FLINT
20CanonicalForm
21gcd_univar_ntl0( const CanonicalForm & F, const CanonicalForm & G )
22{
23    ZZX F1=convertFacCF2NTLZZX(F);
24    ZZX G1=convertFacCF2NTLZZX(G);
25    ZZX R=GCD(F1,G1);
26    return convertNTLZZX2CF(R,F.mvar());
27}
28
29CanonicalForm
30gcd_univar_ntlp( const CanonicalForm & F, const CanonicalForm & G )
31{
32  if (fac_NTL_char!=getCharacteristic())
33  {
34    fac_NTL_char=getCharacteristic();
35    zz_p::init(getCharacteristic());
36  }
37  zz_pX F1=convertFacCF2NTLzzpX(F);
38  zz_pX G1=convertFacCF2NTLzzpX(G);
39  zz_pX R=GCD(F1,G1);
40  return  convertNTLzzpX2CF(R,F.mvar());
41}
42#endif
43#endif
44
45#ifdef HAVE_FLINT
46CanonicalForm
47gcd_univar_flintp (const CanonicalForm& F, const CanonicalForm& G)
48{
49  nmod_poly_t F1, G1;
50  convertFacCF2nmod_poly_t (F1, F);
51  convertFacCF2nmod_poly_t (G1, G);
52  nmod_poly_gcd (F1, F1, G1);
53  CanonicalForm result= convertnmod_poly_t2FacCF (F1, F.mvar());
54  nmod_poly_clear (F1);
55  nmod_poly_clear (G1);
56  return result;
57}
58
59CanonicalForm
60gcd_univar_flint0( const CanonicalForm & F, const CanonicalForm & G )
61{
62  fmpz_poly_t F1, G1;
63  convertFacCF2Fmpz_poly_t(F1, F);
64  convertFacCF2Fmpz_poly_t(G1, G);
65  fmpz_poly_gcd (F1, F1, G1);
66  CanonicalForm result= convertFmpz_poly_t2FacCF (F1, F.mvar());
67  fmpz_poly_clear (F1);
68  fmpz_poly_clear (G1);
69  return result;
70}
71#endif
72
73#ifndef HAVE_NTL
74CanonicalForm gcd_poly_univar0( const CanonicalForm & F, const CanonicalForm & G, bool primitive )
75{
76  CanonicalForm f, g, c, cg, cl, BB, B, M, q, Dp, newD, D, newq;
77  int p, i;
78
79  if ( primitive )
80  {
81    f = F;
82    g = G;
83    c = 1;
84  }
85  else
86  {
87    CanonicalForm cF = content( F ), cG = content( G );
88    f = F / cF;
89    g = G / cG;
90    c = bgcd( cF, cG );
91  }
92  cg = gcd( f.lc(), g.lc() );
93  cl = ( f.lc() / cg ) * g.lc();
94//     B = 2 * cg * tmin(
95//         maxnorm(f)*power(CanonicalForm(2),f.degree())*isqrt(f.degree()+1),
96//         maxnorm(g)*power(CanonicalForm(2),g.degree())*isqrt(g.degree()+1)
97//         )+1;
98  M = tmin( maxNorm(f), maxNorm(g) );
99  BB = power(CanonicalForm(2),tmin(f.degree(),g.degree()))*M;
100  q = 0;
101  i = cf_getNumSmallPrimes() - 1;
102  while ( true )
103  {
104    B = BB;
105    while ( i >= 0 && q < B )
106    {
107      p = cf_getSmallPrime( i );
108      i--;
109      while ( i >= 0 && mod( cl, p ) == 0 )
110      {
111        p = cf_getSmallPrime( i );
112        i--;
113      }
114      setCharacteristic( p );
115      Dp = gcd( mapinto( f ), mapinto( g ) );
116      Dp = ( Dp / Dp.lc() ) * mapinto( cg );
117      setCharacteristic( 0 );
118      if ( Dp.degree() == 0 )
119        return c;
120      if ( q.isZero() )
121      {
122        D = mapinto( Dp );
123        q = p;
124        B = power(CanonicalForm(2),D.degree())*M+1;
125      }
126      else
127      {
128        if ( Dp.degree() == D.degree() )
129        {
130          chineseRemainder( D, q, mapinto( Dp ), p, newD, newq );
131          q = newq;
132          D = newD;
133        }
134        else if ( Dp.degree() < D.degree() )
135        {
136          // all previous p's are bad primes
137          q = p;
138          D = mapinto( Dp );
139          B = power(CanonicalForm(2),D.degree())*M+1;
140        }
141        // else p is a bad prime
142      }
143    }
144    if ( i >= 0 )
145    {
146      // now balance D mod q
147      D = pp( balance_p( D, q ) );
148      if ( fdivides( D, f ) && fdivides( D, g ) )
149        return D * c;
150      else
151        q = 0;
152    }
153    else
154      return gcd_poly( F, G );
155    DEBOUTLN( cerr, "another try ..." );
156  }
157}
158#endif
159
160/** CanonicalForm extgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a, CanonicalForm & b )
161 *
162 * extgcd() - returns polynomial extended gcd of f and g.
163 *
164 * Returns gcd(f, g) and a and b sucht that f*a+g*b=gcd(f, g).
165 * The gcd is calculated using an extended euclidean polynomial
166 * remainder sequence, so f and g should be polynomials over an
167 * euclidean domain.  Normalizes result.
168 *
169 * Note: be sure that f and g have the same level!
170 *
171**/
172CanonicalForm
173extgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a, CanonicalForm & b )
174{
175  if (f.isZero())
176  {
177    a= 0;
178    b= 1;
179    return g;
180  }
181  else if (g.isZero())
182  {
183    a= 1;
184    b= 0;
185    return f;
186  }
187#ifdef HAVE_NTL
188#ifdef HAVE_FLINT
189  if (( getCharacteristic() > 0 ) && (CFFactory::gettype() != GaloisFieldDomain)
190  &&  (f.level()==g.level()) && isPurePoly(f) && isPurePoly(g))
191  {
192    nmod_poly_t F1, G1, A, B, R;
193    convertFacCF2nmod_poly_t (F1, f);
194    convertFacCF2nmod_poly_t (G1, g);
195    nmod_poly_init (R, getCharacteristic());
196    nmod_poly_init (A, getCharacteristic());
197    nmod_poly_init (B, getCharacteristic());
198    nmod_poly_xgcd (R, A, B, F1, G1);
199    a= convertnmod_poly_t2FacCF (A, f.mvar());
200    b= convertnmod_poly_t2FacCF (B, f.mvar());
201    CanonicalForm r= convertnmod_poly_t2FacCF (R, f.mvar());
202    nmod_poly_clear (F1);
203    nmod_poly_clear (G1);
204    nmod_poly_clear (A);
205    nmod_poly_clear (B);
206    nmod_poly_clear (R);
207    return r;
208  }
209#else
210  if (( getCharacteristic() > 0 ) && (CFFactory::gettype() != GaloisFieldDomain)
211  &&  (f.level()==g.level()) && isPurePoly(f) && isPurePoly(g))
212  {
213    if (fac_NTL_char!=getCharacteristic())
214    {
215      fac_NTL_char=getCharacteristic();
216      zz_p::init(getCharacteristic());
217    }
218    zz_pX F1=convertFacCF2NTLzzpX(f);
219    zz_pX G1=convertFacCF2NTLzzpX(g);
220    zz_pX R;
221    zz_pX A,B;
222    XGCD(R,A,B,F1,G1);
223    a=convertNTLzzpX2CF(A,f.mvar());
224    b=convertNTLzzpX2CF(B,f.mvar());
225    return convertNTLzzpX2CF(R,f.mvar());
226  }
227#endif
228#ifdef HAVE_FLINT
229  if (( getCharacteristic() ==0) && (f.level()==g.level())
230       && isPurePoly(f) && isPurePoly(g))
231  {
232    fmpq_poly_t F1, G1;
233    convertFacCF2Fmpq_poly_t (F1, f);
234    convertFacCF2Fmpq_poly_t (G1, g);
235    fmpq_poly_t R, A, B;
236    fmpq_poly_init (R);
237    fmpq_poly_init (A);
238    fmpq_poly_init (B);
239    fmpq_poly_xgcd (R, A, B, F1, G1);
240    a= convertFmpq_poly_t2FacCF (A, f.mvar());
241    b= convertFmpq_poly_t2FacCF (B, f.mvar());
242    CanonicalForm r= convertFmpq_poly_t2FacCF (R, f.mvar());
243    fmpq_poly_clear (F1);
244    fmpq_poly_clear (G1);
245    fmpq_poly_clear (A);
246    fmpq_poly_clear (B);
247    fmpq_poly_clear (R);
248    return r;
249  }
250#else
251  if (( getCharacteristic() ==0)
252  && (f.level()==g.level()) && isPurePoly(f) && isPurePoly(g))
253  {
254    CanonicalForm fc=bCommonDen(f);
255    CanonicalForm gc=bCommonDen(g);
256    ZZX F1=convertFacCF2NTLZZX(f*fc);
257    ZZX G1=convertFacCF2NTLZZX(g*gc);
258    ZZX R=GCD(F1,G1);
259    CanonicalForm r=convertNTLZZX2CF(R,f.mvar());
260    ZZ RR;
261    ZZX A,B;
262    if (r.inCoeffDomain())
263    {
264      XGCD(RR,A,B,F1,G1,1);
265      CanonicalForm rr=convertZZ2CF(RR);
266      if(!rr.isZero())
267      {
268        a=convertNTLZZX2CF(A,f.mvar())*fc/rr;
269        b=convertNTLZZX2CF(B,f.mvar())*gc/rr;
270        return CanonicalForm(1);
271      }
272      else
273      {
274        F1 /= R;
275        G1 /= R;
276        XGCD (RR, A,B,F1,G1,1);
277        rr=convertZZ2CF(RR);
278        a=convertNTLZZX2CF(A,f.mvar())*(fc/rr);
279        b=convertNTLZZX2CF(B,f.mvar())*(gc/rr);
280      }
281    }
282    else
283    {
284      XGCD(RR,A,B,F1,G1,1);
285      CanonicalForm rr=convertZZ2CF(RR);
286      if (!rr.isZero())
287      {
288        a=convertNTLZZX2CF(A,f.mvar())*fc;
289        b=convertNTLZZX2CF(B,f.mvar())*gc;
290      }
291      else
292      {
293        F1 /= R;
294        G1 /= R;
295        XGCD (RR, A,B,F1,G1,1);
296        rr=convertZZ2CF(RR);
297        a=convertNTLZZX2CF(A,f.mvar())*(fc/rr);
298        b=convertNTLZZX2CF(B,f.mvar())*(gc/rr);
299      }
300      return r;
301    }
302  }
303#endif
304#endif
305  // may contain bug in the co-factors, see track 107
306  CanonicalForm contf = content( f );
307  CanonicalForm contg = content( g );
308
309  CanonicalForm p0 = f / contf, p1 = g / contg;
310  CanonicalForm f0 = 1, f1 = 0, g0 = 0, g1 = 1, q, r;
311
312  while ( ! p1.isZero() )
313  {
314      divrem( p0, p1, q, r );
315      p0 = p1; p1 = r;
316      r = g0 - g1 * q;
317      g0 = g1; g1 = r;
318      r = f0 - f1 * q;
319      f0 = f1; f1 = r;
320  }
321  CanonicalForm contp0 = content( p0 );
322  a = f0 / ( contf * contp0 );
323  b = g0 / ( contg * contp0 );
324  p0 /= contp0;
325  if ( p0.sign() < 0 )
326  {
327      p0 = -p0;
328      a = -a;
329      b = -b;
330  }
331  return p0;
332}
Note: See TracBrowser for help on using the repository browser.