source: git/factory/gengftables-conway.cc @ 34f6d2

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