source: git/factory/facAlgExt.cc @ 6ea864

spielwiese
Last change on this file since 6ea864 was 6ea864, checked in by Martin Lee <martinlee84@…>, 11 years ago
chg: faster recovery of factors in univariate factorization over Q(a)
  • Property mode set to 100644
File size: 5.4 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#include "config.h"
18
19#include "cf_assert.h"
20#include "debug.h"
21#include "timing.h"
22
23#include "canonicalform.h"
24#include "cf_random.h"
25#include "cf_algorithm.h"
26#include "facFqBivarUtil.h"
27#include "facAlgExt.h"
28#include "cfModResultant.h"
29#include "fac_sqrfree.h"
30
31TIMING_DEFINE_PRINT(fac_alg_resultant)
32TIMING_DEFINE_PRINT(fac_alg_norm)
33TIMING_DEFINE_PRINT(fac_alg_factor_norm)
34TIMING_DEFINE_PRINT(fac_alg_gcd)
35TIMING_DEFINE_PRINT(fac_alg_sqrf)
36TIMING_DEFINE_PRINT(fac_alg_factor_sqrf)
37
38// squarefree part of F
39CanonicalForm
40uniSqrfPart (const CanonicalForm& F)
41{
42  ASSERT (F.isUnivariate(), "univariate input expected");
43  ASSERT (getCharacteristic() == 0, "characteristic 0 expected");
44  CanonicalForm G= deriv (F, F.mvar());
45  G= gcd (F, G);
46  return F/G;
47}
48
49// i is an integer such that Norm (F (x-i*alpha)) is squarefree
50CanonicalForm sqrfNorm (const CanonicalForm& F, const Variable& alpha, int& i)
51{
52  Variable x= Variable (F.level() + 1);
53  Variable y= F.mvar();
54  CanonicalForm g= F (x, alpha);
55  CanonicalForm mipo= getMipo (alpha);
56  mipo= mipo (x, alpha);
57  mipo *= bCommonDen (mipo);
58
59  int degg= degree (g);
60  int degmipo= degree (mipo);
61  CanonicalForm norm;
62  TIMING_START (fac_alg_resultant);
63  if (degg >= 8 || degmipo >= 8)
64    norm= resultantZ (g, mipo, x);
65  else
66    norm= resultant (g, mipo, x);
67  TIMING_END_AND_PRINT (fac_alg_resultant, "time to compute resultant0: ");
68
69  i= 0;
70  int k;
71  if (degree (gcd (deriv (norm, y), norm)) <= 0)
72    return norm;
73  i= 1;
74  do
75  {
76    k= 1;
77    while (k < 3)
78    {
79      if (k == 1)
80      {
81        g= F (y - i*alpha, y);
82        g *= bCommonDen (g);
83        TIMING_START (fac_alg_resultant);
84        if (degg >= 8 || degmipo >= 8)
85          norm= resultantZ (g (x, alpha), mipo, x);
86        else
87          norm= resultant (g (x, alpha), mipo, x);
88        TIMING_END_AND_PRINT (fac_alg_resultant,"time to compute resultant1: ");
89      }
90      else
91      {
92        g= F (y + i*alpha, y);
93        g *= bCommonDen (g);
94        TIMING_START (fac_alg_resultant);
95        if (degg >= 8 || degmipo >= 8)
96          norm= resultantZ (g (x, alpha), mipo, x);
97        else
98          norm= resultant (g (x, alpha), mipo, x);
99        TIMING_END_AND_PRINT (fac_alg_resultant,"time to compute resultant2: ");
100      }
101      if (degree (gcd (deriv (norm, y), norm)) <= 0)
102      {
103        if (k == 2)
104          i= -i;
105        return norm;
106      }
107      k++;
108    }
109    i++;
110  } while (1);
111}
112
113CFList
114AlgExtSqrfFactorize (const CanonicalForm& F, const Variable& alpha)
115{
116  ASSERT (F.isUnivariate(), "univariate input expected");
117  ASSERT (getCharacteristic() == 0, "characteristic 0 expected");
118
119  bool save_rat=!isOn (SW_RATIONAL);
120  On (SW_RATIONAL);
121  CanonicalForm f= F*bCommonDen (F);
122  int shift;
123  TIMING_START (fac_alg_norm);
124  CanonicalForm norm= sqrfNorm (f, alpha, shift);
125  TIMING_END_AND_PRINT (fac_alg_norm, "time to compute sqrf norm: ");
126  ASSERT (degree (norm, alpha) <= 0, "wrong norm computed");
127  TIMING_START (fac_alg_factor_norm);
128  CFFList normFactors= factorize (norm);
129  TIMING_END_AND_PRINT (fac_alg_factor_norm, "time to factor norm: ");
130  CFList factors;
131  if (normFactors.length() <= 2)
132  {
133    if (save_rat) Off(SW_RATIONAL);
134    return CFList (F);
135  }
136
137  normFactors.removeFirst();
138  CanonicalForm buf;
139  buf= f;
140  CanonicalForm factor;
141  int count= 0;
142  for (CFFListIterator i= normFactors; i.hasItem(); i++)
143  {
144    ASSERT (i.getItem().exp() == 1, "norm not squarefree");
145    TIMING_START (fac_alg_gcd);
146    if (shift == 0)
147      factor= gcd (buf, i.getItem().factor());
148    else
149      factor= gcd (buf, i.getItem().factor() (f.mvar() + shift*alpha, f.mvar()));
150    buf /= factor;
151    TIMING_END_AND_PRINT (fac_alg_gcd, "time to recover factors: ");
152    factors.append (factor);
153    count++;
154    if (normFactors.length() - 1 == count)
155    {
156      factors.append (buf);
157      buf= 1;
158      break;
159    }
160  }
161  ASSERT (degree (buf) <= 0, "incomplete factorization");
162  if (save_rat) Off(SW_RATIONAL);
163  return factors;
164}
165
166CFFList
167AlgExtFactorize (const CanonicalForm& F, const Variable& alpha)
168{
169  ASSERT (F.isUnivariate(), "univariate input expected");
170  ASSERT (getCharacteristic() == 0, "characteristic 0 expected");
171
172
173  if (F.inCoeffDomain())
174    return CFFList (CFFactor (F, 1));
175
176  bool save_rat=!isOn (SW_RATIONAL);
177  On (SW_RATIONAL);
178  TIMING_START (fac_alg_sqrf);
179  CFFList sqrf= sqrFreeZ (F);
180  TIMING_END_AND_PRINT (fac_alg_sqrf, "time for sqrf factors in Q(a)[x]: ");
181  CFList factorsSqrf;
182  CFFList factors;
183  CFListIterator j;
184
185  CanonicalForm lcinv;
186  for (CFFListIterator i= sqrf; i.hasItem(); i++)
187  {
188    if (i.getItem().factor().inCoeffDomain()) continue;
189    TIMING_START (fac_alg_factor_sqrf);
190    factorsSqrf= AlgExtSqrfFactorize (i.getItem().factor(), alpha);
191    TIMING_END_AND_PRINT (fac_alg_factor_sqrf,
192                          "time to factor sqrf factors in Q(a)[x]: ");
193    for (j= factorsSqrf; j.hasItem(); j++)
194    {
195      lcinv= 1/Lc (j.getItem());
196      factors.append (CFFactor (j.getItem()*lcinv, i.getItem().exp()));
197    }
198  }
199
200  factors.insert (CFFactor (Lc(F), 1));
201  if (save_rat) Off(SW_RATIONAL);
202  return factors;
203}
204
Note: See TracBrowser for help on using the repository browser.