Commit d5e94b2c authored by knopp's avatar knopp

decoder_list_t structure for in-place computations

parent d4d2f866
......@@ -22,59 +22,85 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
//#define SHOWCOMP 1
void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU,
inline void computeLLR(double **llr, uint16_t row, uint16_t col,
uint16_t offset, uint8_t approximation) __attribute__((always_inline));
inline void computeLLR(double **llr, uint16_t row, uint16_t col,
uint16_t offset, uint8_t approximation) {
double a;
double b;
double absA,absB;
#ifdef SHOWCOMP
printf("computeLLR (%d,%d,%d,%d)\n",row,col,offset,i);
#endif
a = llr[col + 1][row];
b = llr[col+1][row + offset];
if (approximation) { //eq. (9)
absA = fabs(a);
absB = fabs(b);
llr[col][row] = copysign(1.0, a) * copysign(1.0, b) * fmin(absA, absB);
} else { //eq. (8a)
llr[col][row] = log((exp(a + b) + 1) / (exp(a) + exp(b)));
}
}
void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation) {
uint16_t offset = (xlen/(1<<(ylen-col-1)));
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row-offset][col]==0) updateBit(bit, bitU, listSize, (row-offset), col, xlen, ylen);
if (llrU[row-offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation);
if (llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation);
if (bitU[row-offset][col]==0) updateBit(dlist, bitU, listSize, (row-offset), col, xlen, ylen);
if (llrU[row-offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation);
if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation);
for (uint8_t i=0; i<listSize; i++) {
#ifdef SHOWCOMP
printf("updating LLR (%d,%d,%d) (bit %d,%d,%d, llr0 %d,%d,%d, llr1 %d,%d,%d \n",row,col,i,
row-offset,col,i,row-offset,col+1,i,row,col+1,i);
row-offset,col,i,row-offset,col+1,i,row,col+1,i);
#endif
llr[i][col][row] = (pow((-1),bit[i][col][row-offset])*llr[i][col+1][row-offset]) + llr[i][col+1][row];
dlist[i]->llr[col][row] = (pow((-1),dlist[i]->bit[col][row-offset])*dlist[i]->llr[col+1][row-offset]) + dlist[i]->llr[col+1][row];
}
} else {
if (llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation);
if (llrU[row+offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation);
computeLLR(llr, row, col, listSize, offset, approximation);
if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation);
if (llrU[row+offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation);
for (int i=0;i<listSize;i++) computeLLR(dlist[i]->llr, row, col, offset, approximation);
}
llrU[row][col]=1;
}
void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen) {
uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
for (uint8_t i=0; i<listSize; i++) {
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen);
bit[i][col][row] = bit[i][col-1][row];
void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen) {
uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
for (uint8_t i=0; i<listSize; i++) {
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen);
dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row];
#ifdef SHOWCOMP
printf("updating bit (%d,%d,%d) from (%d,%d,%d)\n",
row,col,i,row,col-1,i);
printf("updating bit (%d,%d,%d) from (%d,%d,%d)\n",
row,col,i,row,col-1,i);
#endif
} else {
if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen);
if (bitU[row+offset][col-1]==0) updateBit(bit, bitU, listSize, (row+offset), (col-1), xlen, ylen);
bit[i][col][row] = ( (bit[i][col-1][row]+bit[i][col-1][row+offset]) % 2);
} else {
if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen);
if (bitU[row+offset][col-1]==0) updateBit(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen);
dlist[i]->bit[col][row] = ( (dlist[i]->bit[col-1][row]+dlist[i]->bit[col-1][row+offset]) % 2);
#ifdef SHOWCOMP
printf("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n",
row,col,i,row,col-1,i,row+offset,col-1,i);
printf("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n",
row,col,i,row,col-1,i,row+offset,col-1,i);
#endif
}
}
bitU[row][col]=1;
}
}
bitU[row][col]=1;
}
void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, uint8_t bitValue,
void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue,
uint16_t row, uint8_t approximation) {
#ifdef SHOWCOMP
......@@ -84,11 +110,11 @@ void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, uint8
if (approximation) { //eq. (12)
for (uint8_t i=0; i<listSize; i++) {
if ((2*bitValue) != ( 1 - copysign(1.0,llr[i][0][row]) )) pathMetric[i] += fabs(llr[i][0][row]);
if ((2*bitValue) != ( 1 - copysign(1.0,dlist[i]->llr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]);
}
} else { //eq. (11b)
int8_t multiplier = (2*bitValue) - 1;
for (uint8_t i=0; i<listSize; i++) pathMetric[i] += log ( 1 + exp(multiplier*llr[i][0][row]) ) ;
for (uint8_t i=0; i<listSize; i++) dlist[i]->pathMetric += log ( 1 + exp(multiplier*dlist[i]->llr[0][row]) ) ;
}
}
......@@ -124,13 +150,13 @@ void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, uint
}
*/
void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, uint16_t row, uint8_t appr) {
double *pm2=&pathMetric[listSize];
memcpy((void*)pm2,(void*)pathMetric,listSize*sizeof(double*));
void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr) {
int i;
for (i=0;i<listSize;i++) dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;
decoder_list_t **dlist2 = &dlist[listSize];
#ifdef SHOWCOMP
printf("updating path_metric from information bit (%d,%d) \n",
row,0);
......@@ -138,65 +164,36 @@ void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, uint
if (appr) { //eq. (12)
for (i = 0; i < listSize; i++) {
// bitValue=0
if (llr[i][0][row]<0) pathMetric[i] -= llr[i][0][row];
if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row];
// bitValue=1
else pm2[i] += llr[i][0][row];
else dlist2[i]->pathMetric += dlist[i]->llr[0][row];
}
} else { //eq. (11b)
for (i = 0; i < listSize; i++) {
// bitValue=0
pathMetric[i] += log(1 + exp(-llr[i][0][row]));
dlist[i]->pathMetric += log(1 + exp(-dlist[i]->llr[0][row]));
// bitValue=1
pm2[i] += log(1 + exp(llr[i][0][row]));
dlist2[i]->pathMetric += log(1 + exp(dlist[i]->llr[0][row]));
}
}
}
inline void computeLLR(double ***llr, uint16_t row, uint16_t col, uint8_t listSize,
uint16_t offset, uint8_t approximation) __attribute__((always_inline));
inline void computeLLR(double ***llr, uint16_t row, uint16_t col, uint8_t listSize,
uint16_t offset, uint8_t approximation) {
double a;
double b;
double absA,absB;
#ifdef SHOWCOMP
printf("computeLLR (%d,%d,%d,%d)\n",row,col,offset,i);
#endif
if (approximation) { //eq. (9)
for (int i=0;i<listSize;i++) {
a = llr[i][col + 1][row];
b = llr[i][col+1][row + offset];
absA = fabs(a);
absB = fabs(b);
llr[i][col][row] = copysign(1.0, a) * copysign(1.0, b) * fmin(absA, absB);
}
} else { //eq. (8a)
for (int i=0;i<listSize;i++) {
a = llr[i][col + 1][row];
b = llr[i][col+1][row + offset];
llr[i][col][row] = log((exp(a + b) + 1) / (exp(a) + exp(b)));
}
}
}
void updateCrcChecksum(uint8_t **crcChecksum, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len) {
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
crcChecksum[j][i] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 );
}
}
void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len) {
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
}
}
}
void updateCrcChecksum2(uint8_t **crcChecksum, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len) {
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
crcChecksum[j][i+listSize] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 );
}
}
void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len) {
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
}
}
}
......@@ -124,27 +124,41 @@ void nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(uint8_t *matrix1, uint8_t **
uint8_t ***nr_alloc_uint8_t_3D_array(uint16_t xlen, uint16_t ylen,
uint16_t zlen);
uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen);
double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen);
double **nr_alloc_double_2D_array(uint16_t xlen, uint16_t ylen);
void nr_free_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen);
void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen);
void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen);
void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen,
uint8_t ylen, uint8_t approximation);
void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen);
void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize,
uint8_t bitValue, uint16_t row, uint8_t approximation);
void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize,
uint16_t row, uint8_t approximation);
void computeLLR(double ***llr, uint16_t row, uint16_t col, uint8_t i,
uint16_t offset, uint8_t approximation);
void updateCrcChecksum(uint8_t **crcChecksum, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len);
void updateCrcChecksum2(uint8_t **crcChecksum, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len);
void nr_free_double_2D_array(double **input, uint16_t xlen);
typedef struct decoder_list_s {
uint8_t **bit;
double **llr;
uint8_t *crcChecksum;
uint8_t crcState;
double pathMetric;
} decoder_list_t;
void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation);
void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen);
void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue,
uint16_t row, uint8_t approximation);
void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr);
void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len);
void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len);
void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len);
uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits);
......
......@@ -66,38 +66,30 @@ uint8_t ***nr_alloc_uint8_t_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen
return output;
}
double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen) {
double ***output;
int i, j;
if ((output = malloc(xlen * sizeof(*output))) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 1D allocation");
return NULL;
}
for (i = 0; i < xlen; i++)
output[i] = NULL;
for (i = 0; i < xlen; i++)
if ((output[i] = malloc(ylen * sizeof *output[i])) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 2D allocation");
nr_free_double_3D_array(output, xlen, ylen);
return NULL;
}
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
output[i][j] = NULL;
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
if ((output[i][j] = malloc(zlen * sizeof *output[i][j])) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 3D allocation");
nr_free_double_3D_array(output, xlen, ylen);
return NULL;
}
return output;
double **nr_alloc_double_2D_array(uint16_t xlen, uint16_t ylen) {
double **output;
int i, j;
if ((output = malloc(xlen * sizeof(*output))) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 1D allocation");
return NULL;
}
for (i = 0; i < xlen; i++)
output[i] = NULL;
for (i = 0; i < xlen; i++)
if ((output[i] = malloc(ylen * sizeof *output[i])) == NULL) {
perror("[nr_alloc_double_2D_array] Problem at 2D allocation");
nr_free_double_2D_array(output, xlen);
return NULL;
}
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
output[i][j] = 0;
return output;
}
uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen) {
......@@ -142,16 +134,13 @@ void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen) {
free(input);
}
void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen) {
int i, j;
for (i = 0; i < xlen; i++) {
for (j = 0; j < ylen; j++) {
free(input[i][j]);
}
free(input[i]);
}
free(input);
void nr_free_double_2D_array(double **input, uint16_t xlen) {
int i;
for (i = 0; i < xlen; i++) {
free(input[i]);
}
free(input);
}
// Modified Bubble Sort.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment