📄 gflib.c
字号:
/* ============================================================================
* gflib.c is a library file including the following functions:
* P.S.: All the parameters in these functions have the type of integer.
* static void gftrunc(*pa, *len_a, len_p, *Iwork)
* M_FILE: C = GFTRUNC(A); Iwork --- len_a
* truncates the results of every GF's computation .
* static void gfpadd(*pa, len_a, *pb, len_b, *pp, np, mp, *pc, *nc, *Iwork)
* M_FILE: C = GFADD(A,B,P); Iwork --- *nc+*nc*mp+np
* computes A adds B in GF when P is a matrix.
* static void gfadd(*pa, len_a, *pb, len_b, pp, len, *pc, *nc, *Iwork)
* M_FILE: C = GFADD(A,B,P,LEN), Iwork --- *nc
* computes A adds B in GF when P is a scalar.
* static void gfpmul(*pa, len_a, *pb, len_b, *pp, np, mp, *pc, *nc, *Iwork)
* M_FILE: C = GFMUL(A,B,P); Iwork --- 2*nc+nc*mp+np
* computes A multiply B in GF(P) when P is a matrix.
* static void gfmul(*pa, len_a, *pb, len_b, pp, *pc)
* M_FILE: C = GFMUL(A,B,P); no Iwork
* computes A multiply B in GF(P) when P is a scalar.
* static void gfconv(*pa, len_a, *pb, len_b, pp, *pc, *Iwork)
* M_FILE: C = GFCONV(A,B,P); Iwork --- 6*(len_b+len_a)-5
* computes the convolution between two GF(P) polynomials when P is a scalar.
* static void gfpconv(*pa, len_a, *pb, len_b, *pp, np, mp, *pc, *Iwork)
* M_FILE: C = GFCONV(A,B,P); Iwork --- 5+3*(np+mp)
* computes the convolution between two GF(P) when P is a Matrix.
* static void gfdeconv(*pb, len_b, *pa, len_a, pp, *pq, len_q, *pr, *len_r, *Iwork)
* M_FILE: [Q, R] = GFDECONV(B,A,P); Iwork --- 14*len_b-2*len_a+2
* computes the deconvolution between two GF(P) polynomials when P is a scalar.
* static void gfpdeconv(*pb, len_b, *pa, len_a, *pp, np, mp, *pq, *pr, *len_r, *Iwork)
* M_FILE: [Q, R] = GFDECONV(B,A,P); Iwork --- (2+mp)*np+len_a-1
* computes the deconvolution between two GF(P) when P is a Matrix.
* static void gfplus(*pi, mi, ni, *pj, mj, nj, *alpha, len_alpha, *beta, len_beta, *pk)
* M_FILE: C = GFPLUS(A,B,ALPHA,BETA)
* Galois Field addition (vectorized).
* static void gffilter(*pb, len_b, *pa, len_a, *px, len_x, p, *pOut, *Iwork)
* M_FILE: Y = GFFILTER(B,A,X,P); Iwork --- 2*len_x+len_b+len_a-2
* filters the data in GF(P).
* static void flxor(*px, mx, nx, *py, my, ny, *pz, *mz, *nz)
* M_FILE: Z = FLXOR(X,Y)
* exclusive OR computation.
* static void fliplr(*pa, len_a, *Iwork)
* M_FILE: Y = FLIPLR(X)
* Iwork --- len_a
* flips matrix in the left/right direction.
* static int isprime(p)
* M_FILE: ISP = ISPRIME(X)
* return TRUE for prime numbers.
* static void errlocp1(*syndr,t,*pNum,*pInv,pow_dim,err_In,*Iwork,*sigma_Out,*len_Out)
* M_FILE: [SIGMA, ERR] = ERRLOCP(SYNDROME,T,TP,POW_DIM,ERR,1);
* Iwork --- 5*(2+t)+(t+4)*(t+1) PS: t=2*T (T is in M_file)
* static void errlocp0(*syndr,t,*pNum,*pInv,pow_dim,err_In,*Iwork,*sigma_Out,*len_Out)
* M_FILE: [SIGMA, ERR] = ERRLOCP(SYNDROME,T,TP,POW_DIM,ERR,0);
* Iwork --- 5*(2+t)+(t+4)*(t+1) PS: t=T (T is in M_file)
* static void bchcore(*code,pow_dim,dim,k,t,*pp,*Iwork,*msg,*err,*ccode)
* M_FILE: [SIGMA, ERR, CCODE] = BCHCORE(CODE,POW_DIM,DIM,K,T,P);
* Iwork --- (2+dim)*(2*pow_dim+1)+t*t+15*t+16
* static void rscore(*code,k,*pp,dim,pow_dim,*Iwork,*msg,*err,*ccode)
* M_FILE: [SIGMA, ERR, CCODE] = RSCORE(CODE,K,P,DIM,POW_DIM);
* Iwork --- (pow_dim-2*k+5*dim+18)*pow_dim+3*dim+k*(k-13)+27
* static void pNumInv(*pp, np, mp, prim, *pNum, *pInv, *Iwork)
* M_CODE: tp_num = tp * prim.^[0 : tp_m-1]'; -- vector pNum
* tp_inv(tp_num+1) = 0:pow_dim; -- vector pInv
* Iwork --- np*mp
* static void bi2de(*pbi, np, mp, prim, *pde)
* ============================================================================
*
* Original designed by Wes Wang,
* Jun Wu, The Mathworks, Inc.
* Jan-25, 1996
*
* Copyright (c) 1996 by The MAthWorks, Inc.
* All Rights Reserved
*
* ===========================================================================
*/
#define Inf 32766
/*
*bi2de()
* Iwork --- np*mp
*/
static void bi2de(pbi, np, mp, prim, pde)
int *pbi, np, mp, prim, *pde;
{
int i, j, k;
for(i=0; i<np; i++)
pde[i] = 0;
for (i=0; i < np; i++){
for (j=0; j < mp; j++){
if (pbi[i+j*np] != 0){
if(j > 0){
for (k=0; k < j; k++)
pbi[i+j*np] = pbi[i+j*np]*prim;
}
}
pde[i] = pde[i] + pbi[i+j*np];
}
}
}
/*end of bi2de()*/
/*
*fliplr()
* Iwork --- len_a
*/
static void fliplr(pa, len_a, Iwork)
int *pa, len_a, *Iwork;
{
int i;
int *tmp;
tmp = Iwork;
for(i=0;i < len_a; i++)
tmp[i]= pa[len_a-1-i];
for(i=0;i<len_a;i++)
pa[i]= tmp[i];
}
/*--end of FLIPLR()--*/
/*
*pNumInv()
* Iwork --- np*mp
*/
static void pNumInv(p, np, mp, prim, pNum, pInv, Iwork)
int *p, np, mp, prim, *pNum, *pInv, *Iwork;
{
int i, j, k;
int *pp;
pp = Iwork;
for(i=0; i < np*mp; i++)
pp[i] = p[i];
for(i=0; i<np; i++){
pNum[i] = 0;
pInv[i] = 0;
}
for (i=0; i < np; i++){
for (j=0; j < mp; j++){
if (pp[i+j*np] != 0){
if(j > 0){
for (k=0; k < j; k++)
pp[i+j*np] = pp[i+j*np]*prim;
}
}
pNum[i] = pNum[i] + pp[i+j*np];
}
pInv[pNum[i]] = i;
}
}
/*--end of pNumInv()--*/
/*
* Check if P is a prime number.
* Return 1 when p is a prime number and return 0 when it is not.
*/
static int isprime(p)
int p;
{
int i, Fox, lenFox;
lenFox = 0;
for ( i=2; i < p; i++){
Fox = p % i;
if(Fox == 0)
lenFox++;
}
if(lenFox == 0)
return(1);
else
return(0);
}
/*--end of ISPRIME()--*/
/*
* GFFilter()
* Iwork --- 2*len_x+len_b+len_a-2
* Iwork = tmp_x
* + len_b+len_x-1 = tmp_y
* + len_a+len_x-1 = bottom of Iwork in gffilter()
*/
static void gffilter(pb, len_b, pa, len_a, px, len_x, p, pOut, Iwork)
int *pb, len_b, *pa, len_a, *px, len_x, p, *pOut, *Iwork;
{
int i, j, q, indx;
int tmp_b, tmp_a, len_xx, len_yy;
int *tmp_x, *tmp_y;
/* make a(1) to be one. */
if (pa[0] == 0){
#ifdef MATLAB_MEX_FILE
printf("First denominator filter coeficient must be non-zero!");
#endif
} else if (pa[0] != 1){
if( isprime(p) ){ /* by Fermat's theory (pp 96 in MacWilliams)
* for any integer q less than p.
*/
q = 1;
for(i=0; i < p-2; i++){
q = q*pa[0];
}
if (((q*pa[0]) % p) != 1){
#ifdef MATLAB_MEX_FILE
printf("Warning: The computation may be not accurate because a large integer\n");
printf(" is introduced in to the calculation.\n");
#endif
}
} else {
#ifdef MATLAB_MEX_FILE
printf("P must be a prime in GFFILTER.");
#endif
}
/* made pa[0] = 1. */
for(i=0; i < len_a; i++)
pa[i] = (pa[i]*q) % p;
}
/* computation length adjustment */
len_xx = len_b+len_x-1;
len_yy = len_a+len_x-1;
tmp_x = Iwork;
tmp_y = Iwork + len_xx;
for(i=len_b-1; i < len_xx; i++)
tmp_x[i] = px[i-len_b+1];
/*
* flip the computation variable
* difference equation iteration
*/
len_a--;
for (i=0; i < len_x; i++){
indx = i + len_a;
tmp_a = 0;
tmp_b = 0;
if ( len_a > 0 ){
/*y(indx) = fb * xx(i:len_b +i-1)' + fa * y(i:indx-1)'; */
for (j=0; j < len_b; j++)
tmp_b = tmp_b + pb[len_b-1-j]*tmp_x[i+j];
for (j=0; j < len_a; j++)
tmp_a = tmp_a + (p-pa[len_a-j])*tmp_y[i+j];
tmp_y[indx] = tmp_b + tmp_a;
}else{
/* y(indx) = fb * xx(i:len_b+i-1)'; */
for (j=0; j < len_b; j++)
tmp_b = tmp_b + pb[len_b-1-j]*tmp_x[i+j];
tmp_y[indx] = tmp_b;
}
tmp_y[indx] = tmp_y[indx] % p;
}
/* remove the added zeros. */
for(i=0; i < len_x; i++)
pOut[i] = tmp_y[i+len_a];
}
/*--end of GFFILTER()--*/
/*
* gftrunc(a)
* Iwork --- *len_a
*/
static void gftrunc(pa, len_a, len_p, Iwork)
int *pa, *len_a, len_p, *Iwork;
{
int i, len_ind, cut_0;
int *ind;
/*if isempty(a)
* c = a;
*else
* cut_0 = 1;
* if nargin > 1
* if length(tp) > 1
* cut_0 = 0;
* end;
* end;
*/
ind = Iwork;
if ( len_p > 1 )
cut_0 = 0;
else
cut_0 = 1;
/* if cut_0
* ind = find(a ~= 0);
* else
* ind = find(a >= 0);
* end;
*/
len_ind = 0;
if ( cut_0 != 0 ){
for (i=0; i < len_a[0]; i++){
if ( pa[i] != 0 ){
ind[len_ind] = i;
len_ind++;
}
}
} else {
for (i=0; i < len_a[0]; i++){
if ( pa[i] >= 0 ){
ind[len_ind] = i;
len_ind++;
}
}
}
/* if ~isempty(ind)
* c = a(1 : ind(length(ind)));
* else
* if cut_0
* c = 0;
* else
* c = -Inf;
* end;
* end;
*end;
*/
if ( len_ind > 0 ){
len_a[0] = ind[len_ind-1]+1;
} else {
if(cut_0 != 0){
pa[0] = 0;
len_a[0] = 1;
}else{
pa[0] = -Inf;
len_a[0] = 1;
}
}
}
/*--end of GFTRUNC()--*/
/*
* gfpadd(a, b, p) adds two GF(P) polynomials A and B.
* When P is a matrix.
* Iwork --- nc+nc*mp+np
* Iwork = indx
* + *nc = tmp
* + (*nc)*mp = sum
* + np = bottom of Iwork
*/
static void gfpadd(pa, len_a, pb, len_b, pp, np, mp, pc, nc, Iwork)
int *pa, len_a, *pb, len_b, *pp, np, mp, *pc, *nc, *Iwork;
{
int prim, cal_len;
int i, j, k, minus_a, minus_b, len_indx, len_indx_a, len_indx_b;
int *indx, *tmp, *sum;
indx = Iwork;
tmp = indx + nc[0];
sum = tmp + nc[0]*mp;
/* GF(Q^M) field calculation.
* The first row of P is -Inf, second is 1 and so on.
*/
/* handle vector case
* indx = find(a > n_p - 2);
* if ~isempty(indx)
* a(indx) = rem(a(indx), n_p - 1);
* end;
* indx = find(b > n_p - 2);
* if ~isempty(indx)
* b(indx) = rem(b(indx), n_p - 1);
* end;
*/
for(i=0; i < len_a; i++){
if(pa[i] > np-2)
pa[i] = pa[i] % (np - 1);
}
for(i=0; i < len_b; i++){
if(pb[i] > np-2)
pb[i] = pb[i] % (np - 1);
}
/* if (a < 0)
* c = b;
* elseif (b < 0)
* c = a;
* else
*/
minus_a = 0;
minus_b = 0;
for(i=0; i < len_a; i++){
if(pa[i] < 0)
minus_a++;
}
for(i=0; i < len_b; i++){
if(pb[i] < 0)
minus_b++;
}
if( minus_a == len_a ){
nc[0] = len_b;
for(i=0; i < len_b; i++)
pc[i] = pb[i];
} else if(minus_b == len_b){
nc[0] = len_a;
for(i=0; i < len_a; i++)
pc[i] = pa[i];
} else {
/* prim = max(max(p)) + 1;
* indx = find(~(a >= 0));
* a(indx) = - ones(1, length(indx));
* indx = find(~(b >= 0));
* b(indx) = - ones(1, length(indx));
* len_a = length(a);
* len_b = length(b);
*/
prim = 0;
for(i=0; i < np*mp; i++){
if(prim < pp[i])
prim = pp[i] + 1;
}
for(i=0; i < len_a; i++){
if(pa[i] < 0)
pa[i] = -1;
}
for(i=0; i < len_b; i++){
if(pb[i] < 0)
pb[i] = -1;
}
/* if (len_a == len_b)
* tmp = rem(p(a + 2, :) + p(b + 2, :), prim);
* cal_len = len_a;
* elseif (len_a == 1)
* tmp = rem(ones(len_b,1)*p(a + 2, :) + p(b + 2, :), prim);
* cal_len = len_b;
* elseif (len_b == 1)
* tmp = rem(p(a + 2, :) + ones(len_a, 1)*p(b + 2, :), prim);
* cal_len = len_a;
* else
* cal_len = min(len_a, len_b);
* tmp = rem(p(a(1:cal_len) + 2, :) + p(b(1:cal_len) + 2, :), prim);
* end;
*/
if( len_a == len_b && len_a != 1){
for(i=0; i < len_a; i++){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -