source: git/factory/fac_absfact.cc @ b962395

spielwiese
Last change on this file since b962395 was b962395, checked in by Martin Lee <martinlee84@…>, 11 years ago
chg: deleted debug output from absfact
  • Property mode set to 100644
File size: 5.7 KB
Line 
1/*****************************************************************************\
2 * Computer Algebra System SINGULAR
3\*****************************************************************************/
4/** @file facMul.cc
5 *
6 * This file implements functions for fast multiplication and division with
7 * remainder
8 *
9 * @author Martin Lee
10 *
11 **/
12/*****************************************************************************/
13
14#include "fac_absfact.h"
15#include "cf_reval.h"
16#include "cf_primes.h"
17#include "cf_algorithm.h"
18#ifdef HAVE_FLINT
19#include "FLINTconvert.h"
20#include <flint/fmpz_poly_factor.h>
21#endif
22#ifdef HAVE_NTL
23#include "NTLconvert.h"
24#include <NTL/LLL.h>
25#endif
26
27#ifdef HAVE_FLINT
28
29int choosePoint (const CanonicalForm& F, int tdegF, CFArray& eval)
30{
31  REvaluation E1 (1, 1, IntRandom (25));
32  REvaluation E2 (2, 2, IntRandom (25));
33  //E1.nextpoint();
34  //E2.nextpoint();
35  CanonicalForm f, Fp;
36  int i;
37  eval=CFArray (2);
38  while (1)
39  {
40    f= E1(F);
41    if (!f.isZero() && factorize (f).length() == 2)
42    {
43      Off (SW_RATIONAL);
44      f= E2(f);
45      if (!f.isZero() && f > cf_getSmallPrime (cf_getNumSmallPrimes()))
46      {
47        for (i= cf_getNumPrimes()-1; i > 0; i--)
48        {
49          if (f % CanonicalForm (cf_getPrime (i)) == 0)
50          {
51            Fp= mod (F,cf_getPrime(i));
52            if (totaldegree (Fp) == tdegF)
53            {
54              eval[0]= E1[1];
55              eval[1]= E2[2];
56              return cf_getPrime(i);
57            }
58          }
59        }
60      }
61      else if (!f.isZero())
62      {
63        for (i= cf_getNumSmallPrimes()-1; i > 0; i--)
64        {
65          if (f % CanonicalForm (cf_getSmallPrime (i)) == 0)
66          {
67            Fp= mod (F,cf_getSmallPrime(i));
68            if (totaldegree (Fp) == tdegF)
69            {
70              eval[0]= E1[1];
71              eval[1]= E2[2];
72              return cf_getSmallPrime(i);
73            }
74          }
75        }
76      }
77      E2.nextpoint();
78      On (SW_RATIONAL);
79    }
80    E1.nextpoint();
81  }
82  return 0;
83}
84
85CFList absFactorize (const CanonicalForm& G)
86{
87  //F is assumed to be bivariate, irreducible over Q, primitive wrt x and y, compressed
88
89  CanonicalForm F= bCommonDen (G)*G;
90  Off (SW_RATIONAL);
91  F /= icontent (F);
92  On (SW_RATIONAL);
93  CFArray eval;
94  int minTdeg, tdegF= totaldegree (F);
95  CanonicalForm Fp, smallestFactor;
96  int p;
97  while (1)
98  {
99    p= choosePoint (F, tdegF, eval);
100
101    setCharacteristic (p);
102    Fp=F.mapinto();
103    CFFList factors= factorize (Fp);
104
105    factors.removeFirst();
106    CFFListIterator iter= factors;
107    smallestFactor= iter.getItem().factor();
108    minTdeg= totaldegree (smallestFactor);
109    iter++;
110    for (; iter.hasItem(); iter++)
111    {
112      if (totaldegree (iter.getItem().factor()) < minTdeg)
113      {
114        smallestFactor= iter.getItem().factor();
115        minTdeg= totaldegree (smallestFactor);
116      }
117    }
118    if (tdegF % minTdeg == 0)
119      break;
120    //TODO else
121  }
122  CanonicalForm Gp= Fp/smallestFactor;
123  Gp= Gp (eval[0].mapinto(), 1);
124  Fp= Fp (eval[0].mapinto(), 1);
125  CanonicalForm smallestFactorEval= smallestFactor (eval[0].mapinto(),1);
126  setCharacteristic (0);
127  CanonicalForm F1= F(eval[0],1);
128  setCharacteristic (p);
129  setCharacteristic (0);
130  int s= tdegF/minTdeg + 1;
131  CanonicalForm bound= power (maxNorm (F1), 2*(s-1));
132  bound *= power (CanonicalForm (s),s-1);
133  bound *= power (CanonicalForm (2), ((s-1)*(s-1))/2); //possible int overflow
134
135  CanonicalForm B = p;
136  long k = 1L;
137  while ( B < bound ) {
138    B *= p;
139    k++;
140  }
141
142  //TODO take floor (log2(k))
143  k= k+1;
144  fmpz_poly_t FLINTF1;
145  convertFacCF2Fmpz_poly_t (FLINTF1, F1);
146  setCharacteristic (p);
147  nmod_poly_t FLINTFp, FLINTGp;
148  convertFacCF2nmod_poly_t (FLINTFp, smallestFactorEval/lc (smallestFactorEval));
149  convertFacCF2nmod_poly_t (FLINTGp, Gp/lc (Gp));
150  nmod_poly_factor_t nmodFactors;
151  nmod_poly_factor_init (nmodFactors);
152  nmod_poly_factor_insert (nmodFactors, FLINTFp, 1L);
153  nmod_poly_factor_insert (nmodFactors, FLINTGp, 1L);
154
155  long * link= new long [2];
156  fmpz_poly_t *v= new fmpz_poly_t[2];
157  fmpz_poly_t *w= new fmpz_poly_t[2];
158  fmpz_poly_init(v[0]);
159  fmpz_poly_init(v[1]);
160  fmpz_poly_init(w[0]);
161  fmpz_poly_init(w[1]);
162
163  fmpz_poly_factor_t liftedFactors;
164  fmpz_poly_factor_init (liftedFactors);
165  _fmpz_poly_hensel_start_lift(liftedFactors, link, v, w, FLINTF1, nmodFactors, k); //lift factors up to p^k
166
167  nmod_poly_factor_clear (nmodFactors);
168  nmod_poly_clear (FLINTFp);
169  nmod_poly_clear (FLINTGp);
170
171  setCharacteristic(0);
172  modpk pk= modpk (p,k);
173  CanonicalForm liftedSmallestFactor= convertFmpz_poly_t2FacCF ((fmpz_poly_t &)liftedFactors->p[0],Variable (2));
174
175  CanonicalForm otherFactor= convertFmpz_poly_t2FacCF ((fmpz_poly_t &)liftedFactors->p[1],Variable (2));
176  CanonicalForm test= pk (otherFactor*liftedSmallestFactor);
177
178  Off (SW_SYMMETRIC_FF);
179  liftedSmallestFactor= pk (liftedSmallestFactor);
180  liftedSmallestFactor= liftedSmallestFactor (eval[1],2);
181  On (SW_SYMMETRIC_FF);
182  CFMatrix M= CFMatrix (s, s);
183  M(s,s)= power (CanonicalForm (p), k);
184  for (int i= 1; i < s; i++)
185  {
186    M (i,i)= 1;
187    M (i+1,i)= -liftedSmallestFactor;
188  }
189
190  mat_ZZ NTLM= *convertFacCFMatrix2NTLmat_ZZ (M);
191
192  ZZ det;
193
194  transpose (NTLM, NTLM);
195  long r=LLL (det, NTLM, 1L, 1L);
196  transpose (NTLM, NTLM);
197  M= *convertNTLmat_ZZ2FacCFMatrix (NTLM);
198
199  CanonicalForm mipo= 0;
200  Variable x= Variable (1);
201  for (int i= 1; i <= s; i++)
202    mipo += M (i,1)*power (x,s-i);
203
204  CFFList mipoFactors= factorize (mipo);
205  mipoFactors.removeFirst();
206  On (SW_RATIONAL);
207  Variable alpha= rootOf (mipo);
208  CFFList QaFactors= factorize (F1, alpha);
209
210  fmpz_poly_clear (v[0]);
211  fmpz_poly_clear (v[1]);
212  fmpz_poly_clear (w[0]);
213  fmpz_poly_clear (w[1]);
214  delete [] v;
215  delete [] w;
216  delete [] link;
217  fmpz_poly_factor_clear (liftedFactors);
218  return CFList();
219}
220#endif
221
222
Note: See TracBrowser for help on using the repository browser.