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

📄 convolutional.h

📁 1、HSDPA; 2、LTE; 3、turbo code; 4、Mobile WiMAX; 5、LDPC
💻 H
📖 第 1 页 / 共 2 页
字号:
		  /* Assign to output */
		  for (j=0;j<nn;j++)
			  output_p[nn*i+j] = bin_vec[j];
	  }
  }

  free(bin_vec);

  return;
}


/* function Gamma()
  
	Description: Computes the branch metric used for decoding.

	Output parameters:
		(returned float) 	The metric between the hypothetical symbol and the recevieved vector
	
	Input parameters:
		rec_array			The received vector, of length nn
		symbol				The hypothetical symbol
		nn					The length of the received vector
	
  This function is used by siso()  */


static float Gamma(float  rec_array[],
				   int    symbol,
				   int    nn )
{
	float rm = 0;
	int i;
	int mask;
	
	mask = 1;
	for (i=0;i<nn;i++) {
		if (symbol&mask)
			rm += rec_array[nn-i-1];
		mask = mask<<1;
	} 
	
	return(rm);
} 


/* Function Viterbi()

  Description: Uses the Viterbi algorithm to perform hard-decision decoding of a convolutional code.

	Input parameters:
		out0[]		The output bits for each state if input is a 0 (generated by rsc_transit).
		state0[]	The next state if input is a 0 (generated by rsc_transit).
		out1[]		The output bits for each state if input is a 1 (generated by rsc_transit).
		state1[]	The next state if input is a 1 (generated by rsc_transit).
		r[]			The received signal in LLR-form. For BPSK, must be in form r = 2*a*y/(sigma^2).
		KK			The constraint length of the convolutional code.
		LL			The number of data bits.

	Output parameters:
		output_u_int[]		Hard decisions on the data bits
	
*/

static void Viterbi(
				int    output_u_int[],
				int    out0[], 
				int    state0[], 
				int    out1[], 
				int    state1[],
				float  input_c[],
				int    KK,
				int    nn,
				int    LL
				)
{
	int i, t, state, mm, states;
	int number_symbols;
	float metric;
	float *prev_section, *next_section;
	int *prev_bit;
	int *prev_state;
	float *metric_c;	/* Set of all possible branch metrics */
	float *rec_array;   /* Received values for one trellis section */
	float max_val;
	
	/* some derived constants */
	mm = KK-1;
	states = 1 << mm;			/* 2^mm */
	number_symbols = 1 << nn;	    /* 2^nn */
	
	/* dynamically allocate memory */ 
	prev_section = calloc( states, sizeof(float) );
	next_section = calloc( states, sizeof(float) );
	prev_bit = calloc( states*(LL+mm), sizeof(int) );
	prev_state = calloc( states*(LL+mm), sizeof(int) );
	rec_array = calloc( nn, sizeof(float) );
	metric_c = calloc( number_symbols, sizeof(float) );
	
	/* initialize trellis */
	for (state=0;state<states;state++) {
		prev_section[state] = -MAXLOG; 
		next_section[state] = -MAXLOG;
	}
	prev_section[0] = 0; /* start in all-zeros state */
	
	/* go through trellis */
	for (t=0;t<LL+mm;t++) {
		for (i=0;i<nn;i++)
			rec_array[i] = input_c[nn*t+i];
		
		/* precompute all possible branch metrics */
		for (i=0;i<number_symbols;i++)
			metric_c[i] = Gamma( rec_array, i, nn ); 
		
		/* step through all states */
		for (state=0;state<states;state++) {
			
			/* hypothesis: info bit is a zero */
			metric = prev_section[state] + metric_c[ out0[ state ] ];
			
			/* store new metric if more than metric in storage */
			if ( metric > next_section[state0[state]] ) {
				next_section[state0[state]] = metric;
				prev_state[t*states+state0[state]] = state;
				prev_bit[t*states+state0[state]] = 0;
			}
			
			/* hypothesis: info bit is a one */
			metric = prev_section[state] + metric_c[ out1[ state ] ];
			
			/* store new metric if more than metric in storage */
			if ( metric > next_section[state1[state]] ) {
				next_section[state1[state]] = metric;
				prev_state[t*states+state1[state]] = state;
				prev_bit[t*states+state1[state]] = 1;
			}
		}

		/* normalize */
		max_val = 0;
		for (state=0;state<states;state++) {
			if (next_section[state]>max_val){
				max_val = next_section[state];
			}
		}
		for (state=0;state<states;state++) {
			prev_section[state] = next_section[state] - max_val;
			next_section[state] = -MAXLOG;
		}
	}
	
	/* trace-back operation */
	state = 0;

	/* tail, no need to output */
	for (t=LL+mm-1; t>=LL; t--) {
		state = prev_state[t*states+state];
	}

	for (t=LL-1; t>=0; t--) {		
		output_u_int[t] = prev_bit[t*states+state];
		state = prev_state[t*states+state];
	}
	
	/* free the dynamically allocated memory */
	free(prev_section);
	free(next_section);
	free(prev_bit);
	free(prev_state);
	free(rec_array);
	free(metric_c); 
	
}

/* Function ViterbiTb()

  Description: Uses the Viterbi algorithm to perform hard-decision decoding of a tail-biting convolutional code.

	Input parameters:
		out0[]		The output bits for each state if input is a 0 (generated by rsc_transit).
		state0[]	The next state if input is a 0 (generated by rsc_transit).
		out1[]		The output bits for each state if input is a 1 (generated by rsc_transit).
		state1[]	The next state if input is a 1 (generated by rsc_transit).
		r[]			The received signal in LLR-form. For BPSK, must be in form r = 2*a*y/(sigma^2).
		KK			The constraint length of the convolutional code.
		LL			The number of data bits.
		depth		head and tail decoding length [Ref. W. Sung, Electronics Letters, vol. 36, no. 7]

	Output parameters:
		output_u_int[]		Hard decisions on the data bits
  
*/


static void ViterbiTb(
				int    output_u_int[],
				int    out0[], 
				int    state0[], 
				int    out1[], 
				int    state1[],
				float  input_c[],
				int    KK,
				int    nn,
				int    LL,
				int	   depth
				)
{
	int i, t, state, mm, states, max_state;
	int number_symbols, starting_bit;
	float metric;
	float *prev_section, *next_section;
	int *prev_bit;
	int *prev_state;
	float *metric_c;	/* Set of all possible branch metrics */
	float *rec_array;   /* Received values for one trellis section */
	float max_val;
	
	/* some derived constants */
	mm = KK-1;
	states = 1 << mm;			/* 2^mm */
	number_symbols = 1 << nn;	    /* 2^nn */
	
	/* dynamically allocate memory */ 
	prev_section = calloc( states, sizeof(float) );
	next_section = calloc( states, sizeof(float) );
	prev_bit = calloc( states*(LL+depth), sizeof(int) );
	prev_state = calloc( states*(LL+depth), sizeof(int) );
	rec_array = calloc( nn, sizeof(float) );
	metric_c = calloc( number_symbols, sizeof(float) );
	
	/* initialize trellis */
	for (state=0;state<states;state++) {
		prev_section[state] = 0; /* equally likely starting state */
		next_section[state] = -MAXLOG;
	}
	
	/* go through trellis */
	for (t=-depth;t<LL+depth;t++) {
		/* determine the corresponding data bits */
		starting_bit = nn*(t%LL);
		if (starting_bit < 0 )
			starting_bit = nn*LL + starting_bit;
		
		/* printf( "start at %d\n", starting_bit ); */
		for (i=0;i<nn;i++) {
			rec_array[i] = input_c[starting_bit+i];
			/* printf( "%1f\n", rec_array[i] ); */
		}

		/* precompute all possible branch metrics */
		for (i=0;i<number_symbols;i++)
			metric_c[i] = Gamma( rec_array, i, nn ); 
		
		/* step through all states */
		for (state=0;state<states;state++) {
			
			/* hypothesis: info bit is a zero */
			metric = prev_section[state] + metric_c[ out0[ state ] ];
			
			/* store new metric if more than metric in storage */
			if ( metric > next_section[state0[state]] ) {
				next_section[state0[state]] = metric;
				if (t>=0) {				
					prev_state[t*states+state0[state]] = state;
					prev_bit[t*states+state0[state]] = 0;
				}
			}
			
			/* hypothesis: info bit is a one */
			metric = prev_section[state] + metric_c[ out1[ state ] ];
			
			/* store new metric if more than metric in storage */
			if ( metric > next_section[state1[state]] ) {
				next_section[state1[state]] = metric;
				if (t>=0) {				
					prev_state[t*states+state1[state]] = state;				
					prev_bit[t*states+state1[state]] = 1;
				}
			}
		}
		
		/* normalize */
		max_val = 0;
		for (state=0;state<states;state++) {
			if (next_section[state]>max_val){
				max_val = next_section[state];
				max_state = state;
			}
		}
		for (state=0;state<states;state++) {
			prev_section[state] = next_section[state] - max_val;
			next_section[state] = -MAXLOG;
		}
	}
	
	/* trace-back operation */
	state = max_state;

	/* tail, no need to output */
	for (t=LL+depth-1; t>=LL; t--) {
		state = prev_state[t*states+state];
	}

	for (t=LL-1; t>=0; t--) {		
		output_u_int[t] = prev_bit[t*states+state];
		state = prev_state[t*states+state];
	}
	
	/* free the dynamically allocated memory */
	free(prev_section);
	free(next_section);
	free(prev_bit);
	free(prev_state);
	free(rec_array);
	free(metric_c); 
	
}

⌨️ 快捷键说明

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