source: git/factory/FLINTconvert.cc @ fa1cd3

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