source: git/factory/gfops.cc @ ff3a4f

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