source: git/factory/FLINTconvert.cc @ 2ce3bf

spielwiese
Last change on this file since 2ce3bf was 2ce3bf, checked in by Hans Schoenemann <hannes@…>, 3 years ago
fq_nmod_get_nmod_poly/fq_nmod_set_nmod_poly for FLINT < 2.6.1
  • Property mode set to 100644
File size: 22.2 KB
Line 
1/*****************************************************************************\
2 * Computer Algebra System SINGULAR
3\*****************************************************************************/
4/** @file FLINTconvert.cc
5 *
6 * This file implements functions for conversion to FLINT (www.flintlib.org)
7 * and back.
8 *
9 * @author Martin Lee
10 *
11 **/
12/*****************************************************************************/
13
14
15
16#include <config.h>
17
18
19#include "canonicalform.h"
20#include "fac_util.h"
21#include "cf_iter.h"
22#include "cf_factory.h"
23#include "gmpext.h"
24#include "singext.h"
25#include "cf_algorithm.h"
26
27#ifdef HAVE_OMALLOC
28#define Alloc(L) omAlloc(L)
29#define Free(A,L) omFreeSize(A,L)
30#else
31#define Alloc(L) malloc(L)
32#define Free(A,L) free(A)
33#endif
34
35#ifdef HAVE_FLINT
36#ifdef HAVE_CSTDIO
37#include <cstdio>
38#else
39#include <stdio.h>
40#endif
41#ifdef __cplusplus
42extern "C"
43{
44#endif
45#ifndef __GMP_BITS_PER_MP_LIMB
46#define __GMP_BITS_PER_MP_LIMB GMP_LIMB_BITS
47#endif
48#include <flint/fmpz.h>
49#include <flint/fmpq.h>
50#include <flint/fmpz_poly.h>
51#include <flint/fmpz_mod_poly.h>
52#include <flint/nmod_poly.h>
53#include <flint/fmpq_poly.h>
54#include <flint/nmod_mat.h>
55#include <flint/fmpz_mat.h>
56#if ( __FLINT_RELEASE >= 20400)
57#include <flint/fq.h>
58#include <flint/fq_poly.h>
59#include <flint/fq_nmod.h>
60#include <flint/fq_nmod_poly.h>
61#include <flint/fq_nmod_mat.h>
62#endif
63#if ( __FLINT_RELEASE >= 20503)
64#include <flint/fmpq_mpoly.h>
65
66#if (__FLINT_RELEASE < 20601)
67// helper for fq_nmod_t -> nmod_poly_t
68static void fq_nmod_get_nmod_poly(nmod_poly_t a, const fq_nmod_t b, const fq_nmod_ctx_t ctx)
69{
70    FLINT_ASSERT(b->mod.n == ctx->modulus->mod.n);
71    a->mod = ctx->modulus->mod;
72    nmod_poly_set(a, b);
73}
74
75// helper for nmod_poly_t -> fq_nmod_t
76static void fq_nmod_set_nmod_poly(fq_nmod_t a, const nmod_poly_t b, const fq_nmod_ctx_t ctx)
77{
78    FLINT_ASSERT(a->mod.n == b->mod.n);
79    FLINT_ASSERT(a->mod.n == ctx->modulus->mod.n);
80    nmod_poly_set(a, b);
81    fq_nmod_reduce(a, ctx);
82}
83#endif
84
85
86#endif
87#ifdef __cplusplus
88}
89#endif
90
91#include "FLINTconvert.h"
92
93void convertCF2Fmpz (fmpz_t result, const CanonicalForm& f)
94{
95  if (f.isImm())
96    fmpz_set_si (result, f.intval());
97  else
98  {
99    mpz_t gmp_val;
100    f.mpzval(gmp_val);
101    fmpz_set_mpz (result, gmp_val);
102    mpz_clear (gmp_val);
103  }
104}
105
106void convertFacCF2Fmpz_poly_t (fmpz_poly_t result, const CanonicalForm& f)
107{
108  fmpz_poly_init2 (result, degree (f)+1);
109  _fmpz_poly_set_length(result, degree(f)+1);
110  for (CFIterator i= f; i.hasTerms(); i++)
111    convertCF2Fmpz (fmpz_poly_get_coeff_ptr(result, i.exp()), i.coeff());
112}
113
114CanonicalForm convertFmpz2CF (const fmpz_t coefficient)
115{
116  if (fmpz_cmp_si (coefficient, MINIMMEDIATE) >= 0 &&
117      fmpz_cmp_si (coefficient, MAXIMMEDIATE) <= 0)
118  {
119    long coeff= fmpz_get_si (coefficient);
120    return CanonicalForm (coeff);
121  }
122  else
123  {
124    mpz_t gmp_val;
125    mpz_init (gmp_val);
126    fmpz_get_mpz (gmp_val, coefficient);
127    CanonicalForm result= CanonicalForm (CFFactory::basic (gmp_val));
128    return result;
129  }
130}
131
132CanonicalForm
133convertFmpz_poly_t2FacCF (const fmpz_poly_t poly, const Variable& x)
134{
135  CanonicalForm result= 0;
136  fmpz* coeff;
137  for (int i= 0; i < fmpz_poly_length (poly); i++)
138  {
139    coeff= fmpz_poly_get_coeff_ptr (poly, i);
140    if (!fmpz_is_zero (coeff))
141      result += convertFmpz2CF (coeff)*power (x,i);
142  }
143  return result;
144}
145
146void
147convertFacCF2nmod_poly_t (nmod_poly_t result, const CanonicalForm& f)
148{
149  bool save_sym_ff= isOn (SW_SYMMETRIC_FF);
150  if (save_sym_ff) Off (SW_SYMMETRIC_FF);
151  nmod_poly_init2 (result, getCharacteristic(), degree (f)+1);
152  for (CFIterator i= f; i.hasTerms(); i++)
153  {
154    CanonicalForm c= i.coeff();
155    if (!c.isImm()) c=c.mapinto(); //c%= getCharacteristic();
156    if (!c.isImm())
157    {  //This case will never happen if the characteristic is in fact a prime
158       // number, since all coefficients are represented as immediates
159       printf("convertCF2nmod_poly_t: coefficient not immediate!, char=%d\n",
160              getCharacteristic());
161    }
162    else
163      nmod_poly_set_coeff_ui (result, i.exp(), c.intval());
164  }
165  if (save_sym_ff) On (SW_SYMMETRIC_FF);
166}
167
168CanonicalForm
169convertnmod_poly_t2FacCF (const nmod_poly_t poly, const Variable& x)
170{
171  CanonicalForm result= 0;
172  for (int i= 0; i < nmod_poly_length (poly); i++)
173  {
174    ulong coeff= nmod_poly_get_coeff_ui (poly, i);
175    if (coeff != 0)
176      result += CanonicalForm ((long)coeff)*power (x,i);
177  }
178  return result;
179}
180
181void convertCF2Fmpq (fmpq_t result, const CanonicalForm& f)
182{
183  //ASSERT (isOn (SW_RATIONAL), "expected rational");
184  if (f.isImm ())
185  {
186    fmpq_set_si (result, f.intval(), 1);
187  }
188  else if(f.inQ())
189  {
190    mpz_t gmp_val;
191    gmp_numerator (f, gmp_val);
192    fmpz_set_mpz (fmpq_numref (result), gmp_val);
193    mpz_clear (gmp_val);
194    gmp_denominator (f, gmp_val);
195    fmpz_set_mpz (fmpq_denref (result), gmp_val);
196    mpz_clear (gmp_val);
197  }
198  else if(f.inZ())
199  {
200    mpz_t gmp_val;
201    f.mpzval(gmp_val);
202    fmpz_set_mpz (fmpq_numref (result), gmp_val);
203    mpz_clear (gmp_val);
204    fmpz_one(fmpq_denref(result));
205  }
206  else
207  {
208    printf("wrong type\n");
209  }
210}
211
212CanonicalForm convertFmpq_t2CF (const fmpq_t q)
213{
214  bool isRat= isOn (SW_RATIONAL);
215  if (!isRat)
216    On (SW_RATIONAL);
217
218  CanonicalForm num, den;
219  mpz_t nnum, nden;
220  mpz_init (nnum);
221  mpz_init (nden);
222  fmpz_get_mpz (nnum, fmpq_numref (q));
223  fmpz_get_mpz (nden, fmpq_denref (q));
224
225  CanonicalForm result;
226  if (mpz_is_imm (nden))
227  {
228    if (mpz_is_imm(nnum))
229    {
230      num= CanonicalForm (mpz_get_si(nnum));
231      den= CanonicalForm (mpz_get_si(nden));
232      mpz_clear (nnum);
233      mpz_clear (nden);
234      result= num/den;
235    }
236    else if (mpz_cmp_si(nden,1)==0)
237    {
238      result= CanonicalForm( CFFactory::basic(nnum));
239      mpz_clear (nden);
240    }
241    else
242      result= CanonicalForm( CFFactory::rational( nnum, nden, false));
243  }
244  else
245  {
246    result= CanonicalForm( CFFactory::rational( nnum, nden, false));
247  }
248  if (!isRat)
249    Off (SW_RATIONAL);
250  return result;
251}
252
253CanonicalForm
254convertFmpq_poly_t2FacCF (const fmpq_poly_t p, const Variable& x)
255{
256  CanonicalForm result= 0;
257  fmpq_t coeff;
258  long n= p->length;
259  for (long i= 0; i < n; i++)
260  {
261    fmpq_init (coeff);
262    fmpq_poly_get_coeff_fmpq (coeff, p, i);
263    if (fmpq_is_zero (coeff))
264    {
265      fmpq_clear (coeff);
266      continue;
267    }
268    result += convertFmpq_t2CF (coeff)*power (x, i);
269    fmpq_clear (coeff);
270  }
271  return result;
272}
273
274void convertFacCF2Fmpz_array (fmpz* result, const CanonicalForm& f)
275{
276  for (CFIterator i= f; i.hasTerms(); i++)
277    convertCF2Fmpz (&result[i.exp()], i.coeff());
278}
279
280void convertFacCF2Fmpq_poly_t (fmpq_poly_t result, const CanonicalForm& f)
281{
282  bool isRat= isOn (SW_RATIONAL);
283  if (!isRat)
284    On (SW_RATIONAL);
285
286  fmpq_poly_init2 (result, degree (f)+1);
287  _fmpq_poly_set_length (result, degree (f) + 1);
288  CanonicalForm den= bCommonDen (f);
289  convertFacCF2Fmpz_array (fmpq_poly_numref (result), f*den);
290  convertCF2Fmpz (fmpq_poly_denref (result), den);
291
292  if (!isRat)
293    Off (SW_RATIONAL);
294}
295
296CFFList
297convertFLINTnmod_poly_factor2FacCFFList (const nmod_poly_factor_t fac,
298                                          const mp_limb_t leadingCoeff,
299                                          const Variable& x
300                                         )
301{
302  CFFList result;
303  if (leadingCoeff != 1)
304    result.insert (CFFactor (CanonicalForm ((long) leadingCoeff), 1));
305
306  long i;
307
308  for (i = 0; i < fac->num; i++)
309    result.append (CFFactor (convertnmod_poly_t2FacCF (
310                             (nmod_poly_t &)fac->p[i],x),
311                             fac->exp[i]));
312  return result;
313}
314
315#if __FLINT_RELEASE >= 20503
316CFFList
317convertFLINTfmpz_poly_factor2FacCFFList (
318                   const fmpz_poly_factor_t fac, ///< [in] a nmod_poly_factor_t
319                   const Variable& x       ///< [in] variable the result should
320                                           ///< have
321                                        )
322
323{
324  CFFList result;
325  long i;
326
327  result.append (CFFactor(convertFmpz2CF(&fac->c),1));
328
329  for (i = 0; i < fac->num; i++)
330    result.append (CFFactor (convertFmpz_poly_t2FacCF (
331                             (fmpz_poly_t &)fac->p[i],x),
332                             fac->exp[i]));
333  return result;
334}
335#endif
336
337#if __FLINT_RELEASE >= 20400
338CFFList
339convertFLINTFq_nmod_poly_factor2FacCFFList (const fq_nmod_poly_factor_t fac,
340                                       const Variable& x, const Variable& alpha,
341                                       const fq_nmod_ctx_t fq_con
342                                         )
343{
344  CFFList result;
345
346  long i;
347
348  for (i = 0; i < fac->num; i++)
349    result.append (CFFactor (convertFq_nmod_poly_t2FacCF (
350                             (fq_nmod_poly_t &)fac->poly[i], x, alpha, fq_con),
351                             fac->exp[i]));
352  return result;
353}
354#endif
355
356void
357convertFacCF2Fmpz_mod_poly_t (fmpz_mod_poly_t result, const CanonicalForm& f,
358                              const fmpz_t p)
359{
360  fmpz_mod_poly_init2 (result, p, degree (f) + 1);
361  fmpz_poly_t buf;
362  convertFacCF2Fmpz_poly_t (buf, f);
363  fmpz_mod_poly_set_fmpz_poly (result, buf);
364  fmpz_poly_clear (buf);
365}
366
367CanonicalForm
368convertFmpz_mod_poly_t2FacCF (const fmpz_mod_poly_t poly, const Variable& x,
369                              const modpk& b)
370{
371  fmpz_poly_t buf;
372  fmpz_poly_init (buf);
373  fmpz_mod_poly_get_fmpz_poly (buf, poly);
374  CanonicalForm result= convertFmpz_poly_t2FacCF (buf, x);
375  fmpz_poly_clear (buf);
376  return b (result);
377}
378
379#if __FLINT_RELEASE >= 20400
380void
381convertFacCF2Fq_nmod_t (fq_nmod_t result, const CanonicalForm& f,
382                        const fq_nmod_ctx_t ctx)
383{
384  bool save_sym_ff= isOn (SW_SYMMETRIC_FF);
385  if (save_sym_ff) Off (SW_SYMMETRIC_FF);
386  nmod_poly_t res;
387  nmod_poly_init(res,getCharacteristic());
388  for (CFIterator i= f; i.hasTerms(); i++)
389  {
390    CanonicalForm c= i.coeff();
391    if (!c.isImm()) c=c.mapinto(); //c%= getCharacteristic();
392    if (!c.isImm())
393    {  //This case will never happen if the characteristic is in fact a prime
394       // number, since all coefficients are represented as immediates
395       printf("convertFacCF2Fq_nmod_t: coefficient not immediate!, char=%d\n",
396              getCharacteristic());
397    }
398    else
399    {
400      STICKYASSERT (i.exp() <= fq_nmod_ctx_degree(ctx), "convertFacCF2Fq_nmod_t: element is not reduced");
401      nmod_poly_set_coeff_ui (res, i.exp(), c.intval());
402    }
403  }
404  fq_nmod_init(result,ctx);
405  fq_nmod_set_nmod_poly(result,res,ctx);
406  if (save_sym_ff) On (SW_SYMMETRIC_FF);
407}
408
409CanonicalForm
410convertFq_nmod_t2FacCF (const fq_nmod_t poly, const fq_nmod_ctx_t ctx, const Variable& alpha)
411{
412  nmod_poly_t p;
413  nmod_poly_init(p,getCharacteristic());
414  fq_nmod_get_nmod_poly(p,poly,ctx);
415  CanonicalForm res= convertnmod_poly_t2FacCF (p, alpha);
416  nmod_poly_clear(p);
417  return res;
418}
419
420void
421convertFacCF2Fq_t (fq_t result, const CanonicalForm& f, const fq_ctx_t ctx)
422{
423  fmpz_poly_init2 (result, fq_ctx_degree(ctx));
424  ASSERT (degree (f) < fq_ctx_degree (ctx), "input is not reduced");
425  _fmpz_poly_set_length(result, degree(f)+1);
426  for (CFIterator i= f; i.hasTerms(); i++)
427    convertCF2Fmpz (fmpz_poly_get_coeff_ptr(result, i.exp()), i.coeff());
428  _fmpz_vec_scalar_mod_fmpz (result->coeffs, result->coeffs, degree (f) + 1,
429                             &ctx->p);
430  _fmpz_poly_normalise (result);
431}
432
433CanonicalForm
434convertFq_t2FacCF (const fq_t poly, const Variable& alpha)
435{
436  return convertFmpz_poly_t2FacCF (poly, alpha);
437}
438
439void
440convertFacCF2Fq_poly_t (fq_poly_t result, const CanonicalForm& f,
441                        const fq_ctx_t ctx)
442{
443  fq_poly_init2 (result, degree (f)+1, ctx);
444  _fq_poly_set_length (result, degree (f) + 1, ctx);
445  fmpz_poly_t buf;
446  for (CFIterator i= f; i.hasTerms(); i++)
447  {
448    convertFacCF2Fmpz_poly_t (buf, i.coeff());
449    _fmpz_vec_scalar_mod_fmpz (buf->coeffs, buf->coeffs, degree (i.coeff()) + 1,
450                               &ctx->p);
451    _fmpz_poly_normalise (buf);
452    fq_poly_set_coeff (result, i.exp(), buf, ctx);
453    fmpz_poly_clear (buf);
454  }
455}
456
457void
458convertFacCF2Fq_nmod_poly_t (fq_nmod_poly_t result, const CanonicalForm& f,
459                             const fq_nmod_ctx_t ctx)
460{
461  fq_nmod_poly_init2 (result, degree (f)+1, ctx);
462  _fq_nmod_poly_set_length (result, degree (f) + 1, ctx);
463  fq_nmod_t buf;
464  fq_nmod_init2 (buf, ctx);
465  for (CFIterator i= f; i.hasTerms(); i++)
466  {
467    convertFacCF2Fq_nmod_t (buf, i.coeff(), ctx);
468    fq_nmod_poly_set_coeff (result, i.exp(), buf, ctx);
469    fq_nmod_zero (buf, ctx);
470  }
471  fq_nmod_clear (buf, ctx);
472}
473
474CanonicalForm
475convertFq_poly_t2FacCF (const fq_poly_t p, const Variable& x,
476                        const Variable& alpha, const fq_ctx_t ctx)
477{
478  CanonicalForm result= 0;
479  fq_t coeff;
480  long n= fq_poly_length (p, ctx);
481  fq_init2 (coeff, ctx);
482  for (long i= 0; i < n; i++)
483  {
484    fq_poly_get_coeff (coeff, p, i, ctx);
485    if (fq_is_zero (coeff, ctx))
486      continue;
487    result += convertFq_t2FacCF (coeff, alpha)*power (x, i);
488    fq_zero (coeff, ctx);
489  }
490  fq_clear (coeff, ctx);
491
492  return result;
493}
494
495CanonicalForm
496convertFq_nmod_poly_t2FacCF (const fq_nmod_poly_t p, const Variable& x,
497                             const Variable& alpha, const fq_nmod_ctx_t ctx)
498{
499  CanonicalForm result= 0;
500  fq_nmod_t coeff;
501  long n= fq_nmod_poly_length (p, ctx);
502  fq_nmod_init2 (coeff, ctx);
503  for (long i= 0; i < n; i++)
504  {
505    fq_nmod_poly_get_coeff (coeff, p, i, ctx);
506    if (fq_nmod_is_zero (coeff, ctx))
507      continue;
508    result += convertFq_nmod_t2FacCF (coeff, alpha, ctx)*power (x, i);
509    fq_nmod_zero (coeff, ctx);
510  }
511  fq_nmod_clear (coeff, ctx);
512
513  return result;
514}
515#endif
516
517void convertFacCFMatrix2Fmpz_mat_t (fmpz_mat_t M, const CFMatrix &m)
518{
519  fmpz_mat_init (M, (long) m.rows(), (long) m.columns());
520
521  int i,j;
522  for(i=m.rows();i>0;i--)
523  {
524    for(j=m.columns();j>0;j--)
525    {
526      convertCF2Fmpz (fmpz_mat_entry (M,i-1,j-1), m(i,j));
527    }
528  }
529}
530CFMatrix* convertFmpz_mat_t2FacCFMatrix(const fmpz_mat_t m)
531{
532  CFMatrix *res=new CFMatrix(fmpz_mat_nrows (m),fmpz_mat_ncols (m));
533  int i,j;
534  for(i=res->rows();i>0;i--)
535  {
536    for(j=res->columns();j>0;j--)
537    {
538      (*res)(i,j)=convertFmpz2CF(fmpz_mat_entry (m,i-1,j-1));
539    }
540  }
541  return res;
542}
543
544void convertFacCFMatrix2nmod_mat_t (nmod_mat_t M, const CFMatrix &m)
545{
546  nmod_mat_init (M, (long) m.rows(), (long) m.columns(), getCharacteristic());
547
548  bool save_sym_ff= isOn (SW_SYMMETRIC_FF);
549  if (save_sym_ff) Off (SW_SYMMETRIC_FF);
550  int i,j;
551  for(i=m.rows();i>0;i--)
552  {
553    for(j=m.columns();j>0;j--)
554    {
555      if(!(m(i,j)).isImm()) printf("convertFacCFMatrix2FLINTmat_zz_p: not imm.\n");
556      nmod_mat_entry (M,i-1,j-1)= (m(i,j)).intval();
557    }
558  }
559  if (save_sym_ff) On (SW_SYMMETRIC_FF);
560}
561
562CFMatrix* convertNmod_mat_t2FacCFMatrix(const nmod_mat_t m)
563{
564  CFMatrix *res=new CFMatrix(nmod_mat_nrows (m), nmod_mat_ncols (m));
565  int i,j;
566  for(i=res->rows();i>0;i--)
567  {
568    for(j=res->columns();j>0;j--)
569    {
570      (*res)(i,j)=CanonicalForm((long) nmod_mat_entry (m, i-1, j-1));
571    }
572  }
573  return res;
574}
575
576#if __FLINT_RELEASE >= 20400
577void
578convertFacCFMatrix2Fq_nmod_mat_t (fq_nmod_mat_t M,
579                                  const fq_nmod_ctx_t fq_con, const CFMatrix &m)
580{
581  fq_nmod_mat_init (M, (long) m.rows(), (long) m.columns(), fq_con);
582  int i,j;
583  for(i=m.rows();i>0;i--)
584  {
585    for(j=m.columns();j>0;j--)
586    {
587      convertFacCF2nmod_poly_t (M->rows[i-1]+j-1, m (i,j));
588    }
589  }
590}
591
592CFMatrix*
593convertFq_nmod_mat_t2FacCFMatrix(const fq_nmod_mat_t m,
594                                 const fq_nmod_ctx_t& fq_con,
595                                 const Variable& alpha)
596{
597  CFMatrix *res=new CFMatrix(fq_nmod_mat_nrows (m, fq_con),
598                             fq_nmod_mat_ncols (m, fq_con));
599  int i,j;
600  for(i=res->rows();i>0;i--)
601  {
602    for(j=res->columns();j>0;j--)
603    {
604      (*res)(i,j)=convertFq_nmod_t2FacCF (fq_nmod_mat_entry (m, i-1, j-1),
605                                          alpha, fq_con);
606    }
607  }
608  return res;
609}
610#endif
611#if __FLINT_RELEASE >= 20503
612static void convFlint_RecPP ( const CanonicalForm & f, ulong * exp, nmod_mpoly_t result, nmod_mpoly_ctx_t ctx, int N )
613{
614  // assume f!=0
615  if ( ! f.inCoeffDomain() )
616  {
617    int l = f.level();
618    for ( CFIterator i = f; i.hasTerms(); i++ )
619    {
620      exp[N-l] = i.exp();
621      convFlint_RecPP( i.coeff(), exp, result, ctx, N );
622    }
623    exp[N-l] = 0;
624  }
625  else
626  {
627    int c=f.intval(); // with Off(SW_SYMMETRIC_FF): 0<=c<p
628    nmod_mpoly_push_term_ui_ui(result,c,exp,ctx);
629  }
630}
631
632static void convFlint_RecPP ( const CanonicalForm & f, ulong * exp, fmpq_mpoly_t result, fmpq_mpoly_ctx_t ctx, int N )
633{
634  // assume f!=0
635  if ( ! f.inBaseDomain() )
636  {
637    int l = f.level();
638    for ( CFIterator i = f; i.hasTerms(); i++ )
639    {
640      exp[N-l] = i.exp();
641      convFlint_RecPP( i.coeff(), exp, result, ctx, N );
642    }
643    exp[N-l] = 0;
644  }
645  else
646  {
647    fmpq_t c;
648    fmpq_init(c);
649    convertCF2Fmpq(c,f);
650    fmpq_mpoly_push_term_fmpq_ui(result,c,exp,ctx);
651    fmpq_clear(c);
652  }
653}
654
655void convFactoryPFlintMP ( const CanonicalForm & f, nmod_mpoly_t res, nmod_mpoly_ctx_t ctx, int N )
656{
657  if (f.isZero()) return;
658  ulong * exp = (ulong*)Alloc(N*sizeof(ulong));
659  memset(exp,0,N*sizeof(ulong));
660  bool save_sym_ff= isOn (SW_SYMMETRIC_FF);
661  if (save_sym_ff) Off (SW_SYMMETRIC_FF);
662  convFlint_RecPP( f, exp, res, ctx, N );
663  if (save_sym_ff) On(SW_SYMMETRIC_FF);
664  Free(exp,N*sizeof(ulong));
665}
666
667void convFactoryPFlintMP ( const CanonicalForm & f, fmpq_mpoly_t res, fmpq_mpoly_ctx_t ctx, int N )
668{
669  if (f.isZero()) return;
670  ulong * exp = (ulong*)Alloc(N*sizeof(ulong));
671  memset(exp,0,N*sizeof(ulong));
672  convFlint_RecPP( f, exp, res, ctx, N );
673  fmpq_mpoly_reduce(res,ctx);
674  Free(exp,N*sizeof(ulong));
675}
676
677CanonicalForm convFlintMPFactoryP(nmod_mpoly_t f, nmod_mpoly_ctx_t ctx, int N)
678{
679  CanonicalForm result;
680  int d=nmod_mpoly_length(f,ctx)-1;
681  ulong* exp=(ulong*)Alloc(N*sizeof(ulong));
682  for(int i=d; i>=0; i--)
683  {
684    ulong c=nmod_mpoly_get_term_coeff_ui(f,i,ctx);
685    nmod_mpoly_get_term_exp_ui(exp,f,i,ctx);
686    CanonicalForm term=(int)c;
687    for ( int i = 0; i <N; i++ )
688    {
689      if (exp[i]!=0) term*=CanonicalForm( Variable( N-i ), exp[i] );
690    }
691    result+=term;
692  }
693  Free(exp,N*sizeof(ulong));
694  return result;
695}
696
697CanonicalForm convFlintMPFactoryP(fmpq_mpoly_t f, fmpq_mpoly_ctx_t ctx, int N)
698{
699  CanonicalForm result;
700  int d=fmpq_mpoly_length(f,ctx)-1;
701  ulong* exp=(ulong*)Alloc(N*sizeof(ulong));
702  fmpq_t c;
703  fmpq_init(c);
704  for(int i=d; i>=0; i--)
705  {
706    fmpq_mpoly_get_term_coeff_fmpq(c,f,i,ctx);
707    fmpq_mpoly_get_term_exp_ui(exp,f,i,ctx);
708    CanonicalForm term=convertFmpq_t2CF(c);
709    for ( int i = 0; i <N; i++ )
710    {
711      if (exp[i]!=0) term*=CanonicalForm( Variable( N-i ), exp[i] );
712    }
713    result+=term;
714  }
715  fmpq_clear(c);
716  Free(exp,N*sizeof(ulong));
717  return result;
718}
719
720// stolen from:
721// https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
722static inline int SI_LOG2(int v)
723{
724  const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
725  const unsigned int S[] = {1, 2, 4, 8, 16};
726
727  unsigned int r = 0; // result of log2(v) will go here
728  if (v & b[4]) { v >>= S[4]; r |= S[4]; }
729  if (v & b[3]) { v >>= S[3]; r |= S[3]; }
730  if (v & b[2]) { v >>= S[2]; r |= S[2]; }
731  if (v & b[1]) { v >>= S[1]; r |= S[1]; }
732  if (v & b[0]) { v >>= S[0]; r |= S[0]; }
733  return (int)r;
734}
735
736CanonicalForm mulFlintMP_Zp(const CanonicalForm& F,int lF, const CanonicalForm& G, int lG,int m)
737{
738  int bits=SI_LOG2(m)+1;
739  int N=F.level();
740  nmod_mpoly_ctx_t ctx;
741  nmod_mpoly_ctx_init(ctx,N,ORD_LEX,getCharacteristic());
742  nmod_mpoly_t f,g,res;
743  nmod_mpoly_init3(f,lF,bits,ctx);
744  nmod_mpoly_init3(g,lG,bits,ctx);
745  convFactoryPFlintMP(F,f,ctx,N);
746  convFactoryPFlintMP(G,g,ctx,N);
747  nmod_mpoly_init(res,ctx);
748  nmod_mpoly_mul(res,f,g,ctx);
749  nmod_mpoly_clear(g,ctx);
750  nmod_mpoly_clear(f,ctx);
751  CanonicalForm RES=convFlintMPFactoryP(res,ctx,N);
752  nmod_mpoly_clear(res,ctx);
753  nmod_mpoly_ctx_clear(ctx);
754  return RES;
755}
756
757CanonicalForm mulFlintMP_QQ(const CanonicalForm& F,int lF, const CanonicalForm& G, int lG, int m)
758{
759  int bits=SI_LOG2(m)+1;
760  int N=F.level();
761  fmpq_mpoly_ctx_t ctx;
762  fmpq_mpoly_ctx_init(ctx,N,ORD_LEX);
763  fmpq_mpoly_t f,g,res;
764  fmpq_mpoly_init3(f,lF,bits,ctx);
765  fmpq_mpoly_init3(g,lG,bits,ctx);
766  convFactoryPFlintMP(F,f,ctx,N);
767  convFactoryPFlintMP(G,g,ctx,N);
768  fmpq_mpoly_init(res,ctx);
769  fmpq_mpoly_mul(res,f,g,ctx);
770  fmpq_mpoly_clear(g,ctx);
771  fmpq_mpoly_clear(f,ctx);
772  CanonicalForm RES=convFlintMPFactoryP(res,ctx,N);
773  fmpq_mpoly_clear(res,ctx);
774  fmpq_mpoly_ctx_clear(ctx);
775  return RES;
776}
777
778CanonicalForm gcdFlintMP_Zp(const CanonicalForm& F, const CanonicalForm& G)
779{
780  int N=F.level();
781  int lf,lg,m=1<<MPOLY_MIN_BITS;
782  lf=size_maxexp(F,m);
783  lg=size_maxexp(G,m);
784  int bits=SI_LOG2(m)+1;
785  nmod_mpoly_ctx_t ctx;
786  nmod_mpoly_ctx_init(ctx,N,ORD_LEX,getCharacteristic());
787  nmod_mpoly_t f,g,res;
788  nmod_mpoly_init3(f,lf,bits,ctx);
789  nmod_mpoly_init3(g,lg,bits,ctx);
790  convFactoryPFlintMP(F,f,ctx,N);
791  convFactoryPFlintMP(G,g,ctx,N);
792  nmod_mpoly_init(res,ctx);
793  int ok=nmod_mpoly_gcd(res,f,g,ctx);
794  nmod_mpoly_clear(g,ctx);
795  nmod_mpoly_clear(f,ctx);
796  CanonicalForm RES=1;
797  if (ok)
798  {
799    RES=convFlintMPFactoryP(res,ctx,N);
800  }
801  nmod_mpoly_clear(res,ctx);
802  nmod_mpoly_ctx_clear(ctx);
803  return RES;
804}
805
806static CanonicalForm b_content ( const CanonicalForm & f )
807{
808    if ( f.inCoeffDomain() )
809        return f;
810    else
811    {
812        CanonicalForm result = 0;
813        CFIterator i;
814        for ( i = f; i.hasTerms() && (!result.isOne()); i++ )
815            result=bgcd( b_content(i.coeff()) , result );
816        return result;
817    }
818}
819
820
821CanonicalForm gcdFlintMP_QQ(const CanonicalForm& F, const CanonicalForm& G)
822{
823  int N=F.level();
824  fmpq_mpoly_ctx_t ctx;
825  fmpq_mpoly_ctx_init(ctx,N,ORD_LEX);
826  fmpq_mpoly_t f,g,res;
827  fmpq_mpoly_init(f,ctx);
828  fmpq_mpoly_init(g,ctx);
829  convFactoryPFlintMP(F,f,ctx,N);
830  convFactoryPFlintMP(G,g,ctx,N);
831  fmpq_mpoly_init(res,ctx);
832  int ok=fmpq_mpoly_gcd(res,f,g,ctx);
833  fmpq_mpoly_clear(g,ctx);
834  fmpq_mpoly_clear(f,ctx);
835  CanonicalForm RES=1;
836  if (ok)
837  {
838    // Flint normalizes the gcd to be monic.
839    // Singular wants a gcd defined over ZZ that is primitive and has a positive leading coeff.
840    if (!fmpq_mpoly_is_zero(res, ctx))
841    {
842      fmpq_t content;
843      fmpq_init(content);
844      fmpq_mpoly_content(content, res, ctx);
845      fmpq_mpoly_scalar_div_fmpq(res, res, content, ctx);
846      fmpq_clear(content);
847    }
848    RES=convFlintMPFactoryP(res,ctx,N);
849    // gcd(2x,4x) should be 2x, so RES should also have the gcd(lc(F),lc(G))
850    RES*=bgcd(b_content(F),b_content(G));
851  }
852  fmpq_mpoly_clear(res,ctx);
853  fmpq_mpoly_ctx_clear(ctx);
854  return RES;
855}
856
857#endif
858
859#endif
860
861
Note: See TracBrowser for help on using the repository browser.