📄 ldpc_decode_ics.c
字号:
PR_DBG( 0, "One of the chest's is not defined\n" ); return -1; } } for ( i=0; i<private->no_rx; i++ ){ var_real[i] = max( swr_sdb_get_stats_int( private->chest[i], "noise_var_real" ), 1 ); var_imag[i] = max( swr_sdb_get_stats_int( private->chest[i], "noise_var_imag" ), 1 ); // here we get the channel transfer matrix (one tap !!!!) ch[i] = swr_sdb_get_stats_block( private->chest[i], "transfer_matrix" ).data; } // =============== ME ! PAY ATTENTION !!! :-)) // Here we prepare the table of f's needed for the "left" itterations // Attention at the mapping! we map [x0 x1 x2 x3] in bar[x3 x2 x1 x0] // This is because we need them like that in the algorithm in decodehelpers.c for ( i=0; i<private->no_rx; i++ ) { for ( j=0; j<private->no_tx; j++ ) { h[i][j] = ch[i][j]; } } // print the channel and the variance to compare with the one which we estimate later // works for a = 0.01 for ( i=0; i<private->no_rx; i++ ){ for ( j=0; j<private->no_tx; j++ ){ PR_DBG_CL( 4, "est-h%i%i(%i:%ii) ", i, j, h[i][j].real, h[i][j].imag ); } } for ( i=0; i<private->no_rx; i++ ){ PR_DBG_CL( 4, "est-var%i(%i:%ii) ", i, var_real[i], var_imag[i] ); } PR_DBG_CL( 4,"\n"); // here we compute the mean and the variance of the h_{ij}'s // needed to compute the true sigma // then we compute the true snr mean_h = 0.0; var_h = 0.0; mean_sigmanoise = 0.0; for ( i=0; i<private->no_rx; i++ ){ for ( j=0; j<private->no_tx; j++ ){ mean_h += h[i][j].real + h[i][j].imag; var_h += pow(h[i][j].real,2) + pow(h[i][j].imag,2); } } if (private->no_tx > 0 && private->no_rx > 0){ mean_h /= 2*private->no_rx*private->no_tx; var_h /= 2*private->no_rx*private->no_tx; } else PR_DBG_CL( 0," Hey, number of tx or rx antennas is 0!!! \n"); if (var_h > pow(mean_h,2)) var_h = sqrt(var_h - pow(mean_h,2)); else PR_DBG_CL( 0," Hey, you have some negative variance of H!!! \n"); PR_DBG_CL( 4,"\n"); PR_DBG_CL( 4, "mean of h = %g \n", mean_h ); PR_DBG_CL( 4, "variance of h = %g \n", var_h ); for ( i=0; i<private->no_rx; i++ ){ mean_sigmanoise += sqrt((double)var_real[i]) + sqrt((double)var_imag[i]); } mean_sigmanoise /= 2*private->no_rx; PR_DBG_CL( 4, "mean noise variance = %g \n", mean_sigmanoise ); true_sigma = 0.0; true_snr = 0.0; code_rate = 0.0; code_rate = 1.0 - (double)cnodenum/(double)vnodenum; PR_DBG_CL( 4, "check = %i, variab = %i, rate of the code = %g \n", cnodenum, vnodenum, code_rate); if (var_h > 0) true_sigma = mean_sigmanoise/var_h; else PR_DBG_CL( 0," Hey, you have some negative variance of var_h!!! \n"); if (true_sigma > 0) true_snr = -10*log10((4*pow(true_sigma,2)*code_rate)/private->no_rx); else PR_DBG_CL( 0," Hey, you have some negative variance of true_sigma!!! \n"); PR_DBG_CL( 4, "true snr = %g \n", true_snr ); for (n=0; n<vnodenum/private->graph->bits_per_left_checknode; n++){ // for (n=0; n<20; n++){ for ( i=0; i<private->no_rx; i++ ){ y[i] = in[i][n]; PR_DBG_CL( 4, "y[%i](%i:%ii) ", i, y[i].real, y[i].imag ); } for( i = 0; i < (1 << private->graph->bits_per_left_checknode); i++){ for(j = 0; j < private->graph->bits_per_left_checknode; j++){ x[j] = ((1 << j) & i) ? -1:1; x[j] /= sqrt(2); PR_DBG_CL( 4, "%2g ", x[j] ); } p = n*( 1 << private->graph->bits_per_left_checknode )+i; // compute y-Hx and sum and get f f = 0.0; for ( j=0; j<private->no_rx; j++ ) { w = 0; for ( k=0; k<private->no_tx; k++ ){ z = x[2*k] + x[2*k+1] * I; u = h[j][k].real + h[j][k].imag * I; w += z * u; } f += pow( (y[j].real - creal( w )), 2)/(2*var_real[j]) + pow( (y[j].imag - cimag( w )), 2)/(2*var_imag[j]); } private->graph->f[p] = -f; PR_DBG_CL( 4,"f = %g \n", -f) } } PR_DBG_CL( 4," f[0] = %g, f[1] = %g, f[2] = %g, f[3] = %g \n", private->graph->f[0], private->graph->f[1], private->graph->f[2], private->graph->f[3]); } PR_DBG( 1, "Initializing graph\n" ); initializegraph(private->graph); for ( i=0; i<private->iterations; i++ ){ for ( j=0; j<private->iterations_left; j++ ){ leftfoldmap( private->graph ); } for ( j=0; j<private->iterations_right; j++ ){ variablemessagemap(private->graph); checkmessagemap(private->graph); } } PR_DBG( 1, "Making decisions\n" ); makedecisions(private->graph, decisions); //copy decoded data to output j=-1; if( size_out(0)*8 < dnodenum ){ PR_DBG( 1,"output to small: decoded information (%i) does not fit in %i\n", size_out(0) * 8, dnodenum ); } for ( i=0; i<min( dnodenum, size_out(0)*8 ); i++ ){ if ( !( i % 8 ) ){ j++; out[j] = 0; } out[j] += decisions[i] << ( i % 8 ); } for ( i=dnodenum; i<size_out(0)*8; i++ ){ if ( !( i % 8 ) ){ j++; out[j] = 0; } } PR_DBG( 1, "Finished\n" ); // Clean up swr_free (decisions); // And calculate the snr for further use swr_sdb_get_stats_struct( context->id, (void**)&stats ); stats->h_var = var_h; stats->true_sigma = true_sigma; stats->true_snr = true_snr; swr_sdb_free_stats_struct( context->id, (void**)&stats ); PR_DBG( 4, "Exiting\n" ); return(0);}/** * User messages */int ics_rcv_custom_msg( swr_sdb_t *context, swr_usr_msg_t *data, swr_msgq ret ){ return 0;}/* * This is the `destructor'. */int ics_rcv_finalize( swr_sdb_t *context ){ swr_free( private->graph ); if ( sizeof( private_t ) > 0 ) swr_free( private ); MOD_DEC_USE_COUNT; return 0;}/* * This function is called upon "insmod" and is used to register the * different parts of the module to the SPM. */swr_spc_id_t ics_rcv_id;int ics_rcv_module_init(void){ swr_spc_desc_t *desc;// int i; /** * Get a description-part from CDB * Give the following parameters: * Input-ports, output-ports, config-params, stat-params */ desc = swr_spc_get_new_desc( MAX_NO_RX, 1, 12, 3 ); if ( !desc ){ PR_DBG( 0, "Can't initialise the module. This is BAD!\n" ); return -1; } /** * Define the different parts of config and stats. You have to define * them in the same order as they appear in the structures. The names * can be freely chosen. * * UM_CONFIG_{INT,DOUBLE,STRING128,POINTER}( "name" ); * UM_STATS_{INT,DOUBLE,STRING128,POINTER,BLOCK}( "name" ); */ UM_CONFIG_INT( "iterations" ); UM_CONFIG_INT( "iterations_left" ); UM_CONFIG_INT( "iterations_right" ); UM_CONFIG_INT( "ldpc_code_id" ); UM_CONFIG_DOUBLE( "channel_param" ); UM_CONFIG_INT( "no_tx" ); UM_CONFIG_INT( "no_rx" ); UM_CONFIG_INT( "chest" ); UM_CONFIG_INT( "chest2" ); UM_CONFIG_INT( "chest3" ); UM_CONFIG_INT( "chest4" ); UM_CONFIG_INT( "drop_blocks" ); UM_STATS_DOUBLE( "h_var" ); UM_STATS_DOUBLE( "true_sigma" ); UM_STATS_DOUBLE( "true_snr" ); /** * The in- and outputs have also to be defined in the right order. First * port first. The additional flag is not used yet, but it will... * * UM_INPUT( SIG_{U8,SYMBOL_{S16,COMPLEX,MMX},SAMPLE_S12,S32}, 0 ); * UM_OUTPUT( SIG_{U8,SYMBOL_{S16,COMPLEX,MMX},SAMPLE_S12,S32}, 0 ); */ UM_INPUT( SIG_SYMBOL_COMPLEX, 0 ); UM_INPUT( SIG_SYMBOL_COMPLEX, 0 ); UM_INPUT( SIG_SYMBOL_COMPLEX, 0 ); UM_INPUT( SIG_SYMBOL_COMPLEX, 0 ); UM_OUTPUT( SIG_U8, 0 ); // Initialise the callback-functions. Delete the ones you don't use desc->fn_init = ics_rcv_init; desc->fn_reconfigure = ics_rcv_reconfig; desc->fn_process_data = ics_rcv_pdata; desc->fn_custom_msg = ics_rcv_custom_msg; desc->fn_finalize = ics_rcv_finalize; // And register the module in the SPM. Change the name! ics_rcv_id = swr_cdb_register_spc( &desc, "ldpc_decode_2fold_general_ics" ); if ( ics_rcv_id == SWR_SPM_INVALID_ID ){ swr_spc_free_desc( desc ); PR_DBG( 0, "Couldn't register the module!\n" ); return 1; } PR_DBG( 4, "Ready\n" ); return 0;}/* * This is called upon rmmod */void ics_rcv_module_exit( void ){ PR_DBG( 4, "Freeing id: %i\n", ics_rcv_id ); if ( swr_cdb_unregister_spc( ics_rcv_id ) < 0 ){ PR_DBG( 0, "Still in use somewhere\n" ); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -