source: git/factory/gengftables-conway.cc

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