source: git/factory/gfops.cc @ 1101a8

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