📄 code4r.c
字号:
/* code4r.c (c) DJCM 94 07 04 94 10 26 94 10 31 95 01 02 95 02 23 (from mnc2 to mnc3) 95 04 01 continued work on mnc3 95 05 01 to mnc4 95 05 02 to code4 95 05 13 to code4r 95 09 26 allow -m - stripped out of mnc4.c to be a special purpose code generator and writer; makes sparse (part-invertible) matrix and writes out the alist matrix, to save everyone making the same inverse The matrix is generated in its transpose, from bottom to top. The invertible bit of the matrix is at the end (the bottom) But actually it's not invertible any more if CHEAP is used usage: code4r -n N -rho rho -seed seed -t1 5 (-t2 5) -o outfile (Default MNC4/N.t1.t2.seed) e.g. code4r -n 1000 -t1 5 -v 0 -rho 1*/#include "./ansi/r.h"#include "./ansi/rand2.h" #include "./ansi/mynr.h"#include "./ansi/cmatrix.h"/* these three are irrelevant: */#include "./ansi/macopt.h"#include "./thing_sort.h"#include "./fe.h"#include "./mnc.h"#include "./code4.h"static void dc_defaults ( code_creation * ) ; static int process_command ( int , char ** , code_creation * ) ; static void print_usage ( char ** , FILE * , code_creation * );static int make_sense ( code_creation * ) ; static int make_code ( code_creation * , mnc_code * , alist_matrix * ) ;static int cheap_make_code ( code_creation * , alist_matrix * ) ;static int report_code ( code_creation * , mnc_code * , alist_matrix * ) ;static int make_space ( code_creation * , mnc_code * , alist_matrix * ) ; static int check_code ( unsigned char ** , int , int , int ) ; static int show_distances ( unsigned char ** , int , int , int ) ; static int check_alist ( alist_matrix * , code_creation * ) ;static int free_code ( code_creation * , mnc_code * ) ;void main ( int , char ** ) ;/* MAIN */void main ( int argc, char *argv[] ){ FILE *fp ; code_creation dc ; mnc_code code ; alist_matrix a ; dc_defaults ( &dc ) ; if ( process_command (argc, argv, &dc ) < 0 ) exit (0) ; if ( make_sense ( &dc ) < 0 ) exit (0) ; if ( make_space ( &dc , &code , &a ) < 0 ) exit (0) ; fprintf(stderr,"code4r MNC=%d, N=%d, rho=%f\n", dc.MNC , dc.N , dc.rho ) ; fflush(stderr); if ( dc.cheap ) { if ( cheap_make_code ( &dc , &a ) < 0 ) { printf ( "FAILED\n" ) ; exit ( 0 ) ; } } else if ( make_code ( &dc , &code , &a ) < 0 ) { report_code ( &dc , &code , &a ) ; printf ( "FAILED\n" ) ; exit ( 0 ) ; } if ( check_alist ( &a , &dc ) < 0 ) { if ( dc.cheap == 0 ) { report_code ( &dc , &code , &a ) ; } printf ( "FAILED\n" ) ; exit ( 0 ) ; } if ( dc.cheap == 0 ) free_code ( &dc , &code ) ; if ( dc.out ) { fp = fopen ( dc.outfile , "w" ) ; if ( !fp ) { fprintf ( stderr , "can't open %s\n" , dc.outfile ) , exit (0) ; } write_alist_transpose ( fp , &a ) ; fclose ( fp ) ; } free_alist ( &a ) ; if ( dc.verbose ) { read_allocate_alist ( &a , dc.outfile ) ; if ( dc.out ) { fp = fopen ( "tmpout" , "w" ) ; if ( !fp ) { fprintf ( stderr , "can't open %s\n" , dc.outfile ) , exit (0) ; } write_alist ( fp , &a ) ; fclose ( fp ) ; } free_alist ( &a ) ; printf ( "diff tmpout %s\n" , dc.outfile ) ; }}static int make_sense ( code_creation *dc ) { /* routine to correct silly control parameters */ int status = 0 ; char junk[100] ; if ( dc->M == 0 ) { dc->NS = (int) ( (double)(dc->N) * dc->rho ) ; /* signal block */ } else { dc->NS = dc->M ; } if ( dc->pC2.per_row == 0 ) dc->pC2.per_row = dc->pC1.per_row ; sprintf ( junk , "MNC%d%s/%d.%d.%d.%ld" , dc->MNC , ( dc->cheap ? "RC" : "R" ) , dc->N , dc->NS , dc->pC1.per_row ,/* dc->pC2.per_row , */ dc->seed ) ; if ( dc->out==1 ) sprintf ( dc->outfile , "%s" , junk ) ; printf ( "code will be written to %s\n" , dc->outfile ) ; return status ; }static int make_space ( code_creation *dc , mnc_code *code , alist_matrix *a) { int status = 0 ; int tr , tc , M , N ; if ( dc->verbose ) printf ( "Making space\n" ) ; N = dc->NS + dc->N ; M = dc->N ; tc = MAX ( dc->pC1.per_row , dc->pC2.per_row ) + 5 ; tr = tc + (int)( (double) dc->pC2.per_row * dc->rho ) ; if ( dc->verbose ) printf ( "for up to %d per col and %d per row\n" , tc , tr ) ; if (dc->cheap ) initialize_alist ( a , M , N , tr , tc ) ; else initialize_alist ( a , N , M , tc , tr ) ; return status ; }static int make_code ( code_creation *dc , mnc_code *code , alist_matrix *a ) { int status = 0 ; FILE *fp ; char junk[100] ; int i , j ; if ( dc->verbose > 1 ) printf ( "s.%6ld." , dc->seed ) ; fflush (stdout ) ; if ( dc->verbose ) printf ( "Making code\n" ) ; ran_seed ( dc->seed ) ; /* New convention. Code is defined as a transpose*/ code->C1 = cmatrix ( 1 , dc->N + dc->NS , 1 , dc->N ) ; for ( i = dc->N + dc->NS ; i >= 1 ; i-- ) for ( j = 1 ; j <= dc->N ; j++ ) code->C1[i][j] = 0 ; do {/* old version sparse_rectangular_cmatrix ( code->C1 , dc->pC1.per_row , dc->N , dc->N + dc->NS , dc->hd ) ;*//* new version makes the square bit first then the other bit; puts the square bit at the RIGHT HAND end*/ sparse_rectangular_cmatrix2 ( code->C1 + dc->NS , 0 , dc->pC1.per_row , dc->N , dc->N , dc->hd ) ; code->C1I = cmatrix ( 1 , dc->N , 1 , dc->N ) ; printf ( "Inverting.." ) ; fflush (stdout ) ; invert_left_hand_end_cmatrix ( code->C1 + dc->NS , code->C1I , dc->N ) ; /* for real implementation, the code inverse should be written somewhere for the encoder to use */ printf ( "Making rest.." ) ; fflush (stdout ) ; sparse_rectangular_cmatrix2 ( code->C1 , dc->N , dc->pC1.per_row , dc->N , dc->N + dc->NS , dc->hd ) ; /* goes back to the last column for HD purposes, but only generates from dc->NS back */ if ( dc->showhd ) status = show_distances ( code->C1 , dc->N , dc->N + dc->NS , dc->showhd ) ; /* see the hamming distances too if you want */ if ( dc->checkhd ) status = check_code ( code->C1 , dc->N , dc->N + dc->NS , dc->checkhd ) ; /* or just check them internally */ } while ( status < 0 ) ; /* keep on making a random matrix till the hamming distance is satisfied (if dc->hd > 0 then hamming distances are checked immediately while making the code */ printf ( "done; making alist\n" ) ; fflush (stdout ) ; status += gen_cmatrix_2_alist ( code->C1 , a , dc->N , dc->N + dc->NS , dc->transpose ) ; /* 1= transpose */ if ( dc->pbm_o ) { fp = fopen ( dc->pbm_ofile , "w" ) ; if ( !fp ) fprintf ( stderr , "can't open %s \n" , dc->pbm_ofile ) ; else { cmatrix2pbm ( code->C1 , 1 , dc->N + dc->NS , 1 , dc->N , fp ) ; fclose ( fp ) ; } if ( dc->pbm_xv ) { sprintf ( junk , "xv %s -geometry +10+10 &" , dc->pbm_ofile ) ; system ( junk ) ; } } return status ; }static int cheap_make_code ( code_creation *dc , alist_matrix *a ) { int status = 0 ; if ( dc->verbose ) printf ( "Making code\n" ) ; ran_seed ( dc->seed ) ; status += sparse_rectangular_alist ( a , 0 , dc->N , dc->pC1.per_row , dc->N , dc->N + dc->NS , dc->hd ) ; status += sparse_rectangular_alist ( a , dc->N , dc->N + dc->NS , dc->pC1.per_row , dc->N , dc->N + dc->NS , dc->hd ) ; /* goes back to the last column for HD purposes, but only generates from dc->NS back */ status += finish_off_alist ( a ) ; return status ; }static int check_code ( unsigned char **A , int M , int N , int hd ) { /* compares all column pairs */ int c1 , c2 , m , i ; int status = 0 ; printf ( "checking hamming distances.." ) ; fflush (stdout ) ; for ( c1 = 1 ; c1 <= N ; c1 ++ ) { for ( c2 = c1 + 1 ; c2 <= N ; c2 ++ ) { i = 0 ; for ( m = 1 ; m <= M && ( i <= hd ) ; m++ ) { i += A[m][c1] ^ A[m][c2] ; } /* i is the hamming distance between cols */ if ( i <= hd ) { fprintf ( stderr , "cols %d %d hd %d\n" , c1 , c2 , i ) ; status -- ; } } } printf ( "done\n" ) ; fflush (stdout ) ; return status ;}static int show_distances ( unsigned char **A , int M , int N , int hd ) { /* compares all column pairs */ int c1 , c2 , m , i ; int status = 0 ; FILE *fp ; char ofile[100] ; char junk[200] ; unsigned char **B ; printf ( "checking hamming distances.." ) ; fflush (stdout ) ; sprintf ( ofile ,"tmp.pbm" ) ; B = cmatrix ( 1,N,1,N ) ; for ( c1 = 1 ; c1 <= N ; c1 ++ ) { for ( c2 = 1 ; c2 <= c1 ; c2 ++ ) { B[c1][c2] = 0 ; } for ( c2 = c1 + 1 ; c2 <= N ; c2 ++ ) { i = 0 ; for ( m = 1 ; m <= M && ( i <= hd ) ; m++ ) { i += A[m][c1] ^ A[m][c2] ; } /* i is the hamming distance between cols */ B[c1][c2] = ( i <= hd ) ? 1 : 0 ; if ( i <= hd ) status -- ; } } fp = fopen ( ofile , "w" ) ; if ( !fp ) fprintf ( stderr , "can't open %s \n" , ofile ) ; else { cmatrix2pbm ( B , 1 , N , 1 , N , fp ) ; fclose ( fp ) ; } sprintf ( junk , "xv %s -geometry +10+10 &" , ofile ) ; system ( junk ) ; free_cmatrix ( B , 1,N,1,N ) ; printf ( "done\n" ) ; fflush (stdout ) ; return status ;}static int report_code ( code_creation *dc , mnc_code *code , alist_matrix *a ) { int status = 0 ; if ( dc->verbose ) printf ( "The code\n" ) ; if ( dc->verbose ) { printoutcmatrix ( code->C1 , 1 , dc->N , 1 , dc->N ) ; } report_alist ( a , dc->verbose + 1 ) ; return status ; }static int free_code ( code_creation *dc , mnc_code *code ) {/* frees up the C matrix bit of the code (leaving the alist alone) */ int status = 0 ; int N = dc->N ; free_cmatrix ( code->C1 , 1 , N + dc->NS , 1 , N ) ; free_cmatrix ( code->C1I , 1 , N , 1 , N ) ; return status ; }static int check_alist ( alist_matrix *alist , code_creation *dc ){ int status = 0 ; int tmpi = 0 , n , m , MNC = dc->MNC ; if ( dc->verbose ) printf ( "Checking alist\n" ) ; if ( MNC == 0 || MNC == 1 || MNC == 2 || MNC == 4 ) { /* then every col should have more than 1 1 in it */ for ( n = 1 ; n <= alist->N ; n ++ ) { if ( alist->num_nlist[n] <= 1 ) { tmpi ++ ; fprintf ( stderr , "%d:" , n ) ; } } if ( tmpi > 0 ) { fprintf ( stderr , "Warning unchecked bits n : %d\n", tmpi ) ; status -- ; } } if ( MNC == 1 || MNC == 2 || MNC == 3 || MNC == 4 ) { /* then every row should have more than 1 1 in it */ tmpi = 0 ; for ( m = 1 ; m <= alist->M ; m ++ ) { if ( alist->num_mlist[m] <= 1 ) { tmpi ++ ; fprintf ( stderr , "%d:" , m ) ; } } if ( tmpi > 0 ) { fprintf ( stderr , "Warning unchecked bits n : %d\n", tmpi ) ; status -= 10 ; } } if ( status < 0 && dc->verbose ) { fprintf ( stderr , "Failing ... here is the offending alist\n" ) ; report_alist ( alist , 2 ) ; } else if ( dc->verbose >= 2 ) { report_alist ( alist , dc->verbose ) ; } return status ; }static void dc_defaults ( code_creation *dc ) {#include "code4_var_def.c"}static int process_command ( int argc , char **argv , code_creation *dc ) { int p_usage = 0 ; int status = 0 ; int cs , i , fake ; if ( argc < 1 ) { p_usage = 1 ; status -- ; }#define ERROR1 fprintf ( stderr , "arg to `%s' missing\n" , argv[i] ) ; \ status --#define ERROR2 fprintf ( stderr , "args to `%s' missing\n" , argv[i] ) ; \ status --#define ERRORREG fprintf ( stderr , "regtype must be defined before `%s'\n" , argv[i] ) ; \ status -- for (i = 1 ; i < argc; i++) { cs = 1 ; if ( strcmp (argv[i], "-fake") == 0 ) { if ( i + 1 == argc ) { ERROR1; } else cs *= sscanf(argv[++i], "%d", &(fake)); } #include "code4_var_clr.c" else { fprintf ( stderr , "arg `%s' not recognised\n" , argv[i] ) ; p_usage = 1 ; status -- ; } if ( cs == 0 ) { fprintf ( stderr , "arg at or before `%s' has incorrect format\n" , argv[i] ) ; p_usage = 1 ; status -- ; } } if ( p_usage ) print_usage ( argv , stderr , dc ) ; return ( status ) ;}#undef ERROR1#undef ERROR2#undef ERRORREG#define DNT fprintf( fp, "\n ")#define NLNE fprintf( fp, "\n")static void print_usage ( char **argv , FILE * fp , code_creation *dc){ fprintf( fp, "Usage: %s ",argv[0]); fprintf( fp, " [optional arguments]");#include "code4_var_usg.c" return ;}#undef DNT#undef NLNE/*<!-- hhmts start -->Last modified: Wed Nov 8 14:24:28 1995<!-- hhmts end -->*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -