source: git/factory/cfGcdUtil.cc @ c1f4d51

spielwiese
Last change on this file since c1f4d51 was c1f4d51, checked in by Hans Schoenemann <hannes@…>, 4 years ago
factory: implement findMinPoly/mapPrimElem and related
  • Property mode set to 100644
File size: 7.9 KB
Line 
1#include "config.h"
2
3#include "canonicalform.h"
4#include "cf_factory.h"
5#include "cf_reval.h"
6#include "cf_util.h"
7#include "cf_iter.h"
8#include "gfops.h"
9#include "cf_map_ext.h"
10#include "templates/ftmpl_functions.h"
11
12#ifdef HAVE_NTL
13#include "NTLconvert.h"
14#endif
15
16#ifdef HAVE_FLINT
17#include "FLINTconvert.h"
18#endif
19
20/// Coprimality Check. f and g are assumed to have the same level. If swap is
21/// true, the main variables of f and g are swapped with Variable(1). If the
22/// result is false, d is set to the degree of the gcd of f and g evaluated at a
23/// random point in K^n-1. This gcd is a gcd of univariate polynomials.
24bool
25gcd_test_one ( const CanonicalForm & f, const CanonicalForm & g, bool swap, int & d )
26{
27    d= 0;
28    int count = 0;
29    // assume polys have same level;
30
31    Variable v= Variable (1);
32    bool algExtension= (hasFirstAlgVar (f, v) || hasFirstAlgVar (g, v));
33    CanonicalForm lcf, lcg;
34    if ( swap )
35    {
36        lcf = swapvar( LC( f ), Variable(1), f.mvar() );
37        lcg = swapvar( LC( g ), Variable(1), f.mvar() );
38    }
39    else
40    {
41        lcf = LC( f, Variable(1) );
42        lcg = LC( g, Variable(1) );
43    }
44
45    CanonicalForm F, G;
46    if ( swap )
47    {
48        F=swapvar( f, Variable(1), f.mvar() );
49        G=swapvar( g, Variable(1), g.mvar() );
50    }
51    else
52    {
53        F = f;
54        G = g;
55    }
56
57    #define TEST_ONE_MAX 50
58    int p= getCharacteristic();
59    bool passToGF= false;
60    int k= 1;
61    bool extOfExt= false;
62    Variable v3;
63    if (p > 0 && p < TEST_ONE_MAX && CFFactory::gettype() != GaloisFieldDomain && !algExtension)
64    {
65      if (p == 2)
66        setCharacteristic (2, 6, 'Z');
67      else if (p == 3)
68        setCharacteristic (3, 4, 'Z');
69      else if (p == 5 || p == 7)
70        setCharacteristic (p, 3, 'Z');
71      else
72        setCharacteristic (p, 2, 'Z');
73      passToGF= true;
74    }
75    else if (p > 0 && CFFactory::gettype() == GaloisFieldDomain && ipower (p , getGFDegree()) < TEST_ONE_MAX)
76    {
77      k= getGFDegree();
78      if (ipower (p, 2*k) > TEST_ONE_MAX)
79        setCharacteristic (p, 2*k, gf_name);
80      else
81        setCharacteristic (p, 3*k, gf_name);
82      F= GFMapUp (F, k);
83      G= GFMapUp (G, k);
84      lcf= GFMapUp (lcf, k);
85      lcg= GFMapUp (lcg, k);
86    }
87    else if (p > 0 && p < TEST_ONE_MAX && algExtension)
88    {
89#if defined(HAVE_NTL) || defined(HAVE_FLINT)
90      int d= degree (getMipo (v));
91      CFList source, dest;
92      Variable v2;
93      CanonicalForm primElem, imPrimElem;
94      #if defined(HAVE_NTL) && !defined(HAVE_FLINT)
95      if (fac_NTL_char != p)
96      {
97        fac_NTL_char= p;
98        zz_p::init (p);
99      }
100      #endif
101      if (p == 2 && d < 6)
102      {
103        bool primFail= false;
104        Variable vBuf;
105        primElem= primitiveElement (v, vBuf, primFail);
106        ASSERT (!primFail, "failure in integer factorizer");
107        if (d < 3)
108        {
109          #ifdef HAVE_FLINT
110          nmod_poly_t Irredpoly;
111          nmod_poly_init(Irredpoly,p);
112          nmod_poly_randtest_monic_irreducible(Irredpoly, FLINTrandom, 3*d+1);
113          CanonicalForm newMipo=convertnmod_poly_t2FacCF(Irredpoly,Variable(1));
114          nmod_poly_clear(Irredpoly);
115          #elif defined(HAVE_NTL)
116          zz_pX NTLIrredpoly;
117          BuildIrred (NTLIrredpoly, d*3);
118          CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));
119          #endif
120          v2= rootOf (newMipo);
121        }
122        else
123        {
124          #ifdef HAVE_FLINT
125          nmod_poly_t Irredpoly;
126          nmod_poly_init(Irredpoly,p);
127          nmod_poly_randtest_monic_irreducible(Irredpoly, FLINTrandom, 3*d+1);
128          CanonicalForm newMipo=convertnmod_poly_t2FacCF(Irredpoly,Variable(1));
129          nmod_poly_clear(Irredpoly);
130          #elif defined(HAVE_NTL)
131          zz_pX NTLIrredpoly;
132          BuildIrred (NTLIrredpoly, d*2);
133          CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));
134          #endif
135          v2= rootOf (newMipo);
136        }
137        imPrimElem= mapPrimElem (primElem, v, v2);
138        extOfExt= true;
139      }
140      else if ((p == 3 && d < 4) || ((p == 5 || p == 7) && d < 3))
141      {
142        bool primFail= false;
143        Variable vBuf;
144        primElem= primitiveElement (v, vBuf, primFail);
145        ASSERT (!primFail, "failure in integer factorizer");
146        #ifdef HAVE_FLINT
147        nmod_poly_t Irredpoly;
148        nmod_poly_init(Irredpoly,p);
149        nmod_poly_randtest_monic_irreducible(Irredpoly, FLINTrandom, 2*d+1);
150        CanonicalForm newMipo=convertnmod_poly_t2FacCF(Irredpoly,Variable(1));
151        nmod_poly_clear(Irredpoly);
152        #elif defined(HAVE_NTL)
153        zz_pX NTLIrredpoly;
154        BuildIrred (NTLIrredpoly, d*2);
155        CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));
156        #endif
157        v2= rootOf (newMipo);
158        imPrimElem= mapPrimElem (primElem, v, v2);
159        extOfExt= true;
160      }
161      if (extOfExt)
162      {
163        v3= v;
164        F= mapUp (F, v, v2, primElem, imPrimElem, source, dest);
165        G= mapUp (G, v, v2, primElem, imPrimElem, source, dest);
166        lcf= mapUp (lcf, v, v2, primElem, imPrimElem, source, dest);
167        lcg= mapUp (lcg, v, v2, primElem, imPrimElem, source, dest);
168        v= v2;
169      }
170#endif
171    }
172
173    CFRandom * sample;
174    if ((!algExtension && p > 0) || p == 0)
175      sample = CFRandomFactory::generate();
176    else
177      sample = AlgExtRandomF (v).clone();
178
179    REvaluation e( 2, tmax( f.level(), g.level() ), *sample );
180    delete sample;
181
182    if (passToGF)
183    {
184      lcf= lcf.mapinto();
185      lcg= lcg.mapinto();
186    }
187
188    CanonicalForm eval1, eval2;
189    if (passToGF)
190    {
191      eval1= e (lcf);
192      eval2= e (lcg);
193    }
194    else
195    {
196      eval1= e (lcf);
197      eval2= e (lcg);
198    }
199
200    while ( ( eval1.isZero() || eval2.isZero() ) && count < TEST_ONE_MAX )
201    {
202        e.nextpoint();
203        count++;
204        eval1= e (lcf);
205        eval2= e (lcg);
206    }
207    if ( count >= TEST_ONE_MAX )
208    {
209        if (passToGF)
210          setCharacteristic (p);
211        if (k > 1)
212          setCharacteristic (p, k, gf_name);
213        if (extOfExt)
214          prune1 (v3);
215        return false;
216    }
217
218
219    if (passToGF)
220    {
221      F= F.mapinto();
222      G= G.mapinto();
223      eval1= e (F);
224      eval2= e (G);
225    }
226    else
227    {
228      eval1= e (F);
229      eval2= e (G);
230    }
231
232    CanonicalForm c= gcd (eval1, eval2);
233    d= c.degree();
234    bool result= d < 1;
235    if (d < 0)
236      d= 0;
237
238    if (passToGF)
239      setCharacteristic (p);
240    if (k > 1)
241      setCharacteristic (p, k, gf_name);
242    if (extOfExt)
243      prune1 (v3);
244    return result;
245}
246
247/**
248 * same as balance_p ( const CanonicalForm & f, const CanonicalForm & q )
249 * but qh= q/2 is provided, too.
250**/
251CanonicalForm
252balance_p ( const CanonicalForm & f, const CanonicalForm & q, const CanonicalForm & qh )
253{
254    Variable x = f.mvar();
255    CanonicalForm result = 0;
256    CanonicalForm c;
257    CFIterator i;
258    for ( i = f; i.hasTerms(); i++ )
259    {
260        c = i.coeff();
261        if ( c.inCoeffDomain())
262        {
263          if ( c > qh )
264            result += power( x, i.exp() ) * (c - q);
265          else
266            result += power( x, i.exp() ) * c;
267        }
268        else
269          result += power( x, i.exp() ) * balance_p(c,q,qh);
270    }
271    return result;
272}
273
274/** static CanonicalForm balance_p ( const CanonicalForm & f, const CanonicalForm & q )
275 *
276 * balance_p() - map f from positive to symmetric representation
277 *   mod q.
278 *
279 * This makes sense for polynomials over Z only.
280 * q should be an integer.
281 *
282**/
283CanonicalForm
284balance_p ( const CanonicalForm & f, const CanonicalForm & q )
285{
286    CanonicalForm qh = q / 2;
287    return balance_p (f, q, qh);
288}
289
290
291/*static CanonicalForm
292balance ( const CanonicalForm & f, const CanonicalForm & q )
293{
294    Variable x = f.mvar();
295    CanonicalForm result = 0, qh = q / 2;
296    CanonicalForm c;
297    CFIterator i;
298    for ( i = f; i.hasTerms(); i++ ) {
299        c = mod( i.coeff(), q );
300        if ( c > qh )
301            result += power( x, i.exp() ) * (c - q);
302        else
303            result += power( x, i.exp() ) * c;
304    }
305    return result;
306}*/
Note: See TracBrowser for help on using the repository browser.