source: git/factory/FLINTconvert.cc @ a8af6a8

spielwiese
Last change on this file since a8af6a8 was edd818, checked in by Martin Lee <martinlee84@…>, 12 years ago
fix: do not add lead coeff to factorization if it's 1 fix: do not compute factorization twice
  • Property mode set to 100644
File size: 7.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#include <config.h>
16
17#include "canonicalform.h"
18#include "fac_util.h"
19#include "cf_iter.h"
20#include "cf_factory.h"
21#include "gmpext.h"
22#include "singext.h"
23#include "cf_algorithm.h"
24
25#ifdef HAVE_FLINT
26#ifdef HAVE_CSTDIO
27#include <cstdio>
28#else
29#include <stdio.h>
30#endif
31#ifdef __cplusplus
32extern "C"
33{
34#endif
35#ifndef __GMP_BITS_PER_MP_LIMB
36#define __GMP_BITS_PER_MP_LIMB GMP_LIMB_BITS
37#endif
38#include <fmpz.h>
39#include <fmpq.h>
40#include <fmpz_poly.h>
41#include <fmpz_mod_poly.h>
42#include <nmod_poly.h>
43#include <fmpq_poly.h>
44#ifdef __cplusplus
45}
46#endif
47
48#include "FLINTconvert.h"
49
50void convertCF2Fmpz (fmpz_t result, const CanonicalForm& f)
51{
52  if (f.isImm())
53    fmpz_set_si (result, f.intval());
54  else
55  {
56    mpz_t gmp_val;
57    gmp_val[0]= *getmpi(f.getval());
58    fmpz_set_mpz (result, gmp_val);
59    mpz_clear (gmp_val);
60  }
61}
62
63void convertFacCF2Fmpz_poly_t (fmpz_poly_t result, const CanonicalForm& f)
64{
65  fmpz_poly_init2 (result, degree (f)+1);
66  _fmpz_poly_set_length(result, degree(f)+1);
67  for (CFIterator i= f; i.hasTerms(); i++)
68    convertCF2Fmpz (fmpz_poly_get_coeff_ptr(result, i.exp()), i.coeff());
69}
70
71CanonicalForm convertFmpz2CF (fmpz_t coefficient)
72{
73  if (fmpz_cmp_si (coefficient, MINIMMEDIATE) >= 0 && fmpz_cmp_si (coefficient, MAXIMMEDIATE) <= 0) //this should work with flint 2.3 now
74  {
75    long coeff= fmpz_get_si (coefficient);
76    return CanonicalForm (coeff);
77  }
78  else
79  {
80    mpz_t gmp_val;
81    mpz_init (gmp_val);
82    fmpz_get_mpz (gmp_val, coefficient);
83    CanonicalForm result= CanonicalForm (CFFactory::basic (gmp_val));
84    return result;
85  }
86
87  /*mpz_t gmp_val;
88  mpz_init (gmp_val);
89  fmpz_get_mpz (gmp_val, coefficient); //TODO fmpz_fits_si
90  if (mpz_is_imm (gmp_val)) //TODO for long
91  {
92    long coeff= mpz_get_si (gmp_val);
93    mpz_clear (gmp_val);
94    return CanonicalForm (coeff);
95  }
96
97  CanonicalForm result= CanonicalForm (CFFactory::basic (gmp_val));
98  return result;*/
99}
100
101CanonicalForm convertFmpz_poly_t2FacCF (fmpz_poly_t poly, const Variable& x)
102{
103  CanonicalForm result= 0;
104  fmpz* coeff;
105  for (int i= 0; i < fmpz_poly_length (poly); i++)
106  {
107    coeff= fmpz_poly_get_coeff_ptr (poly, i);
108    if (!fmpz_is_zero (coeff))
109      result += convertFmpz2CF (coeff)*power (x,i);
110  }
111  return result;
112}
113
114void convertFacCF2nmod_poly_t (nmod_poly_t result, const CanonicalForm& f)
115{
116  bool save_sym_ff= isOn (SW_SYMMETRIC_FF);
117  if (save_sym_ff) Off (SW_SYMMETRIC_FF);
118  nmod_poly_init2 (result, getCharacteristic(), degree (f)+1);
119  for (CFIterator i= f; i.hasTerms(); i++)
120  {
121    CanonicalForm c= i.coeff();
122    if (!c.isImm()) c.mapinto(); //c%= getCharacteristic();
123    if (!c.isImm())
124    {  //This case will never happen if the characteristic is in fact a prime
125       // number, since all coefficients are represented as immediates
126       printf("convertCF2nmod_poly_t: coefficient not immediate!, char=%d\n",
127              getCharacteristic());
128    }
129    else
130      nmod_poly_set_coeff_ui (result, i.exp(), c.intval());
131  }
132  if (save_sym_ff) On (SW_SYMMETRIC_FF);
133}
134
135CanonicalForm convertnmod_poly_t2FacCF (nmod_poly_t poly, const Variable& x)
136{
137  CanonicalForm result= 0;
138  for (int i= 0; i < nmod_poly_length (poly); i++)
139  {
140    ulong coeff= nmod_poly_get_coeff_ui (poly, i);
141    if (!coeff == 0)
142      result += CanonicalForm (coeff)*power (x,i);
143  }
144  return result;
145}
146
147void convertCF2Fmpq (fmpq_t result, const CanonicalForm& f) //TODO wie oben bei CF2Fmpz
148{
149  ASSERT (isOn (SW_RATIONAL), "expected rational");
150  fmpz_t tmp1, tmp2;
151  fmpz_init (tmp1);
152  fmpz_init (tmp2);
153  if (f.isImm ())
154  {
155    fmpz_set_si (tmp1, f.num().intval());
156    fmpz_set_si (tmp2, f.den().intval());
157  }
158  else
159  {
160    mpz_t gmp_val;
161    gmp_numerator (f, gmp_val);
162    fmpz_set_mpz (tmp1, gmp_val);
163    mpz_clear (gmp_val);
164    gmp_denominator (f, gmp_val);
165    fmpz_set_mpz (tmp2, gmp_val);
166    mpz_clear (gmp_val);
167  }
168
169  fmpz_set (fmpq_numref (result), tmp1);
170  fmpz_set (fmpq_denref (result), tmp2);
171  fmpz_clear (tmp1);
172  fmpz_clear (tmp2);
173}
174
175CanonicalForm convertFmpq_t2CF (const fmpq_t q)
176{
177  ASSERT (isOn (SW_RATIONAL), "expected rational");
178  //TODO as for Fmpz check first if num and den are immediate
179
180  CanonicalForm num, den;
181  mpz_t nnum, nden;
182  mpz_init (nnum);
183  mpz_init (nden);
184  fmpz_get_mpz (nnum, fmpq_numref (q));
185  fmpz_get_mpz (nden, fmpq_denref (q));
186
187  if (mpz_is_imm (nnum) && mpz_is_imm (nden))
188  {
189    num= CanonicalForm (mpz_get_si(nnum));
190    den= CanonicalForm (mpz_get_si(nden));
191    mpz_clear (nnum);
192    mpz_clear (nden);
193    return num/den;
194  }
195  else
196    return make_cf (nnum, nden, false);
197}
198
199CanonicalForm convertFmpq_poly_t2FacCF (fmpq_poly_t p, const Variable& x)
200{
201#if 0
202  ASSERT (isOn (SW_RATIONAL), "expected poly over Q");
203  CanonicalForm den= convertFmpz2CF (fmpq_poly_denref (p));
204  fmpz_poly_t FLINTnum;
205  long n= fmpq_poly_length (p);
206  fmpz_poly_init2 (FLINTnum, fmpq_poly_length (p));
207
208  for (long i= 0; i < n; i++)
209    fmpz_set (FLINTnum->coeffs + i,fmpq_poly_numref (p) + i);
210  _fmpz_poly_set_length (FLINTnum, n);
211  CanonicalForm result= convertFmpz_poly_t2FacCF (FLINTnum, x);
212  fmpz_poly_clear (FLINTnum);
213  return result/den;
214#else
215  CanonicalForm result= 0;
216  fmpq_t coeff;
217  long n= fmpq_poly_length (p);
218  for (long i= 0; i < n; i++)
219  {
220    fmpq_init (coeff);
221    fmpq_poly_get_coeff_fmpq (coeff, p, i);
222    if (fmpq_is_zero (coeff))
223    {
224      fmpq_clear (coeff);
225      continue;
226    }
227    result += convertFmpq_t2CF (coeff)*power (x, i);
228    fmpq_clear (coeff);
229  }
230  return result;
231#endif
232}
233
234void convertFacCF2Fmpz_array (fmpz* result, const CanonicalForm& f)
235{
236  for (CFIterator i= f; i.hasTerms(); i++)
237    convertCF2Fmpz (&result[i.exp()], i.coeff());
238}
239
240//TODO multiply by bCommonDen and convertFacCF2Fmpz_poly_t
241void convertFacCF2Fmpq_poly_t (fmpq_poly_t result, const CanonicalForm& f)
242{
243  ASSERT (isOn (SW_RATIONAL), "expected poly over Q");
244
245  fmpq_poly_init2 (result, degree (f)+1);
246  _fmpq_poly_set_length (result, degree (f) + 1);
247  CanonicalForm den= bCommonDen (f);
248  convertFacCF2Fmpz_array (fmpq_poly_numref (result), f*den);
249  convertCF2Fmpz (fmpq_poly_denref (result), den);
250  /*fmpq_t coeff;
251  for (CFIterator i= f; i.hasTerms(); i++)
252  {
253    fmpq_init (coeff);
254    convertCF2Fmpq (coeff, i.coeff());
255    fmpq_poly_set_coeff_fmpq (result, i.exp(), coeff);
256    fmpq_clear (coeff);
257  }*/
258}
259
260CFFList
261convertFLINTnmod_poly_factor2FacCFFList (nmod_poly_factor_t fac,
262                                          mp_limb_t leadingCoeff,
263                                          const Variable& x
264                                         )
265{
266  CFFList result;
267  if (leadingCoeff != 1)
268    result.insert (CFFactor (CanonicalForm ((long) leadingCoeff), 1));
269
270  long i;
271
272  for (i = 0; i < fac->num_factors; i++)
273    result.append (CFFactor (convertnmod_poly_t2FacCF ((nmod_poly_t &)fac->factors[i],x),
274                             fac->exponents[i]));
275  return result;
276}
277
278void
279convertFacCF2Fmpz_mod_poly_t (fmpz_mod_poly_t result, const CanonicalForm& f,
280                              const fmpz_t p)
281{
282  fmpz_mod_poly_init2 (result, p, degree (f) + 1);
283  fmpz_poly_t buf;
284  convertFacCF2Fmpz_poly_t (buf, f);
285  fmpz_mod_poly_set_fmpz_poly (result, buf);
286  fmpz_poly_clear (buf);
287}
288
289CanonicalForm
290convertFmpz_mod_poly_t2FacCF (fmpz_mod_poly_t poly, const Variable& x,
291                              const modpk& b)
292{
293  fmpz_poly_t buf;
294  fmpz_poly_init (buf);
295  fmpz_mod_poly_get_fmpz_poly (buf, poly);
296  CanonicalForm result= convertFmpz_poly_t2FacCF (buf, x);
297  fmpz_poly_clear (buf);
298  return b (result);
299}
300
301#endif
302
303
Note: See TracBrowser for help on using the repository browser.