decoder_list_t structure for in-place computations
This commit is contained in:
@@ -29,14 +29,16 @@
|
|||||||
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
|
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
|
||||||
#include "PHY/TOOLS/time_meas.h"
|
#include "PHY/TOOLS/time_meas.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int8_t polar_decoder(
|
int8_t polar_decoder(
|
||||||
double *input,
|
double *input,
|
||||||
uint8_t *output,
|
uint8_t *output,
|
||||||
t_nrPolar_params *polarParams,
|
t_nrPolar_params *polarParams,
|
||||||
uint8_t listSize,
|
uint8_t listSize,
|
||||||
double *aPrioriPayload,
|
double *aPrioriPayload,
|
||||||
uint8_t pathMetricAppr,
|
uint8_t pathMetricAppr,
|
||||||
time_stats_t *init,
|
time_stats_t *init,
|
||||||
time_stats_t *polar_rate_matching,
|
time_stats_t *polar_rate_matching,
|
||||||
time_stats_t *decoding,
|
time_stats_t *decoding,
|
||||||
time_stats_t *bit_extraction,
|
time_stats_t *bit_extraction,
|
||||||
@@ -48,23 +50,24 @@ int8_t polar_decoder(
|
|||||||
|
|
||||||
start_meas(init);
|
start_meas(init);
|
||||||
|
|
||||||
uint8_t ***bit = nr_alloc_uint8_t_3D_array(2*listSize, (polarParams->n+1), polarParams->N);
|
|
||||||
uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
|
uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
|
||||||
uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
|
uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
|
||||||
double ***llr = nr_alloc_double_3D_array(2*listSize,(polarParams->n+1), polarParams->N);
|
decoder_list_t dlist[2*listSize];
|
||||||
uint8_t **crcChecksum = nr_alloc_uint8_t_2D_array(polarParams->crcParityBits, 2*listSize);
|
|
||||||
double *pathMetric = malloc(sizeof(double)*(2*listSize));
|
|
||||||
uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True
|
|
||||||
|
|
||||||
for (int i=0; i<(2*listSize); i++) {
|
for ( int i=0;i<2*listSize;i++) {
|
||||||
pathMetric[i] = 0;
|
dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N);
|
||||||
crcState[i]=1;
|
dlist[i].llr = nr_alloc_double_2D_array((polarParams->n+1), polarParams->N);
|
||||||
for (int j=0; j< polarParams->n+1; j++) {
|
dlist[i].crcChecksum = malloc(sizeof(uint8_t)*polarParams->crcParityBits);
|
||||||
memset((void*)&bit[i][j][0],0,sizeof(uint8_t)*polarParams->N);
|
for (int j=0; j< polarParams->n+1; j++) {
|
||||||
memset((void*)&llr[i][j][0],0,sizeof(double)*polarParams->N);
|
memset((void*)&dlist[i].bit[j][0],0,sizeof(uint8_t)*polarParams->N);
|
||||||
}
|
memset((void*)&dlist[i].llr[j][0],0,sizeof(double)*polarParams->N);
|
||||||
for (int j=0;j<polarParams->crcParityBits;j++) crcChecksum[j][i] = 0;
|
}
|
||||||
|
for (int j=0;j<polarParams->crcParityBits;j++) dlist[i].crcChecksum[j] = 0;
|
||||||
|
dlist[i].crcState = 1;
|
||||||
|
dlist[i].pathMetric = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<polarParams->N; i++) {
|
for (int i=0; i<polarParams->N; i++) {
|
||||||
memset((void *)&llrUpdated[i][0],0,sizeof(uint8_t)*polarParams->n);
|
memset((void *)&llrUpdated[i][0],0,sizeof(uint8_t)*polarParams->n);
|
||||||
memset((void *)&bitUpdated[i][0],0,sizeof(uint8_t)*polarParams->n);
|
memset((void *)&bitUpdated[i][0],0,sizeof(uint8_t)*polarParams->n);
|
||||||
@@ -114,7 +117,7 @@ int8_t polar_decoder(
|
|||||||
|
|
||||||
double *d_tilde = malloc(sizeof(double) * polarParams->N);
|
double *d_tilde = malloc(sizeof(double) * polarParams->N);
|
||||||
nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength);
|
nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength);
|
||||||
memcpy((void*)&llr[0][polarParams->n][0],(void*)&d_tilde[0],sizeof(double)*polarParams->N);
|
memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(double)*polarParams->N);
|
||||||
stop_meas(polar_rate_matching);
|
stop_meas(polar_rate_matching);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -125,69 +128,81 @@ int8_t polar_decoder(
|
|||||||
uint8_t currentListSize=1;
|
uint8_t currentListSize=1;
|
||||||
uint8_t decoderIterationCheck=0;
|
uint8_t decoderIterationCheck=0;
|
||||||
int16_t checkCrcBits=-1;
|
int16_t checkCrcBits=-1;
|
||||||
uint8_t listIndex[2*listSize], copyIndex=0;
|
uint8_t copyIndex=0;
|
||||||
|
|
||||||
|
decoder_list_t *sorted_dlist[2*listSize];
|
||||||
|
int listIndex[2*listSize];
|
||||||
|
double pathMetric[2*listSize];
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i];
|
||||||
|
|
||||||
// for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
|
|
||||||
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++){
|
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++){
|
||||||
// printf("***************** BIT %d\n",currentBit);
|
// printf("***************** BIT %d\n",currentBit);
|
||||||
|
|
||||||
start_meas(update_LLR);
|
start_meas(update_LLR);
|
||||||
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
|
updateLLR(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
|
||||||
stop_meas(update_LLR);
|
stop_meas(update_LLR);
|
||||||
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
|
|
||||||
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
|
|
||||||
} else { //Information or CRC bit.
|
|
||||||
if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) {
|
|
||||||
printf("app[%d] %f, payloadBits %d\n",polarParams->interleaving_pattern[nonFrozenBit],
|
|
||||||
polarParams->payloadBits,
|
|
||||||
aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]]);
|
|
||||||
|
|
||||||
//Information bit with known value of "0".
|
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
|
||||||
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr);
|
updatePathMetric(sorted_dlist,currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
|
||||||
bitUpdated[currentBit][0]=1; //0=False, 1=True
|
} else { //Information or CRC bit.
|
||||||
} else if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) {
|
if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) {
|
||||||
//Information bit with known value of "1".
|
printf("app[%d] %f, payloadBits %d\n",polarParams->interleaving_pattern[nonFrozenBit],
|
||||||
updatePathMetric(pathMetric, llr, currentListSize, 1, currentBit, pathMetricAppr);
|
polarParams->payloadBits,
|
||||||
for (uint8_t i=0; i<currentListSize; i++) bit[i][0][currentBit]=1;
|
aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]]);
|
||||||
bitUpdated[currentBit][0]=1;
|
|
||||||
updateCrcChecksum(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
|
//Information bit with known value of "0".
|
||||||
} else {
|
updatePathMetric(sorted_dlist, currentListSize, 0, currentBit, pathMetricAppr);
|
||||||
start_meas(path_metric);
|
bitUpdated[currentBit][0]=1; //0=False, 1=True
|
||||||
updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr);
|
} else if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) {
|
||||||
stop_meas(path_metric);
|
//Information bit with known value of "1".
|
||||||
start_meas(sorting);
|
updatePathMetric(sorted_dlist, currentListSize, 1, currentBit, pathMetricAppr);
|
||||||
for (int i = 0; i < currentListSize; i++) {
|
for (uint8_t i=0; i<currentListSize; i++) sorted_dlist[i]->bit[0][currentBit]=1;
|
||||||
for (int k = 0; k < (polarParams->n+1); k++) {
|
bitUpdated[currentBit][0]=1;
|
||||||
/*
|
updateCrcChecksum(sorted_dlist, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
|
||||||
for (int j = 0; j < polarParams->N; j++) {
|
} else {
|
||||||
bit[i+currentListSize][k][j]=bit[i][k][j];
|
start_meas(path_metric);
|
||||||
llr[i+currentListSize][k][j]=llr[i][k][j];
|
updatePathMetric2(sorted_dlist, currentListSize, currentBit, pathMetricAppr);
|
||||||
}*/
|
stop_meas(path_metric);
|
||||||
memcpy((void*)&bit[i+currentListSize][k][0],(void*)&bit[i][k][0],sizeof(uint8_t)*polarParams->N);
|
start_meas(sorting);
|
||||||
memcpy((void*)&llr[i+currentListSize][k][0],(void*)&llr[i][k][0],sizeof(double)*polarParams->N);
|
for (int i = 0; i < currentListSize; i++) {
|
||||||
}
|
for (int k = 0; k < (polarParams->n+1); k++) {
|
||||||
}
|
/*
|
||||||
|
for (int j = 0; j < polarParams->N; j++) {
|
||||||
|
bit[i+currentListSize][k][j]=bit[i][k][j];
|
||||||
|
llr[i+currentListSize][k][j]=llr[i][k][j];
|
||||||
|
}*/
|
||||||
|
memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],(void*)&sorted_dlist[i]->bit[k][0],sizeof(uint8_t)*polarParams->N);
|
||||||
|
memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],(void*)&sorted_dlist[i]->llr[k][0],sizeof(double)*polarParams->N);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < currentListSize; i++) {
|
||||||
|
sorted_dlist[i]->bit[0][currentBit]=0;
|
||||||
|
sorted_dlist[i+currentListSize]->crcState=sorted_dlist[i]->crcState;
|
||||||
|
}
|
||||||
|
for (int i = currentListSize; i < 2*currentListSize; i++) sorted_dlist[i]->bit[currentBit]=1;
|
||||||
|
bitUpdated[currentBit][0]=1;
|
||||||
|
updateCrcChecksum2(sorted_dlist,extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
|
||||||
|
currentListSize*=2;
|
||||||
|
|
||||||
|
//Keep only the best "listSize" number of entries.
|
||||||
|
if (currentListSize > listSize) {
|
||||||
|
for (int i = 0; i < 2*listSize; i++) {
|
||||||
|
listIndex[i]=i;
|
||||||
|
pathMetric[i] = dlist[i].pathMetric;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < currentListSize; i++) {
|
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
|
||||||
bit[i][0][currentBit]=0;
|
for (int i = 0; i < 2*listSize; i++) sorted_dlist[i]=&dlist[listIndex[i]];
|
||||||
crcState[i+currentListSize]=crcState[i];
|
}
|
||||||
}
|
/*
|
||||||
for (int i = currentListSize; i < 2*currentListSize; i++) bit[i][0][currentBit]=1;
|
//sort listIndex[listSize, ..., 2*listSize-1] in descending order.
|
||||||
bitUpdated[currentBit][0]=1;
|
uint8_t swaps, tempInd;
|
||||||
updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
|
for (uint8_t i = 0; i < listSize; i++) {
|
||||||
currentListSize*=2;
|
swaps = 0;
|
||||||
|
for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) {
|
||||||
//Keep only the best "listSize" number of entries.
|
if (listIndex[j+1] > listIndex[j]) {
|
||||||
if (currentListSize > listSize) {
|
|
||||||
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
|
|
||||||
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
|
|
||||||
|
|
||||||
//sort listIndex[listSize, ..., 2*listSize-1] in descending order.
|
|
||||||
uint8_t swaps, tempInd;
|
|
||||||
for (uint8_t i = 0; i < listSize; i++) {
|
|
||||||
swaps = 0;
|
|
||||||
for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) {
|
|
||||||
if (listIndex[j+1] > listIndex[j]) {
|
|
||||||
tempInd = listIndex[j];
|
tempInd = listIndex[j];
|
||||||
listIndex[j] = listIndex[j + 1];
|
listIndex[j] = listIndex[j + 1];
|
||||||
listIndex[j + 1] = tempInd;
|
listIndex[j + 1] = tempInd;
|
||||||
@@ -201,11 +216,11 @@ int8_t polar_decoder(
|
|||||||
//First, backup the best "listSize" number of entries.
|
//First, backup the best "listSize" number of entries.
|
||||||
for (int k=(listSize-1); k>0; k--) {
|
for (int k=(listSize-1); k>0; k--) {
|
||||||
for (int j=0; j<(polarParams->n+1); j++) {
|
for (int j=0; j<(polarParams->n+1); j++) {
|
||||||
/*
|
|
||||||
for (int i=0; i<polarParams->N; i++) {
|
//for (int i=0; i<polarParams->N; i++) {
|
||||||
bit[listIndex[(2*listSize-1)-k]][j][i]=bit[listIndex[k]][j][i];
|
// bit[listIndex[(2*listSize-1)-k]][j][i]=bit[listIndex[k]][j][i];
|
||||||
llr[listIndex[(2*listSize-1)-k]][j][i]=llr[listIndex[k]][j][i];
|
// llr[listIndex[(2*listSize-1)-k]][j][i]=llr[listIndex[k]][j][i];
|
||||||
}*/
|
// }
|
||||||
memcpy((void*)&bit[listIndex[(2*listSize-1)-k]][j][0],
|
memcpy((void*)&bit[listIndex[(2*listSize-1)-k]][j][0],
|
||||||
(void*)&bit[listIndex[k]][j][0],
|
(void*)&bit[listIndex[k]][j][0],
|
||||||
sizeof(uint8_t)*polarParams->N);
|
sizeof(uint8_t)*polarParams->N);
|
||||||
@@ -231,10 +246,10 @@ int8_t polar_decoder(
|
|||||||
|
|
||||||
if (copyIndex!=k) {
|
if (copyIndex!=k) {
|
||||||
for (int j = 0; j < (polarParams->n + 1); j++) {
|
for (int j = 0; j < (polarParams->n + 1); j++) {
|
||||||
/* for (int i = 0; i < polarParams->N; i++) {
|
//for (int i = 0; i < polarParams->N; i++) {
|
||||||
bit[k][j][i] = bit[copyIndex][j][i];
|
// bit[k][j][i] = bit[copyIndex][j][i];
|
||||||
llr[k][j][i] = llr[copyIndex][j][i];
|
// llr[k][j][i] = llr[copyIndex][j][i];
|
||||||
}*/
|
// }
|
||||||
memcpy((void*)&bit[k][j][0],(void*)&bit[copyIndex][j][0],sizeof(uint8_t)*polarParams->N);
|
memcpy((void*)&bit[k][j][0],(void*)&bit[copyIndex][j][0],sizeof(uint8_t)*polarParams->N);
|
||||||
memcpy((void*)&llr[k][j][0],(void*)&llr[copyIndex][j][0],sizeof(double)*polarParams->N);
|
memcpy((void*)&llr[k][j][0],(void*)&llr[copyIndex][j][0],sizeof(double)*polarParams->N);
|
||||||
}
|
}
|
||||||
@@ -259,7 +274,7 @@ int8_t polar_decoder(
|
|||||||
crcState[k]=crcState[copyIndex];
|
crcState[k]=crcState[copyIndex];
|
||||||
}
|
}
|
||||||
currentListSize = listSize;
|
currentListSize = listSize;
|
||||||
}
|
}*/
|
||||||
stop_meas(sorting);
|
stop_meas(sorting);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,21 +287,21 @@ int8_t polar_decoder(
|
|||||||
|
|
||||||
if ( checkCrcBits > (-1) ) {
|
if ( checkCrcBits > (-1) ) {
|
||||||
for (uint8_t i = 0; i < currentListSize; i++) {
|
for (uint8_t i = 0; i < currentListSize; i++) {
|
||||||
if (crcChecksum[checkCrcBits][i]==1) {
|
if (dlist[i].crcChecksum[checkCrcBits]==1) {
|
||||||
crcState[i]=0; //0=False, 1=True
|
dlist[i].crcState=0; //0=False, 1=True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i];
|
for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=sorted_dlist[i]->crcState;
|
||||||
if (decoderIterationCheck==0) {
|
if (decoderIterationCheck==0) {
|
||||||
//perror("[SCL polar decoder] All list entries have failed the CRC checks.");
|
//perror("[SCL polar decoder] All list entries have failed the CRC checks.");
|
||||||
free(d_tilde);
|
free(d_tilde);
|
||||||
free(pathMetric);
|
for (int i=0;i<2*listSize;i++) {
|
||||||
free(crcState);
|
nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1));
|
||||||
nr_free_uint8_t_3D_array(bit, 2*listSize, (polarParams->n+1));
|
nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1));
|
||||||
nr_free_double_3D_array(llr, 2*listSize, (polarParams->n+1));
|
free(dlist[i].crcChecksum);
|
||||||
nr_free_uint8_t_2D_array(crcChecksum, polarParams->crcParityBits);
|
}
|
||||||
stop_meas(decoding);
|
stop_meas(decoding);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
@@ -301,30 +316,30 @@ int8_t polar_decoder(
|
|||||||
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
|
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
|
||||||
|
|
||||||
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
|
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
|
||||||
if ( crcState[listIndex[i]] == 1 ) {
|
if ( dlist[i].crcState == 1 ) {
|
||||||
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=bit[listIndex[i]][0][j];
|
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=dlist[listIndex[i]].bit[0][j];
|
||||||
|
|
||||||
start_meas(bit_extraction);
|
start_meas(bit_extraction);
|
||||||
//Extract the information bits (û to ĉ)
|
//Extract the information bits (û to ĉ)
|
||||||
nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N);
|
nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N);
|
||||||
stop_meas(bit_extraction);
|
stop_meas(bit_extraction);
|
||||||
//Deinterleaving (ĉ to b)
|
//Deinterleaving (ĉ to b)
|
||||||
start_meas(deinterleaving);
|
start_meas(deinterleaving);
|
||||||
nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K);
|
nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K);
|
||||||
stop_meas(deinterleaving);
|
stop_meas(deinterleaving);
|
||||||
//Remove the CRC (â)
|
//Remove the CRC (â)
|
||||||
for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j];
|
for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(d_tilde);
|
free(d_tilde);
|
||||||
free(pathMetric);
|
for (int i=0;i<2*listSize;i++) {
|
||||||
free(crcState);
|
nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1));
|
||||||
nr_free_uint8_t_3D_array(bit, 2*listSize, (polarParams->n+1));
|
nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1));
|
||||||
nr_free_double_3D_array(llr, 2*listSize, (polarParams->n+1));
|
free(dlist[i].crcChecksum);
|
||||||
nr_free_uint8_t_2D_array(crcChecksum, polarParams->crcParityBits);
|
}
|
||||||
nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K);
|
nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K);
|
||||||
nr_free_uint8_t_2D_array(tempECGM, polarParams->K);
|
nr_free_uint8_t_2D_array(tempECGM, polarParams->K);
|
||||||
stop_meas(decoding);
|
stop_meas(decoding);
|
||||||
|
|||||||
@@ -22,59 +22,85 @@
|
|||||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||||
//#define SHOWCOMP 1
|
//#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) {
|
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)));
|
uint16_t offset = (xlen/(1<<(ylen-col-1)));
|
||||||
if (( (row) % (2*offset) ) >= offset ) {
|
if (( (row) % (2*offset) ) >= offset ) {
|
||||||
if (bitU[row-offset][col]==0) updateBit(bit, bitU, listSize, (row-offset), col, xlen, ylen);
|
if (bitU[row-offset][col]==0) updateBit(dlist, 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-offset][col+1]==0) updateLLR(dlist, llrU, 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 (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation);
|
||||||
for (uint8_t i=0; i<listSize; i++) {
|
for (uint8_t i=0; i<listSize; i++) {
|
||||||
|
|
||||||
|
|
||||||
#ifdef SHOWCOMP
|
#ifdef SHOWCOMP
|
||||||
printf("updating LLR (%d,%d,%d) (bit %d,%d,%d, llr0 %d,%d,%d, llr1 %d,%d,%d \n",row,col,i,
|
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
|
#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 {
|
} else {
|
||||||
if (llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, 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(llr, llrU, bit, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation);
|
if (llrU[row+offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation);
|
||||||
computeLLR(llr, row, col, listSize, offset, approximation);
|
for (int i=0;i<listSize;i++) computeLLR(dlist[i]->llr, row, col, offset, approximation);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
llrU[row][col]=1;
|
llrU[row][col]=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t 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 col, uint16_t xlen, uint8_t ylen) {
|
||||||
uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
|
uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
|
||||||
|
|
||||||
for (uint8_t i=0; i<listSize; i++) {
|
for (uint8_t i=0; i<listSize; i++) {
|
||||||
if (( (row) % (2*offset) ) >= offset ) {
|
if (( (row) % (2*offset) ) >= offset ) {
|
||||||
if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen);
|
if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen);
|
||||||
bit[i][col][row] = bit[i][col-1][row];
|
dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row];
|
||||||
#ifdef SHOWCOMP
|
#ifdef SHOWCOMP
|
||||||
printf("updating bit (%d,%d,%d) from (%d,%d,%d)\n",
|
printf("updating bit (%d,%d,%d) from (%d,%d,%d)\n",
|
||||||
row,col,i,row,col-1,i);
|
row,col,i,row,col-1,i);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen);
|
if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen);
|
||||||
if (bitU[row+offset][col-1]==0) updateBit(bit, bitU, listSize, (row+offset), (col-1), xlen, ylen);
|
if (bitU[row+offset][col-1]==0) updateBit(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen);
|
||||||
bit[i][col][row] = ( (bit[i][col-1][row]+bit[i][col-1][row+offset]) % 2);
|
dlist[i]->bit[col][row] = ( (dlist[i]->bit[col-1][row]+dlist[i]->bit[col-1][row+offset]) % 2);
|
||||||
#ifdef SHOWCOMP
|
#ifdef SHOWCOMP
|
||||||
printf("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n",
|
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);
|
row,col,i,row,col-1,i,row+offset,col-1,i);
|
||||||
#endif
|
#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) {
|
uint16_t row, uint8_t approximation) {
|
||||||
|
|
||||||
#ifdef SHOWCOMP
|
#ifdef SHOWCOMP
|
||||||
@@ -84,11 +110,11 @@ void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, uint8
|
|||||||
|
|
||||||
if (approximation) { //eq. (12)
|
if (approximation) { //eq. (12)
|
||||||
for (uint8_t i=0; i<listSize; i++) {
|
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)
|
} else { //eq. (11b)
|
||||||
int8_t multiplier = (2*bitValue) - 1;
|
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) {
|
void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr) {
|
||||||
|
|
||||||
double *pm2=&pathMetric[listSize];
|
|
||||||
memcpy((void*)pm2,(void*)pathMetric,listSize*sizeof(double*));
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
for (i=0;i<listSize;i++) dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;
|
||||||
|
decoder_list_t **dlist2 = &dlist[listSize];
|
||||||
|
|
||||||
#ifdef SHOWCOMP
|
#ifdef SHOWCOMP
|
||||||
printf("updating path_metric from information bit (%d,%d) \n",
|
printf("updating path_metric from information bit (%d,%d) \n",
|
||||||
row,0);
|
row,0);
|
||||||
@@ -138,65 +164,36 @@ void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, uint
|
|||||||
if (appr) { //eq. (12)
|
if (appr) { //eq. (12)
|
||||||
for (i = 0; i < listSize; i++) {
|
for (i = 0; i < listSize; i++) {
|
||||||
// bitValue=0
|
// 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
|
// bitValue=1
|
||||||
else pm2[i] += llr[i][0][row];
|
else dlist2[i]->pathMetric += dlist[i]->llr[0][row];
|
||||||
}
|
}
|
||||||
} else { //eq. (11b)
|
} else { //eq. (11b)
|
||||||
for (i = 0; i < listSize; i++) {
|
for (i = 0; i < listSize; i++) {
|
||||||
// bitValue=0
|
// bitValue=0
|
||||||
pathMetric[i] += log(1 + exp(-llr[i][0][row]));
|
dlist[i]->pathMetric += log(1 + exp(-dlist[i]->llr[0][row]));
|
||||||
// bitValue=1
|
// 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
|
void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen,
|
||||||
printf("computeLLR (%d,%d,%d,%d)\n",row,col,offset,i);
|
uint8_t listSize, uint32_t i2, uint8_t len) {
|
||||||
#endif
|
for (uint8_t i = 0; i < listSize; i++) {
|
||||||
if (approximation) { //eq. (9)
|
for (uint8_t j = 0; j < len; j++) {
|
||||||
for (int i=0;i<listSize;i++) {
|
dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
|
||||||
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,
|
void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen,
|
||||||
uint8_t listSize, uint32_t i2, uint8_t len) {
|
uint8_t listSize, uint32_t i2, uint8_t len) {
|
||||||
for (uint8_t i = 0; i < listSize; i++) {
|
for (uint8_t i = 0; i < listSize; i++) {
|
||||||
for (uint8_t j = 0; j < len; j++) {
|
for (uint8_t j = 0; j < len; j++) {
|
||||||
crcChecksum[j][i] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 );
|
dlist[i+listSize]->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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
uint8_t ***nr_alloc_uint8_t_3D_array(uint16_t xlen, uint16_t ylen,
|
||||||
uint16_t zlen);
|
uint16_t zlen);
|
||||||
uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen);
|
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_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_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 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 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_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, 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);
|
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;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
double ***output;
|
double **output;
|
||||||
int i, j;
|
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;
|
||||||
|
|
||||||
|
|
||||||
if ((output = malloc(xlen * sizeof(*output))) == NULL) {
|
return output;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen) {
|
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);
|
free(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen) {
|
void nr_free_double_2D_array(double **input, uint16_t xlen) {
|
||||||
int i, j;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < xlen; i++) {
|
for (i = 0; i < xlen; i++) {
|
||||||
for (j = 0; j < ylen; j++) {
|
free(input[i]);
|
||||||
free(input[i][j]);
|
}
|
||||||
}
|
free(input);
|
||||||
free(input[i]);
|
|
||||||
}
|
|
||||||
free(input);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modified Bubble Sort.
|
// Modified Bubble Sort.
|
||||||
|
|||||||
Reference in New Issue
Block a user