source: git/factory/gfops.cc @ aa5055

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