source: git/factory/facFqSquarefree.cc @ 1101a8

spielwiese
Last change on this file since 1101a8 was 16f511, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Fixed the usage of "config.h" (if defined HAVE_CONFIG_H)
  • Property mode set to 100644
File size: 6.5 KB
Line 
1/*****************************************************************************\
2 * Computer Algebra System SINGULAR
3\*****************************************************************************/
4/** @file facFqSquarefree.cc
5 *
6 * This file provides functions for squarefrees factorizing over
7 * \f$ F_{p} \f$ , \f$ F_{p}(\alpha ) \f$ or GF, as decribed in "Factoring
8 * multivariate polynomials over a finite field" by L. Bernardin
9 *
10 * @author Martin Lee
11 *
12 **/
13/*****************************************************************************/
14
15#ifdef HAVE_CONFIG_H
16#include "config.h"
17#endif /* HAVE_CONFIG_H */
18
19#include "canonicalform.h"
20
21#include "cf_gcd_smallp.h"
22#include "cf_iter.h"
23#include "cf_map.h"
24#include "cf_util.h"
25#include "cf_factory.h"
26#include "facFqSquarefree.h"
27
28#ifdef HAVE_NTL
29#include "NTLconvert.h"
30#endif
31
32static inline
33CanonicalForm
34pthRoot (const CanonicalForm & F, const int & q)
35{
36  CanonicalForm A= F;
37  int p= getCharacteristic ();
38  if (A.inCoeffDomain())
39  {
40    A= power (A, q/p);
41    return A;
42  }
43  else
44  {
45    CanonicalForm buf= 0;
46    for (CFIterator i= A; i.hasTerms(); i++)
47      buf= buf + power(A.mvar(), i.exp()/p)*pthRoot (i.coeff(), q);
48    return buf;
49  }
50}
51
52#ifdef HAVE_NTL
53CanonicalForm
54pthRoot (const CanonicalForm & F, const ZZ& q, const Variable& alpha)
55{
56  CanonicalForm A= F;
57  int p= getCharacteristic ();
58  if (A.inCoeffDomain())
59  {
60    zz_p::init (p);
61    zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
62    zz_pE::init (NTLMipo);
63    zz_pX NTLA= convertFacCF2NTLzzpX (A);
64    zz_pE NTLA2= to_zz_pE (NTLA);
65    power (NTLA2, NTLA2, q/p);
66    A= convertNTLzzpE2CF (NTLA2, alpha);
67    return A;
68  }
69  else
70  {
71    CanonicalForm buf= 0;
72    for (CFIterator i= A; i.hasTerms(); i++)
73      buf= buf + power(A.mvar(), i.exp()/p)*pthRoot (i.coeff(), q, alpha);
74    return buf;
75  }
76}
77#endif
78
79CanonicalForm
80maxpthRoot (const CanonicalForm & F, const int & q, int& l)
81{
82  CanonicalForm result= F;
83  bool derivZero= true;
84  l= 0;
85  while (derivZero)
86  {
87    for (int i= 1; i <= result.level(); i++)
88    {
89      if (!deriv (result, Variable (i)).isZero())
90      {
91        derivZero= false;
92        break;
93      }
94    }
95    if (!derivZero)
96      break;
97    result= pthRoot (result, q);
98    l++;
99  }
100  return result;
101}
102
103static inline
104CFFList
105sqrfPosDer (const CanonicalForm & F, const Variable & x,
106            CanonicalForm & c)
107{
108  CanonicalForm b= deriv (F, x);
109  c= gcd (F, b);
110  CanonicalForm w= F/c;
111  CanonicalForm v= b/c;
112  CanonicalForm u= v - deriv (w, x);
113  int j= 1;
114  int p= getCharacteristic();
115  CanonicalForm g;
116  CFFList result;
117  while (j < p - 1 && degree(u) >= 0)
118  {
119    g= gcd (w, u);
120    if (!g.inCoeffDomain())
121      result.append (CFFactor (g, j));
122    w= w/g;
123    c= c/w;
124    v= u/g;
125    u= v - deriv (w, x);
126    j++;
127  }
128  if (!w.inCoeffDomain())
129    result.append (CFFactor (w, j));
130  return result;
131}
132
133CFFList
134squarefreeFactorization (const CanonicalForm & F, const Variable & alpha)
135{
136  int p= getCharacteristic();
137  CanonicalForm A= F;
138  CFMap M;
139  A= compress (A, M);
140  Variable x= A.mvar();
141  int l= x.level();
142  int k;
143  if (CFFactory::gettype() == GaloisFieldDomain)
144    k= getGFDegree();
145  else if (alpha.level() != 1)
146    k= degree (getMipo (alpha));
147  else
148    k= 1;
149  Variable buf, buf2;
150  CanonicalForm tmp;
151
152  CFFList tmp1, tmp2;
153  bool found;
154  for (int i= l; i > 0; i--)
155  {
156    buf= Variable (i);
157    if (degree (deriv (A, buf)) >= 0)
158    {
159      tmp1= sqrfPosDer (A, buf, tmp);
160      A= tmp;
161      for (CFFListIterator j= tmp1; j.hasItem(); j++)
162      {
163        found= false;
164        CFFListIterator k= tmp2;
165        if (!k.hasItem() && !j.getItem().factor().inCoeffDomain()) tmp2.append (j.getItem());
166        else
167        {
168          for (; k.hasItem(); k++)
169          {
170            if (k.getItem().exp() == j.getItem().exp())
171            {
172              k.getItem()= CFFactor (k.getItem().factor()*j.getItem().factor(),
173                                     j.getItem().exp());
174              found= true;
175            }
176          }
177          if (found == false && !j.getItem().factor().inCoeffDomain())
178            tmp2.append(j.getItem());
179        }
180      }
181    }
182  }
183
184  bool degcheck= false;;
185  for (int i= l; i > 0; i--)
186  if (degree (A, Variable(i)) >= p)
187    degcheck= true;
188
189  if (degcheck == false && tmp1.isEmpty() && tmp2.isEmpty())
190    return CFFList (CFFactor (F/Lc(F), 1));
191
192  CanonicalForm buffer;
193#ifdef HAVE_NTL
194  if (alpha.level() == 1)
195#endif
196    buffer= pthRoot (A, ipower (p, k));
197#ifdef HAVE_NTL
198  else
199  {
200    ZZ q;
201    power (q, p, k);
202    buffer= pthRoot (A, q, alpha);
203  }
204#endif
205
206  tmp1= squarefreeFactorization (buffer, alpha);
207
208  CFFList result;
209  buf= alpha;
210  for (CFFListIterator i= tmp2; i.hasItem(); i++)
211  {
212    for (CFFListIterator j= tmp1; j.hasItem(); j++)
213    {
214      tmp= gcd (i.getItem().factor(), j.getItem().factor());
215      i.getItem()= CFFactor (i.getItem().factor()/tmp, i.getItem().exp());
216      j.getItem()= CFFactor (j.getItem().factor()/tmp, j.getItem().exp());
217      if (!tmp.inCoeffDomain())
218      {
219        tmp= M (tmp);
220        result.append (CFFactor (tmp/Lc(tmp),
221                       j.getItem().exp()*p + i.getItem().exp()));
222      }
223    }
224  }
225  for (CFFListIterator i= tmp2; i.hasItem(); i++)
226  {
227    if (!i.getItem().factor().inCoeffDomain())
228    {
229      tmp= M (i.getItem().factor());
230      result.append (CFFactor (tmp/Lc(tmp), i.getItem().exp()));
231    }
232  }
233  for (CFFListIterator j= tmp1; j.hasItem(); j++)
234  {
235    if (!j.getItem().factor().inCoeffDomain())
236    {
237      tmp= M (j.getItem().factor());
238      result.append (CFFactor (tmp/Lc(tmp), j.getItem().exp()*p));
239    }
240  }
241  return result;
242}
243
244CanonicalForm
245sqrfPart (const CanonicalForm& F, CanonicalForm& pthPower,
246          const Variable& alpha)
247{
248  if (F.inCoeffDomain())
249  {
250    pthPower= 1;
251    return F;
252  }
253  CFMap M;
254  CanonicalForm A= compress (F, M);
255  Variable vBuf= alpha;
256  CanonicalForm w, v, b;
257  pthPower= 1;
258  CanonicalForm result;
259  int i= 1;
260  bool allZero= true;
261  for (; i <= A.level(); i++)
262  {
263    if (!deriv (A, Variable (i)).isZero())
264    {
265      allZero= false;
266      break;
267    }
268  }
269  if (allZero)
270  {
271    pthPower= F;
272    return 1;
273  }
274  w= gcd (A, deriv (A, Variable (i)));
275
276  b= A/w;
277  result= b;
278  if (degree (w) < 1)
279    return M (result);
280  i++;
281  for (; i <= A.level(); i++)
282  {
283    if (!deriv (w, Variable (i)).isZero())
284    {
285      b= w;
286      w= gcd (w, deriv (w, Variable (i)));
287      b /= w;
288      if (degree (b) < 1)
289        break;
290      CanonicalForm g;
291      g= gcd (b, result);
292      if (degree (g) > 0)
293        result *= b/g;
294      if (degree (g) <= 0)
295        result *= b;
296    }
297  }
298  result= M (result);
299  return result;
300}
301
Note: See TracBrowser for help on using the repository browser.