source: git/factory/gengftables-conway.cc @ f4b180

fieker-DuValspielwiese
Last change on this file since f4b180 was b478f8, checked in by Hans Schönemann <hannes@…>, 17 years ago
*hannes: Conway polynomials, new gcd for char p git-svn-id: file:///usr/local/Singular/svn/trunk@10278 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 8.4 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: gengftables-conway.cc,v 1.1 2007-07-31 12:57:59 Singular 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>
16
17#include <factory.h>
18
19#include <assert.h>
20#include <gf_tabutil.h>
21
22using namespace std;
23
24//{{{ constants
25//{{{ docu
26//
27// - constants.
28//
29// maxtable: maximal size of a gf_table
30// primes, primes_len:
31//   used to step through possible extensions
32//
33//}}}
34const int maxtable = 65536;
35
36const int primes_len = 54;
37static unsigned short primes [] =
38{
39      2,   3,   5,   7,  11,  13,  17,  19,
40     23,  29,  31,  37,  41,  43,  47,  53,
41     59,  61,  67,  71,  73,  79,  83,  89,
42     97, 101, 103, 107, 109, 113, 127, 131,
43    137, 139, 149, 151, 157, 163, 167, 173,
44    179, 181, 191, 193, 197, 199, 211, 223, 
45        227, 229, 233, 239, 241, 251
46};
47//}}}
48
49//{{{ bool isIrreducible ( const CanonicalForm & f )
50//{{{ docu
51//
52// isIrreducible() - return true iff f is irreducible.
53//
54//}}}
55bool
56isIrreducible ( const CanonicalForm & f )
57{
58    CFFList F = factorize( f );
59    return F.length() == 1 && F.getFirst().exp() == 1;
60}
61//}}}
62
63//{{{ int exponent ( const CanonicalForm & f, int q )
64//{{{ docu
65//
66// exponent() - return e > 0 such that x^e == 1 mod f.
67//
68// q: upper limit for e (?)
69//
70//}}}
71int
72exponent ( const CanonicalForm & f, int q )
73{
74    Variable x = f.mvar();
75    int e = 1;
76    CanonicalForm prod = x;
77    while ( e <= q && ! prod.isOne() ) {
78        e++;
79        prod = ( prod * x ) % f;
80    }
81    return e;
82}
83//}}}
84
85//{{{ bool findGenRec ( int d, int n, int q, const CanonicalForm & m, const Variable & x, CanonicalForm & result )
86//{{{ docu
87//
88// findGenRec() - find a generator of GF(q).
89//
90// Returns true iff result is a valid generator.
91//
92// d: degree of extension
93// q: the q in GF(q) (q == p^d)
94// x: generator should be a poly in x
95// n, m: used to step recursively through all polys in FF(p)
96//   Initially, n == d and m == 0.  If 0 <= n <= d we are
97//   in the process of building m, if n < 0 we built m and
98//   may test whether it generates GF(q).
99// result: generator found
100//
101// i: used to step through GF(p)
102// p: current characteristic
103//
104//}}}
105bool
106findGenRec ( int d, int n, int q,
107             const CanonicalForm & m, const Variable & x,
108             CanonicalForm & result )
109{
110    int i, p = getCharacteristic();
111    if ( n < 0 ) {
112        cerr << "."; cerr.flush();
113        // check whether m is irreducible
114        if ( isIrreducible( m ) ) {
115            cerr << "*"; cerr.flush();
116            // check whether m generates multiplicative group
117            if ( exponent( m, q ) == q - 1 ) {
118                result = m;
119                return true;
120            }
121            else
122                return false;
123        }
124        else
125            return false;
126    }
127    // for each monomial x^0, ..., x^n, ..., x^d, try all possible coefficients
128    else  if ( n == d || n == 0 ) {
129        // we want to have a leading coefficient and a constant term,
130        // so start with coefficient >= 1
131        for ( i = 1; i < p; i++ )
132            if ( findGenRec( d, n-1, q, m + i * power( x, n ), x, result ) )
133                return true;
134    }
135    else {
136        for ( i = 0; i < p; i++ )
137            if ( findGenRec( d, n-1, q, m + i * power( x, n ), x, result ) )
138                return true;
139    }
140    return false;
141}
142//}}}
143
144//{{{ CanonicalForm findGen ( int d, int q )
145//{{{ docu
146//
147// findGen() - find and return a generator of GF(q).
148//
149// d: degree of extension
150// q: the q in GF(q)
151//
152//}}}
153CanonicalForm
154findGen ( int d, int q )
155{
156    Variable x( 1 );
157    CanonicalForm result;
158    cerr << "testing p = " << getCharacteristic() << ", d = " << d << " ... ";
159    cerr.flush();
160    bool ok = findGenRec( d, d, q, 0, x, result );
161    cerr << endl;
162    if ( ! ok )
163        return 0;
164    else
165        return result;
166}
167//}}}
168
169//{{{ void printTable ( int d, int q, CanonicalForm mipo )
170//{{{ docu
171//
172// printTable - print +1 table of field GF(q).
173//
174// d: degree of extension
175// q: the q in GF(q)
176// mipo: the minimal polynomial of the extension
177//
178// p: current characteristic
179//
180//}}}
181void
182printTable ( int d, int q, CanonicalForm mipo )
183{
184    int i, p = getCharacteristic();
185
186    // open file to write to
187        ostrstream fname;
188    fname << "gftables/gftable." << p << "." << d << '\0';
189    char * fn = fname.str();
190    ofstream outfile;
191    outfile.open( fn, ios::out );
192    STICKYASSERT1( outfile, "can not open GF(q) table %s for writing", fn );
193    delete fn;
194
195    cerr << "mipo = " << mipo << ": ";
196    cerr << "generating multiplicative group ... ";
197    cerr.flush();
198
199    CanonicalForm * T = new CanonicalForm[maxtable];
200    Variable x( 1 );
201
202    // fill T with powers of x
203    T[0] = 1;
204    for ( i = 1; i < q; i++ )
205        T[i] = ( T[i-1] * x ) % mipo;
206
207    cerr << "generating addition table ... ";
208    cerr.flush();
209
210    // brute force method
211    int * table = new int[maxtable];
212    CanonicalForm f;
213
214    for ( i = 0; i < q; i++ ) {
215        f = T[i] + 1;
216        int j = 0;
217        while ( j < q && T[j] != f ) j++;
218        table[i] = j;
219    }
220
221    cerr << "writing table ... ";
222    cerr.flush();
223
224    outfile << "@@ factory GF(q) table @@" << endl;
225    outfile << p << " " << d << " " << mipo << "; ";
226
227    // print simple reprenstation of mipo
228    outfile << d;
229    CFIterator MiPo = mipo;
230    for ( i = d; MiPo.hasTerms(); i--, MiPo++ ) {
231        int exp;
232        for ( exp = MiPo.exp(); exp < i; i-- )
233            outfile << " 0";
234        outfile << " " << MiPo.coeff();
235    }
236    // since mipo is irreducible, it has a constant term,
237    // so i == 0 at this point
238    outfile << endl;
239
240    int m = gf_tab_numdigits62( q );
241    char * outstr = new char[30*m+1];
242    outstr[30*m] = '\0';
243    i = 1;
244    while ( i < q ) {
245        int k = 0;
246        char * sptr = outstr;
247        while ( i < q && k < 30 ) {
248            convert62( table[i], m, sptr );
249            sptr += m;
250            k++; i++;
251        }
252        while ( k < 30 ) {
253            convert62( 0, m, sptr );
254            sptr += m;
255            k++;
256        }
257        outfile << outstr << endl;
258    }
259    outfile.close();
260
261    delete [] outstr;
262    delete [] T;
263    delete [] table;
264
265    cerr << endl;
266}
267//}}}
268
269// The new function for getting the minimal polynomials.
270// It uses the Conway polynomials.
271// It reads the polynomials from a file.
272// The file contains all poynomials with p^k <= 2^16
273// but currently only polynomials with p^k <= 2^14 are used.
274static CanonicalForm findGenNew(int n, int q)
275// n is the exponent
276// parameter q is not used. It is added to respect the old version
277{
278        CanonicalForm conway = 0;
279        Variable x( 1 );
280        int p = getCharacteristic();
281        int ntmp,ptmp,pos1,pos2,ii;
282        string ns, ps;
283        string LineSe,coef,PC;
284        int flag=1;
285        ifstream in("./ConwayList.txt");
286        getline(in,LineSe); // For the first line
287
288        string err="END"; //to check if we are at the end of the file
289        while((flag) and (err != LineSe))
290        {
291                getline(in,LineSe); //for the line: allConwayPolynomials := [   
292                if(LineSe == err){
293                        break;
294                }
295                pos1 = LineSe.find( ",", 0 );
296                pos2 = LineSe.find( ",", pos1 + 1);     // we check where are the "," to now p and n of this line
297                ps = LineSe.substr(0, pos1);
298                ns = LineSe.substr(pos1 + 1,pos2 - pos1);
299                ptmp = std::atoi(ps.c_str());           //we have the value of p and n of these line
300                ntmp = std::atoi(ns.c_str());
301
302        if((ntmp==n)&&(ptmp==p)){flag=0;}       // we check if they are our p and n to stop the search
303                       
304        }       
305       
306        if (err==LineSe) // If the Conway Polynomial is not in the list, there is an error.
307        {
308                //cout << "Error: This Conway polinomial is not in the list" << endl;
309                return(0);             
310        }
311
312        // Read the polynomial from the file
313        pos1 = pos2 + 1; 
314        pos2 = LineSe.find(",", pos1 + 1);
315        conway = std::atoi(LineSe.substr(pos1, pos2 - pos1).c_str()); // value of the constant term in PC=Conway Polynomial
316    pos1 = pos2;
317        pos2 = LineSe.find(",", pos1 + 1);
318
319        for(ii = 2; ii <= n; ii++)
320        {
321                coef = LineSe.substr(pos1 + 1,pos2 - pos1 - 1); //Coefficient of the monomial of degree ii-1
322        if(coef != "0")
323                {
324                        conway = conway + std::atoi(coef.c_str()) * power(x, ii - 1) ; //We add this monomial to the Conway Polynomial
325                }
326                pos1 = pos2;
327                pos2 = LineSe.find( ",", pos1+1);
328        }
329
330        pos2 = LineSe.find( ",END", pos1 + 1); // To obtain the last coefficient we search "END" instead of ","
331        coef = LineSe.substr(pos1 + 1,pos2 - pos1 - 1);
332        conway = conway + std::atoi(coef.c_str()) * power(x, ii - 1) ; //We add the last monomial to the Conway Polynomial
333
334        in.close();
335       
336        return(conway); 
337       
338}
339
340
341int
342main()
343{
344    int i, p, q, n;
345    for ( i = 0; i < primes_len; i++ ) {
346                p = primes[i];
347                q = p*p;
348                n = 2;
349                setCharacteristic( p );
350                while ( q < maxtable ) {
351                        CanonicalForm f = findGenNew( n, q );
352                        ASSERT( f != 0, "no generator found" );
353                        printTable( n, q, f );
354                        n++; q *= p;
355                }
356    }
357}
358
Note: See TracBrowser for help on using the repository browser.