source: git/factory/fac_sqrfree.cc @ c1b52b

spielwiese
Last change on this file since c1b52b was c1b52b, checked in by Hans Schoenemann <hannes@…>, 4 years ago
factory: factorize char p, univariate (w/o FLINT, w/o NTL)
  • Property mode set to 100644
File size: 4.1 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2
3
4#include "config.h"
5
6
7#include "cf_assert.h"
8
9#include "cf_defs.h"
10#include "canonicalform.h"
11#include "cf_map.h"
12#include "cf_algorithm.h"
13
14static int
15compareFactors( const CFFactor & f, const CFFactor & g )
16{
17    return f.exp() > g.exp();
18}
19
20CFFList
21sortCFFList( CFFList & F )
22{
23    F.sort( compareFactors );
24
25    int exp;
26    CanonicalForm f;
27    CFFListIterator I = F;
28    CFFList result;
29
30    // join elements with the same degree
31    while ( I.hasItem() ) {
32        f = I.getItem().factor();
33        exp = I.getItem().exp();
34        I++;
35        while ( I.hasItem() && I.getItem().exp() == exp ) {
36            f *= I.getItem().factor();
37            I++;
38        }
39        result.append( CFFactor( f, exp ) );
40    }
41
42    return result;
43}
44
45CFFList sqrFreeZ ( const CanonicalForm & a )
46{
47    if ( a.inCoeffDomain() )
48        return CFFactor( a, 1 );
49    CanonicalForm aa, LcA;
50    if (isOn (SW_RATIONAL))
51    {
52      LcA= bCommonDen (a);
53      aa= a*LcA;
54    }
55    else
56    {
57      LcA= icontent (a);
58      if (lc (a).sign() < 0)
59        LcA= -LcA;
60      aa= a/LcA;
61    }
62    CanonicalForm cont = content( aa );
63    aa /= cont;
64    CanonicalForm b = aa.deriv(), c = gcd( aa, b );
65    CanonicalForm y, z, w = aa / c;
66    int i = 1;
67    CFFList F;
68    Variable v = aa.mvar();
69    CanonicalForm lcinv;
70    while ( c.degree(v) != 0 )
71    {
72        y = gcd( w, c ); z = w / y;
73        if ( degree( z, v ) > 0 )
74        {
75          if (isOn (SW_RATIONAL))
76          {
77            lcinv= 1/Lc (z);
78            z *= lcinv;
79            z *= bCommonDen (z);
80          }
81          if (lc (z).sign() < 0)
82            z= -z;
83          F.append( CFFactor( z, i ) );
84        }
85        i++;
86        w = y; c = c / y;
87    }
88    if ( degree( w,v ) > 0 )
89    {
90      if (isOn (SW_RATIONAL))
91      {
92        lcinv= 1/Lc (w);
93        w *= lcinv;
94        w *= bCommonDen (w);
95      }
96      if (lc (w).sign() < 0)
97        w= -w;
98      F.append( CFFactor( w, i ) );
99    }
100    if ( ! cont.isOne() )
101    {
102        CFFList buf= sqrFreeZ (cont);
103        buf.removeFirst();
104        F = Union( F, buf );
105    }
106    F.insert (CFFactor (LcA, 1));
107    return F;
108}
109
110CanonicalForm
111sqrfPart (const CanonicalForm& F)
112{
113  if (F.inCoeffDomain())
114    return F;
115  CFMap M;
116  CanonicalForm A= compress (F, M);
117  CanonicalForm w, v, b;
118  CanonicalForm result;
119  int i= 1;
120  for (; i <= A.level(); i++)
121  {
122    if (!deriv (A, Variable (i)).isZero())
123      break;
124  }
125
126  w= gcd (A, deriv (A, Variable (i)));
127  b= A/w;
128  result= b;
129  if (degree (w) < 1)
130    return M (result);
131  i++;
132  for (; i <= A.level(); i++)
133  {
134    if (!deriv (w, Variable (i)).isZero())
135    {
136      b= w;
137      w= gcd (w, deriv (w, Variable (i)));
138      b /= w;
139      if (degree (b) < 1)
140        break;
141      CanonicalForm g= gcd (b, result);
142      if (degree (g) > 0)
143        result *= b/g;
144      if (degree (g) <= 0)
145        result *= b;
146    }
147  }
148  result= M (result);
149  return result;
150}
151
152#if !defined(HAVE_NTL) && !defined(HAVE_FLINT)
153static int divexp = 1;
154
155static void divexpfunc ( CanonicalForm &, int & e )
156{
157    e /= divexp;
158}
159
160CFFList sqrFreeFp ( const CanonicalForm & f )
161{
162    CanonicalForm t0 = f, t, v, w, h;
163    CanonicalForm leadcf = t0.lc();
164    Variable x = f.mvar();
165    CFFList F;
166    int p = getCharacteristic();
167    int k, e = 1;
168
169    if ( ! leadcf.isOne() )
170        t0 /= leadcf;
171
172    divexp = p;
173    while ( t0.degree(x) > 0 )
174    {
175        t = gcd( t0, t0.deriv() );
176        v = t0 / t;
177        k = 0;
178        while ( v.degree(x) > 0 )
179        {
180            k = k+1;
181            if ( k % p == 0 )
182            {
183                t /= v;
184                k = k+1;
185            }
186            w = gcd( t, v );
187            h = v / w;
188            v = w;
189            t /= v;
190            if ( h.degree(x) > 0 )
191                F.append( CFFactor( h/h.lc(), e*k ) );
192        }
193        t0 = apply( t, divexpfunc );
194        e = p * e;
195    }
196    if ( ! leadcf.isOne() )
197    {
198        if ( !F.isEmpty() && (F.getFirst().exp() == 1) )
199        {
200            leadcf = F.getFirst().factor() * leadcf;
201            F.removeFirst();
202        }
203        F.insert( CFFactor( leadcf, 1 ) );
204    }
205    return F;
206}
207#endif
Note: See TracBrowser for help on using the repository browser.