📄 decode.c
字号:
/* DECODE.C - Decode blocks of received data. *//* Copyright (c) 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 <stdio.h>#include <stdlib.h>#include <math.h>#include "rand.h"#include "alloc.h"#include "blockio.h"#include "mod2sparse.h"#include "mod2dense.h"#include "mod2convert.h"#include "rcode.h"#include "dec.h"void usage(void);unsigned enum_decode (double *, char *, double *, int);/* MAIN PROGRAM. */int main( int argc, char **argv){ enum { BSC, AWGN } channel; enum { Enum_block, Enum_bit, Prprp } method; double error_prob, std_dev; int max_iter, table; char *pchk_file, *rfile, *dfile, *pfile; char **chan, **meth; char *gen_file; FILE *rf, *df, *pf; char *dblk, *pchk; double *awgn_data; double *lratio; double *bitpr; int *bsc_data; float tot_iter; int tot_valid; unsigned iters; char junk; int valid; int i, j, n; /* Look at arguments. */ table = 0; if (argc>1 && strcmp(argv[1],"-t")==0) { table = 1; argc -= 1; argv += 1; } if (!(pchk_file = argv[1]) || !(rfile = argv[2]) || !(dfile = argv[3])) { usage(); } if (argc==8) { pfile = 0; chan = argv+4; meth = argv+6; } else if (argc==9) { pfile = argv[4]; chan = argv+5; meth = argv+7; } if (strcmp(chan[0],"bsc")==0 || strcmp(chan[0],"BSC")==0) { channel = BSC; if (sscanf(chan[1],"%lf%c",&error_prob,&junk)!=1 || error_prob<=0 || error_prob>=1) { usage(); } } else if (strcmp(chan[0],"awgn")==0 || strcmp(chan[0],"AWGN")==0) { channel = AWGN; if (sscanf(chan[1],"%lf%c",&std_dev,&junk)!=1 || std_dev<=0) { usage(); } } else { usage(); } if (strcmp(meth[0],"prprp")==0) { method = Prprp; if (sscanf(meth[1],"%d%c",&max_iter,&junk)!=1) usage(); } else if (strcmp(meth[0],"enum-block")==0) { method = Enum_block; gen_file = meth[1]; } else if (strcmp(meth[0],"enum-bit")==0) { method = Enum_bit; gen_file = meth[1]; } else { usage(); } /* Read parity check file. */ read_pchk(pchk_file); if (N<=M) { fprintf(stderr, "Number of bits (%d) should be greater than number of checks (%d)\n",N,M); exit(1); } /* Open file of received data. */ rf = fopen(rfile,"r"); if (rf==NULL) { fprintf(stderr,"Can't open file of received data: %s\n",rfile); exit(1); } /* Create file for decoded data. */ df = fopen(dfile,"w"); if (df==NULL) { fprintf(stderr,"Can't create file for decoded data: %s\n",dfile); exit(1); } /* Create file for bit probabilities, if specified. */ if (pfile) { pf = fopen(pfile,"w"); if (pf==NULL) { fprintf(stderr,"Can't create file for bit probabilities: %s\n",pfile); exit(1); } } /* Allocate space. */ switch (channel) { case BSC: { bsc_data = chk_alloc (N, sizeof *bsc_data); break; } case AWGN: { awgn_data = chk_alloc (N, sizeof *awgn_data); break; } default: { abort(); } } dblk = chk_alloc (N, sizeof *dblk); lratio = chk_alloc (N, sizeof *lratio); pchk = chk_alloc (M, sizeof *pchk); bitpr = pfile || method==Enum_bit ? chk_alloc (N, sizeof *bitpr) : 0; /* Read generator file, if decoding by exhaustive enumeration. Also make sure we don't have more than 31 message bits in this case. */ if (method==Enum_block || method==Enum_bit) { read_gen(gen_file,0,0); if (N-M>31) { fprintf(stderr,"Trying to decode messages with %d bits by exhaustive enumeration is absurd!\n", N-M); exit(1); } } /* Print header for table. */ if (table) { printf(" block iterations valid\n"); } /* Read received blocks, decode, and write decoded blocks. */ tot_iter = 0; tot_valid = 0; for (n = 0; ; n++) { /* Read block from received file, exit if end-of-file encountered. */ for (i = 0; i<N; i++) { int c; switch (channel) { case BSC: c = fscanf(rf,"%1d",&bsc_data[i]); break; case AWGN: c = fscanf(rf,"%lf",&awgn_data[i]); break; default: abort(); } if (c==EOF) { if (i>0) { fprintf(stderr, "Warning: Short block (%d long) at end of received file ignored\n",i); } goto done; } if (c<1 || channel==BSC && bsc_data[i]!=0 && bsc_data[i]!=1) { fprintf(stderr,"File of received data is garbled\n"); exit(1); } } /* Find likelihood ratio for each bit. */ switch (channel) { case BSC: { for (i = 0; i<N; i++) { lratio[i] = bsc_data[i]==1 ? (1-error_prob) / error_prob : error_prob / (1-error_prob); } break; } case AWGN: { for (i = 0; i<N; i++) { lratio[i] = exp(2*awgn_data[i]/(std_dev*std_dev)); } break; } default: abort(); } /* Try to decode. */ switch (method) { case Prprp: { iters = prprp_decode (H, lratio, dblk, pchk, bitpr, max_iter); break; } case Enum_block: case Enum_bit: { iters = enum_decode (lratio, dblk, bitpr, method==Enum_block); break; } default: abort(); } valid = check (H, dblk, pchk); tot_iter += iters; tot_valid += valid; /* Print table entry. */ if (table) { printf("%7d %10d %d\n",n,iters,valid); fflush(stdout); } /* Write decoded block. */ blockio_write(df,dblk,N); /* Write bit probabilities, if asked to. */ if (pfile) { for (j = 0; j<N; j++) { fprintf(pf," %.5f",bitpr[j]); } fprintf(pf,"\n"); } } /* Finish up. */done: fprintf(stderr, "Decoded %d blocks of size %d, %d valid, in average of %.1f iterations\n", n, N, tot_valid, tot_iter/n); if (ferror(df) || fclose(df)!=0) { fprintf(stderr,"Error writing decoded blocks to %s\n",dfile); exit(1); } if (pfile) { if (ferror(pf) || fclose(pf)!=0) { fprintf(stderr,"Error writing bit probabilities to %s\n",dfile); exit(1); } } exit(0);}/* PRINT USAGE MESSAGE AND EXIT. */void usage(void){ fprintf(stderr,"Usage:\n decode [ -t ] pchk-file received-file decoded-file [ bp-file ] channel method\n"); fprintf(stderr,"Channel: bsc error-probability | awgn standard-deviation\n"); fprintf(stderr,"Method: enum-block gen-file | enum-bit gen-file | prprp [-]max-iterations\n"); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -