source: git/factory/gfops.cc

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