source: git/factory/cf_map_ext.cc @ 767da0

spielwiese
Last change on this file since 767da0 was 0ad478, checked in by Hans Schoenemann <hannes@…>, 4 years ago
opt: getChracteristic, compiler warnings
  • Property mode set to 100644
File size: 17.6 KB
Line 
1// -*- c++ -*-
2//*****************************************************************************
3/** @file cf_map_ext.cc
4 *
5 * This file implements functions to map between extensions of finite fields
6 *
7 * @par Copyright:
8 *   (c) by The SINGULAR Team, see LICENSE file
9 *
10 * @author Martin Lee
11 * @date   16.11.2009
12**/
13//*****************************************************************************
14
15
16#include "config.h"
17
18
19#include "cf_assert.h"
20#include "debug.h"
21
22#include "canonicalform.h"
23#include "cf_util.h"
24#include "imm.h"
25#include "cf_iter.h"
26
27#ifdef HAVE_NTL
28#include "NTLconvert.h"
29#endif
30
31#ifdef HAVE_FLINT
32#include "FLINTconvert.h"
33#endif
34
35// cyclotomoic polys:
36#include "cf_cyclo.h"
37
38#include "cf_map_ext.h"
39
40/// helper function
41int findItem (const CFList& list, const CanonicalForm& item)
42{
43  int result= 1;
44  for (CFListIterator i= list; i.hasItem(); i++, result++)
45  {
46    if (i.getItem() == item)
47      return result;
48  }
49  return 0;
50}
51
52/// helper function
53CanonicalForm getItem (const CFList& list, const int& pos)
54{
55  int j= 1;
56  if ((pos > 0) && (pos <= list.length()))
57  {
58    for (CFListIterator i= list; j <= pos; i++, j++)
59    {
60      if (j == pos)
61        return i.getItem();
62    }
63  }
64  return 0;
65}
66
67/// \f$ F_{p} (\alpha ) \subset F_{p}(\beta ) \f$ and \f$ \alpha \f$ is a
68/// primitive element, returns the image of \f$ \alpha \f$
69static inline
70CanonicalForm mapUp (const Variable& alpha, const Variable& beta)
71{
72  #if defined(HAVE_FLINT) && (__FLINT_RELEASE >= 20503)
73    // convert mipo1
74    nmod_poly_t mipo1;
75    convertFacCF2nmod_poly_t(mipo1,getMipo(beta));
76    fq_nmod_ctx_t ctx;
77    fq_nmod_ctx_init_modulus(ctx,mipo1,"t");
78    nmod_poly_clear(mipo1);
79    // convert mipo2 (alpah)
80    fq_nmod_poly_t mipo2;
81    convertFacCF2Fq_nmod_poly_t(mipo2,getMipo(alpha),ctx);
82    fq_nmod_poly_factor_t fac;
83    fq_nmod_poly_factor_init(fac,ctx);
84    fq_nmod_poly_roots(fac, mipo2, 0, ctx);
85    // root of first (linear) factor: -absolute Term
86    fq_nmod_t r0;
87    fq_nmod_init(r0, ctx);
88    fq_nmod_poly_get_coeff(r0,fac->poly,0,ctx);
89    fq_nmod_neg(r0, r0, ctx);
90    // convert
91    CanonicalForm r1=convertFq_nmod_t2FacCF(r0,beta,ctx);
92    // cleanup
93    fq_nmod_poly_factor_clear(fac,ctx);
94    fq_nmod_clear(r0, ctx);
95    fq_nmod_poly_clear(mipo2,ctx);
96    fq_nmod_ctx_clear(ctx);
97    return r1;
98  #elif defined(HAVE_NTL)
99  int p= getCharacteristic ();
100  if (fac_NTL_char != p)
101  {
102    fac_NTL_char= p;
103    zz_p::init (p);
104  }
105  zz_pX NTL_mipo= convertFacCF2NTLzzpX (getMipo (beta));
106  zz_pE::init (NTL_mipo);
107  zz_pEX NTL_alpha_mipo= convertFacCF2NTLzz_pEX (getMipo(alpha), NTL_mipo);
108  zz_pE root= FindRoot (NTL_alpha_mipo);
109  return convertNTLzzpE2CF (root, beta);
110  #else
111  factoryError("NTL/FLINT missing: mapUp");
112  return CanonicalForm(0); // to avoid warnings
113  #endif
114}
115
116
117/// the CanonicalForm G is the output of map_up, returns F considered as an
118/// element over \f$ F_{p}(\alpha ) \f$, WARNING: make sure coefficients of F
119/// are really elements of a subfield of \f$ F_{p}(\beta ) \f$ which is
120/// isomorphic to \f$ F_{p}(\alpha ) \f$
121static inline
122CanonicalForm
123mapDown (const CanonicalForm& F, const Variable& alpha, const
124          CanonicalForm& G, CFList& source, CFList& dest)
125{
126  CanonicalForm buf, buf2;
127  int counter= 0;
128  int pos;
129  int p= getCharacteristic();
130  int d= degree(getMipo(alpha));
131  int bound= ipower(p, d);
132  CanonicalForm result= 0;
133  CanonicalForm remainder;
134  CanonicalForm alpha_power;
135  if (degree(F) == 0) return F;
136  if (F.level() < 0 && F.isUnivariate())
137  {
138    buf= F;
139    remainder= mod (buf, G);
140    ASSERT (remainder.isZero(), "alpha is not primitive");
141    pos= findItem (source, buf);
142    if (pos == 0)
143      source.append (buf);
144    buf2= buf;
145    while (degree (buf) != 0 && counter < bound)
146    {
147      buf /= G;
148      counter++;
149      if (buf == buf2) break;
150    }
151    ASSERT (counter >= bound, "alpha is not primitive");
152    if (pos == 0)
153    {
154      alpha_power= power (alpha, counter);
155      dest.append (alpha_power);
156    }
157    else
158      alpha_power= getItem (dest, pos);
159    result = alpha_power;
160    return result;
161  }
162  else
163  {
164    for (CFIterator i= F; i.hasTerms(); i++)
165    {
166      buf= mapDown (i.coeff(), alpha, G, source, dest);
167      result += buf*power(F.mvar(), i.exp());
168    }
169    return result;
170  }
171}
172
173/// helper function
174static inline
175CanonicalForm GF2FalphaHelper (const CanonicalForm& F, const Variable& alpha)
176{
177  if (F.isZero())
178    return 0;
179  int exp;
180  CanonicalForm result= 0;
181  InternalCF* buf;
182  if (F.inBaseDomain())
183  {
184    if (F.isOne()) return 1;
185    buf= F.getval();
186    exp= imm2int(buf);
187    result= power (alpha, exp).mapinto();
188    return result;
189  }
190  for (CFIterator i= F; i.hasTerms(); i++)
191    result += GF2FalphaHelper (i.coeff(), alpha)*power (F.mvar(), i.exp());
192  return result;
193}
194
195CanonicalForm GF2FalphaRep (const CanonicalForm& F, const Variable& alpha)
196{
197  Variable beta= rootOf (gf_mipo);
198  CanonicalForm result= GF2FalphaHelper (F, beta) (alpha, beta);
199  prune (beta);
200  return result;
201}
202
203CanonicalForm Falpha2GFRep (const CanonicalForm& F)
204{
205  CanonicalForm result= 0;
206  InternalCF* buf;
207
208  if (F.inCoeffDomain())
209  {
210    if (F.inBaseDomain())
211      return F.mapinto();
212    else
213    {
214      for (CFIterator i= F; i.hasTerms(); i++)
215      {
216        buf= int2imm_gf (i.exp());
217        result += i.coeff().mapinto()*CanonicalForm (buf);
218      }
219    }
220    return result;
221  }
222  for (CFIterator i= F; i.hasTerms(); i++)
223    result += Falpha2GFRep (i.coeff())*power (F.mvar(), i.exp());
224  return result;
225}
226
227/// GF_map_up helper
228static inline
229CanonicalForm GFPowUp (const CanonicalForm & F, int k)
230{
231  if (F.isOne()) return F;
232  CanonicalForm result= 0;
233  if (F.inBaseDomain())
234    return power(F, k);
235  for (CFIterator i= F; i.hasTerms(); i++)
236    result += GFPowUp (i.coeff(), k)*power (F.mvar(), i.exp());
237  return result;
238}
239
240CanonicalForm GFMapUp (const CanonicalForm & F, int k)
241{
242  int d= getGFDegree();
243  ASSERT (d%k == 0, "multiple of GF degree expected");
244  int p= getCharacteristic();
245  int ext_field_size= ipower (p, d);
246  int field_size= ipower ( p, k);
247  int diff= (ext_field_size - 1)/(field_size - 1);
248  return GFPowUp (F, diff);
249}
250
251/// GFMapDown helper
252static inline
253CanonicalForm GFPowDown (const CanonicalForm & F, int k)
254{
255  if (F.isOne()) return F;
256  CanonicalForm result= 0;
257  int exp;
258  InternalCF* buf;
259  if (F.inBaseDomain())
260  {
261    buf= F.getval();
262    exp= imm2int (buf);
263    if ((exp % k) == 0)
264      exp= exp/k;
265    else
266      return -1;
267
268    buf= int2imm_gf (exp);
269    return CanonicalForm (buf);
270  }
271  for (CFIterator i= F; i.hasTerms(); i++)
272    result += GFPowDown (i.coeff(), k)*power (F.mvar(), i.exp());
273  return result;
274}
275
276CanonicalForm GFMapDown (const CanonicalForm & F, int k)
277{
278  int d= getGFDegree();
279  ASSERT (d % k == 0, "multiple of GF degree expected");
280  int p= getCharacteristic();
281  int ext_field_size= ipower (p, d);
282  int field_size= ipower ( p, k);
283  int diff= (ext_field_size - 1)/(field_size - 1);
284  return GFPowDown (F, diff);
285}
286
287/// map F in \f$ F_{p} (\alpha ) \f$ which is generated by G into some
288/// \f$ F_{p}(\beta ) \f$ which is generated by H
289static inline
290CanonicalForm mapUp (const CanonicalForm& F, const CanonicalForm& G,
291                      const Variable& alpha, const CanonicalForm& H,
292                      CFList& source, CFList& dest)
293{
294  CanonicalForm buf, buf2;
295  int counter= 0;
296  int pos;
297  int p= getCharacteristic();
298  int d= degree (getMipo(alpha));
299  int bound= ipower(p, d);
300  CanonicalForm result= 0;
301  CanonicalForm remainder;
302  CanonicalForm H_power;
303  if (degree(F) <= 0) return F;
304  if (F.level() < 0 && F.isUnivariate())
305  {
306    buf= F;
307    remainder= mod (buf, G);
308    ASSERT (remainder.isZero(), "alpha is not primitive");
309    pos= findItem (source, buf);
310    if (pos == 0)
311      source.append (buf);
312    buf2= buf;
313    while (degree (buf) != 0 && counter < bound)
314    {
315      buf /= G;
316      counter++;
317      if (buf == buf2) break;
318    }
319    ASSERT (counter <= bound, "alpha is not primitive");
320    if (pos == 0)
321    {
322      H_power= buf*power (H, counter);
323      dest.append (H_power);
324    }
325    else
326      H_power= getItem (dest, pos);
327    result = H_power;
328    return result;
329  }
330  else
331  {
332    for (CFIterator i= F; i.hasTerms(); i++)
333    {
334      buf= mapUp (i.coeff(), G, alpha, H, source, dest);
335      result += buf*power(F.mvar(), i.exp());
336    }
337    return result;
338  }
339}
340
341CanonicalForm
342primitiveElement (const Variable& alpha, Variable& beta, bool& fail)
343{
344  bool primitive= false;
345  fail= false;
346  primitive= isPrimitive (alpha, fail);
347  if (fail)
348    return 0;
349  if (primitive)
350  {
351    beta= alpha;
352    return alpha;
353  }
354  CanonicalForm mipo= getMipo (alpha);
355  int d= degree (mipo);
356  int p= getCharacteristic ();
357  #if defined(HAVE_FLINT) && (__FLINT_RELEASE >= 20503)
358  nmod_poly_t FLINT_mipo;
359  nmod_poly_init(FLINT_mipo,p);
360  #elif defined(HAVE_NTL)
361  if (fac_NTL_char != p)
362  {
363    fac_NTL_char= p;
364    zz_p::init (p);
365  }
366  zz_pX NTL_mipo;
367  #else
368  factoryError("NTL/FLINT missing: primitiveElement");
369  return CanonicalForm(0);
370  #endif
371  CanonicalForm mipo2;
372  primitive= false;
373  fail= false;
374  bool initialized= false;
375  do
376  {
377    #if defined(HAVE_FLINT) && (__FLINT_RELEASE >= 20503)
378    nmod_poly_randtest_monic_irreducible(FLINT_mipo, FLINTrandom, d+1);
379    mipo2=convertnmod_poly_t2FacCF(FLINT_mipo,Variable(1));
380    #elif defined(HAVE_NTL)
381    BuildIrred (NTL_mipo, d);
382    mipo2= convertNTLzzpX2CF (NTL_mipo, Variable (1));
383    #endif
384    if (!initialized)
385      beta= rootOf (mipo2);
386    else
387      setMipo (beta, mipo2);
388    primitive= isPrimitive (beta, fail);
389    if (primitive)
390      break;
391    if (fail)
392      return 0;
393  } while (1);
394  #if defined(HAVE_FLINT) && (__FLINT_RELEASE >= 20503)
395  nmod_poly_clear(FLINT_mipo);
396  // convert alpha_mipo
397  nmod_poly_t alpha_mipo;
398  convertFacCF2nmod_poly_t(alpha_mipo,mipo);
399  fq_nmod_ctx_t ctx;
400  fq_nmod_ctx_init_modulus(ctx,alpha_mipo,"t");
401  nmod_poly_clear(alpha_mipo);
402  // convert beta_mipo (mipo2)
403  fq_nmod_poly_t FLINT_beta_mipo;
404  convertFacCF2Fq_nmod_poly_t(FLINT_beta_mipo,mipo2,ctx);
405  fq_nmod_poly_factor_t fac;
406  fq_nmod_poly_factor_init(fac,ctx);
407  fq_nmod_poly_roots(fac, FLINT_beta_mipo, 0, ctx);
408  // root of first (linear) factor: -absolute Term
409  fq_nmod_t r0;
410  fq_nmod_init(r0, ctx);
411  fq_nmod_poly_get_coeff(r0,fac->poly,0,ctx);
412  fq_nmod_neg(r0, r0, ctx);
413  // convert
414  CanonicalForm r1=convertFq_nmod_t2FacCF(r0,alpha,ctx);
415  // cleanup
416  fq_nmod_poly_factor_clear(fac,ctx);
417  fq_nmod_clear(r0, ctx);
418  fq_nmod_poly_clear(FLINT_beta_mipo,ctx);
419  fq_nmod_ctx_clear(ctx);
420  return r1;
421  #elif defined(HAVE_NTL)
422  zz_pX alpha_mipo= convertFacCF2NTLzzpX (mipo);
423  zz_pE::init (alpha_mipo);
424  zz_pEX NTL_beta_mipo= to_zz_pEX (NTL_mipo);
425  zz_pE root= FindRoot (NTL_beta_mipo);
426  return convertNTLzzpE2CF (root, alpha);
427  #endif
428}
429
430CanonicalForm
431mapDown (const CanonicalForm& F, const CanonicalForm& prim_elem, const
432          CanonicalForm& im_prim_elem, const Variable& alpha, CFList& source,
433          CFList& dest)
434{
435  return mapUp (F, im_prim_elem, alpha, prim_elem, dest, source);
436}
437
438CanonicalForm
439mapUp (const CanonicalForm& F, const Variable& alpha, const Variable& /*beta*/,
440        const CanonicalForm& prim_elem, const CanonicalForm& im_prim_elem,
441        CFList& source, CFList& dest)
442{
443  if (prim_elem == alpha)
444    return F (im_prim_elem, alpha);
445  return mapUp (F, prim_elem, alpha, im_prim_elem, source, dest);
446}
447
448#if defined(HAVE_NTL) || defined(HAVE_FLINT)
449CanonicalForm
450mapPrimElem (const CanonicalForm& primElem, const Variable& alpha,
451             const Variable& beta)
452{
453  if (primElem == alpha)
454    return mapUp (alpha, beta);
455  else
456  {
457    CanonicalForm primElemMipo= findMinPoly (primElem, alpha);
458    #if defined(HAVE_FLINT) && (__FLINT_RELEASE >= 20503)
459    // convert mipo1
460    nmod_poly_t mipo1;
461    convertFacCF2nmod_poly_t(mipo1,getMipo(beta));
462    fq_nmod_ctx_t ctx;
463    fq_nmod_ctx_init_modulus(ctx,mipo1,"t");
464    nmod_poly_clear(mipo1);
465    // convert mipo2 (primElemMipo)
466    fq_nmod_poly_t mipo2;
467    convertFacCF2Fq_nmod_poly_t(mipo2,primElemMipo,ctx);
468    fq_nmod_poly_factor_t fac;
469    fq_nmod_poly_factor_init(fac,ctx);
470    fq_nmod_poly_roots(fac, mipo2, 0, ctx);
471    // root of first (linear) factor: -absolute Term
472    fq_nmod_t r0;
473    fq_nmod_init(r0, ctx);
474    fq_nmod_poly_get_coeff(r0,fac->poly,0,ctx);
475    fq_nmod_neg(r0, r0, ctx);
476    // convert
477    CanonicalForm r1=convertFq_nmod_t2FacCF(r0,beta,ctx);
478    // cleanup
479    fq_nmod_poly_factor_clear(fac,ctx);
480    fq_nmod_clear(r0, ctx);
481    fq_nmod_poly_clear(mipo2,ctx);
482    fq_nmod_ctx_clear(ctx);
483    return r1;
484    #elif defined(HAVE_NTL)
485    int p= getCharacteristic ();
486    if (fac_NTL_char != p)
487    {
488      fac_NTL_char= p;
489      zz_p::init (p);
490    }
491    zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (beta));
492    zz_pE::init (NTLMipo);
493    zz_pEX NTLPrimElemMipo= convertFacCF2NTLzz_pEX (primElemMipo, NTLMipo);
494    zz_pE root= FindRoot (NTLPrimElemMipo);
495    return convertNTLzzpE2CF (root, beta);
496    #else
497    factoryError("NTL/FLINT missing: mapPrimElem");
498    #endif
499  }
500}
501#endif
502
503CanonicalForm
504map (const CanonicalForm& primElem, const Variable& alpha,
505     const CanonicalForm& F, const Variable& beta)
506{
507  CanonicalForm G= F;
508  int order= 0;
509  while (!G.isOne())
510  {
511    G /= primElem;
512    order++;
513  }
514  #if defined(HAVE_FLINT) && (__FLINT_RELEASE >= 20503)
515  // convert mipo
516  nmod_poly_t mipo1;
517  convertFacCF2nmod_poly_t(mipo1,getMipo(beta));
518  fq_nmod_ctx_t ctx;
519  fq_nmod_ctx_init_modulus(ctx,mipo1,"t");
520  nmod_poly_clear(mipo1);
521  // convert mipo2 (alpha)
522  fq_nmod_poly_t mipo2;
523  convertFacCF2Fq_nmod_poly_t(mipo2,getMipo(alpha),ctx);
524  fq_nmod_poly_factor_t fac;
525  fq_nmod_poly_factor_init(fac,ctx);
526  fq_nmod_poly_roots(fac, mipo2, 0, ctx);
527  // roots in fac, #=fac->num
528  int ind=-1;
529  fq_nmod_t r0,FLINTbeta;
530  fq_nmod_init(r0, ctx);
531  fq_nmod_init(FLINTbeta, ctx);
532  convertFacCF2Fq_nmod_t(FLINTbeta,beta,ctx);
533  fmpz_t FLINTorder;
534  fmpz_set_si(FLINTorder,order);
535  for(int i=0;i< fac->num;i++)
536  {
537    // get the root (-abs.term of linear factor)
538    fq_nmod_poly_get_coeff(r0,fac->poly+i,0,ctx);
539    fq_nmod_neg(r0,r0,ctx);
540    // r^order
541    fq_nmod_pow(r0,r0,FLINTorder,ctx);
542    // ==beta?
543    if (fq_nmod_equal(r0,FLINTbeta,ctx))
544    {
545       ind=i;
546       break;
547    }
548  }
549  fmpz_clear(FLINTorder);
550  // convert
551  fq_nmod_poly_get_coeff(r0,fac->poly+ind,0,ctx);
552  fq_nmod_neg(r0,r0,ctx);
553  CanonicalForm r1=convertFq_nmod_t2FacCF(r0,beta,ctx);
554  // cleanup
555  fq_nmod_poly_factor_clear(fac,ctx);
556  fq_nmod_clear(r0, ctx);
557  fq_nmod_clear(FLINTbeta,ctx);
558  fq_nmod_poly_clear(mipo2,ctx);
559  fq_nmod_ctx_clear(ctx);
560  return r1;
561  #elif defined(HAVE_NTL)
562  int p= getCharacteristic ();
563  if (fac_NTL_char != p)
564  {
565    fac_NTL_char= p;
566    zz_p::init (p);
567  }
568  zz_pX NTL_mipo= convertFacCF2NTLzzpX (getMipo (beta));
569  zz_pE::init (NTL_mipo);
570  zz_pEX NTL_alpha_mipo= convertFacCF2NTLzz_pEX (getMipo(alpha), NTL_mipo);
571  zz_pE NTLBeta= to_zz_pE (convertFacCF2NTLzzpX (beta));
572  vec_zz_pE roots= FindRoots (NTL_alpha_mipo);
573  long ind=-1;
574  for (long i= 0; i < roots.length(); i++)
575  {
576    if (power (roots [i], order)== NTLBeta)
577    {
578      ind= i;
579      break;
580    }
581  }
582  return (convertNTLzzpE2CF (roots[ind], beta));
583  #else
584  factoryError("NTL/FLINT missing: map");
585  return CanonicalForm(0);
586  #endif
587}
588
589#if defined(HAVE_FLINT) && (__FLINT_RELEASE >= 20503)
590/*
591    g is in Fp[x]
592    F is in Fp[t]
593    h is in Fp[t]
594    In the finite field Fp[t]/h(t), find g(x) in Fp[x] such that
595        g(F(t)) = 0 mod h(t)
596    i.e. g is the minpoly of the element F(t) of the finite field.
597*/
598static void minpoly(nmod_poly_t g, const nmod_poly_t F, const nmod_poly_t h)
599{
600    slong i;
601    slong d = nmod_poly_degree(h);
602    mp_limb_t p = h->mod.n;
603    nmod_poly_t Fpow;
604    nmod_berlekamp_massey_t bma;
605
606    nmod_poly_init(Fpow, p);
607    nmod_berlekamp_massey_init(bma, p);
608
609    nmod_poly_one(Fpow);
610    for (i = 0; i < 2*d; i++)
611    {
612        nmod_berlekamp_massey_add_point(bma, nmod_poly_get_coeff_ui(Fpow, 0));
613        nmod_poly_mulmod(Fpow, Fpow, F, h);
614    }
615
616    nmod_berlekamp_massey_reduce(bma);
617
618    /* something went horribly wrong if V does not kill the whole sequence */
619    FLINT_ASSERT(nmod_poly_degree(nmod_berlekamp_massey_R_poly(bma)) <
620                 nmod_poly_degree(nmod_berlekamp_massey_V_poly(bma)));
621
622    nmod_poly_make_monic(g, nmod_berlekamp_massey_V_poly(bma));
623#if WANT_ASSERT
624    {
625        nmod_poly_t z;
626        nmod_poly_init(z, p);
627        nmod_poly_compose_mod(z, g, F, h);
628        FLINT_ASSERT(nmod_poly_is_zero(z));
629        nmod_poly_clear(z);
630    }
631#endif
632    nmod_poly_clear(Fpow);
633    nmod_berlekamp_massey_clear(bma);
634}
635#endif
636
637
638#if defined(HAVE_NTL) || defined(HAVE_FLINT)
639CanonicalForm
640findMinPoly (const CanonicalForm& F, const Variable& alpha)
641{
642  ASSERT (F.isUnivariate() && F.mvar()==alpha,"expected element of F_p(alpha)");
643
644  int p=getCharacteristic();
645  #if defined(HAVE_FLINT) && (__FLINT_RELEASE >= 20503)
646  nmod_poly_t FLINT_F,FLINT_alpha,g;
647  nmod_poly_init(g,p);
648  convertFacCF2nmod_poly_t(FLINT_F,F);
649  convertFacCF2nmod_poly_t(FLINT_alpha,getMipo(alpha));
650  minpoly(g,FLINT_F,FLINT_alpha);
651  nmod_poly_clear(FLINT_alpha);
652  nmod_poly_clear(FLINT_F);
653  CanonicalForm res=convertnmod_poly_t2FacCF(g,Variable(1));
654  nmod_poly_clear(g);
655  return res;
656  #elif defined(HAVE_NTL)
657  if (fac_NTL_char != p)
658  {
659    fac_NTL_char= p;
660    zz_p::init (p);
661  }
662  zz_pX NTLF= convertFacCF2NTLzzpX (F);
663  int d= degree (getMipo (alpha));
664
665  zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo(alpha));
666  zz_pE::init (NTLMipo);
667  vec_zz_p pows;
668  pows.SetLength (2*d);
669
670  zz_pE powNTLF;
671  set (powNTLF);
672  zz_pE NTLFE= to_zz_pE (NTLF);
673  zz_pX buf;
674  for (int i= 0; i < 2*d; i++)
675  {
676    buf= rep (powNTLF);
677    buf.rep.SetLength (d);
678    pows [i]= buf.rep[0];
679    powNTLF *= NTLFE;
680  }
681
682  zz_pX NTLMinPoly;
683  MinPolySeq (NTLMinPoly, pows, d);
684
685  return convertNTLzzpX2CF (NTLMinPoly, Variable (1));
686  #else
687  factoryError("NTL/FLINT missing: findMinPoly");
688  #endif
689}
690#endif
Note: See TracBrowser for help on using the repository browser.