/* This program is directly translated from ???'s program written in Fortran By Yaohang Li */ #include #define NIEDMAXDIM 100 #define NIEDNBITS 31 #define NIEDMAXQ 50 /* The following definitions concern the representation of polynomials. */ #define NIEDMAXDEG 50 #define NIEDDEG 10 /* In order to adjust the limit of C array, we change the definition of the polynomial array. In fortran code, POLY(-1) stores the degree. In our C code POLY(MAXDEG+1) stores the degree. Yaohang Li Nov 2000 The parameter MAXDEG gives the highest degree of polynomial to be handled. Polynomials stored as arrays have the coefficient of degree n in POLY(N), and the degree of the polynomial in POLY(). The parameter DEG is just to remind us of this last fact. A polynomial which is identically 0 is given degree -1. A polynomial can also be stored in an integer I, with I = AN*Q**N + ... + A0. Routines ITOP and PTOI convert between these two formats. MAXE - We need MAXDIM irreducible polynomials over Z2. MAXE is the highest degree among these. MAXV - The maximum possible index used in V. */ #define NIEDMAXE 9 #define NIEDMAXV NIEDNBITS+NIEDMAXE /* CJ - Contains the packed values of Niederreiter's C(I,J,R) DIMEN - The dimension of the sequence to be generated COUNT - The index of the current item in the sequence, expressed as an array of bits. COUNT(R) is the same as Niederreiter's AR(N) (page 54) except that N is implicit. NEXTQ - The numerators of the next item in the series. These are like Niederreiter's XI(N) (page 54) except that N is implicit, and the NEXTQ are integers. To obtain the values of XI(N), multiply by RECIP (see GOLO2). Array CJ of the common block is set up by subroutine CALCC2. The other items in the common block are set up by INLO2. */ int niedcj[NIEDMAXDIM][NIEDNBITS]; int niedcount; int niednextq[NIEDMAXDIM]; /* The following COMMON block, used by many subroutines, gives the order Q of a field, its characteristic P, and its addition, multiplication and subtraction tables. The parameter MAXQ gives the order of the largest field to be handled. */ int niedp, niedq, niedadd[NIEDMAXQ][NIEDMAXQ]; int niedmul[NIEDMAXQ][NIEDMAXQ], niedsub[NIEDMAXQ][NIEDMAXQ]; int niedmax(int, int); int niedmin(int, int); int charac(int); void calcc2(int); void calcv(int *, int, int *, int *, int *, int); void plymul(int *, int, int *, int, int *, int *); void setfld(int); int nied(int dimen, double *quasi) { /* The parameter RECIP is the multiplier which changes the integers in NEXTQ into the required real values in QUASI. */ double recip; int i,r; recip=0.5/(double)(1<>=1; } /* Check that we have not passed 2**NBITS calls on GOLO2 */ if (r>=NIEDNBITS) { fprintf(stderr, "Too many calls\n"); return(-1); } /* Compute the new numerators in vector NEXTQ */ for (i=0;iNIEDMAXDIM) { fprintf(stderr,"Error: init_nied() bad dimension\n"); return(-1); } calcc2(dimen); /* Translate SKIP into Gray code */ gray=skip^(skip/2); /* Now set up NEXTQ appropriately for this value of the Gray code */ for (i=0;iNIEDMAXDEG) { fprintf(stderr,"Error: PLYMUL: Degree of product exceeds NIEDMAXDEG\n"); exit(-1); } for (i=0;i<=degc;i++) { term=0; for (j=niedmax(0,i-dega);j<=niedmin(degb,i);j++) term=niedadd[term][niedmul[pa[i-j]][pb[j]]]; pt[i]=term; } *pcdeg=degc; for (i=0;i<=degc;i++) pc[i]=pt[i]; for (i=degc+1;i<=NIEDMAXDEG;i++) pc[i]=0; } /* This version : 12 December 1991 This subroutine sets up addition, multiplication, and subtraction tables for the finite field of order QIN. If necessary, it reads precalculated tables from the file 'gftabs.dat' using unit 1. These precalculated tables are supposed to have been put there by GFARIT. ***** For the base-2 programs, these precalculated ***** tables are not needed and, therefore, neither ***** is GFARIT. Unit 1 is closed both before and after the call of SETFLD. USES Integer function CHARAC gets the characteristic of a field. */ void setfld(int qin) { int i, j, n; if (qin<1||qin>NIEDMAXQ) { fprintf(stderr,"Error: setfld: Bad Value of Q\n"); exit(-1); } niedq=qin; niedp=charac(niedq-1); if (niedp==0) { fprintf(stderr,"Error: setfld: There is no field of order %d\n", niedq); exit(-1); } /* set up to handle a field of prime order: calculate ADD and MUL */ if (niedp==niedq) for (i=0;iNIEDMAXQ) return(0); else return(ch[qin]); } int niedmax(int x, int y) { if (x>y) return(x); else return(y); } int niedmin(int x, int y) { if (x