source: git/factory/gfops.cc @ e3198f

spielwiese
Last change on this file since e3198f was 83976e, checked in by Martin Lee <martinlee84@…>, 12 years ago
chg: enable setting of gftables location by program courtesy of "Grayson, Daniel R." <dan@math.uiuc.edu>
  • Property mode set to 100644
File size: 6.0 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id$ */
3
4#include "config.h"
5
6#ifdef HAVE_CSTDIO
7#include <cstdio>
8#include <cstdlib>
9#else
10#include <stdio.h>
11#include <stdlib.h>
12#endif
13#include <string.h>
14
15#include "cf_assert.h"
16
17#include "cf_defs.h"
18#include "gf_tabutil.h"
19#include "cf_util.h"
20#include "canonicalform.h"
21#include "variable.h"
22#include "gfops.h"
23
24#ifdef SINGULAR
25#include "singext.h"
26#endif
27
28
29const int gf_maxtable = 63001;
30const int gf_maxbuffer = 200;
31
32const int gf_primes_len = 42;
33//static unsigned short gf_primes [] =
34//{
35//      2,   3,   5,   7,  11,  13,  17,  19,
36//     23,  29,  31,  37,  41,  43,  47,  53,
37//     59,  61,  67,  71,  73,  79,  83,  89,
38//     97, 101, 103, 107, 109, 113, 127, 131,
39//    137, 139, 149, 151, 157, 163, 167, 173,
40//    179, 181, 191, 193, 197, 199, 223, 211,
41//    227, 229, 233, 239, 241, 251
42//};
43
44int gf_q = 0;
45int gf_p = 0;
46int gf_n = 0;
47int gf_q1 = 0;
48int gf_m1 = 0;
49char gf_name = 'Z';
50
51unsigned short * gf_table = 0;
52
53CanonicalForm gf_mipo(0);
54
55static CanonicalForm intVec2CF ( int degree, int * coeffs, int level )
56{
57    int i;
58    CanonicalForm result;
59    for ( i = 0; i <= degree; i++ )
60    {
61        result += CanonicalForm( coeffs[ i ] ) * power( Variable( level ), degree - i );
62    }
63    return result;
64}
65
66static char *gftable_dir;
67extern "C" {
68  void set_gftable_dir(char *d){
69    gftable_dir = d;
70  }
71}
72
73static void gf_get_table ( int p, int n )
74{
75    char buffer[gf_maxbuffer];
76    int q = ipower( p, n );
77
78    // do not read the table a second time
79    if ( gf_q == q )
80    {
81        return;
82    }
83
84    if ( gf_table == 0 )
85        gf_table = new unsigned short[gf_maxtable];
86
87/*#ifdef SINGULAR
88    // just copy the table if Singular already read it
89    //printf("init_gf(gf_get_table) q=%d, nfCharQ=%d\n",q,nfCharQ);
90    if ( q == nfCharQ )
91    {
92        gf_p = p; gf_n = n;
93        gf_q = q; gf_q1 = q - 1;
94        gf_m1 = nfM1;
95        gf_mipo = intVec2CF( nfMinPoly[0], nfMinPoly + 1, 1 );
96        (void)memcpy( gf_table, nfPlus1Table, gf_q * sizeof( unsigned short ) );
97        gf_table[gf_q] = 0;
98        return;
99    }
100#endif*/
101
102    // try to open file
103    char *gffilename;
104    FILE * inputfile;
105    if (gftable_dir)
106    {
107      sprintf( buffer, "/gftable.%d.%d", p, n );
108      gffilename = (char *)malloc(strlen(gftable_dir) + strlen(buffer) + 1);
109      STICKYASSERT(gffilename,"out of memory");
110      strcpy(gffilename,gftable_dir);
111      strcat(gffilename,buffer);
112      inputfile = fopen( gffilename, "r" );
113    }
114    else
115    {
116#ifndef SINGULAR
117      sprintf( buffer, GFTABLEDIR "/gftable.%d.%d", p, n );
118      gffilename = buffer;
119      inputfile = fopen( buffer, "r" );
120#else
121      sprintf( buffer, "gftables/%d", q );
122      gffilename = buffer;
123      inputfile = feFopen( buffer, "r" );
124#endif
125    }
126    if (!inputfile)
127    {
128      fprintf(stderr,"can not open GF(q) addition table: %s\n",gffilename);
129      STICKYASSERT(inputfile, "can not open GF(q) table");
130    }
131
132    // read ID
133    char * bufptr;
134    char * success;
135    success = fgets( buffer, gf_maxbuffer, inputfile );
136    STICKYASSERT( success, "illegal table (reading ID)" );
137    STICKYASSERT( strcmp( buffer, "@@ factory GF(q) table @@\n" ) == 0, "illegal table" );
138    // read p and n from file
139    int pFile, nFile;
140    success = fgets( buffer, gf_maxbuffer, inputfile );
141    STICKYASSERT( success, "illegal table (reading p and n)" );
142    sscanf( buffer, "%d %d", &pFile, &nFile );
143    STICKYASSERT( p == pFile && n == nFile, "illegal table" );
144    // skip (sic!) factory-representation of mipo
145    // and terminating "; "
146    bufptr = (char *)strchr( buffer, ';' ) + 2;
147    // read simple representation of mipo
148    int i, degree;
149    sscanf( bufptr, "%d", &degree );
150    bufptr = (char *)strchr( bufptr, ' ' ) + 1;
151    int * mipo = new int[degree + 1];
152    for ( i = 0; i <= degree; i++ )
153    {
154        sscanf( bufptr, "%d", mipo + i );
155        bufptr = (char *)strchr( bufptr, ' ' ) + 1;
156    }
157
158    gf_p = p; gf_n = n;
159    gf_q = q; gf_q1 = q-1;
160    gf_mipo = intVec2CF( degree, mipo, 1 );
161    delete [] mipo;
162
163    // now for the table
164    int k, digs = gf_tab_numdigits62( gf_q );
165    i = 1;
166    while ( i < gf_q )
167    {
168        success = fgets( buffer, gf_maxbuffer, inputfile );
169        STICKYASSERT( strlen( buffer ) - 1 == (size_t)digs * 30, "illegal table" );
170        bufptr = buffer;
171        k = 0;
172        while ( i < gf_q && k < 30 )
173        {
174            gf_table[i] = convertback62( bufptr, digs );
175            bufptr += digs;
176            if ( gf_table[i] == gf_q )
177            {
178                if ( i == gf_q1 )
179                    gf_m1 = 0;
180                else
181                    gf_m1 = i;
182            }
183            i++; k++;
184        }
185    }
186    gf_table[0] = gf_table[gf_q1];
187    gf_table[gf_q] = 0;
188
189    (void)fclose( inputfile );
190}
191
192//static bool gf_valid_combination ( int p, int n )
193//{
194//    int i = 0;
195//    while ( i < gf_primes_len && gf_primes[i] != p ) i++;
196//    if ( i == gf_primes_len )
197//        return false;
198//    else
199//    {
200//        i = n;
201//        int a = 1;
202//        while ( a < gf_maxtable && i > 0 )
203//        {
204//            a *= p;
205//            i--;
206//        }
207//        if ( i > 0 || a > gf_maxtable )
208//            return false;
209//        else
210//            return true;
211//    }
212//}
213
214void gf_setcharacteristic ( int p, int n, char name )
215{
216    ASSERT( gf_valid_combination( p, n ), "illegal immediate GF(q)" );
217    gf_name = name;
218    gf_get_table( p, n );
219}
220
221int gf_gf2ff ( int a )
222{
223    if ( gf_iszero( a ) )
224        return 0;
225    else
226    {
227        // starting from z^0=1, step through the table
228        // counting the steps until we hit z^a or z^0
229        // again.  since we are working in char(p), the
230        // latter is guaranteed to be fulfilled.
231        int i = 0, ff = 1;
232        do
233        {
234            if ( i == a )
235                return ff;
236            ff++;
237            i = gf_table[i];
238        } while ( i != 0 );
239        return -1;
240    }
241}
242
243bool gf_isff ( int a )
244{
245    if ( gf_iszero( a ) )
246        return true;
247    else
248    {
249        // z^a in GF(p) iff (z^a)^p-1=1
250        return gf_isone( gf_power( a, gf_p - 1 ) );
251    }
252}
Note: See TracBrowser for help on using the repository browser.