source: git/factory/facFqSquarefree.cc @ 17b1f3

spielwiese
Last change on this file since 17b1f3 was ac8e1a, checked in by Martin Lee <martinlee84@…>, 13 years ago
compiler warnings git-svn-id: file:///usr/local/Singular/svn/trunk@14267 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 5.8 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 * @internal @version \$Id$
13 *
14 **/
15/*****************************************************************************/
16
17#include <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
28static inline
29CanonicalForm
30pthRoot (const CanonicalForm & F, const int & q)
31{
32  CanonicalForm A= F;
33  int p= getCharacteristic ();
34  if (A.inCoeffDomain())
35  {
36    A= power (A, q/p);
37    return A;
38  }
39  else
40  {
41    CanonicalForm buf= 0;
42    for (CFIterator i= A; i.hasTerms(); i++)
43      buf= buf + power(A.mvar(), i.exp()/p)*pthRoot (i.coeff(), q);
44    return buf;
45  }
46}
47
48CanonicalForm
49maxpthRoot (const CanonicalForm & F, const int & q, int& l)
50{
51  CanonicalForm result= F;
52  bool derivZero= true;
53  l= 0;
54  while (derivZero)
55  {
56    for (int i= 1; i <= result.level(); i++)
57    {
58      if (!deriv (result, Variable (i)).isZero())
59      {
60        derivZero= false;
61        break;
62      }
63    }
64    if (!derivZero)
65      break;
66    result= pthRoot (result, q);
67    l++;
68  }
69  return result;
70}
71
72static inline
73CFFList
74sqrfPosDer (const CanonicalForm & F, const Variable & x, const int & k,
75            const Variable & alpha, CanonicalForm & c)
76{
77  Variable buf= alpha;
78  CanonicalForm b= deriv (F, x);
79  c= gcd (F, b);
80  CanonicalForm w= F/c;
81  CanonicalForm v= b/c;
82  CanonicalForm u= v - deriv (w, x);
83  int j= 1;
84  int p= getCharacteristic();
85  CanonicalForm g;
86  CFFList result;
87  while (j < p - 1 && degree(u) >= 0)
88  {
89    g= gcd (w, u);
90    if (degree(g) > 0)
91      result.append (CFFactor (g, j));
92    w= w/g;
93    c= c/w;
94    v= u/g;
95    u= v - deriv (w, x);
96    j++;
97  }
98  if (degree(w) > 0)
99    result.append (CFFactor (w, j));
100  return result;
101}
102
103CFFList
104squarefreeFactorization (const CanonicalForm & F, const Variable & alpha)
105{
106  int p= getCharacteristic();
107  CanonicalForm A= F;
108  CFMap M;
109  A= compress (A, M);
110  Variable x= A.mvar();
111  int l= x.level();
112  int k;
113  bool GF= false;
114  if (CFFactory::gettype() == GaloisFieldDomain)
115  {
116    k= getGFDegree();
117    GF= true;
118  }
119  if (alpha.level() != 1)
120    k= degree (getMipo (alpha));
121  else
122    k= 1;
123  Variable buf, buf2;
124  CanonicalForm tmp;
125
126  CFFList tmp1, tmp2;
127  bool found;
128  for (int i= l; i > 0; i--)
129  {
130    buf= Variable (i);
131    if (degree (deriv (A, buf)) >= 0)
132    {
133      if (GF)
134        tmp1= sqrfPosDer (A, buf, k, alpha, tmp);
135      else if (GF == false && alpha.level() != 1)
136        tmp1= sqrfPosDer (A, buf, k, alpha, tmp);
137      else
138        tmp1= sqrfPosDer (A, buf, 1, alpha, tmp);
139      A= tmp;
140      for (CFFListIterator j= tmp1; j.hasItem(); j++)
141      {
142        found= false;
143        CFFListIterator k= tmp2;
144        if (!k.hasItem()) tmp2.append (j.getItem());
145        else
146        {
147          for (; k.hasItem(); k++)
148          {
149            if (k.getItem().exp() == j.getItem().exp())
150            {
151              k.getItem()= CFFactor (k.getItem().factor()*j.getItem().factor(),
152                                     j.getItem().exp());
153              found= true;
154            }
155          }
156          if (found == false)
157            tmp2.append(j.getItem());
158        }
159      }
160    }
161  }
162
163  bool degcheck= false;;
164  for (int i= l; i > 0; i--)
165  if (degree (A, Variable(i)) >= p)
166    degcheck= true;
167
168  if (degcheck == false && tmp1.isEmpty() && tmp2.isEmpty())
169    return CFFList (CFFactor (F/Lc(F), 1));
170
171  CanonicalForm buffer= pthRoot (A, ipower (p, k));
172
173  tmp1= squarefreeFactorization (buffer, alpha);
174
175  CFFList result;
176  buf= alpha;
177  for (CFFListIterator i= tmp2; i.hasItem(); i++)
178  {
179    for (CFFListIterator j= tmp1; j.hasItem(); j++)
180    {
181      tmp= gcd (i.getItem().factor(), j.getItem().factor());
182      i.getItem()= CFFactor (i.getItem().factor()/tmp, i.getItem().exp());
183      j.getItem()= CFFactor (j.getItem().factor()/tmp, j.getItem().exp());
184      if (degree (tmp) > 0 && tmp.level() > 0)
185        result.append (CFFactor (M (tmp),
186                       j.getItem().exp()*p + i.getItem().exp()));
187    }
188  }
189  for (CFFListIterator i= tmp2; i.hasItem(); i++)
190    if (degree (i.getItem().factor()) > 0 && i.getItem().factor().level() >= 0)
191      result.append (CFFactor (M (i.getItem().factor()), i.getItem().exp()));
192  for (CFFListIterator j= tmp1; j.hasItem(); j++)
193    if (degree (j.getItem().factor()) > 0 && j.getItem().factor().level() >= 0)
194      result.append (CFFactor (M (j.getItem().factor()), j.getItem().exp()*p));
195  return result;
196}
197
198CanonicalForm
199sqrfPart (const CanonicalForm& F, CanonicalForm& pthPower,
200          const Variable& alpha)
201{
202  if (F.inCoeffDomain())
203  {
204    pthPower= 1;
205    return F;
206  }
207  CFMap M;
208  CanonicalForm A= compress (F, M);
209  Variable vBuf= alpha;
210  CanonicalForm w, v, b;
211  pthPower= 1;
212  CanonicalForm result;
213  int i= 1;
214  bool allZero= true;
215  for (; i <= A.level(); i++)
216  {
217    if (!deriv (A, Variable (i)).isZero())
218    {
219      allZero= false;
220      break;
221    }
222  }
223  if (allZero)
224  {
225    pthPower= F;
226    return 1;
227  }
228  w= gcd (A, deriv (A, Variable (i)));
229
230  b= A/w;
231  result= b;
232  if (degree (w) < 1)
233    return M (result);
234  i++;
235  for (; i <= A.level(); i++)
236  {
237    if (!deriv (w, Variable (i)).isZero())
238    {
239      b= w;
240      w= gcd (w, deriv (w, Variable (i)));
241      b /= w;
242      if (degree (b) < 1)
243        break;
244      CanonicalForm g;
245      g= gcd (b, result);
246      if (degree (g) > 0)
247        result *= b/g;
248      if (degree (g) <= 0)
249        result *= b;
250    }
251  }
252  result= M (result);
253  return result;
254}
255
Note: See TracBrowser for help on using the repository browser.