source: git/factory/FLINTconvert.cc @ 55b50e3

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