source: git/factory/gfops.cc @ d56aae9

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