source: git/factory/facFqSquarefree.cc @ 99bdcf

fieker-DuValspielwiese
Last change on this file since 99bdcf was 963057, checked in by Martin Lee <martinlee84@…>, 14 years ago
more syntax fixes and bug fix in uni gcd git-svn-id: file:///usr/local/Singular/svn/trunk@12896 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 7.0 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  bool GF= (CFFactory::gettype() == GaloisFieldDomain);
80  if (GF) 
81    c= GCD_GF (F, b);
82  else if (GF == false && k != 1) 
83    c= GCD_Fp_extension (F, b, buf);
84  else 
85    c= GCD_small_p (F, b);
86  CanonicalForm w= F/c;
87  CanonicalForm v= b/c;
88  CanonicalForm u= v - deriv (w, x);
89  int j= 1;
90  int p= getCharacteristic();
91  CanonicalForm g;
92  CFFList result;
93  while (j < p - 1 && degree(u) >= 0) 
94  {
95    if (GF) 
96      g= GCD_GF (w, u);
97    else if (GF == false && k != 1)
98      g= GCD_Fp_extension (w, u, buf); 
99    else 
100      g= GCD_small_p (w, u);
101    if (degree(g) > 0) 
102      result.append (CFFactor (g, j));
103    w= w/g;
104    c= c/w;
105    v= u/g;
106    u= v - deriv (w, x);
107    j++;
108  }
109  if (degree(w) > 0)
110    result.append (CFFactor (w, j));
111  return result;
112}
113
114CFFList
115squarefreeFactorization (const CanonicalForm & F, const Variable & alpha) 
116{
117  int p= getCharacteristic();
118  CanonicalForm A= F;
119  CFMap M;
120  A= compress (A, M);
121  Variable x= A.mvar();
122  int l= x.level();
123  int k;
124  bool GF= false;
125  if (CFFactory::gettype() == GaloisFieldDomain) 
126  {
127    k= getGFDegree();
128    GF= true;
129  }
130  if (alpha != Variable(1)) 
131    k= degree (getMipo (alpha));
132  else 
133    k= 1;
134  Variable buf, buf2;
135  CanonicalForm tmp;
136
137  CFFList tmp1, tmp2;
138  bool found;
139  for (int i= l; i > 0; i--) 
140  {
141    buf= Variable (i);
142    if (degree (deriv (A, buf)) >= 0) 
143    {
144      if (GF)
145        tmp1= sqrfPosDer (A, buf, k, alpha, tmp);
146      else if (GF == false && alpha != Variable(1)) 
147        tmp1= sqrfPosDer (A, buf, k, alpha, tmp);
148      else 
149        tmp1= sqrfPosDer (A, buf, 1, alpha, tmp);
150      A= tmp; 
151      for (CFFListIterator j= tmp1; j.hasItem(); j++) 
152      {
153        found= false;
154        CFFListIterator k= tmp2;
155        if (!k.hasItem()) tmp2.append (j.getItem());
156        else 
157        { 
158          for (; k.hasItem(); k++) 
159          {
160            if (k.getItem().exp() == j.getItem().exp()) 
161            {
162              k.getItem()= CFFactor (k.getItem().factor()*j.getItem().factor(), 
163                                     j.getItem().exp());
164              found= true;
165            }
166          }
167          if (found == false)
168            tmp2.append(j.getItem());
169        }
170      }
171    }
172  }
173
174  bool degcheck= false;;
175  for (int i= l; i > 0; i--)
176  if (degree (A, Variable(i)) >= p)
177    degcheck= true;
178
179  if (degcheck == false && tmp1.isEmpty() && tmp2.isEmpty())
180    return CFFList (CFFactor (F/Lc(F), 1));
181
182  CanonicalForm buffer= pthRoot (A, ipower (p, k));
183
184  tmp1= squarefreeFactorization (buffer, alpha);
185
186  CFFList result; 
187  buf= alpha;
188  for (CFFListIterator i= tmp2; i.hasItem(); i++) 
189  {
190    for (CFFListIterator j= tmp1; j.hasItem(); j++) 
191    {
192      if (GF)
193        tmp= GCD_GF (i.getItem().factor(), j.getItem().factor());     
194      else if (GF == false && buf == Variable (1)) 
195        tmp= GCD_small_p (i.getItem().factor(), j.getItem().factor()); 
196      else 
197        tmp= GCD_Fp_extension (i.getItem().factor(),j.getItem().factor(),buf);
198      i.getItem()= CFFactor (i.getItem().factor()/tmp, i.getItem().exp());
199      j.getItem()= CFFactor (j.getItem().factor()/tmp, j.getItem().exp());
200      if (degree (tmp) > 0 && tmp.level() > 0)
201        result.append (CFFactor (M (tmp), 
202                       j.getItem().exp()*p + i.getItem().exp()));   
203    }
204  }
205  for (CFFListIterator i= tmp2; i.hasItem(); i++)
206    if (degree (i.getItem().factor()) > 0 && i.getItem().factor().level() >= 0)
207      result.append (CFFactor (M (i.getItem().factor()), i.getItem().exp()));
208  for (CFFListIterator j= tmp1; j.hasItem(); j++)
209    if (degree (j.getItem().factor()) > 0 && j.getItem().factor().level() >= 0)
210      result.append (CFFactor (M (j.getItem().factor()), j.getItem().exp()*p));
211  return result; 
212}
213
214CanonicalForm
215sqrfPart (const CanonicalForm& F, CanonicalForm& pthPower, 
216          const Variable& alpha)
217{
218  if (F.inCoeffDomain())
219  {
220    pthPower= 1;
221    return F;
222  }
223  CFMap M;
224  CanonicalForm A= compress (F, M);
225  Variable vBuf= alpha;
226  CanonicalForm w, v, b;
227  pthPower= 1;
228  CanonicalForm result;
229  int i= 1;
230  bool GF= (CFFactory::gettype() == GaloisFieldDomain);
231  bool allZero= true;
232  for (; i <= A.level(); i++)
233  {
234    if (!deriv (A, Variable (i)).isZero())
235    {
236      allZero= false;
237      break;
238    } 
239  }
240  if (allZero)
241  {
242    pthPower= F;
243    return 1;
244  }
245  if (GF)
246    w= GCD_GF (A, deriv (A, Variable (i)));
247  else if (GF == false && alpha == Variable (1))
248    w= GCD_small_p (A, deriv (A, Variable (i)));
249  else 
250    w= GCD_Fp_extension (A, deriv (A, Variable (i)), vBuf);
251
252  b= A/w;
253  result= b;
254  if (degree (w) < 1)
255    return M (result);
256  i++;
257  for (; i <= A.level(); i++)
258  {
259    if (!deriv (w, Variable (i)).isZero())
260    {
261      b= w;
262      if (GF)
263        w= GCD_GF (w, deriv (w, Variable (i)));
264      else if (GF == false && vBuf == Variable (1))
265        w= GCD_small_p (w, deriv (w, Variable (i)));
266      else 
267        w= GCD_Fp_extension (w, deriv (w, Variable (i)), vBuf);
268      b /= w;
269      if (degree (b) < 1)
270        break;
271      CanonicalForm g;
272      if (GF)
273        g= GCD_GF (b, result);
274      else if (GF == false && vBuf == Variable (1))
275        g= GCD_small_p (b, result);
276      else 
277        g= GCD_Fp_extension (b, result, vBuf);
278      if (degree (g) > 0)
279        result *= b/g;
280      if (degree (g) <= 0)
281        result *= b;
282    }
283  }
284  result= M (result);
285  return result;
286}
287
Note: See TracBrowser for help on using the repository browser.