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

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