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

📄 mod2dense.c

📁 用C语言编写的LDPC译码程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* MOD2DENSE.C - Procedures for handling dense mod2 matrices. *//* Copyright (c) 1996, 2000 by Radford M. Neal  * * Permission is granted for anyone to copy, use, or modify this program  * for purposes of research or education, provided this copyright notice  * is retained, and note is made of any changes that have been made.  * * This program is distributed without any warranty, express or implied. * As this program was written for research purposes only, it has not been * tested to the degree that would be advisable in any important application. * All use of this program is entirely at the user's own risk. */#include <stdlib.h>#include <stdio.h>#include <math.h>#include "alloc.h"#include "intio.h"#include "mod2dense.h"/* ALLOCATE SPACE FOR A DENSE MOD2 MATRIX.  Prints a message and exits if there    is not enough memory available for the matrix. */mod2dense *mod2dense_allocate ( int n_rows, 		/* Number of rows in matrix */  int n_cols		/* Number of columns in matrix */){  mod2dense *m;  int j;  if (n_rows<=0 || n_cols<=0)  { fprintf(stderr,"mod2dense_allocate: Invalid number of rows or columns\n");    exit(1);  }  m = chk_alloc (1, sizeof *m);  m->n_rows = n_rows;  m->n_cols = n_cols;  m->n_words = (n_rows+mod2_wordsize-1) >> mod2_wordsize_shift;  m->col = chk_alloc (m->n_cols, sizeof *m->col);  m->bits = chk_alloc(m->n_words*m->n_cols, sizeof *m->bits);  for (j = 0; j<m->n_cols; j++)  { m->col[j] = m->bits + j*m->n_words;  }  return m;}/* FREE SPACE OCCUPIED BY A DENSE MOD2 MATRIX.  The pointer passed should no   longer be used after mod2dense_free returns. */void mod2dense_free( mod2dense *m		/* Matrix to free */){ free(m->bits);  free(m->col);  free(m);}/* CLEAR A DENSE MOD2 MATRIX.  Sets all the elements of the matrix to 0. */void mod2dense_clear( mod2dense *r){  int k, j;  for (j = 0; j<mod2dense_cols(r); j++)  { for (k = 0; k<r->n_words; k++)    { r->col[j][k] = 0;    }  }}/* COPY A DENSE MOD2 MATRIX.  The first matrix is copied to the second, which   must already have been allocated, and must have dimensions at least as   big as the first.  If the second matrix is larger, elements outside the   boundaries of the first matrix are set to zero. */void mod2dense_copy( mod2dense *m,		/* Matrix to copy */  mod2dense *r		/* Place to store copy of matrix */){   int k, j;  if (mod2dense_rows(m)>mod2dense_rows(r)    || mod2dense_cols(m)>mod2dense_cols(r))  { fprintf(stderr,"mod2dense_copy: Destination matrix is too small\n");    exit(1);  }  for (j = 0; j<mod2dense_cols(m); j++)  { for (k = 0; k<m->n_words; k++)    { r->col[j][k] = m->col[j][k];    }    for ( ; k<r->n_words; k++)    { r->col[j][k] = 0;    }  }  for ( ; j<mod2dense_cols(r); j++)  { for (k = 0; k<r->n_words; k++)    { r->col[j][k] = 0;    }  }}/* COPY COLUMNS OF A DENSE MOD2 MATRIX.  Copies selected columns of the    first matrix to the second matrix (which must already exist, and have    at least as many rows as the first matrix).  The columns to copy   are given in order as an array of length the same as the number of    columns in the second matrix; duplicates are allowed. */void mod2dense_copycols( mod2dense *m,		/* Matrix to copy */  mod2dense *r,		/* Place to store copy of matrix */  int *cols		/* Index of columns to copy, from 0 */){   int k, j;  if (mod2dense_rows(m)>mod2dense_rows(r))  { fprintf(stderr,      "mod2dense_copycols: Destination matrix has fewer rows than source\n");    exit(1);  }  for (j = 0; j<mod2dense_cols(r); j++)  { if (cols[j]<0 || cols[j]>=mod2dense_cols(m))    { fprintf(stderr,"mod2dense_copycols: Column index out of range\n");      exit(1);    }    for (k = 0; k<m->n_words; k++)    { r->col[j][k] = m->col[cols[j]][k];    }    for ( ; k<r->n_words; k++)    { r->col[j][k] = 0;    }  }}/* PRINT A DENSE MOD2 MATRIX IN HUMAN-READABLE FORM.  The matrix is printed   as "0" and "1" characters, with one line of "0"s and "1"s for each row    of the matrix. */void mod2dense_print     ( FILE *f,  mod2dense *m){   int i, j;  for (i = 0; i<mod2dense_rows(m); i++)  { for (j = 0; j<mod2dense_cols(m); j++)    { fprintf(f," %d",mod2dense_get(m,i,j));    }    fprintf(f,"\n");  }}/* WRITE A DENSE MOD2 MATRIX TO A FILE IN MACHINE-READABLE FORM.  Returns    one if successful, zero if an error of some sort occurred.    The data written to the file consists of the number of rows and the   number of columns (in machine-readable, not human-readable, form),   followed by the bits in each column, packed into words.    Data is written using intio_write, so that it will be readable on a machine   with a different byte-ordering.  At present, this assumes that the words    used to pack bits into are no longer than 32 bits. */int mod2dense_write     ( FILE *f,   mod2dense *m){   int j, k;  intio_write(f,m->n_rows);  if (ferror(f)) return 0;  intio_write(f,m->n_cols);  if (ferror(f)) return 0;  for (j = 0; j<mod2dense_cols(m); j++)  {    for (k = 0; k<m->n_words; k++)    { intio_write(f,m->col[j][k]);      if (ferror(f)) return 0;    }  }  return 1;}/* READ A DENSE MOD2 MATRIX STORED IN MACHINE-READABLE FORM FROM A FILE.     The data is expected to be in the format written by mod2dense_write.  The    value returned is zero if some sort of error occurred (either an error    reading the file, or data not in the right format).   The file is left positioned after the last of the data read.  Other data   (such as another matrix) may follow. */mod2dense *mod2dense_read  ( FILE *f){   int n_rows, n_cols;  mod2dense *m;  int j, k;    n_rows = intio_read(f);  if (feof(f) || ferror(f) || n_rows<=0) return 0;  n_cols = intio_read(f);  if (feof(f) || ferror(f) || n_cols<=0) return 0;  m = mod2dense_allocate(n_rows,n_cols);  for (j = 0; j<mod2dense_cols(m); j++)  {    for (k = 0; k<m->n_words; k++)    { m->col[j][k] = intio_read(f);      if (feof(f) || ferror(f))       { mod2dense_free(m);        return 0;      }    }  }  return m;}/* GET AN ELEMENT FROM A DENSE MOD2 MATRIX. */int mod2dense_get  ( mod2dense *m, 	/* Matrix to get element from */  int row,		/* Row of element (starting with zero) */  int col		/* Column of element (starting with zero) */){  if (row<0 || row>=mod2dense_rows(m) || col<0 || col>=mod2dense_cols(m))  { fprintf(stderr,"mod2dense_get: row or column index out of bounds\n");    exit(1);  }  return mod2_getbit (m->col[col][row>>mod2_wordsize_shift],                       row&mod2_wordsize_mask);}/* SET AN ELEMENT IN A DENSE MOD2 MATRIX. */void mod2dense_set ( mod2dense *m, 	/* Matrix to modify element of */  int row,		/* Row of element (starting with zero) */  int col,		/* Column of element (starting with zero) */  int value		/* New value of element (0 or 1) */){   mod2word *w;  if (row<0 || row>=mod2dense_rows(m) || col<0 || col>=mod2dense_cols(m))  { fprintf(stderr,"mod2dense_set: row or column index out of bounds\n");    exit(1);  }  w = &m->col[col][row>>mod2_wordsize_shift];  *w = value ? mod2_setbit1(*w,row&mod2_wordsize_mask)              : mod2_setbit0(*w,row&mod2_wordsize_mask);}/* FLIP AN ELEMENT OF A DENSE MOD2 MATRIX.  Returns the new value of the bit. */int mod2dense_flip  ( mod2dense *m, 	/* Matrix to flip element in */  int row,		/* Row of element (starting with zero) */  int col		/* Column of element (starting with zero) */){  mod2word *w;  int b;  if (row<0 || row>=mod2dense_rows(m) || col<0 || col>=mod2dense_cols(m))  { fprintf(stderr,"mod2dense_flip: row or column index out of bounds\n");    exit(1);  }  b = 1 ^ mod2_getbit (m->col[col][row>>mod2_wordsize_shift],                        row&mod2_wordsize_mask);  w = &m->col[col][row>>mod2_wordsize_shift];  *w = b ? mod2_setbit1(*w,row&mod2_wordsize_mask)          : mod2_setbit0(*w,row&mod2_wordsize_mask);  return b;}/* COMPUTE THE TRANSPOSE OF A DENSE MOD2 MATRIX.  Stores the transpose of    the first matrix in the second matrix (which must already exist, and   have as many rows as the first matrix has columns, and as many columns    as the first matrix has rows).   The result matrix must not be the same as the operand. */void mod2dense_transpose( mod2dense *m,		/* Matrix to compute transpose of (left unchanged) */  mod2dense *r		/* Result of transpose operation */){  mod2word w, v, *p;  int k1, j1, i2, j2;  if (mod2dense_rows(m)!=mod2dense_cols(r)    || mod2dense_cols(m)!=mod2dense_rows(r))  { fprintf(stderr,     "mod2dense_transpose: Matrices have incompatible dimensions\n");    exit(1);  }  if (r==m)  { fprintf(stderr,      "mod2dense_transpose: Result matrix is the same as the operand\n");    exit(1);  }  mod2dense_clear(r);  for (j1 = 0; j1<mod2dense_cols(m); j1++)  {     i2 = j1 >> mod2_wordsize_shift;    v = 1 << (j1 & mod2_wordsize_mask);    p = m->col[j1];    k1 = 0;    for (j2 = 0; j2<mod2dense_cols(r); j2++)    { if (k1==0)      { w = *p++;        k1 = mod2_wordsize;      }      if (w&1)      { r->col[j2][i2] |= v;      }      w >>= 1;           k1 -= 1;    }  }}/* ADD TWO DENSE MOD2 MATRICES.  Adds the first matrix and the second matrix,    storing the result in the third matrix.  Neither of the first two matrices   is changed by this operation.  The three matrices must have the same numbers    of rows and columns.     It is permissible for the result matrix to be the same as one of the    operands. */void mod2dense_add( mod2dense *m1,	/* Left operand of add */  mod2dense *m2,	/* Right operand of add */  mod2dense *r		/* Place to store result of add */){  int j, k;  if (mod2dense_rows(m1)!=mod2dense_rows(r)    || mod2dense_cols(m1)!=mod2dense_cols(r)    || mod2dense_rows(m2)!=mod2dense_rows(r)   || mod2dense_cols(m2)!=mod2dense_cols(r))  { fprintf(stderr,"mod2dense_add: Matrices have different dimensions\n");    exit(1);  }  for (j = 0; j<mod2dense_cols(r); j++)  { for (k = 0; k<r->n_words; k++)    { r->col[j][k] = m1->col[j][k] ^ m2->col[j][k];    }  }

⌨️ 快捷键说明

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