⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gflib.c

📁 density evolution for LDPC codes design and some related documents
💻 C
字号:
/* * GFlib.c * Description: Library for arithmetics over GF(2^x) (1<x <=23) * Author: Tadashi WADAYAMA * Created:1997/11/22 * Copyright (C) 1997 Tadashi WADAYAMA * */#include <stdio.h>#include <stdlib.h>#include "GFlib.h"/*The library "GFlib" offers arithmetics functions over GF(2^x) andfunctions for polynomials over GF(2^x).0. InitializationBefore using the functions  in the following, you need to make tables on Zech logarithm. The function make_table(x)prepares the tables for GF(2^m).1. Arithmetics on GF(2^x)We must declare an variable which stores a value in GF(2^x) type "GF".     Addition        : add(a,b) or  a^b    Multiplication  : mult(a,b)    Inverse         : inv(a)    x-th power of     the primitive     element         : alpha(x)    Power a^b       : power(a,b)    Division        : gfdiv(a,b)2. Polynomial We must declare an variable which stores a polynomial over GF(2^x) type "GF_poly". The type GF_poly consists of two members:  GF_poly A:       A.deg  : the degree of the polynomial A       A.x[i] : the coefficient (in GF(2^x)) corresponding to x^iThe followings are the functions you can use:  void print_poly(FILE* file,GF_poly *a)   Display the polynomial.  void copy_poly(GF_poly *A, GF_poly *B)  Copy from A to B.  void clear_poly(GF_poly *A,int pdeg)  Clear the polynomial A, where  pdeg is the degree of A.  void add_poly(GF_poly *A, GF_poly *B, GF_poly *C)  The result of A + B  is stored in C    void mult_poly(GF_poly *A, GF_poly *B, GF_poly *C)  The result of A * B is stored in C    void div_poly(GF_poly *X, GF_poly *Y, GF_poly *Q, GF_poly *R)  The result of X/Y is stored in Q and the remainder is stored in R  void print_roots(GF_poly *poly)  The roots of the poly is displayed in standard output.*/int* etov; /* etov[exponent] : table for exponent to vector conversion  */int* vtoe; /* vtoe[vector]   : table for vector to exponent conversion */int MODULUS;int MASK;GF gfdiv(GF a, GF b){  if (a == 0) return 0;  if (b == 0) {    fprintf(stderr, "gfdiv : div by zero\n");    exit(-1);  }  return alpha(gflog(a) - gflog(b));}GF inv(GF a){  if (a == 1) return  1;  else return etov[MODULUS-vtoe[a]];}GF mult(GF a, GF b){  if (a == 0 || b == 0) return 0;  else return etov[(vtoe[a] + vtoe[b]) % MODULUS];}GF alpha(int x)	{  if (x >= 0) return etov[x % MODULUS ];  else return etov[(MODULUS + x) % MODULUS ];}GF power(int a, int b){  if (b == 0) return 1;  if (a == 0) return 0;  if (b < 0) {    b = -b;    a = inv(a);  }  return etov[(vtoe[a] * b) % MODULUS];}int make_table(int x){  int i, poly;    switch (x) {   case 2:     poly =   07; MASK=03;break; /* x^2 + x + 1 */  case 3:     poly =  013; MASK=07;break; /* x^3 + x + 1 */  case 4:     poly =  023; MASK=017;break; /* x^4 + x + 1 */  case 5:     poly =  045; MASK=037;break; /* x^5 + x^2 + 1 */  case 6:     poly = 0103; MASK=077;break; /* x^6 + x + 1 */  case 7:     poly = 0203; MASK=0177;break; /* x^7 + x + 1 */  case 8:     poly = 0435; MASK=0377;break; /* x^8+x^4+x^3+x^2+1 */				/* 11/22 */  case 9:     poly = 01021; MASK=0777;break; /*  1 000 010 001  */  case 10:     poly = 02011; MASK=01777;break; /* 10 000 001 001 */  case 11:     poly = 04005; MASK=03777;break; /* 100 000 000 101 */  case 12:     poly = 010123; MASK=07777;break; /* 1 000 001 010 011 */  case 13:     poly = 020033; MASK=017777;break; /* 10 000 000 011 011 */  case 14:     poly = 042103; MASK=037777;break; /* 100 010 001 000 011 */  case 15:     poly = 0100003; MASK=077777;break; /* 1 000 000 000 000 011 */  case 16:     poly = 0210013; MASK=0177777;break; /* 10 001 000 000 001 011 */  case 17:     poly = 0400011; MASK=0377777;break; /* 100 000 000 000 001 001 */  case 18:     poly = 01000201; MASK=0777777;break; /* 1 000 000 000 010 000 001 */  case 19:     poly = 02000047; MASK=01777777;break; /* 10 000 000 000 000 100 111 */  case 20:     poly = 04000011; MASK=03777777;break; /* 100 000 000 000 000 001 001 */  case 21:     poly = 010000005; MASK=07777777;break; /* 1 000 000 000 000 000 000 101 */  case 22:     poly = 020000003; MASK=017777777;break; /* 10 000 000 000 000 000 000 011*/  case 23:     poly = 040000041; MASK=037777777;break;/* 100 000 000 000 000 000 100 001*/  default: fprintf(stderr,"maketable: invalid argument.\n");    exit(-1);  }   MODULUS = (1<<x)-1;  if ((etov = (int*)malloc(sizeof(int)*(MODULUS+1))) == NULL) {    fprintf(stderr,"Can't allocate memory\n");    exit(-1);  }  if ((vtoe = (int*)malloc(sizeof(int)*(MODULUS+1))) == NULL) {    fprintf(stderr,"Can't allocate memory\n");    exit(-1);  }  etov[0] = 1;  for (i = 1; i <= MODULUS - 1; i++) {    etov[i] = etov[i-1] << 1;    if (((etov[i]>>x)&1) == 1) etov[i] ^= poly;    vtoe[etov[i]] = i;  }  vtoe[0] = -1;  return MODULUS;}void print_poly(FILE* fp, GF_poly *a){  int i;  for (i = 0; i <= a->deg; i++) {    if (a->x[i] != 0)  {      fprintf(fp,"a[%d] x^%d",vtoe[a->x[i]],i);      if (i != a->deg) fprintf(fp," + ");    }  }  fprintf(fp,"\n");}void copy_poly(GF_poly *A, GF_poly *B){  int i;  B->deg = A->deg;  for (i = 0; i <= A->deg; i++) {    B->x[i] = A->x[i];  }}void add_poly(GF_poly *A, GF_poly *B, GF_poly *C){  int i;    C->deg = A->deg;   if (A->deg > B->deg) {    for (i = B->deg+1; i<=A->deg; i++) B->x[i] = 0;  }  if (A->deg < B->deg) {    C->deg = B->deg;     for (i = A->deg+1; i<=B->deg; i++) A->x[i] = 0;  }  for (i = 0; i <= C->deg; i++)     C->x[i] = add(A->x[i], B->x[i]);  i = C->deg;  while ( (C->x[i] == 0) && (i > 0)) i--;  C->deg = i;}void mult_poly(GF_poly *A, GF_poly *B, GF_poly *C){  int i, ia, ib;  if (((A->deg == 0) && (A->x[0] == 0)) || ((B->deg == 0) && (B->x[0] == 0))) {    C->deg = 0;    C->x[0] = 0;    return;  }  C->deg = A->deg + B->deg;  for (i = 0; i <= C->deg; i++) {    C->x[i] = 0;  }  for (ib = 0; ib <= B->deg; ib++) {    for(ia = 0; ia <= A->deg; ia++) {      C->x[ia + ib] ^= mult(A->x[ia],B->x[ib]);    }  }}void div_poly(GF_poly *X, GF_poly *Y, GF_poly *Q, GF_poly *R){  int i, qi, yi;  GF inverse_y_head;  GF quotient;  if ((Y->deg == 0) && (Y->x[0] == 0)) {    fprintf(stderr,"div_poly: div by zero\n");    exit(-1);  }  while (X->x[X->deg] == 0)    X->deg--;  while (Y->x[Y->deg] == 0)    Y->deg--;  inverse_y_head = inv(Y->x[Y->deg]);  Q->deg = X->deg - Y->deg;  R->deg = X->deg;  for (i = 0; i <= R->deg; i++) R->x[i] = X->x[i];  if (X->deg < Y->deg) {    Q->deg = 0;    Q->x[0] = 0;    R->deg = X->deg;    return;  }  for (qi = 0; qi <= Q->deg; qi++) {    quotient = mult( R->x[R->deg - qi], inverse_y_head);    Q->x[Q->deg - qi] = quotient;    for (yi = 0; yi <= Y->deg; yi++) {      R->x[R->deg - yi - qi] ^= 	    mult(quotient,Y->x[Y->deg - yi]);    }  }  i = R->deg;  while((R->x[i] == 0)&&(i>0)) i--;  R->deg = i;}void print_roots(GF_poly *poly){  GF i;  printf("roots: ");  for (i = 0; i <= MODULUS; i++) {    if (subst(poly,i) == 0) {      printf("a[%d]  ",gflog(i));    }  }  printf("\n");}GF subst(GF_poly *a, GF in){  int i;  GF sum;  sum = 0;    if (in == 0) return a->x[0];  for (i = 0; i <= a->deg; i++) {    if (a->x[i] != 0)       sum ^= mult(a->x[i],etov[(vtoe[in]*i) % MODULUS]);  }  return sum;}void clear_poly(GF_poly *a,int pdeg){  int i;   a->deg = 0;  for (i = 0; i <= pdeg; i++) {    a->x[i] = 0;  }  a->deg = pdeg;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -