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

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