source: git/factory/fac_cantzass.cc @ b973c0

spielwiese
Last change on this file since b973c0 was b973c0, checked in by Jens Schmidt <schmidt@…>, 27 years ago
#include <config.h> added git-svn-id: file:///usr/local/Singular/svn/trunk@136 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 7.3 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2// $Id: fac_cantzass.cc,v 1.1 1997-04-07 16:20:23 schmidt Exp $
3
4/*
5$Log: not supported by cvs2svn $
6Revision 1.0  1996/05/17 10:59:45  stobbe
7Initial revision
8
9*/
10
11#include <config.h>
12
13#include "cf_gmp.h"
14
15#include "assert.h"
16
17#include "cf_defs.h"
18#include "cf_globals.h"
19#include "cf_random.h"
20#include "cf_util.h"
21#include "fac_cantzass.h"
22#include "fac_sqrfree.h"
23#include "gmpext.h"
24
25int initializeGMP();
26
27static int initialized = initializeGMP();
28
29static CanonicalForm randomPoly( int n, const Variable & x, const CFRandom & gen );
30
31static CFFList CantorZassenhausFactorFFGF( const CanonicalForm & f, int d, int q, const CFRandom & );
32
33static CFFList CantorZassenhausFactorExt( const CanonicalForm & g, int s, MP_INT * q, const CFRandom & gen );
34
35static CFFList distinctDegreeFactorFFGF ( const CanonicalForm & f, int q );
36
37static CFFList distinctDegreeFactorExt ( const CanonicalForm & f, int p, int n );
38
39// calculates f^m % d
40
41static CanonicalForm powerMod( const CanonicalForm & f, int m, const CanonicalForm & d );
42
43// calculates f^(p^s) % d
44
45static CanonicalForm powerMod( const CanonicalForm & f, int p, int s, const CanonicalForm & d );
46
47// calculates f^((p^s-1)/2) % d
48
49static CanonicalForm powerMod2( const CanonicalForm & f, int p, int s, const CanonicalForm & d );
50
51static CanonicalForm powerMod2( const CanonicalForm & f, MP_INT * q, int s, const CanonicalForm & d );
52
53CFFList FpFactorizeUnivariateCZ( const CanonicalForm& f, bool issqrfree, int numext, const Variable & alpha, const Variable & beta )
54{
55    CFFList F, G, H, HH;
56    CanonicalForm fac;
57    ListIterator<CFFactor> i, j, k;
58    int d, q, n = 0;
59    bool galoisfield = getGFDegree() > 1;
60    MP_INT qq;
61
62    if ( galoisfield )
63        q = ipower( getCharacteristic(), getGFDegree() );
64    else
65        q = getCharacteristic();
66    if ( numext > 0 ) {
67        if ( numext == 1 )
68            n = getMipo( alpha ).degree();
69        else
70            n = getMipo( alpha ).degree() * getMipo( beta ).degree();
71        mpz_init( &qq );
72        mpz_mypow_ui( &qq, q, n );
73    }
74    if ( LC( f ).isOne() )
75        if ( issqrfree )
76            F.append( CFFactor( f, 1 ) );
77        else
78            F = sqrFreeFp( f );
79    else {
80        if ( issqrfree )
81            F.append( CFFactor( f / LC( f ), 1 ) );
82        else
83            F = sqrFreeFp( f / LC( f ) );
84        H.append( LC( f ) );
85    }
86    for ( i = F; i.hasItem(); ++i ) {
87        d = i.getItem().exp();
88        if ( numext > 0 )
89            G = distinctDegreeFactorExt( i.getItem().factor(), q, n );
90        else
91            G = distinctDegreeFactorFFGF( i.getItem().factor(), q );
92        for ( j = G; j.hasItem(); ++j ) {
93            if ( numext > 0 ) {
94                if ( numext == 1 )
95                    HH = CantorZassenhausFactorExt( j.getItem().factor(), j.getItem().exp(), &qq, AlgExtRandomF( alpha ) );
96                else
97                    HH = CantorZassenhausFactorExt( j.getItem().factor(), j.getItem().exp(), &qq, AlgExtRandomF( alpha, beta ) );
98            }
99            else  if ( galoisfield )
100                HH = CantorZassenhausFactorFFGF( j.getItem().factor(), j.getItem().exp(), q, GFRandom() );
101            else
102                HH = CantorZassenhausFactorFFGF( j.getItem().factor(), j.getItem().exp(), q, FFRandom() );
103            for ( k = HH; k.hasItem(); ++k ) {
104                fac = k.getItem().factor();
105                H.append( CFFactor( fac / LC( fac ), d ) );
106            }
107        }
108    }
109    if ( numext > 0 )
110        mpz_clear( &qq );
111    return H;
112}
113
114CFFList distinctDegreeFactorFFGF ( const CanonicalForm & f, int q )
115{
116    int i;
117    Variable x = f.mvar();
118    CanonicalForm g = f, h, r = x;
119    CFFList F;
120    i = 1;
121    while ( g.degree(x) > 0 && i <= g.degree(x) ) {
122        r = powerMod( r, q, g );
123        h = gcd( g, r - x );
124        if ( h.degree(x) > 0 ) {
125            F.append( CFFactor( h, i ) );
126            g /= h;
127        }
128        i++;
129    }
130    ASSERT( g.degree(x) == 0, "fatal fatal" );
131    return F;
132}
133
134CFFList distinctDegreeFactorExt ( const CanonicalForm & f, int p, int n )
135{
136    int i;
137    Variable x = f.mvar();
138    CanonicalForm g = f, h, r = x;
139    CFFList F;
140    i = 1;
141    while ( g.degree(x) > 0 && i <= g.degree(x) ) {
142        r = powerMod( r, p, n, g );
143        h = gcd( g, r - x );
144        if ( h.degree(x) > 0 ) {
145            F.append( CFFactor( h, i ) );
146            g /= h;
147        }
148        i++;
149    }
150    ASSERT( g.degree(x) == 0, "fatal fatal" );
151    return F;
152}
153
154CFFList CantorZassenhausFactorFFGF( const CanonicalForm & g, int s, int q, const CFRandom & gen )
155{
156    CanonicalForm f = g;
157    CanonicalForm b, f1;
158    int d, d1;
159    Variable x = f.mvar();
160
161    if ( (d=f.degree(x)) == s )
162        return CFFactor( f, 1 );
163    else while ( 1 ) {
164        b = randomPoly( d, x, gen );
165        f1 = gcd( b, f );
166        if ( (d1 = f1.degree(x)) > 0 && d1 < d )
167            return Union( CantorZassenhausFactorFFGF( f1, s, q, gen ), CantorZassenhausFactorFFGF( f/f1, s, q, gen ) );
168        else {
169            f1 = gcd( f, powerMod2( b, q, s, f ) - 1 );
170            if ( (d1 = f1.degree(x)) > 0 && d1 < d )
171                return Union( CantorZassenhausFactorFFGF( f1, s, q, gen ), CantorZassenhausFactorFFGF( f/f1, s, q, gen ) );
172        }
173    }
174}
175
176CFFList CantorZassenhausFactorExt( const CanonicalForm & g, int s, MP_INT * q, const CFRandom & gen )
177{
178    CanonicalForm f = g;
179    CanonicalForm b, f1;
180    int d, d1;
181    Variable x = f.mvar();
182
183    if ( (d=f.degree(x)) == s )
184        return CFFactor( f, 1 );
185    else while ( 1 ) {
186        b = randomPoly( d, x, gen );
187        f1 = gcd( b, f );
188        if ( (d1 = f1.degree(x)) > 0 && d1 < d )
189            return Union( CantorZassenhausFactorExt( f1, s, q, gen ), CantorZassenhausFactorExt( f/f1, s, q, gen ) );
190        else {
191            f1 = gcd( f, powerMod2( b, q, s, f ) - 1 );
192            if ( (d1 = f1.degree(x)) > 0 && d1 < d )
193                return Union( CantorZassenhausFactorExt( f1, s, q, gen ), CantorZassenhausFactorExt( f/f1, s, q, gen ) );
194        }
195    }
196}
197
198CanonicalForm randomPoly( int d, const Variable & x, const CFRandom & g )
199{
200    CanonicalForm result = 0;
201    for ( int i = 0; i < d; i++ )
202        result += power( x, i ) * g.generate();
203    result += power( x, d );
204    return result;
205}
206
207CanonicalForm powerMod( const CanonicalForm & f, int m, const CanonicalForm & d )
208{
209    CanonicalForm prod = 1;
210    CanonicalForm b = f % d;
211
212    while ( m != 0 ) {
213        if ( m % 2 != 0 )
214            prod = (prod * b) % d;
215        m /= 2;
216        if ( m != 0 )
217            b = (b * b) % d;
218    }
219    return prod;
220}
221
222CanonicalForm powerMod( const CanonicalForm & f, int p, int s, const CanonicalForm & d )
223{
224    CanonicalForm prod = 1;
225    CanonicalForm b = f % d;
226    int odd;
227
228    MP_INT m;
229
230    mpz_init( &m );
231    mpz_mypow_ui( &m, p, s );
232    while ( mpz_cmp_si( &m, 0 ) != 0 ) {
233        odd = mpz_mdivmod_ui( &m, 0, &m, 2 );
234        if ( odd != 0 )
235            prod = (prod * b) % d;
236        if ( mpz_cmp_si( &m, 0 ) != 0 )
237            b = (b*b) % d;
238    }
239    mpz_clear( &m );
240    return prod;
241}
242
243CanonicalForm powerMod2( const CanonicalForm & f, int p, int s, const CanonicalForm & d )
244{
245    CanonicalForm prod = 1;
246    CanonicalForm b = f % d;
247    int odd;
248
249    MP_INT m;
250
251    mpz_init( &m );
252    mpz_mypow_ui( &m, p, s );
253    mpz_sub_ui( &m, &m, 1 );
254    mpz_div_ui( &m, &m, 2 );
255    while ( mpz_cmp_si( &m, 0 ) != 0 ) {
256        odd = mpz_mdivmod_ui( &m, 0, &m, 2 );
257        if ( odd != 0 )
258            prod = (prod * b) % d;
259        if ( mpz_cmp_si( &m, 0 ) != 0 )
260            b = (b*b) % d;
261    }
262    mpz_clear( &m );
263    return prod;
264}
265
266CanonicalForm powerMod2( const CanonicalForm & f, MP_INT * q, int s, const CanonicalForm & d )
267{
268    CanonicalForm prod = 1;
269    CanonicalForm b = f % d;
270    int odd;
271
272    MP_INT m;
273
274    mpz_init( &m );
275    mpz_mypow( &m, q, s );
276    mpz_sub_ui( &m, &m, 1 );
277    mpz_div_ui( &m, &m, 2 );
278    while ( mpz_cmp_si( &m, 0 ) != 0 ) {
279        odd = mpz_mdivmod_ui( &m, 0, &m, 2 );
280        if ( odd != 0 )
281            prod = (prod * b) % d;
282        if ( mpz_cmp_si( &m, 0 ) != 0 )
283            b = (b*b) % d;
284    }
285    mpz_clear( &m );
286    return prod;
287}
Note: See TracBrowser for help on using the repository browser.