source: git/factory/gengftables-conway.cc @ 8530d34

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