source: git/factory/FLINTconvert.cc @ ba9e24

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