📄 siso.h
字号:
/* File siso.h
Description: General functions used to implement SISO decoding.
Copyright (C) 2005-2006 Matthew C. Valenti
Last updated on Jan. 11, 2006
Functions Gamma and siso are part of the Iterative Solutions
Coded Modulation Library. The Iterative Solutions Coded Modulation
Library is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Note: Need to also include convolutional.h and maxstar.h */
/* define constants used throughout the library */
#define MAXLOG 1e7 /* Define infinity */
/* 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 siso()
Description: Uses the (max)-log-MAP algorithm to perform soft-input, soft-output
decoding of a RSC 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. Must be in form r = 2*a*y/(sigma^2).
z_in[] The APP input. This is the extrinsic output from the other decoder.
KK The constraint length of the convolutional code.
LL The number of data bits.
DecOpts Decoder termination option = 0 for unterminated and = 1 for terminated.
DecoderType = 0 Linear approximation to log-MAP correction function.
= 1 For max-log-MAP algorithm (i.e. max*(x,y) = max(x,y) )
= 2 For Constant-log-MAP algorithm
= 3 For log-MAP, correction factor using piecewise linear approximation
= 4 For log-MAP, correction factor uses C function calls
Output parameters:
llr[] The log-likelihood ratio of each data bit.
z_out[] The extrinsic information of each data bit.
This function is used by turbo_decode()
*/
static void siso(
float output_u[],
float output_c[],
int out0[],
int state0[],
int out1[],
int state1[],
float input_u[],
float input_c[],
int KK,
int nn,
int LL,
int DecoderType
)
{
int mm; /* Memory of the RSC encoder. */
int max_states; /* Number of states in the RSC encoder. */
int i, k, state;/* Counting variables. */
float num; /* Normalization values. */
float delta1, delta2; /* Arguments passed to max_star operation. */
float num_llr_u, den_llr_u; /* Temporary variable used to compute LLR. */
float *num_llr_c, *den_llr_c; /* Temp variable for LLR of code bits */
int symbol0, symbol1; /* Symbols associated with data 0 and data 1 */
int number_symbols; /* number of symbols */
float *metric_c; /* Set of all possible branch metrics */
float *beta; /* Reverse trellis metrics for the entire trellis. */
float *alpha; /* Forward trellis metric for the current stage only. */
float *alpha_prime; /* Forward trellis metrics for the last stage only. */
float *rec_array; /* Received values for one trellis section */
float sys_in, par_in, app_in;
int mask;
float (*max_star[])(float, float) =
{
max_star0, max_star1, max_star2, max_star3, max_star4
};
/* derived constants */
mm = KK-1;
max_states = 1 << mm; /* 2^mm */
number_symbols = 1 << nn; /* 2^nn */
/* initialize internal arrays */
alpha = calloc( max_states, sizeof(float) );
alpha_prime = calloc( max_states, sizeof(float) );
beta = calloc( max_states*(LL+KK), sizeof(float) );
metric_c = calloc( number_symbols, sizeof(int) );
rec_array = calloc( nn, sizeof(float) );
num_llr_c = calloc( nn, sizeof(float) );
den_llr_c = calloc( nn, sizeof(float) );
/* initialize alphas */
for (state=1;state<max_states;state++)
alpha_prime[state] = -MAXLOG;
alpha_prime[0] = 0;
/* initialize betas */
for (state=1;state<max_states;state++) {
beta[(LL+mm)*max_states+state] = -MAXLOG;
}
/* compute betas */
for (k=LL+mm-1;k>=0;k--) {
if (k<LL)
app_in = input_u[k];
else
app_in = 0;
/* precompute all possible branch metrics */
for (i=0;i<nn;i++)
rec_array[i] = input_c[nn*k+i];
for (i=0;i<number_symbols;i++)
metric_c[i] = Gamma( rec_array, i, nn );
/* step through all states */
for ( state=0; state< max_states; state++ ) {
/* data 0 branch */
delta1 = beta[ (k+1)*max_states + state0[ state ]] + metric_c[ out0[ state ] ];
/* data 1 branch */
delta2 = beta[ (k+1)*max_states + state1[ state ]] + metric_c[ out1[ state ] ] + app_in;
/* update beta */
beta[ k*max_states + state] = ( *max_star[DecoderType] )(delta1, delta2);
}
/* normalize */
for (state=1;state<max_states;state++)
beta[k*max_states+state] = beta[k*max_states+state] - beta[k*max_states];
beta[k*max_states] = 0;
}
/* compute alphas and LLRs */
for (k=1;k<=LL+mm;k++) {
/* den_llr and num_llr are used to compute the LLR and extrinsic info */
den_llr_u = -MAXLOG;
num_llr_u = -MAXLOG;
/* intialize alpha */
for (state=0;state<max_states;state++)
alpha[state] = -MAXLOG;
/* assign inputs */
if (k-1 < LL)
app_in = input_u[k-1];
else
app_in = 0;
/* precompute all possible branch metrics */
for (i=0;i<nn;i++) {
den_llr_c[i] = -MAXLOG;
num_llr_c[i] = -MAXLOG;
rec_array[i] = input_c[nn*(k-1)+i];
}
for (i=0;i<number_symbols;i++)
metric_c[i] = Gamma( rec_array, i, nn );
/* step through all states and find alpha */
for ( state=0; state<max_states; state++ ) {
/* Data 0 branch */
delta1 = alpha_prime[ state ] + metric_c[ out0[ state ] ];
delta2 = alpha[ state0[state] ];
alpha[ state0[state] ] = ( *max_star[DecoderType] )(delta1, delta2);
/* Data 1 branch */
delta1 = alpha_prime[ state ] + metric_c[ out1[ state ] ] + app_in;
delta2 = alpha[ state1[state] ];
alpha[ state1[state] ] = ( *max_star[DecoderType] )(delta1, delta2);
}
/* compute the LLRs */
for (state=0;state<max_states;state++) {
symbol0 = out0[state];
symbol1 = out1[state];
/* data 0 branch (departing) */
delta1 = alpha_prime[state] + metric_c[ symbol0 ] + beta[k*max_states+state0[state]];
/* the information bit */
delta2 = den_llr_u;
den_llr_u = ( *max_star[DecoderType] )( delta1, delta2 );
mask = 1<<(nn-1);
/* go through all the code bits */
for (i=0;i<nn;i++) {
if ( symbol0&mask ) {
/* this code bit 1 */
delta2 = num_llr_c[i];
num_llr_c[i] = ( *max_star[DecoderType] )( delta1, delta2 );
} else {
/* this code bit is 0 */
delta2 = den_llr_c[i];
den_llr_c[i] = ( *max_star[DecoderType] )( delta1, delta2 );
}
mask = mask>>1;
}
/* data 1 branch (departing) */
delta1 = alpha_prime[state] + metric_c[ symbol1] + beta[k*max_states+state1[state]] + app_in;
/* the information bit */
delta2 = num_llr_u;
num_llr_u = ( *max_star[DecoderType] )( delta1, delta2 );
mask = 1<<(nn-1);
/* go through all the code bits */
for (i=0;i<nn;i++) {
if ( symbol1&mask ) {
/* this code bit 1 */
delta2 = num_llr_c[i];
num_llr_c[i] = ( *max_star[DecoderType] )( delta1, delta2 );
} else {
/* this code bit is 0 */
delta2 = den_llr_c[i];
den_llr_c[i] = ( *max_star[DecoderType] )( delta1, delta2 );
}
mask = mask>>1;
}
/* normalize and shift */
alpha_prime[state] = alpha[state] - alpha[0];
}
if (k-1<LL)
output_u[k-1] = num_llr_u - den_llr_u;
for (i=0;i<nn;i++)
output_c[nn*(k-1)+i] = num_llr_c[i] - den_llr_c[i];
}
free(alpha_prime);
free(beta);
free(alpha);
free(metric_c);
free(rec_array);
free( num_llr_c );
free( den_llr_c );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -