source: git/factory/gengftables.cc @ f0596e

spielwiese
Last change on this file since f0596e was 65efd3, checked in by Jens Schmidt <schmidt@…>, 27 years ago
Initial revision git-svn-id: file:///usr/local/Singular/svn/trunk@407 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 6.0 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: gengftables.cc,v 1.1 1997-06-19 12:40:00 schmidt Exp $ */
3
4//{{{ docu
5//
6// gengftables.cc - generate addition tables used by factory
7//   to calculate in GF(q).
8//
9// Note: This may take quite a while ...
10//
11//}}}
12
13#include <iostream.h>
14#include <fstream.h>
15#include <strstream.h>
16
17#include <factory.h>
18
19#include <assert.h>
20#include <gf_tabutil.h>
21
22//{{{ constants
23//{{{ docu
24//
25// - constants.
26//
27// maxtable: maximal size of a gf_table
28// primes, primes_len:
29//   used to step through possible extensions
30//
31//}}}
32const int maxtable = 32767;
33
34const int primes_len = 42;
35static unsigned short primes [] =
36{
37      2,   3,   5,   7,  11,  13,  17,  19,
38     23,  29,  31,  37,  41,  43,  47,  53,
39     59,  61,  67,  71,  73,  79,  83,  89,
40     97, 101, 103, 107, 109, 113, 127, 131,
41    137, 139, 149, 151, 157, 163, 167, 173,
42    179, 181
43};
44//}}}
45
46//{{{ bool isIrreducible ( const CanonicalForm & f )
47//{{{ docu
48//
49// isIrreducible() - return true iff f is irreducible.
50//
51//}}}
52bool
53isIrreducible ( const CanonicalForm & f )
54{
55    CFFList F = factorize( f );
56    return F.length() == 1 && F.getFirst().exp() == 1;
57}
58//}}}
59
60//{{{ int exponent( const CanonicalForm & f, int q )
61//{{{ docu
62//
63// exponent() - return e > 0 such that x^e == 1 mod f.
64//
65// q: upper limit for e (?)
66//
67//}}}
68int
69exponent( const CanonicalForm & f, int q )
70{
71    Variable x = f.mvar();
72    int e = 1;
73    CanonicalForm prod = x;
74    while ( e <= q && ! prod.isOne() ) {
75        e++;
76        prod = ( prod * x ) % f;
77    }
78    return e;
79}
80//}}}
81
82//{{{ bool findGenRec ( int d, int n, int q, const CanonicalForm & m, const Variable & x, CanonicalForm & result )
83//{{{ docu
84//
85// findGenRec() - find a generator of GF(q).
86//
87// Returns true iff result is a valid generator.
88//
89// d: degree of extension
90// q: the q in GF(q) (q == p^d)
91// x: generator should be a poly in x
92// n, m: used to step recursively through all polys in FF(p)
93//   Initially, n == d and m == 0.  If 0 <= n <= d we are
94//   in the process of building m, if n < 0 we built m and
95//   may test whether it generates GF(q).
96// result: generator found
97//
98// i: used to step through GF(p)
99// p: current characteristic
100//
101//}}}
102bool
103findGenRec ( int d, int n, int q,
104             const CanonicalForm & m, const Variable & x,
105             CanonicalForm & result )
106{
107    int i, p = getCharacteristic();
108    if ( n < 0 ) {
109        cerr << "."; cerr.flush();
110        // check whether m is irreducible
111        if ( isIrreducible( m ) ) {
112            cerr << "*"; cerr.flush();
113            // check whether m generates multiplicative group
114            if ( exponent( m, q ) == q - 1 ) {
115                result = m;
116                return true;
117            }
118            else
119                return false;
120        }
121        else
122            return false;
123    }
124    // for each monomial x^0, ..., x^n, ..., x^d, try all possible coefficients
125    else  if ( n == d || n == 0 ) {
126        // we want to have a leading coefficient and a constant term,
127        // so start with coefficient >= 1
128        for ( i = 1; i < p; i++ )
129            if ( findGenRec( d, n-1, q, m + i * power( x, n ), x, result ) )
130                return true;
131    }
132    else {
133        for ( i = 0; i < p; i++ )
134            if ( findGenRec( d, n-1, q, m + i * power( x, n ), x, result ) )
135                return true;
136    }
137    return false;
138}
139//}}}
140
141//{{{ CanonicalForm findGen( int d, int q )
142//{{{ docu
143//
144// findGen() - find and return a generator of GF(q).
145//
146// d: degree of extension
147// q: the q in GF(q)
148//
149//}}}
150CanonicalForm
151findGen( int d, int q )
152{
153    Variable x( 1 );
154    CanonicalForm result;
155    cerr << "testing p = " << getCharacteristic() << ", d = " << d << " ... ";
156    cerr.flush();
157    bool ok = findGenRec( d, d, q, 0, x, result );
158    cerr << endl;
159    if ( ! ok )
160        return 0;
161    else
162        return result;
163}
164//}}}
165
166//{{{ void printTable( int d, int q, CanonicalForm mipo )
167//{{{ docu
168//
169// printTable - print +1 table of field GF(q).
170//
171// d: degree of extension
172// q: the q in GF(q)
173// mipo: the minimal polynomial of the extension
174//
175// p: current characteristic
176//
177//}}}
178void
179printTable( int d, int q, CanonicalForm mipo )
180{
181    int i, p = getCharacteristic();
182
183    // open file to write to
184    ostrstream fname;
185    fname << "gftables/gftable." << p << "." << d << '\0';
186    char * fn = fname.str();
187    ofstream outfile;
188    outfile.open( fn, ios::out );
189    STICKYASSERT1( outfile, "can not open GF(q) table %s for writing", fn );
190    delete fn;
191
192    cerr << "mipo = " << mipo << ": ";
193    cerr << "generating multiplicative group ... ";
194    cerr.flush();
195
196    CanonicalForm * T = new CanonicalForm[maxtable];
197    Variable x( 1 );
198
199    // fill T with powers of x
200    T[0] = 1;
201    for ( i = 1; i < q; i++ )
202        T[i] = ( T[i-1] * x ) % mipo;
203
204    cerr << "generating addition table ... ";
205    cerr.flush();
206
207    // brute force method
208    int * table = new int[maxtable];
209    CanonicalForm f;
210
211    for ( i = 0; i < q; i++ ) {
212        f = T[i] + 1;
213        int j = 0;
214        while ( j < q && T[j] != f ) j++;
215        table[i] = j;
216    }
217
218    cerr << "writing table ... ";
219    cerr.flush();
220
221    outfile << "@@ factory GF(q) table @@" << endl;
222    outfile << p << " " << d << " " << mipo << "; ";
223
224    // print simple reprenstation of mipo
225    outfile << d;
226    CFIterator MiPo = mipo;
227    for ( i = d; MiPo.hasTerms(); i--, MiPo++ ) {
228        int exp;
229        for ( exp = MiPo.exp(); exp < i; i-- )
230            outfile << " 0";
231        outfile << " " << MiPo.coeff();
232    }
233    // since mipo is irreducible, it has a constant term,
234    // so i == 0 at this point
235    outfile << endl;
236
237    int m = gf_tab_numdigits62( q );
238    char * outstr = new char[30*m+1];
239    outstr[30*m] = '\0';
240    i = 1;
241    while ( i < q ) {
242        int k = 0;
243        char * sptr = outstr;
244        while ( i < q && k < 30 ) {
245            convert62( table[i], m, sptr );
246            sptr += m;
247            k++; i++;
248        }
249        while ( k < 30 ) {
250            convert62( 0, m, sptr );
251            sptr += m;
252            k++;
253        }
254        outfile << outstr << endl;
255    }
256    outfile.close();
257
258    delete [] outstr;
259    delete [] T;
260    delete [] table;
261
262    cerr << endl;
263}
264//}}}
265
266int
267main()
268{
269    int i, p, q, n;
270    for ( i = 0; i < primes_len; i++ ) {
271        p = primes[i];
272        q = p*p;
273        n = 2;
274        setCharacteristic( p );
275        while ( q < maxtable ) {
276            CanonicalForm f = findGen( n, q );
277            ASSERT( f != 0, "no generator found" );
278            printTable( n, q, f );
279            n++; q *= p;
280        }
281    }
282}
Note: See TracBrowser for help on using the repository browser.