Added precoding test

This commit is contained in:
ismagom 2014-03-11 21:46:54 -05:00
parent 67b8cf3ee2
commit 590f6748a8
4 changed files with 98 additions and 65 deletions

View File

@ -46,10 +46,10 @@ int precoding_diversity(cf_t *x[MAX_LAYERS], cf_t *y[MAX_PORTS], int nof_ports,
if (nof_ports == 2) { if (nof_ports == 2) {
/* FIXME: Use VOLK here */ /* FIXME: Use VOLK here */
for (i=0;i<nof_symbols;i++) { for (i=0;i<nof_symbols;i++) {
y[0][2*i] = (crealf(x[0][i]) + I * cimagf(x[0][i]))/sqrtf(2); y[0][2*i] = x[0][i]/sqrtf(2);
y[1][2*i] = (-crealf(x[1][i]) + I * cimagf(x[1][i]))/sqrtf(2); y[1][2*i] = -conjf(x[1][i])/sqrtf(2);
y[0][2*i+1] = (crealf(x[1][i]) + I * cimagf(x[1][i]))/sqrtf(2); y[0][2*i+1] = x[1][i]/sqrtf(2);
y[1][2*i+1] = (crealf(x[0][i]) + I * cimagf(x[0][i]))/sqrtf(2); y[1][2*i+1] = conjf(x[0][i])/sqrtf(2);
} }
return i; return i;
} else if (nof_ports == 4) { } else if (nof_ports == 4) {
@ -85,7 +85,7 @@ int precoding_type(cf_t *x[MAX_LAYERS], cf_t *y[MAX_PORTS], int nof_layers, int
break; break;
case TX_DIVERSITY: case TX_DIVERSITY:
if (nof_ports == nof_layers) { if (nof_ports == nof_layers) {
return precoding_diversity(y, x, nof_ports, nof_symbols); return precoding_diversity(x, y, nof_ports, nof_symbols);
} else { } else {
fprintf(stderr, "Error number of layers must equal number of ports in transmit diversity\n"); fprintf(stderr, "Error number of layers must equal number of ports in transmit diversity\n");
return -1; return -1;
@ -115,11 +115,12 @@ int predecoding_diversity_zf(cf_t *y[MAX_PORTS], cf_t *ce[MAX_PORTS],
for (i=0;i<nof_symbols/2;i++) { for (i=0;i<nof_symbols/2;i++) {
h0 = ce[0][2*i]; h0 = ce[0][2*i];
h1 = ce[1][2*i]; h1 = ce[1][2*i];
hh = cabs(h0)*cabs(h0)+cabs(h1)*cabs(h1); hh = crealf(h0)*crealf(h0)+cimagf(h0)*cimagf(h0)+
crealf(h1)*crealf(h1)+cimagf(h1)*cimagf(h1);
r0 = y[0][2*i]; r0 = y[0][2*i];
r1 = y[0][2*i+1]; r1 = y[0][2*i+1];
x[0][i] = (conj(h0)*r0 + h1*conj(r1))/hh; x[0][i] = (conjf(h0)*r0 + h1*conjf(r1))/hh * sqrt(2);
x[1][i] = (h0*conj(r1) - h1*conj(r0))/hh; x[1][i] = (-h1*conj(r0) + conj(h0)*r1)/hh * sqrt(2);
} }
return i; return i;
} else if (nof_ports == 4) { } else if (nof_ports == 4) {

View File

@ -54,9 +54,11 @@ ADD_TEST(layermap_multiplex_28 layermap_test -n 1000 -m multiplex -c 2 -l 8)
# LAYER MAPPING TEST # LAYER MAPPING TEST
######################################################################## ########################################################################
ADD_EXECUTABLE(precoding_test precoding_test.c)
#ADD_EXECUTABLE(precoding_test precoding_test.c) TARGET_LINK_LIBRARIES(precoding_test lte)
#TARGET_LINK_LIBRARIES(precoding_test lte)
ADD_TEST(precoding_single precoding_test -n 1000 -m single)
ADD_TEST(precoding_diversity precoding_test -n 1000 -m diversity -l 2 -p 2)

View File

@ -123,13 +123,13 @@ int main(int argc, char **argv) {
} }
} }
/* layer encode */ /* layer mapping */
if ((symbols_layer = layermap_type(d, x, nof_cw, nof_layers, nof_symb_cw, type)) < 0) { if ((symbols_layer = layermap_type(d, x, nof_cw, nof_layers, nof_symb_cw, type)) < 0) {
fprintf(stderr, "Error layer mapper encoder\n"); fprintf(stderr, "Error layer mapper encoder\n");
exit(-1); exit(-1);
} }
/* layer decode */ /* layer de-mapping */
if (layerdemap_type(x, dp, nof_layers, nof_cw, nof_symbols/nof_layers, nof_symb_cw, type) < 0) { if (layerdemap_type(x, dp, nof_layers, nof_cw, nof_symbols/nof_layers, nof_symb_cw, type) < 0) {
fprintf(stderr, "Error layer mapper encoder\n"); fprintf(stderr, "Error layer mapper encoder\n");
exit(-1); exit(-1);

View File

@ -36,24 +36,26 @@
#include "lte.h" #include "lte.h"
#define MSE_THRESHOLD 0.00001
int nof_symbols = 1000; int nof_symbols = 1000;
int nof_cw = 1, nof_layers = 1; int nof_layers = 1, nof_ports = 1;
char *mimo_type_name = NULL; char *mimo_type_name = NULL;
void usage(char *prog) { void usage(char *prog) {
printf("Usage: %s -m [single|diversity|multiplex] -c [nof_cw] -l [nof_layers]\n", prog); printf("Usage: %s -m [single|diversity|multiplex] -l [nof_layers] -p [nof_ports]\n", prog);
printf("\t-n num_symbols [Default %d]\n", nof_symbols); printf("\t-n num_symbols [Default %d]\n", nof_symbols);
} }
void parse_args(int argc, char **argv) { void parse_args(int argc, char **argv) {
int opt; int opt;
while ((opt = getopt(argc, argv, "mcln")) != -1) { while ((opt = getopt(argc, argv, "mpln")) != -1) {
switch (opt) { switch (opt) {
case 'n': case 'n':
nof_symbols = atoi(argv[optind]); nof_symbols = atoi(argv[optind]);
break; break;
case 'c': case 'p':
nof_cw = atoi(argv[optind]); nof_ports = atoi(argv[optind]);
break; break;
case 'l': case 'l':
nof_layers = atoi(argv[optind]); nof_layers = atoi(argv[optind]);
@ -73,88 +75,116 @@ void parse_args(int argc, char **argv) {
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
int i, j, num_errors, symbols_layer; int i, j;
cf_t *d[MAX_CODEWORDS], *x[MAX_LAYERS], *dp[MAX_CODEWORDS]; float mse;
cf_t *x[MAX_LAYERS], *r[MAX_PORTS], *y[MAX_PORTS], *h[MAX_PORTS], *xr[MAX_LAYERS];
mimo_type_t type; mimo_type_t type;
int nof_symb_cw[MAX_CODEWORDS];
int n[2];
parse_args(argc, argv); parse_args(argc, argv);
if (nof_ports > MAX_PORTS || nof_layers > MAX_LAYERS) {
fprintf(stderr, "Invalid number of layers or ports\n");
exit(-1);
}
if (lte_str2mimotype(mimo_type_name, &type)) { if (lte_str2mimotype(mimo_type_name, &type)) {
fprintf(stderr, "Invalid MIMO type %s\n", mimo_type_name); fprintf(stderr, "Invalid MIMO type %s\n", mimo_type_name);
exit(-1); exit(-1);
} }
if (nof_cw > 1) {
n[0] = nof_layers / nof_cw;
n[1] = nof_layers - n[0];
nof_symb_cw[0] = nof_symbols * n[0];
nof_symb_cw[1] = nof_symbols * n[1];
} else {
nof_symb_cw[0] = nof_symbols;
nof_symb_cw[1] = 0;
}
for (i=0;i<nof_cw;i++) {
d[i] = malloc(sizeof(cf_t) * nof_symb_cw[i]);
if (!d[i]) {
perror("malloc");
exit(-1);
}
dp[i] = malloc(sizeof(cf_t) * nof_symb_cw[i]);
if (!dp[i]) {
perror("malloc");
exit(-1);
}
}
for (i=0;i<nof_layers;i++) { for (i=0;i<nof_layers;i++) {
x[i] = malloc(sizeof(cf_t) * nof_symbols); x[i] = malloc(sizeof(cf_t) * nof_symbols);
if (!x[i]) { if (!x[i]) {
perror("malloc"); perror("malloc");
exit(-1); exit(-1);
} }
xr[i] = malloc(sizeof(cf_t) * nof_symbols);
if (!xr[i]) {
perror("malloc");
exit(-1);
}
} }
for (i=0;i<nof_ports;i++) {
/* generate random data */ y[i] = malloc(sizeof(cf_t) * nof_symbols * nof_layers);
for (i=0;i<nof_cw;i++) { // TODO: The number of symbols per port is different in spatial multiplexing.
for (j=0;j<nof_symb_cw[i];j++) { if (!y[i]) {
d[i][j] = 100 * (rand()/RAND_MAX + I*rand()/RAND_MAX); perror("malloc");
exit(-1);
}
h[i] = malloc(sizeof(cf_t) * nof_symbols * nof_layers);
if (!h[i]) {
perror("malloc");
exit(-1);
} }
} }
/* layer encode */ /* only 1 receiver antenna supported now */
if ((symbols_layer = layermap_type(d, x, nof_cw, nof_layers, nof_symb_cw, type)) < 0) { r[0] = malloc(sizeof(cf_t) * nof_symbols * nof_layers);
if (!r[0]) {
perror("malloc");
exit(-1);
}
/* generate random data */
for (i=0;i<nof_layers;i++) {
for (j=0;j<nof_symbols;j++) {
x[i][j] = 100 * ((float) rand()/RAND_MAX + (float) I*rand()/RAND_MAX);
}
}
/* precoding */
if (precoding_type(x, y, nof_layers, nof_ports, nof_symbols, type) < 0) {
fprintf(stderr, "Error layer mapper encoder\n"); fprintf(stderr, "Error layer mapper encoder\n");
exit(-1); exit(-1);
} }
/* layer decode */ /* generate channel */
if (layerdemap_type(x, dp, nof_layers, nof_cw, nof_symbols/nof_layers, nof_symb_cw, type) < 0) { for (i=0;i<nof_ports;i++) {
for (j=0;j<nof_symbols * nof_layers;j++) {
float hc = -1+(float) i/nof_ports + j/nof_symbols;
h[i][j] = (3+hc) * cexpf(I * hc);
}
}
/* pass signal through channel
(we are in the frequency domain so it's a multiplication) */
/* there's only one receiver antenna, signals from different transmitter
* ports are simply combined at the receiver
*/
for (j=0;j<nof_symbols * nof_layers;j++) {
r[0][j] = 0;
for (i=0;i<nof_ports;i++) {
r[0][j] += y[i][j] * h[i][j];
}
}
/* predecoding / equalization */
if (predecoding_type(r, h, xr, nof_ports, nof_layers, nof_symbols * nof_layers, type) < 0) {
fprintf(stderr, "Error layer mapper encoder\n"); fprintf(stderr, "Error layer mapper encoder\n");
exit(-1); exit(-1);
} }
/* check errors */ /* check errors */
num_errors = 0; mse = 0;
for (i=0;i<nof_cw;i++) { for (i=0;i<nof_layers;i++) {
for (j=0;j<nof_symb_cw[i];j++) { for (j=0;j<nof_symbols;j++) {
if (d[i][j] != dp[i][j]) { mse += cabsf(xr[i][j] - x[i][j])/nof_layers/nof_symbols;
num_errors++;
}
} }
} }
for (i=0;i<nof_cw;i++) {
free(d[i]);
free(dp[i]);
}
for (i=0;i<nof_layers;i++) { for (i=0;i<nof_layers;i++) {
free(x[i]); free(x[i]);
free(xr[i]);
}
for (i=0;i<nof_ports;i++) {
free(y[i]);
free(h[i]);
} }
if (num_errors) { free(r[0]);
printf("%d Errors\n", num_errors);
if (mse > MSE_THRESHOLD) {
printf("MSE: %f\n", mse);
exit(-1); exit(-1);
} else { } else {
printf("Ok\n"); printf("Ok\n");