source: git/factory/fac_sqrfree.cc @ 16f511

spielwiese
Last change on this file since 16f511 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: 5.0 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2
3#ifdef HAVE_CONFIG_H
4#include "config.h"
5#endif /* HAVE_CONFIG_H */
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 divexp = 1;
15
16static void divexpfunc ( CanonicalForm &, int & e )
17{
18    e /= divexp;
19}
20
21static int
22compareFactors( const CFFactor & f, const CFFactor & g )
23{
24    return f.exp() > g.exp();
25}
26
27CFFList
28sortCFFList( CFFList & F )
29{
30    F.sort( compareFactors );
31
32    int exp;
33    CanonicalForm f;
34    CFFListIterator I = F;
35    CFFList result;
36
37    // join elements with the same degree
38    while ( I.hasItem() ) {
39        f = I.getItem().factor();
40        exp = I.getItem().exp();
41        I++;
42        while ( I.hasItem() && I.getItem().exp() == exp ) {
43            f *= I.getItem().factor();
44            I++;
45        }
46        result.append( CFFactor( f, exp ) );
47    }
48
49    return result;
50}
51
52CFFList sqrFreeFp ( const CanonicalForm & f )
53{
54    CanonicalForm t0 = f, t, v, w, h;
55    CanonicalForm leadcf = t0.lc();
56    Variable x = f.mvar();
57    CFFList F;
58    int p = getCharacteristic();
59    int k, e = 1;
60
61    if ( ! leadcf.isOne() )
62        t0 /= leadcf;
63
64    divexp = p;
65    while ( t0.degree(x) > 0 )
66    {
67        t = gcd( t0, t0.deriv() );
68        v = t0 / t;
69        k = 0;
70        while ( v.degree(x) > 0 )
71        {
72            k = k+1;
73            if ( k % p == 0 )
74            {
75                t /= v;
76                k = k+1;
77            }
78            w = gcd( t, v );
79            h = v / w;
80            v = w;
81            t /= v;
82            if ( h.degree(x) > 0 )
83                F.append( CFFactor( h/h.lc(), e*k ) );
84        }
85        t0 = apply( t, divexpfunc );
86        e = p * e;
87    }
88    if ( ! leadcf.isOne() )
89    {
90        if ( !F.isEmpty() && (F.getFirst().exp() == 1) )
91        {
92            leadcf = F.getFirst().factor() * leadcf;
93            F.removeFirst();
94        }
95        F.insert( CFFactor( leadcf, 1 ) );
96    }
97    return F;
98}
99
100bool isSqrFreeFp( const CanonicalForm & f )
101{
102  CFFList F = sqrFreeFp( f );
103  return ( F.length() == 1 && F.getFirst().exp() == 1 );
104}
105
106bool isSqrFreeZ ( const CanonicalForm & f )
107{
108    return gcd( f, f.deriv() ).degree() == 0;
109}
110
111/*
112
113CFFList sqrFreeZ ( const CanonicalForm & a )
114{
115    CanonicalForm b = a.deriv(), c = gcd( a, b );
116    CanonicalForm y, z, w = a / c;
117    int i = 1;
118    CFFList F;
119
120    while ( ! c.degree() == 0 )
121    {
122        y = gcd( w, c ); z = w / y;
123        if ( degree( z ) > 0 )
124            if ( lc( z ).sign() < 0 )
125                F.append( CFFactor( -z, i ) );
126            else
127                F.append( CFFactor( z, i ) );
128        i++;
129        w = y; c = c / y;
130    }
131    if ( degree( w ) > 0 )
132        if ( lc( w ).sign() < 0 )
133            F.append( CFFactor( -w, i ) );
134        else
135            F.append( CFFactor( w, i ) );
136    return F;
137}
138*/
139
140CFFList sqrFreeZ ( const CanonicalForm & a )
141{
142    if ( a.inCoeffDomain() )
143        return CFFactor( a, 1 );
144    CanonicalForm aa, LcA;
145    if (isOn (SW_RATIONAL))
146    {
147      LcA= bCommonDen (a);
148      aa= a*LcA;
149    }
150    else
151    {
152      LcA= icontent (a);
153      if (lc (a).sign() < 0)
154        LcA= -LcA;
155      aa= a/LcA;
156    }
157    CanonicalForm cont = content( aa );
158    aa /= cont;
159    CanonicalForm b = aa.deriv(), c = gcd( aa, b );
160    CanonicalForm y, z, w = aa / c;
161    int i = 1;
162    CFFList F;
163    Variable v = aa.mvar();
164    CanonicalForm lcinv;
165    while ( ! c.degree(v) == 0 )
166    {
167        y = gcd( w, c ); z = w / y;
168        if ( degree( z, v ) > 0 )
169        {
170          if (isOn (SW_RATIONAL))
171          {
172            lcinv= 1/Lc (z);
173            z *= lcinv;
174            z *= bCommonDen (z);
175          }
176          if (lc (z).sign() < 0)
177            z= -z;
178          F.append( CFFactor( z, i ) );
179        }
180        i++;
181        w = y; c = c / y;
182    }
183    if ( degree( w,v ) > 0 )
184    {
185      if (isOn (SW_RATIONAL))
186      {
187        lcinv= 1/Lc (w);
188        w *= lcinv;
189        w *= bCommonDen (w);
190      }
191      if (lc (w).sign() < 0)
192        w= -w;
193      F.append( CFFactor( w, i ) );
194    }
195    if ( ! cont.isOne() )
196    {
197        CFFList buf= sqrFreeZ (cont);
198        buf.removeFirst();
199        F = Union( F, buf );
200    }
201    F.insert (CFFactor (LcA, 1));
202    return F;
203}
204
205CanonicalForm
206sqrfPart (const CanonicalForm& F)
207{
208  if (F.inCoeffDomain())
209    return F;
210  CFMap M;
211  CanonicalForm A= compress (F, M);
212  CanonicalForm w, v, b;
213  CanonicalForm result;
214  int i= 1;
215  for (; i <= A.level(); i++)
216  {
217    if (!deriv (A, Variable (i)).isZero())
218      break;
219  }
220
221  w= gcd (A, deriv (A, Variable (i)));
222  b= A/w;
223  result= b;
224  if (degree (w) < 1)
225    return M (result);
226  i++;
227  for (; i <= A.level(); i++)
228  {
229    if (!deriv (w, Variable (i)).isZero())
230    {
231      b= w;
232      w= gcd (w, deriv (w, Variable (i)));
233      b /= w;
234      if (degree (b) < 1)
235        break;
236      CanonicalForm g= gcd (b, result);
237      if (degree (g) > 0)
238        result *= b/g;
239      if (degree (g) <= 0)
240        result *= b;
241    }
242  }
243  result= M (result);
244  return result;
245}
246
Note: See TracBrowser for help on using the repository browser.