source: git/factory/facAlgExt.cc @ f5d2647

spielwiese
Last change on this file since f5d2647 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.2 KB
Line 
1// -*- c++ -*-
2//*****************************************************************************
3/** @file facAlgExt.cc
4 *
5 * @author Martin Lee
6 * @date
7 *
8 * Univariate factorization over algebraic extension of Q using Trager's
9 * algorithm
10 *
11 * @par Copyright:
12 *   (c) by The SINGULAR Team, see LICENSE file
13 *
14**/
15//*****************************************************************************
16
17#ifdef HAVE_CONFIG_H
18#include "config.h"
19#endif /* HAVE_CONFIG_H */
20
21#include "cf_assert.h"
22#include "debug.h"
23#include "timing.h"
24
25#include "canonicalform.h"
26#include "cf_random.h"
27#include "cf_algorithm.h"
28#include "facFqBivarUtil.h"
29#include "facAlgExt.h"
30#include "cfModResultant.h"
31#include "fac_sqrfree.h"
32
33TIMING_DEFINE_PRINT(fac_alg_resultant)
34TIMING_DEFINE_PRINT(fac_alg_norm)
35TIMING_DEFINE_PRINT(fac_alg_factor_norm)
36TIMING_DEFINE_PRINT(fac_alg_gcd)
37TIMING_DEFINE_PRINT(fac_alg_sqrf)
38TIMING_DEFINE_PRINT(fac_alg_factor_sqrf)
39TIMING_DEFINE_PRINT(fac_alg_time_shift)
40
41// squarefree part of F
42CanonicalForm
43uniSqrfPart (const CanonicalForm& F)
44{
45  ASSERT (F.isUnivariate(), "univariate input expected");
46  ASSERT (getCharacteristic() == 0, "characteristic 0 expected");
47  CanonicalForm G= deriv (F, F.mvar());
48  G= gcd (F, G);
49  return F/G;
50}
51
52// i is an integer such that Norm (F (x-i*alpha)) is squarefree
53CanonicalForm sqrfNorm (const CanonicalForm& F, const Variable& alpha, int& i)
54{
55  Variable x= Variable (F.level() + 1);
56  Variable y= F.mvar();
57  CanonicalForm g= F (x, alpha);
58  CanonicalForm mipo= getMipo (alpha);
59  mipo= mipo (x, alpha);
60  mipo *= bCommonDen (mipo);
61
62  int degg= degree (g);
63  int degmipo= degree (mipo);
64  CanonicalForm norm;
65  TIMING_START (fac_alg_resultant);
66  if (degg >= 8 || degmipo >= 8)
67    norm= resultantZ (g, mipo, x);
68  else
69    norm= resultant (g, mipo, x);
70  TIMING_END_AND_PRINT (fac_alg_resultant, "time to compute resultant0: ");
71
72  i= 0;
73  int k;
74  if (degree (gcd (deriv (norm, y), norm)) <= 0)
75    return norm;
76  i= 1;
77  do
78  {
79    k= 1;
80    while (k < 3)
81    {
82      if (k == 1)
83      {
84        g= F (y - i*alpha, y);
85        g *= bCommonDen (g);
86        TIMING_START (fac_alg_resultant);
87        if (degg >= 8 || degmipo >= 8)
88          norm= resultantZ (g (x, alpha), mipo, x);
89        else
90          norm= resultant (g (x, alpha), mipo, x);
91        TIMING_END_AND_PRINT (fac_alg_resultant,"time to compute resultant1: ");
92      }
93      else
94      {
95        g= F (y + i*alpha, y);
96        g *= bCommonDen (g);
97        TIMING_START (fac_alg_resultant);
98        if (degg >= 8 || degmipo >= 8)
99          norm= resultantZ (g (x, alpha), mipo, x);
100        else
101          norm= resultant (g (x, alpha), mipo, x);
102        TIMING_END_AND_PRINT (fac_alg_resultant,"time to compute resultant2: ");
103      }
104      if (degree (gcd (deriv (norm, y), norm)) <= 0)
105      {
106        if (k == 2)
107          i= -i;
108        return norm;
109      }
110      k++;
111    }
112    i++;
113  } while (1);
114}
115
116CFList
117AlgExtSqrfFactorize (const CanonicalForm& F, const Variable& alpha)
118{
119  ASSERT (F.isUnivariate(), "univariate input expected");
120  ASSERT (getCharacteristic() == 0, "characteristic 0 expected");
121
122  bool save_rat=!isOn (SW_RATIONAL);
123  On (SW_RATIONAL);
124  CanonicalForm f= F*bCommonDen (F);
125  int shift;
126  TIMING_START (fac_alg_norm);
127  CanonicalForm norm= sqrfNorm (f, alpha, shift);
128  TIMING_END_AND_PRINT (fac_alg_norm, "time to compute sqrf norm: ");
129  ASSERT (degree (norm, alpha) <= 0, "wrong norm computed");
130  TIMING_START (fac_alg_factor_norm);
131  bool save_sort= !isOn (SW_USE_NTL_SORT);
132  On (SW_USE_NTL_SORT);
133  CFFList normFactors= factorize (norm);
134  if (save_sort)
135    Off (SW_USE_NTL_SORT);
136  TIMING_END_AND_PRINT (fac_alg_factor_norm, "time to factor norm: ");
137  CFList factors;
138  if (normFactors.length() <= 2)
139  {
140    if (save_rat) Off(SW_RATIONAL);
141    return CFList (F);
142  }
143
144  normFactors.removeFirst();
145  CFFListIterator i= normFactors;
146  CanonicalForm buf;
147  bool shiftBuf= false;
148  if (!(normFactors.length() == 2 && degree (i.getItem().factor()) <= degree (f)))
149  {
150    TIMING_START (fac_alg_time_shift);
151    if (shift != 0)
152      buf= f (f.mvar() - shift*alpha, f.mvar());
153    else
154      buf= f;
155    shiftBuf= true;
156    TIMING_END_AND_PRINT (fac_alg_time_shift, "time to shift: ");
157  }
158  else
159    buf= f;
160  CanonicalForm factor;
161  int count= 0;
162  for (; i.hasItem(); i++)
163  {
164    ASSERT (i.getItem().exp() == 1, "norm not squarefree");
165    TIMING_START (fac_alg_gcd);
166    if (shiftBuf)
167      factor= gcd (buf, i.getItem().factor());
168    else
169    {
170      if (shift == 0)
171        factor= gcd (buf, i.getItem().factor());
172      else
173        factor= gcd (buf, i.getItem().factor() (f.mvar() + shift*alpha, f.mvar()));
174    }
175    buf /= factor;
176    if (shiftBuf)
177    {
178      if (shift != 0)
179        factor= factor (f.mvar() + shift*alpha, f.mvar());
180    }
181    TIMING_END_AND_PRINT (fac_alg_gcd, "time to recover factors: ");
182    factors.append (factor);
183    count++;
184    if (normFactors.length() - 1 == count)
185    {
186      if (shiftBuf)
187        factors.append (buf (f.mvar() + shift*alpha, f.mvar()));
188      else
189        factors.append (buf);
190      buf= 1;
191      break;
192    }
193  }
194  ASSERT (degree (buf) <= 0, "incomplete factorization");
195  if (save_rat) Off(SW_RATIONAL);
196  return factors;
197}
198
199CFFList
200AlgExtFactorize (const CanonicalForm& F, const Variable& alpha)
201{
202  ASSERT (F.isUnivariate(), "univariate input expected");
203  ASSERT (getCharacteristic() == 0, "characteristic 0 expected");
204
205
206  if (F.inCoeffDomain())
207    return CFFList (CFFactor (F, 1));
208
209  bool save_rat=!isOn (SW_RATIONAL);
210  On (SW_RATIONAL);
211  TIMING_START (fac_alg_sqrf);
212  CFFList sqrf= sqrFreeZ (F);
213  TIMING_END_AND_PRINT (fac_alg_sqrf, "time for sqrf factors in Q(a)[x]: ");
214  CFList factorsSqrf;
215  CFFList factors;
216  CFListIterator j;
217
218  CanonicalForm lcinv;
219  for (CFFListIterator i= sqrf; i.hasItem(); i++)
220  {
221    if (i.getItem().factor().inCoeffDomain()) continue;
222    TIMING_START (fac_alg_factor_sqrf);
223    factorsSqrf= AlgExtSqrfFactorize (i.getItem().factor(), alpha);
224    TIMING_END_AND_PRINT (fac_alg_factor_sqrf,
225                          "time to factor sqrf factors in Q(a)[x]: ");
226    for (j= factorsSqrf; j.hasItem(); j++)
227    {
228      lcinv= 1/Lc (j.getItem());
229      factors.append (CFFactor (j.getItem()*lcinv, i.getItem().exp()));
230    }
231  }
232
233  factors.insert (CFFactor (Lc(F), 1));
234  if (save_rat) Off(SW_RATIONAL);
235  return factors;
236}
237
Note: See TracBrowser for help on using the repository browser.