Merge pull request #41 from marojevic/master

Optimization of soft-demodulation algorithm
This commit is contained in:
Ismael Gómez-Miguelez 2014-07-22 11:56:49 +02:00
commit 9069f93fcd
1 changed files with 53 additions and 55 deletions

View File

@ -54,45 +54,40 @@ void llr_approx(const _Complex float *in, float *out, int N, int M, int B,
_Complex float *symbols, uint32_t (*S)[6][32], float sigma2) { _Complex float *symbols, uint32_t (*S)[6][32], float sigma2) {
int i, s, b; int i, s, b;
float num, den; float num, den;
float new_num, new_den;
float idiff0, qdiff0, idiff1, qdiff1;
int change_sign = -1; int change_sign = -1;
float x, y, d[64];
for (s=0; s<N; s++) { /* recevied symbols */ for (s=0; s<N; s++) { /* recevied symbols */
for (b=0; b<B; b++) {/* bits per symbol*/ /* Compute the distances squared d[i] between the received symbol and all constellation points */
/* initiate num[b] and den[b] */ for (i=0; i<M; i++) {
idiff0 = __real__ in[s] - __real__ symbols[S[0][b][0]]; x = __real__ in[s] - __real__ symbols[i];
qdiff0 = __imag__ in[s] - __imag__ symbols[S[0][b][0]]; y = __imag__ in[s] - __imag__ symbols[i];
num = idiff0*idiff0 + qdiff0*qdiff0; d[i] = x*x + y*y;
}
idiff1 = __real__ in[s] - __real__ symbols[S[1][b][0]]; for (b=0; b<B; b++) {/* bits per symbol*/
qdiff1 = __imag__ in[s] - __imag__ symbols[S[1][b][0]]; /* initiate num[b] and den[b] */
den = idiff1*idiff1 + qdiff1*qdiff1; num = d[S[0][b][0]];
den = d[S[1][b][0]];
/* half the constellation symbols have '1'|'0' at any bit pos. */ /* Minimum distance squared search between recevied symbol and a constellation point with a
for (i=1; i<M/2; i++) { '1' and a '0' for each bit position */
idiff0 = __real__ in[s] - __real__ symbols[S[0][b][i]]; for (i=1; i<M/2; i++) { /* half the constellation points have '1'|'0' at any given bit position */
qdiff0 = __imag__ in[s] - __imag__ symbols[S[0][b][i]]; if (d[S[0][b][i]] < num) {
new_num = idiff0*idiff0 + qdiff0*qdiff0; num = d[S[0][b][i]];
}
idiff1 = __real__ in[s] - __real__ symbols[S[1][b][i]]; if (d[S[1][b][i]] < den) {
qdiff1 = __imag__ in[s] - __imag__ symbols[S[1][b][i]]; den = d[S[1][b][i]];
new_den = idiff1*idiff1 + qdiff1*qdiff1; }
}
if (new_num < num) { /* Theoretical LLR and approximate LLR values are positive if
num = new_num; * symbol(s) with '0' is/are closer and negative if symbol(s)
} * with '1' are closer.
if (new_den < den) { * Change sign if mapping negative to '0' and positive to '1' */
den = new_den; out[s*B+b] = change_sign*(den-num)/sigma2;
} }
}
/* Theoretical LLR and approximate LLR values are positive if
* symbol(s) with '0' is/are closer and negative if symbol(s)
* with '1' are closer.
* Change sign if mapping negative to '0' and positive to '1' */
out[s*B+b] = change_sign*(den-num)/sigma2;
}
} }
} }
/** /**
@ -115,29 +110,32 @@ void llr_exact(const _Complex float *in, float *out, int N, int M, int B,
_Complex float *symbols, uint32_t (*S)[6][32], float sigma2) { _Complex float *symbols, uint32_t (*S)[6][32], float sigma2) {
int i, s, b; int i, s, b;
float num, den; float num, den;
float idiff0, qdiff0, idiff1, qdiff1;
int change_sign = -1; int change_sign = -1;
float x, y, d[64];
for (s=0; s<N; s++) { /* recevied symbols */ for (s=0; s<N; s++) { /* recevied symbols */
for (b=0; b<B; b++) {/* bits per symbol*/ /* Compute exp{·} of the distances squared d[i] between the received symbol and all constellation points */
/* initiate num[b] and den[b] */ for (i=0; i<M; i++) {
num = 0; x = __real__ in[s] - __real__ symbols[i];
den = 0; y = __imag__ in[s] - __imag__ symbols[i];
/* half the constellation symbols have '1'|'0' at any bit pos. */ d[i] = exp(-1*(x*x + y*y)/sigma2);
for (i=0; i<M/2; i++) { }
idiff0 = __real__ in[s] - __real__ symbols[S[0][b][i]];
qdiff0 = __imag__ in[s] - __imag__ symbols[S[0][b][i]];
num += exp(-1*(idiff0*idiff0 + qdiff0*qdiff0)/sigma2);
idiff1 = __real__ in[s] - __real__ symbols[S[1][b][i]]; /* Sum up the corresponding d[i]'s for each bit position */
qdiff1 = __imag__ in[s] - __imag__ symbols[S[1][b][i]]; for (b=0; b<B; b++) {/* bits per symbol*/
den += exp(-1*(idiff1*idiff1 + qdiff1*qdiff1)/sigma2); /* initiate num[b] and den[b] */
} num = 0;
/* Theoretical LLR and approximate LLR values are positive if den = 0;
* symbol(s) with '0' is/are closer and negative if symbol(s)
* with '1' are closer. for (i=0; i<M/2; i++) { /* half the constellation points have '1'|'0' at any given bit position */
* Change sign if mapping negative to '0' and positive to '1' */ num += d[S[0][b][i]];
out[s*B+b] = change_sign*log(num/den); den += d[S[1][b][i]];
} }
/* Theoretical LLR and approximate LLR values are positive if
* symbol(s) with '0' is/are closer and negative if symbol(s)
* with '1' are closer.
* Change sign if mapping negative to '0' and positive to '1' */
out[s*B+b] = change_sign*log(num/den);
}
} }
} }