Commit 5449a37b authored by Elena Lukashova's avatar Elena Lukashova

Adding changes related to whitening filter.

MRC core function to be further optimized in the future commits.
At this point some configurations could fail.
parent 38925d35
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
#include "linear_preprocessing_rec.h" #include "linear_preprocessing_rec.h"
#define NOCYGWIN_STATIC #define NOCYGWIN_STATIC
//#define DEBUG_MMSE //#define DEBUG_FRONT_END
/* dynamic shift for LLR computation for TM3/4 /* dynamic shift for LLR computation for TM3/4
...@@ -1782,6 +1782,7 @@ void dlsch_channel_compensation_core(int **rxdataF_ext, ...@@ -1782,6 +1782,7 @@ void dlsch_channel_compensation_core(int **rxdataF_ext,
length2 = length>>3; length2 = length>>3;
for (ii=0; ii<length2; ++ii) { for (ii=0; ii<length2; ++ii) {
if (mod_order>2) { if (mod_order>2) {
// get channel amplitude if not QPSK // get channel amplitude if not QPSK
...@@ -3366,7 +3367,6 @@ void dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext, ...@@ -3366,7 +3367,6 @@ void dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext,
{ {
#if defined(__x86_64__)||defined(__i386__) #if defined(__x86_64__)||defined(__i386__)
unsigned short rb;
__m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128,mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128,mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
unsigned char aarx; unsigned char aarx;
int ii, length2, length_mod8; int ii, length2, length_mod8;
...@@ -3601,8 +3601,11 @@ void dlsch_detection_mrc_core(int **rxdataF_comp, ...@@ -3601,8 +3601,11 @@ void dlsch_detection_mrc_core(int **rxdataF_comp,
unsigned char aatx; unsigned char aatx;
int i; int i;
__m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1, __m128i *rxdataF_comp128_0, *rxdataF_comp128_1, *rxdataF_comp128_2, *rxdataF_comp128_3;
*dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b; __m128i *dl_ch_mag128_0, *dl_ch_mag128_1, *dl_ch_mag128_2, *dl_ch_mag128_3;
__m128i *dl_ch_mag128_0b, *dl_ch_mag128_1b, *dl_ch_mag128_2b, *dl_ch_mag128_3b;
__m128i *rho128_0, *rho128_1, *rho128_2, *rho128_3;
__m128i *rho128_i0, *rho128_i1, *rho128_i2, *rho128_i3;
int length_mod4 = 0; int length_mod4 = 0;
int length2; int length2;
...@@ -3628,16 +3631,19 @@ void dlsch_detection_mrc_core(int **rxdataF_comp, ...@@ -3628,16 +3631,19 @@ void dlsch_detection_mrc_core(int **rxdataF_comp,
} }
} }
if (rho) { if (rho) {
rho128_0 = (__m128i *) &rho[0][start_point]; rho128_0 = (__m128i *) &rho[0][start_point];
rho128_1 = (__m128i *) &rho[1][start_point]; rho128_1 = (__m128i *) &rho[1][start_point];
rho128_2 = (__m128i *) &rho[2][start_point];
rho128_3 = (__m128i *) &rho[3][start_point];
if (length_mod4 == 0){ if (length_mod4 == 0){
length2 = length>>2; length2 = length>>2;
for (i=0; i<length2; ++i) { for (i=0; i<length2; ++i) {
rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1)); rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
rho128_2[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_2[i],1),_mm_srai_epi16(rho128_3[i],1));
} }
} }
} }
...@@ -3645,14 +3651,63 @@ void dlsch_detection_mrc_core(int **rxdataF_comp, ...@@ -3645,14 +3651,63 @@ void dlsch_detection_mrc_core(int **rxdataF_comp,
if (rho_i){ if (rho_i){
rho128_i0 = (__m128i *) &rho_i[0][start_point]; rho128_i0 = (__m128i *) &rho_i[0][start_point];
rho128_i1 = (__m128i *) &rho_i[1][start_point]; rho128_i1 = (__m128i *) &rho_i[1][start_point];
rho128_i2 = (__m128i *) &rho_i[2][start_point];
rho128_i3 = (__m128i *) &rho_i[3][start_point];
if (length_mod4 == 0){ if (length_mod4 == 0){
length2 = length>>2; length2 = length>>2;
for (i=0; i<length2; ++i) for (i=0; i<length2; ++i)
rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1)); rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1));
rho128_i2[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i2[i],1),_mm_srai_epi16(rho128_i3[i],1));
} }
} }
if (n_tx == 4){
rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][start_point];
rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[2][start_point];
rxdataF_comp128_2 = (__m128i *)&rxdataF_comp[4][start_point];
rxdataF_comp128_3 = (__m128i *)&rxdataF_comp[6][start_point];
dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[0][start_point];
dl_ch_mag128_1 = (__m128i *)&dl_ch_mag[2][start_point];
dl_ch_mag128_2 = (__m128i *)&dl_ch_mag[4][start_point];
dl_ch_mag128_3 = (__m128i *)&dl_ch_mag[6][start_point];
dl_ch_mag128_0b = (__m128i *)&dl_ch_magb[0][start_point];
dl_ch_mag128_1b = (__m128i *)&dl_ch_magb[2][start_point];
dl_ch_mag128_2b = (__m128i *)&dl_ch_magb[4][start_point];
dl_ch_mag128_3b = (__m128i *)&dl_ch_magb[6][start_point];
rho128_0 = (__m128i *)&rho[0][start_point];
rho128_1 = (__m128i *)&rho[2][start_point];
rho128_i0 = (__m128i *)&rho_i[0][start_point];
rho128_i1 = (__m128i *)&rho_i[2][start_point];
if (length_mod4 == 0){
length2 = length>>2;
for (i=0; i<length2; ++i) {
rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
rxdataF_comp128_2[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_2[i],1),_mm_srai_epi16(rxdataF_comp128_3[i],1));
dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1));
dl_ch_mag128_2[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_2[i],1),_mm_srai_epi16(dl_ch_mag128_3[i],1));
dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1));
dl_ch_mag128_2b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_2b[i],1),_mm_srai_epi16(dl_ch_mag128_3b[i],1));
rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1));
}
}
}
} }
_mm_empty(); _mm_empty();
...@@ -3662,7 +3717,7 @@ void dlsch_detection_mrc_core(int **rxdataF_comp, ...@@ -3662,7 +3717,7 @@ void dlsch_detection_mrc_core(int **rxdataF_comp,
unsigned char aatx; unsigned char aatx;
int i; int i;
int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1,*dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b; int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1;
int length_mod4 = 0; int length_mod4 = 0;
int length2; int length2;
int ii=0; int ii=0;
...@@ -4174,14 +4229,12 @@ void dlsch_channel_level_median(int **dl_ch_estimates_ext, ...@@ -4174,14 +4229,12 @@ void dlsch_channel_level_median(int **dl_ch_estimates_ext,
short ii; short ii;
int aatx,aarx; int aatx,aarx;
int length_mod4; int length_mod8;
int length2; int length2;
int max = 0, min=0; int max = 0, min=0;
int norm_pack; int norm_pack;
__m128i *dl_ch128, norm128D; __m128i *dl_ch128, norm128D;
int16_t x = factor2(length);
int16_t y = (length)>>x;
for (aatx=0; aatx<n_tx; aatx++){ for (aatx=0; aatx<n_tx; aatx++){
for (aarx=0; aarx<n_rx; aarx++) { for (aarx=0; aarx<n_rx; aarx++) {
...@@ -4191,14 +4244,15 @@ void dlsch_channel_level_median(int **dl_ch_estimates_ext, ...@@ -4191,14 +4244,15 @@ void dlsch_channel_level_median(int **dl_ch_estimates_ext,
dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*2 + aarx][start_point]; dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*2 + aarx][start_point];
length_mod4=length&3; length_mod8=length&3;
if (length_mod8 == 0){
length2 = length>>2; length2 = length>>2;
for (ii=0;ii<length2;ii++) { for (ii=0;ii<length2;ii++) {
norm128D = _mm_srai_epi32( _mm_madd_epi16(dl_ch128[0],dl_ch128[0]), 1); norm128D = _mm_srai_epi32( _mm_madd_epi16(dl_ch128[0],dl_ch128[0]), 1);
//print_ints("norm128D",&norm128D[0]); //print_ints("norm128D",&norm128D[0]);
norm_pack = ((int32_t*)&norm128D)[0] + norm_pack = ((int32_t*)&norm128D)[0] +
((int32_t*)&norm128D)[1] + ((int32_t*)&norm128D)[1] +
((int32_t*)&norm128D)[2] + ((int32_t*)&norm128D)[2] +
...@@ -4208,12 +4262,13 @@ void dlsch_channel_level_median(int **dl_ch_estimates_ext, ...@@ -4208,12 +4262,13 @@ void dlsch_channel_level_median(int **dl_ch_estimates_ext,
max = norm_pack; max = norm_pack;
if (norm_pack < min) if (norm_pack < min)
min = norm_pack; min = norm_pack;
dl_ch128+=1; dl_ch128+=1;
} }
median[aatx*n_rx + aarx] = (max+min)>>1; median[aatx*n_rx + aarx] = (max+min)>>1;
}else {
printf ("channel_level_median: Received number of subcarriers is not multiple of 8, \n"
"need to adapt the code!\n");
}
// printf("Channel level median [%d]: %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx]); // printf("Channel level median [%d]: %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx]);
} }
} }
...@@ -4224,12 +4279,14 @@ void dlsch_channel_level_median(int **dl_ch_estimates_ext, ...@@ -4224,12 +4279,14 @@ void dlsch_channel_level_median(int **dl_ch_estimates_ext,
#elif defined(__arm__) #elif defined(__arm__)
short rb; short rb;
unsigned char aatx,aarx,nre=12,symbol_mod; unsigned char aatx,aarx;
int length_mod8;
int length2;
int32x4_t norm128D; int32x4_t norm128D;
int16x4_t *dl_ch128; int16x4_t *dl_ch128;
for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++){ for (aatx=0; aatx<n_tx; aatx++){
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { for (aarx=0; aarx<n_rx; aarx++) {
max = 0; max = 0;
min = 0; min = 0;
norm128D = vdupq_n_s32(0); norm128D = vdupq_n_s32(0);
...@@ -4237,6 +4294,8 @@ void dlsch_channel_level_median(int **dl_ch_estimates_ext, ...@@ -4237,6 +4294,8 @@ void dlsch_channel_level_median(int **dl_ch_estimates_ext,
dl_ch128=(int16x4_t *)&dl_ch_estimates_ext[aatx*n_rx + aarx][start_point]; dl_ch128=(int16x4_t *)&dl_ch_estimates_ext[aatx*n_rx + aarx][start_point];
length_mod8=length&3; length_mod8=length&3;
if (length_mod8 == 0){
length2 = length>>2; length2 = length>>2;
for (ii=0;ii<length2;ii++) { for (ii=0;ii<length2;ii++) {
...@@ -4255,6 +4314,10 @@ void dlsch_channel_level_median(int **dl_ch_estimates_ext, ...@@ -4255,6 +4314,10 @@ void dlsch_channel_level_median(int **dl_ch_estimates_ext,
} }
median[aatx*n_rx + aarx] = (max+min)>>1; median[aatx*n_rx + aarx] = (max+min)>>1;
}else {
printf ("channel_level_median: Received number of subcarriers is not multiple of 8, \n"
"need to adapt the code!\n");
}
//printf("Channel level median [%d]: %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx]); //printf("Channel level median [%d]: %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx]);
} }
...@@ -4346,26 +4409,36 @@ void mmse_processing_core(int32_t **rxdataF_ext, ...@@ -4346,26 +4409,36 @@ void mmse_processing_core(int32_t **rxdataF_ext,
float real; float real;
float complex **W_MMSE= malloc(n_tx*n_rx*sizeof(float complex*)); float complex **W_MMSE = malloc(n_tx*n_rx*sizeof(float complex*));
for (int j=0; j<n_tx*n_rx; j++) { for (int j=0; j<n_tx*n_rx; j++) {
W_MMSE[j] = malloc(sizeof(float complex)*length); W_MMSE[j] = malloc(sizeof(float complex)*length);
} }
float complex *H= malloc(n_tx*n_rx*sizeof(float complex)); float complex *H = malloc(n_tx*n_rx*sizeof(float complex));
float complex *W_MMSE_re= malloc(n_tx*n_rx*sizeof(float complex)); float complex *W_MMSE_re= malloc(n_tx*n_rx*sizeof(float complex));
float complex** dl_ch_estimates_ext_flcpx = malloc(n_tx*n_rx*sizeof(float complex*)); float complex** dl_ch_estimates_ext_flp = malloc(n_tx*n_rx*sizeof(float complex*));
for (int j=0; j<n_tx*n_rx; j++) {
dl_ch_estimates_ext_flp[j] = malloc(sizeof(float complex)*length);
}
float complex** dl_ch_estimates_ext_eff_flp = malloc(n_tx*n_rx*sizeof(float complex*));
for (int j=0; j<n_tx*n_rx; j++) { for (int j=0; j<n_tx*n_rx; j++) {
dl_ch_estimates_ext_flcpx[j] = malloc(sizeof(float complex)*length); dl_ch_estimates_ext_eff_flp[j] = malloc(sizeof(float complex)*length);
} }
float complex** rxdataF_ext_flcpx = malloc(n_rx*sizeof(float complex*)); float complex** rxdataF_ext_flp = malloc(n_rx*sizeof(float complex*));
for (int j=0; j<n_rx; j++) { for (int j=0; j<n_rx; j++) {
rxdataF_ext_flcpx[j] = malloc(sizeof(float complex)*length); rxdataF_ext_flp[j] = malloc(sizeof(float complex)*length);
}
float complex** rxdataF_ext_mmse_flp = malloc(n_rx*sizeof(float complex*));
for (int j=0; j<n_rx; j++) {
rxdataF_ext_mmse_flp[j] = malloc(sizeof(float complex)*length);
} }
chan_est_to_float(dl_ch_estimates_ext, chan_est_to_float(dl_ch_estimates_ext,
dl_ch_estimates_ext_flcpx, dl_ch_estimates_ext_flp,
n_tx, n_tx,
n_rx, n_rx,
length, length,
...@@ -4374,8 +4447,8 @@ void mmse_processing_core(int32_t **rxdataF_ext, ...@@ -4374,8 +4447,8 @@ void mmse_processing_core(int32_t **rxdataF_ext,
for (re=0; re<length; re++){ for (re=0; re<length; re++){
for (aatx=0; aatx<n_tx; aatx++){ for (aatx=0; aatx<n_tx; aatx++){
for (aarx=0; aarx<n_rx; aarx++) { for (aarx=0; aarx<n_rx; aarx++) {
imag = cimag(dl_ch_estimates_ext_flcpx[aatx*n_rx + aarx][re]); imag = cimag(dl_ch_estimates_ext_flp[aatx*n_rx + aarx][re]);
real = creal(dl_ch_estimates_ext_flcpx[aatx*n_rx + aarx][re]); real = creal(dl_ch_estimates_ext_flp[aatx*n_rx + aarx][re]);
H[aatx*n_rx + aarx] = real+ I*imag; H[aatx*n_rx + aarx] = real+ I*imag;
} }
} }
...@@ -4388,37 +4461,40 @@ void mmse_processing_core(int32_t **rxdataF_ext, ...@@ -4388,37 +4461,40 @@ void mmse_processing_core(int32_t **rxdataF_ext,
} }
rxdataF_to_float(rxdataF_ext, rxdataF_to_float(rxdataF_ext,
rxdataF_ext_flcpx, rxdataF_ext_flp,
n_rx, n_rx,
length, length,
start_point); start_point);
mult_mmse_rxdataF(W_MMSE, mult_filter_rxdataF(W_MMSE,
rxdataF_ext_flcpx, rxdataF_ext_flp,
rxdataF_ext_mmse_flp,
n_tx, n_tx,
n_rx, n_rx,
length, length,
start_point); start_point);
mult_mmse_chan_est(W_MMSE, mult_filter_chan_est(W_MMSE,
dl_ch_estimates_ext_flcpx, dl_ch_estimates_ext_flp,
dl_ch_estimates_ext_eff_flp,
n_tx, n_tx,
n_rx, n_rx,
n_tx,
length, length,
start_point); start_point);
float_to_rxdataF(rxdataF_ext, float_to_rxdataF(rxdataF_ext_mmse_flp,
rxdataF_ext_flcpx, rxdataF_ext,
n_tx, n_tx,
n_rx, n_rx,
length, length,
start_point); start_point);
float_to_chan_est(dl_ch_estimates_ext, float_to_chan_est(dl_ch_estimates_ext_eff_flp,
dl_ch_estimates_ext_flcpx, dl_ch_estimates_ext,
n_tx, n_tx,
n_rx, n_rx,
length, length,
...@@ -4427,48 +4503,253 @@ void mmse_processing_core(int32_t **rxdataF_ext, ...@@ -4427,48 +4503,253 @@ void mmse_processing_core(int32_t **rxdataF_ext,
free(W_MMSE); free(W_MMSE);
free(H); free(H);
free(W_MMSE_re); free(W_MMSE_re);
free(dl_ch_estimates_ext_flcpx); free(dl_ch_estimates_ext_flp);
free(rxdataF_ext_flcpx); free(dl_ch_estimates_ext_eff_flp);
free(rxdataF_ext_flp);
free(rxdataF_ext_mmse_flp);
} }
/*THIS FUNCTION TAKES FLOAT_POINT INPUT. SHOULD NOT BE USED WITH OAI*/ /*THIS FUNCTION TAKES FLOAT_POINT INPUT. SHOULD NOT BE USED WITH OAI*/
void mmse_processing_core_flp(float complex** rxdataF_ext_flcpx, void whitening_processing_core_flp(float complex **rxdataF_flp,
float complex **H, float complex **chan_est_flp_0,
int32_t **rxdataF_ext, float complex **chan_est_flp_1,
int32_t **dl_ch_estimates_ext, int32_t **rxdataF_filt_fp_0,
float noise_power, int32_t **rxdataF_filt_fp_1,
int n_tx, int32_t **chan_est_eff_fp_0,
int n_rx, int32_t **chan_est_eff_fp_1,
int length, float sigma2,
int start_point){ uint8_t n_tx,
uint8_t n_rx,
int32_t length,
int32_t start_point)
{
uint8_t aatx, aarx;
float max_0 = 0.0;
float max_1 = 0.0;
float one_over_max_0 = 0.0;
float one_over_max_1 = 0.0;
int32_t i, re;
float complex *W_Wh_0_vec, *W_Wh_1_vec;
float complex *rxdataF_filt_flp_0_vec, *rxdataF_filt_flp_1_vec;
float complex *chan_est_eff_flp_0_vec, *chan_est_eff_flp_1_vec;
float complex *W_Wh_0[n_tx*n_rx], *W_Wh_1[n_tx*n_rx];
float complex *rxdataF_filt_flp_0[n_rx], *rxdataF_filt_flp_1[n_rx];
float complex *chan_est_eff_flp_0[n_rx*(n_tx>>1)], *chan_est_eff_flp_1[n_rx*(n_tx>>1)];
float complex *W_Wh_0_re, *W_Wh_1_re;
float complex *chan_est_flp_re_0, *chan_est_flp_re_1;
int aatx, aarx, re; W_Wh_0_vec = (float complex*)calloc(n_tx*n_rx*length, sizeof(float complex*));
float max = 0; W_Wh_1_vec = (float complex*)calloc(n_tx*n_rx*length, sizeof(float complex*));
float one_over_max = 0;
float complex **W_MMSE= malloc(n_tx*n_rx*sizeof(float complex*)); for (i = 0; i < n_tx*n_rx; ++i) {
for (int j=0; j<n_tx*n_rx; j++) { W_Wh_0[i] = &W_Wh_0_vec[i*length];
W_MMSE[j] = malloc(sizeof(float complex)*length); W_Wh_1[i] = &W_Wh_1_vec[i*length];
} }
float complex *H_re= malloc(n_tx*n_rx*sizeof(float complex)); rxdataF_filt_flp_0_vec = (float complex*)calloc(n_rx*length,sizeof(float complex*));
float complex *W_MMSE_re= malloc(n_tx*n_rx*sizeof(float complex)); rxdataF_filt_flp_1_vec = (float complex*)calloc(n_rx*length,sizeof(float complex*));
for (i = 0; i < n_rx; ++i) {
// Received signal after W_wh on branch 0 and branch 1
rxdataF_filt_flp_0[i] = &rxdataF_filt_flp_0_vec[i*length];
rxdataF_filt_flp_1[i] = &rxdataF_filt_flp_1_vec[i*length];
}
chan_est_eff_flp_0_vec = (float complex*)calloc(n_rx*(n_tx>>1)*length, sizeof(float complex*));
chan_est_eff_flp_1_vec = (float complex*)calloc(n_rx*(n_tx>>1)*length, sizeof(float complex*));
for (i = 0; i < n_rx*(n_tx>>1); ++i) {
// Received signal after W_wh on branch 0 and branch 1
chan_est_eff_flp_0[i] = &chan_est_eff_flp_0_vec[i*length];
chan_est_eff_flp_1[i] = &chan_est_eff_flp_1_vec[i*length];
}
W_Wh_0_re = (float complex*)calloc(n_tx*n_rx, sizeof(float complex));
W_Wh_1_re = (float complex*)calloc(n_tx*n_rx, sizeof(float complex));
chan_est_flp_re_0 = (float complex*)calloc(n_rx*(n_tx>>1), sizeof(float complex));
chan_est_flp_re_1 = (float complex*)calloc(n_rx*(n_tx>>1), sizeof(float complex));
for (re = 0; re < length; ++re){
for (aatx = 0; aatx < n_tx/2; ++aatx){
for (aarx = 0; aarx < n_rx; ++aarx) {
chan_est_flp_re_0[aatx*n_rx + aarx] = chan_est_flp_0[aatx*n_rx + aarx][re];
chan_est_flp_re_1[aatx*n_rx + aarx] = chan_est_flp_1[aatx*n_rx + aarx][re];
}
}
compute_white_filter(chan_est_flp_re_0, chan_est_flp_re_1, sigma2, n_tx, n_rx, W_Wh_0_re, W_Wh_1_re);
for (aatx = 0; aatx < n_tx; ++aatx){
for (aarx = 0; aarx < n_rx; ++aarx) {
W_Wh_0[aatx*n_rx + aarx][re] = W_Wh_0_re[aatx*n_rx + aarx];
W_Wh_1[aatx*n_rx + aarx][re] = W_Wh_1_re[aatx*n_rx + aarx];
if (fabs(creal(W_Wh_0_re[aatx*n_rx + aarx])) > max_0)
max_0 = fabs(creal(W_Wh_0_re[aatx*n_rx + aarx]));
if (fabs(cimag(W_Wh_0_re[aatx*n_rx + aarx])) > max_0)
max_0 = fabs(cimag(W_Wh_0_re[aatx*n_rx + aarx]));
if (fabs(creal(W_Wh_1_re[aatx*n_rx + aarx])) > max_1)
max_1 = fabs(creal(W_Wh_1_re[aatx*n_rx + aarx]));
if (fabs(cimag(W_Wh_1_re[aatx*n_rx + aarx])) > max_1)
max_1 = fabs(cimag(W_Wh_1_re[aatx*n_rx + aarx]));
}
}
}
// Not convinced normalization is needed.
#if 0
one_over_max_0 = 1.0;///max_0;
one_over_max_1 = 1.0;//max_1;
for (re=0; re<length; re++){ for (re=0; re<length; re++){
for (aatx=0; aatx<n_tx; aatx++){ for (aatx=0; aatx<n_tx; aatx++){
for (aarx=0; aarx<n_rx; aarx++) { for (aarx=0; aarx<n_rx; aarx++){
H_re[aatx*n_rx + aarx] = H[aatx*n_rx + aarx][re]; #ifdef DEBUG_FRONT_END
#ifdef DEBUG_MMSE if (re == 0){
printf("whitening_processing_core_flp: W_Wh_0[%d] = (%f + i%f)\n", aatx*n_rx + aarx, creal(W_Wh_0[aatx*n_rx + aarx][re]), cimag(W_Wh_0[aatx*n_rx + aarx][re]));
printf("whitening_processing_core_flp: W_Wh_1[%d] = (%f + i%f)\n", aatx*n_rx + aarx, creal(W_Wh_1[aatx*n_rx + aarx][re]), cimag(W_Wh_1[aatx*n_rx + aarx][re]));
}
#endif
W_Wh_0[aatx*n_rx + aarx][re] = one_over_max_0*W_Wh_0[aatx*n_rx + aarx][re];
W_Wh_1[aatx*n_rx + aarx][re] = one_over_max_1*W_Wh_1[aatx*n_rx + aarx][re];
#ifdef DEBUG_FRONT_END
if (re == 0) if (re == 0)
printf(" H_re[%d]= (%f + i%f)\n", aatx*n_rx + aarx, creal(H_re[aatx*n_rx + aarx]), cimag(H_re[aatx*n_rx + aarx])); printf("whitening_processing_core_flp: AFTER NORM W_Wh_0[%d] = (%f + i%f), max_0 = %f \n", aatx*n_rx + aarx, creal(W_Wh_0[aatx*n_rx + aarx][re]), cimag(W_Wh_0[aatx*n_rx + aarx][re]), max_0);
printf("whitening_processing_core_flp: AFTER NORM W_Wh_1[%d] = (%f + i%f), max_1 = %f \n", aatx*n_rx + aarx, creal(W_Wh_1[aatx*n_rx + aarx][re]), cimag(W_Wh_1[aatx*n_rx + aarx][re]), max_1);
#endif #endif
} }
} }
compute_MMSE(H_re, n_tx, noise_power, W_MMSE_re); }
for (aatx=0; aatx<n_tx; aatx++){ #endif
for (aarx=0; aarx<n_rx; aarx++) {
// Branch 0
mult_filter_rxdataF(W_Wh_0,
rxdataF_flp,
rxdataF_filt_flp_0,
n_tx,
n_rx,
length,
start_point);
mult_filter_chan_est(W_Wh_0,
chan_est_flp_0,
chan_est_eff_flp_0,
n_tx,
n_rx,
(n_tx>>1),
length,
start_point);
float_to_rxdataF(rxdataF_filt_flp_0,
rxdataF_filt_fp_0,
n_tx,
n_rx,
length,
start_point);
float_to_chan_est(chan_est_eff_flp_0,
chan_est_eff_fp_0,
(n_tx>>1),
n_rx,
length,
start_point);
// Branch 1
mult_filter_rxdataF(W_Wh_1,
rxdataF_flp,
rxdataF_filt_flp_1,
n_tx,
n_rx,
length,
start_point);
mult_filter_chan_est(W_Wh_1,
chan_est_flp_1,
chan_est_eff_flp_1,
n_tx,
n_rx,
(n_tx>>1),
length,
start_point);
float_to_rxdataF(rxdataF_filt_flp_1,
rxdataF_filt_fp_1,
n_tx,
n_rx,
length,
start_point);
float_to_chan_est(chan_est_eff_flp_1,
chan_est_eff_fp_1,
(n_tx>>1),
n_rx,
length,
start_point);
free(W_Wh_0_vec);
free(W_Wh_1_vec);
free(rxdataF_filt_flp_0_vec);
free(rxdataF_filt_flp_1_vec);
free(chan_est_eff_flp_0_vec);
free(chan_est_eff_flp_1_vec);
free(W_Wh_0_re);
free(W_Wh_1_re);
free(chan_est_flp_re_0);
free(chan_est_flp_re_1);
}
/*THIS FUNCTION TAKES FLOAT_POINT INPUT. SHOULD NOT BE USED WITH OAI*/
void mmse_processing_core_flp(float complex** rxdataF_flp,
float complex **chan_est_flp,
int32_t **rxdataF_filt_fp,
int32_t **chan_est_eff_fp,
float noise_power,
uint8_t n_tx,
uint8_t n_rx,
int32_t length,
int32_t start_point){
uint8_t aatx, aarx;
float max = 0;
float one_over_max = 0;
int32_t i, re;
float complex *W_MMSE_vec, *rxdataF_filt_flp_vec, *chan_est_eff_flp_vec;
float complex *W_MMSE[n_tx*n_rx], *rxdataF_filt_flp[n_rx], *chan_est_eff_flp[n_tx*n_rx];
W_MMSE_vec = (float complex*)calloc(n_tx*n_rx*length, sizeof(float complex*));
for (i = 0; i < n_tx*n_rx; ++i) {
W_MMSE[i] = &W_MMSE_vec[i*length];
}
rxdataF_filt_flp_vec = (float complex*)calloc(n_rx*length, sizeof(float complex*));
for (i = 0; i < n_rx; ++i) {
rxdataF_filt_flp[i] = &rxdataF_filt_flp_vec[i*length];
}
chan_est_eff_flp_vec = (float complex*)calloc(n_tx*n_rx*length, sizeof(float complex*));
for (i = 0; i < n_tx*n_rx; ++i) {
chan_est_eff_flp[i] = &chan_est_eff_flp_vec[i*length];
}
float complex *chan_est_flp_re = calloc(n_tx*n_rx, sizeof(float complex));
float complex *W_MMSE_re = calloc(n_tx*n_rx, sizeof(float complex));
for (re = 0; re < length; ++re){
for (aatx = 0; aatx < n_tx; ++aatx){
for (aarx = 0; aarx < n_rx; ++aarx) {
chan_est_flp_re[aatx*n_rx + aarx] = chan_est_flp[aatx*n_rx + aarx][re];
}
}
compute_MMSE(chan_est_flp_re, n_tx, noise_power, W_MMSE_re);
for (aatx = 0; aatx < n_tx; ++aatx){
for (aarx = 0; aarx < n_rx; ++aarx) {
W_MMSE[aatx*n_rx + aarx][re] = W_MMSE_re[aatx*n_rx + aarx]; W_MMSE[aatx*n_rx + aarx][re] = W_MMSE_re[aatx*n_rx + aarx];
if (fabs(creal(W_MMSE_re[aatx*n_rx + aarx])) > max) if (fabs(creal(W_MMSE_re[aatx*n_rx + aarx])) > max)
max = fabs(creal(W_MMSE_re[aatx*n_rx + aarx])); max = fabs(creal(W_MMSE_re[aatx*n_rx + aarx]));
...@@ -4477,54 +4758,67 @@ void mmse_processing_core_flp(float complex** rxdataF_ext_flcpx, ...@@ -4477,54 +4758,67 @@ void mmse_processing_core_flp(float complex** rxdataF_ext_flcpx,
} }
} }
} }
one_over_max = 1.0/max; one_over_max = 1.0/max;
for (re=0; re<length; re++) for (re = 0; re < length; ++re){
for (aatx=0; aatx<n_tx; aatx++) for (aatx = 0; aatx < n_tx; ++aatx){
for (aarx=0; aarx<n_rx; aarx++){ for (aarx = 0; aarx < n_rx; ++aarx){
#ifdef DEBUG_MMSE
if (re == 0) #ifdef DEBUG_FRONT_END
printf(" W_MMSE[%d] = (%f + i%f)\n", aatx*n_rx + aarx, creal(W_MMSE[aatx*n_rx + aarx][re]), cimag(W_MMSE[aatx*n_rx + aarx][re])); if (re == 0){
printf("mmse_processing_core_flp: W_MMSE[%d] = (%f + i%f)\n", aatx*n_rx + aarx, creal(W_MMSE[aatx*n_rx + aarx][re]), cimag(W_MMSE[aatx*n_rx + aarx][re]));
}
#endif #endif
W_MMSE[aatx*n_rx + aarx][re] = one_over_max*W_MMSE[aatx*n_rx + aarx][re]; W_MMSE[aatx*n_rx + aarx][re] = one_over_max*W_MMSE[aatx*n_rx + aarx][re];
#ifdef DEBUG_MMSE
if (re == 0) #ifdef DEBUG_FRONT_END
printf(" AFTER NORM W_MMSE[%d] = (%f + i%f), max = %f \n", aatx*n_rx + aarx, creal(W_MMSE[aatx*n_rx + aarx][re]), cimag(W_MMSE[aatx*n_rx + aarx][re]), max); if (re == 0){
#endif printf("mmse_processing_core_flp: AFTER NORM W_MMSE[%d] = (%f + i%f), max = %f \n", aatx*n_rx + aarx, creal(W_MMSE[aatx*n_rx + aarx][re]), cimag(W_MMSE[aatx*n_rx + aarx][re]), max);
} }
#endif
}
}
}
mult_mmse_rxdataF(W_MMSE, mult_filter_rxdataF(W_MMSE,
rxdataF_ext_flcpx, rxdataF_flp,
rxdataF_filt_flp,
n_tx, n_tx,
n_rx, n_rx,
length, length,
start_point); start_point);
mult_mmse_chan_est(W_MMSE, mult_filter_chan_est(W_MMSE,
H, chan_est_flp,
chan_est_eff_flp,
n_tx, n_tx,
n_rx, n_rx,
n_tx,
length, length,
start_point); start_point);
float_to_rxdataF(rxdataF_ext, float_to_rxdataF(rxdataF_filt_flp,
rxdataF_ext_flcpx, rxdataF_filt_fp,
n_tx, n_tx,
n_rx, n_rx,
length, length,
start_point); start_point);
float_to_chan_est(dl_ch_estimates_ext, float_to_chan_est(chan_est_eff_flp,
H, chan_est_eff_fp,
n_tx, n_tx,
n_rx, n_rx,
length, length,
start_point); start_point);
free(H_re);
free(W_MMSE);
free(W_MMSE_re);
free(W_MMSE_vec);
free(W_MMSE_re);
free(rxdataF_filt_flp_vec);
free(chan_est_eff_flp_vec);
free(chan_est_flp_re);
} }
...@@ -4636,7 +4930,7 @@ void rxdataF_to_float(int32_t **rxdataF_ext, ...@@ -4636,7 +4930,7 @@ void rxdataF_to_float(int32_t **rxdataF_ext,
imag = (int16_t) (rxdataF_ext[aarx][start_point + re] >> 16); imag = (int16_t) (rxdataF_ext[aarx][start_point + re] >> 16);
real = (int16_t) (rxdataF_ext[aarx][start_point + re] & 0xffff); real = (int16_t) (rxdataF_ext[aarx][start_point + re] & 0xffff);
rxdataF_f[aarx][re] = (float)(real/(32768.0)) + I*(float)(imag/(32768.0)); rxdataF_f[aarx][re] = (float)(real/(32768.0)) + I*(float)(imag/(32768.0));
#ifdef DEBUG_MMSE #ifdef DEBUG_FRONT_END
if (re==0){ if (re==0){
printf("rxdataF_to_float: aarx = %d, real= %d, imag = %d\n", aarx, real, imag); printf("rxdataF_to_float: aarx = %d, real= %d, imag = %d\n", aarx, real, imag);
//printf("rxdataF_to_float: rxdataF_ext[%d][%d] = %d\n", aarx, start_point + re, rxdataF_ext[aarx][start_point + re]); //printf("rxdataF_to_float: rxdataF_ext[%d][%d] = %d\n", aarx, start_point + re, rxdataF_ext[aarx][start_point + re]);
...@@ -4651,26 +4945,26 @@ void rxdataF_to_float(int32_t **rxdataF_ext, ...@@ -4651,26 +4945,26 @@ void rxdataF_to_float(int32_t **rxdataF_ext,
void chan_est_to_float(int32_t **dl_ch_estimates_ext, void chan_est_to_float(int32_t **dl_ch_estimates_ext,
float complex **dl_ch_estimates_ext_f, float complex **dl_ch_estimates_ext_f,
int n_tx, uint8_t n_tx,
int n_rx, uint8_t n_rx,
int length, int32_t length,
int start_point) int32_t start_point)
{ {
short re; int32_t re;
int aatx,aarx; uint8_t aatx,aarx;
int16_t imag; int16_t imag;
int16_t real; int16_t real;
for (aatx=0; aatx<n_tx; aatx++){ for (aatx = 0; aatx < n_tx; ++aatx){
for (aarx=0; aarx<n_rx; aarx++) { for (aarx = 0; aarx < n_rx; ++aarx) {
for (re=0; re<length; re++){ for (re = 0; re < length; ++re){
imag = (int16_t) (dl_ch_estimates_ext[aatx*n_rx + aarx][start_point + re] >> 16); imag = (int16_t) (dl_ch_estimates_ext[aatx*n_rx + aarx][start_point + re] >> 16);
real = (int16_t) (dl_ch_estimates_ext[aatx*n_rx + aarx][start_point+ re] & 0xffff); real = (int16_t) (dl_ch_estimates_ext[aatx*n_rx + aarx][start_point+ re] & 0xffff);
dl_ch_estimates_ext_f[aatx*n_rx + aarx][re] = (float)(real/(32768.0)) + I*(float)(imag/(32768.0)); dl_ch_estimates_ext_f[aatx*n_rx + aarx][re] = (float)(real/(32768.0)) + I*(float)(imag/(32768.0));
#ifdef DEBUG_MMSE #ifdef DEBUG_FRONT_END
if (re==0){ if (re == 0){
printf("ant %d, re = %d, real = %d, imag = %d \n", aatx*n_rx + aarx, re, real, imag); printf("chan_est_to_float: ant %d, re = %d, real = %d, imag = %d \n", aatx*n_rx + aarx, re, real, imag);
printf("ant %d, re = %d, real = %f, imag = %f \n", aatx*n_rx + aarx, re, creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re]), cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])); printf("chan_est_to_float: ant %d, re = %d, real = %f, imag = %f \n", aatx*n_rx + aarx, re, creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re]), cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re]));
} }
#endif #endif
} }
...@@ -4678,82 +4972,84 @@ void chan_est_to_float(int32_t **dl_ch_estimates_ext, ...@@ -4678,82 +4972,84 @@ void chan_est_to_float(int32_t **dl_ch_estimates_ext,
} }
} }
void float_to_chan_est(int32_t **dl_ch_estimates_ext, void float_to_chan_est(float complex **chan_est_flp,
float complex **dl_ch_estimates_ext_f, int32_t **result,
int n_tx, int n_tx,
int n_rx, int n_rx,
int length, int length,
int start_point) int start_point)
{ {
short re; short re;
int aarx, aatx; int aarx, aatx;
int16_t imag; int16_t imag;
int16_t real; int16_t real;
for (aatx=0; aatx<n_tx; aatx++){ for (aatx = 0; aatx < n_tx; ++aatx){
for (aarx=0; aarx<n_rx; aarx++) { for (aarx = 0; aarx < n_rx; ++aarx) {
for (re=0; re<length; re++){ for (re = 0; re < length; ++re){
if (cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])<-1) if (cimag(chan_est_flp[aatx*n_rx + aarx][re]) < -1)
imag = 0x8000; imag = 0x8000;
else if (cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])>=1) else if (cimag(chan_est_flp[aatx*n_rx + aarx][re]) >= 1)
imag = 0x7FFF; imag = 0x7FFF;
else else
imag = cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])*32768; imag = cimag(chan_est_flp[aatx*n_rx + aarx][re]) * 32768;
if (creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])<-1) if (creal(chan_est_flp[aatx*n_rx + aarx][re]) < -1)
real = 0x8000; real = 0x8000;
else if (creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])>=1) else if (creal(chan_est_flp[aatx*n_rx + aarx][re]) >= 1)
real = 0x7FFF; real = 0x7FFF;
else else
real = creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])*32768; real = creal(chan_est_flp[aatx*n_rx + aarx][re]) * 32768;
dl_ch_estimates_ext[aatx*n_rx + aarx][start_point + re] = (((int32_t)imag)<<16)|((int32_t)real & 0xffff); result[aatx*n_rx + aarx][start_point + re] = (((int32_t)imag)<<16)|((int32_t)real & 0xffff);
#ifdef DEBUG_MMSE
if (re==0){ #ifdef DEBUG_FRONT_END
printf(" float_to_chan_est: chan est real = %f, chan est imag = %f\n",creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re]), cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])); if (re == 0){
printf(" float_to_chan_est: chan est real = %f, chan est imag = %f\n",creal(chan_est_flp[aatx*n_rx + aarx][re]), cimag(chan_est_flp[aatx*n_rx + aarx][re]));
printf("float_to_chan_est: real fixed = %d, imag fixed = %d\n", real, imag); printf("float_to_chan_est: real fixed = %d, imag fixed = %d\n", real, imag);
printf("float_to_chan_est: ant %d, re = %d, dl_ch_estimates_ext = %d \n", aatx*n_rx + aarx, re, dl_ch_estimates_ext[aatx*n_rx + aarx][start_point + re]); printf("float_to_chan_est: ant %d, re = %d, result = %d \n", aatx*n_rx + aarx, re, result[aatx*n_rx + aarx][start_point + re]);
} }
#endif #endif
} }
} }
} }
} }
void float_to_rxdataF(int32_t **rxdataF_ext, void float_to_rxdataF(float complex **rxdataF_flp,
float complex **rxdataF_f, int32_t **result,
int n_tx, uint8_t n_tx,
int n_rx, uint8_t n_rx,
int length, int32_t length,
int start_point) int32_t start_point)
{ {
int32_t re;
short re; uint8_t aarx;
int aarx;
int16_t imag; int16_t imag;
int16_t real; int16_t real;
for (aarx=0; aarx<n_rx; aarx++) { for (aarx = 0; aarx < n_rx; ++aarx) {
for (re=0; re<length; re++){ for (re = 0; re < length; ++re){
if (cimag(rxdataF_f[aarx][re])<-1) if (cimag(rxdataF_flp[aarx][re]) < -1)
imag = 0x8000; imag = 0x8000;
else if (cimag(rxdataF_f[aarx][re])>=1) else if (cimag(rxdataF_flp[aarx][re]) >= 1)
imag = 0x7FFF; imag = 0x7FFF;
else else
imag = cimag(rxdataF_f[aarx][re])*32768; imag = cimag(rxdataF_flp[aarx][re]) * 32768;
if (creal(rxdataF_f[aarx][re])<-1) if (creal(rxdataF_flp[aarx][re]) < -1)
real = 0x8000; real = 0x8000;
else if (creal(rxdataF_f[aarx][re])>=1) else if (creal(rxdataF_flp[aarx][re]) >= 1)
real = 0x7FFF; real = 0x7FFF;
else else
real = creal(rxdataF_f[aarx][re])*32768; real = creal(rxdataF_flp[aarx][re]) * 32768;
rxdataF_ext[aarx][start_point + re] = (((int32_t)imag)<<16)|(((int32_t)real) & 0xffff);
#ifdef DEBUG_MMSE result[aarx][start_point + re] = (((int32_t)imag)<<16)|(((int32_t)real) & 0xffff);
if (re==0){
printf(" float_to_rxdataF: real = %f, imag = %f\n",creal(rxdataF_f[aarx][re]), cimag(rxdataF_f[aarx][re])); #ifdef DEBUG_FRONT_END
if (re == 0){
printf(" float_to_rxdataF: real = %f, imag = %f\n",creal(rxdataF_flp[aarx][re]), cimag(rxdataF_flp[aarx][re]));
printf("float_to_rxdataF: real fixed = %d, imag fixed = %d\n", real, imag); printf("float_to_rxdataF: real fixed = %d, imag fixed = %d\n", real, imag);
printf("float_to_rxdataF: ant %d, re = %d, rxdataF_ext = %d \n", aarx, re, rxdataF_ext[aarx][start_point + re]); printf("float_to_rxdataF: ant %d, re = %d, result = %d \n", aarx, re, result[aarx][start_point + re]);
} }
#endif #endif
} }
...@@ -4761,95 +5057,110 @@ void float_to_rxdataF(int32_t **rxdataF_ext, ...@@ -4761,95 +5057,110 @@ void float_to_rxdataF(int32_t **rxdataF_ext,
} }
void mult_mmse_rxdataF(float complex** Wmmse, void mult_filter_rxdataF(float complex **W,
float complex** rxdataF_ext_f, float complex **rxdataF_flp,
int n_tx, float complex **result,
int n_rx, uint8_t n_tx,
int length, uint8_t n_rx,
int start_point) int32_t length,
int32_t start_point)
{ {
short re; int32_t re;
int aarx, aatx; uint8_t aarx, aatx;
float complex *rxdata_re = malloc(n_rx*sizeof(float complex));
float complex *result_re = malloc(n_rx*sizeof(float complex));
float complex *W_re = malloc(n_tx*n_rx*sizeof(float complex));
float complex* rxdata_re = malloc(n_rx*sizeof(float complex)); for (re = 0;re < length; ++re){
float complex* rxdata_mmse_re = malloc(n_rx*sizeof(float complex)); for (aarx = 0; aarx < n_rx; ++aarx){
float complex* Wmmse_re = malloc(n_tx*n_rx*sizeof(float complex)); rxdata_re[aarx] = rxdataF_flp[aarx][re];
for (re=0;re<length; re++){ #ifdef DEBUG_FRONT_END
for (aarx=0; aarx<n_rx; aarx++){ if (re == 0)
rxdata_re[aarx] = rxdataF_ext_f[aarx][re]; printf("mult_filter_rxdataF before: rxdata_re[%d] = (%f, %f)\n", aarx, creal(rxdata_re[aarx]), cimag(rxdata_re[aarx]));
#ifdef DEBUG_MMSE
if (re==0)
printf("mult_mmse_rxdataF before: rxdata_re[%d] = (%f, %f)\n", aarx, creal(rxdata_re[aarx]), cimag(rxdata_re[aarx]));
#endif #endif
} }
for (aatx=0; aatx<n_tx; aatx++){
for (aarx=0; aarx<n_rx; aarx++){ for (aatx = 0; aatx < n_tx; ++aatx){
Wmmse_re[aatx*n_rx + aarx] = Wmmse[aatx*n_rx + aarx][re]; for (aarx = 0; aarx < n_rx; ++aarx){
W_re[aatx*n_rx + aarx] = W[aatx*n_rx + aarx][re];
} }
} }
mutl_matrix_matrix_col_based(Wmmse_re, rxdata_re, n_rx, n_tx, n_rx, 1, rxdata_mmse_re);
for (aarx=0; aarx<n_rx; aarx++){ mutl_matrix_matrix_col_based(W_re, rxdata_re, n_rx, n_tx, n_rx, 1, result_re);
rxdataF_ext_f[aarx][re] = rxdata_mmse_re[aarx];
#ifdef DEBUG_MMSE for (aarx = 0; aarx < n_rx; ++aarx){
if (re==0) result[aarx][re] = result_re[aarx];
printf("mult_mmse_rxdataF after: rxdataF_ext_f[%d] = (%f, %f)\n", aarx, creal(rxdataF_ext_f[aarx][re]), cimag(rxdataF_ext_f[aarx][re]));
#ifdef DEBUG_FRONT_END
if (re == 0)
printf("mult_filter_rxdataF after: result[%d] = (%f, %f)\n", aarx, creal(result[aarx][re]), cimag(result[aarx][re]));
#endif #endif
} }
} }
free(rxdata_re); free(rxdata_re);
free(rxdata_mmse_re); free(result_re);
free(Wmmse_re); free(W_re);
} }
void mult_mmse_chan_est(float complex** Wmmse, void mult_filter_chan_est(float complex **W,
float complex** dl_ch_estimates_ext_f, float complex **chan_est_flp,
int n_tx, float complex **result,
int n_rx, uint8_t n_tx,
int length, uint8_t n_rx,
int start_point) int32_t n_col_chan_est_flp,
int32_t length,
int32_t start_point)
{ {
short re; int32_t re;
int aarx, aatx; uint8_t aarx, aatx;
float complex* chan_est_re = malloc(n_tx*n_rx*sizeof(float complex)); float complex* chan_est_re = malloc(n_col_chan_est_flp*n_rx*sizeof(float complex));
float complex* chan_est_mmse_re = malloc(n_tx*n_rx*sizeof(float complex)); float complex* result_re = malloc(n_col_chan_est_flp*n_rx*sizeof(float complex));
float complex* Wmmse_re = malloc(n_tx*n_rx*sizeof(float complex)); float complex* W_re = malloc(n_tx*n_rx*sizeof(float complex));
for (re=0;re<length; re++){ for (re = 0;re < length; ++re){
for (aatx=0; aatx<n_tx; aatx++){ for (aatx = 0; aatx < n_tx; ++aatx){
for (aarx=0; aarx<n_rx; aarx++){ for (aarx = 0; aarx < n_rx; ++aarx){
chan_est_re[aatx*n_rx + aarx] = dl_ch_estimates_ext_f[aatx*n_rx + aarx][re]; W_re[aatx*n_rx + aarx] = W[aatx*n_rx + aarx][re];
Wmmse_re[aatx*n_rx + aarx] = Wmmse[aatx*n_rx + aarx][re]; }
#ifdef DEBUG_MMSE }
for (aatx = 0; aatx < n_col_chan_est_flp; ++aatx){
for (aarx = 0; aarx < n_rx; ++aarx){
chan_est_re[aatx*n_rx + aarx] = chan_est_flp[aatx*n_rx + aarx][re];
#ifdef DEBUG_FRONT_END
if (re==0) if (re==0)
printf("mult_mmse_chan_est: chan_est_re[%d] = (%f, %f)\n", aatx*n_rx + aarx, creal(chan_est_re[aatx*n_rx + aarx]), cimag(chan_est_re[aatx*n_rx + aarx])); printf("mult_filter_chan_est: chan_est_re[%d] = (%f, %f)\n", aatx*n_rx + aarx, creal(chan_est_re[aatx*n_rx + aarx]), cimag(chan_est_re[aatx*n_rx + aarx]));
#endif #endif
} }
} }
mutl_matrix_matrix_col_based(Wmmse_re, chan_est_re, n_rx, n_tx, n_rx, n_tx, chan_est_mmse_re);
for (aatx=0; aatx<n_tx; aatx++){ mutl_matrix_matrix_col_based(W_re, chan_est_re, n_rx, n_tx, n_rx, n_col_chan_est_flp, result_re);
for (aarx=0; aarx<n_rx; aarx++){
dl_ch_estimates_ext_f[aatx*n_rx + aarx][re] = chan_est_mmse_re[aatx*n_rx + aarx]; for (aatx = 0; aatx < n_col_chan_est_flp; ++aatx){
#ifdef DEBUG_MMSE for (aarx = 0; aarx < n_rx; ++aarx){
if (re==0) result[aatx*n_rx + aarx][re] = result_re[aatx*n_rx + aarx];
printf("mult_mmse_chan_est: dl_ch_estimates_ext_f[%d][%d] = (%f, %f)\n", aatx*n_rx + aarx, re, creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re]), cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])); #ifdef DEBUG_FRONT_END
if (re==0){
printf("mult_filter_chan_est: result[%d][%d] = (%f, %f)\n", aatx*n_rx + aarx, re, creal(result[aatx*n_rx + aarx][re]), cimag(result[aatx*n_rx + aarx][re]));
}
#endif #endif
} }
} }
} }
free(Wmmse_re); free(W_re);
free(chan_est_re); free(chan_est_re);
free(chan_est_mmse_re); free(result_re);
} }
//compute average channel_level of effective (precoded) channel //compute average channel_level of effective (precoded) channel
void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, void dlsch_channel_level_TM34(int **dl_ch_estimates_ext,
LTE_DL_FRAME_PARMS *frame_parms, LTE_DL_FRAME_PARMS *frame_parms,
......
...@@ -59,42 +59,26 @@ void transpose (int N, float complex *A, float complex *Result) ...@@ -59,42 +59,26 @@ void transpose (int N, float complex *A, float complex *Result)
} }
void conjugate_transpose (int N, float complex *A, float complex *Result)
void conjugate_transpose (int rows_A, int col_A, float complex *A, float complex *Result)
{ {
// Computes C := alpha*op(A)*op(B) + beta*C, // Computes C := alpha*op(A)*op(B) + beta*C,
enum CBLAS_TRANSPOSE transa = CblasConjTrans; enum CBLAS_TRANSPOSE transa = CblasConjTrans;
enum CBLAS_TRANSPOSE transb = CblasNoTrans; enum CBLAS_TRANSPOSE transb = CblasNoTrans;
int rows_opA = N; // number of rows in op(A) and in C float complex alpha = 1.0;
int col_opB = N; //number of columns of op(B) and in C float complex beta = 0.0;
int col_opA = N; //number of columns in op(A) and rows in op(B)
int col_B; //number of columns in B
float complex alpha = 1.0+I*0;
int lda = rows_opA;
float complex beta = 0.0+I*0;
int ldc = rows_opA;
int i; int i;
float complex* B; float complex* B;
int ldb = col_opB;
if (transb == CblasNoTrans) { B = (float complex*)calloc(rows_A*rows_A,sizeof(float complex));
B = (float complex*)calloc(ldb*col_opB,sizeof(float complex));
col_B= col_opB;
}
else {
B = (float complex*)calloc(ldb*col_opA, sizeof(float complex));
col_B = col_opA;
}
float complex* C = (float complex*)malloc(ldc*col_opB*sizeof(float complex));
for (i=0; i<lda*col_B; i+=N+1)
B[i]=1.0+I*0;
cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, A, lda, B, ldb, &beta, C, ldc); for (i=0; i<rows_A*rows_A; i+=rows_A+1)
B[i]=1.0;
memcpy(Result, C, N*N*sizeof(float complex)); cblas_cgemm(CblasColMajor, transa, transb, col_A, rows_A, rows_A, &alpha, A, rows_A, B, rows_A, &beta, Result, col_A);
free(B); free(B);
free(C);
} }
void H_hermH_plus_sigma2I (int N, int M, float complex *A, float sigma2, float complex *Result) void H_hermH_plus_sigma2I (int N, int M, float complex *A, float sigma2, float complex *Result)
...@@ -124,27 +108,20 @@ void H_hermH_plus_sigma2I (int N, int M, float complex *A, float sigma2, float c ...@@ -124,27 +108,20 @@ void H_hermH_plus_sigma2I (int N, int M, float complex *A, float sigma2, float c
} }
void HH_herm_plus_sigma2I (int M, int N, float complex *A, float sigma2, float complex *Result) void HH_herm_plus_sigma2I (int rows_A, int col_A, float complex *A, float sigma2, float complex *Result)
{ {
//C := alpha*op(A)*op(B) + beta*C, //C := alpha*op(A)*op(B) + beta*C,
enum CBLAS_TRANSPOSE transa = CblasNoTrans; enum CBLAS_TRANSPOSE transa = CblasNoTrans;
enum CBLAS_TRANSPOSE transb = CblasConjTrans; enum CBLAS_TRANSPOSE transb = CblasConjTrans;
int k = N; //number of columns in op(A) and rows in op(B),k
float complex alpha = 1.0+I*0; float complex alpha = 1.0+I*0;
int lda = N;
int ldb = N;
int ldc = M;
int i; int i;
float complex* C = (float complex*)calloc(M*M, sizeof(float complex)); for (i = 0; i < rows_A*rows_A; i += rows_A+1)
Result[i]=1.0+I*0;
for (i=0; i<M*M; i+=M+1)
C[i]=1.0+I*0;
cblas_cgemm(CblasRowMajor, transa, transb, M, M, k, &alpha, A, lda, A, ldb, &sigma2, C, ldc); cblas_cgemm(CblasColMajor, transa, transb, rows_A, rows_A, col_A, &alpha, A, rows_A, A, rows_A, &sigma2, Result, rows_A);
memcpy(Result, C, M*M*sizeof(float complex));
free(C);
} }
...@@ -153,14 +130,14 @@ void eigen_vectors_values (int N, float complex *A, float complex *Vectors, floa ...@@ -153,14 +130,14 @@ void eigen_vectors_values (int N, float complex *A, float complex *Vectors, floa
// This function computes ORTHONORMAL eigenvectors and eigenvalues of matrix A, // This function computes ORTHONORMAL eigenvectors and eigenvalues of matrix A,
// where Values_Matrix is a diagonal matrix of eigenvalues. // where Values_Matrix is a diagonal matrix of eigenvalues.
// A=Vectors*Values_Matrix*Vectors' // A=Vectors*Values_Matrix*Vectors'
char jobz = 'V'; char jobz = 'V'; // compute both eigenvectors and eigenvalues
char uplo = 'U'; char uplo = 'U';
int order_A = N; int order_A = N;
int lda = N; int lda = N;
int i; int i;
float* Values = (float*)malloc(sizeof(float)*1*N); float* Values = (float*)calloc(1*N, sizeof(float));
LAPACKE_cheev(LAPACK_ROW_MAJOR, jobz, uplo, order_A, A, lda, Values); LAPACKE_cheev(LAPACK_COL_MAJOR, jobz, uplo, order_A, A, lda, Values);
memcpy(Vectors, A, N*N*sizeof(float complex)); memcpy(Vectors, A, N*N*sizeof(float complex));
...@@ -178,7 +155,7 @@ void eigen_vectors_values (int N, float complex *A, float complex *Vectors, floa ...@@ -178,7 +155,7 @@ void eigen_vectors_values (int N, float complex *A, float complex *Vectors, floa
int nrhs = N; int nrhs = N;
char transa = 'N'; char transa = 'N';
int* IPIV = malloc(N*N*sizeof(int)); int* IPIV = calloc(N*N, sizeof(int));
// Compute LU-factorization // Compute LU-factorization
LAPACKE_cgetrf(LAPACK_ROW_MAJOR, n, nrhs, A, lda, IPIV); LAPACKE_cgetrf(LAPACK_ROW_MAJOR, n, nrhs, A, lda, IPIV);
...@@ -208,23 +185,24 @@ void mutl_matrix_matrix_row_based(float complex* M0, float complex* M1, int rows ...@@ -208,23 +185,24 @@ void mutl_matrix_matrix_row_based(float complex* M0, float complex* M1, int rows
#ifdef DEBUG_PREPROC #ifdef DEBUG_PREPROC
int i=0; int i=0;
printf("rows_M0 %d, col_M0 %d, rows_M1 %d, col_M1 %d\n", rows_M0, col_M0, rows_M1, col_M1); printf("mutl_matrix_matrix_row_based: rows_M0 %d, col_M0 %d, rows_M1 %d, col_M1 %d\n", rows_M0, col_M0, rows_M1, col_M1);
for(i=0; i<rows_M0*col_M0; ++i) for(i=0; i<rows_M0*col_M0; ++i)
printf(" rows_opA = %d, col_opB = %d, W_MMSE[%d] = (%f + i%f)\n", rows_opA, col_opB, i , creal(M0[i]), cimag(M0[i])); printf("mutl_matrix_matrix_row_based: rows_opA = %d, col_opB = %d, W_MMSE[%d] = (%f + i%f)\n", rows_opA, col_opB, i , creal(M0[i]), cimag(M0[i]));
for(i=0; i<rows_M1*col_M1; ++i) for(i=0; i<rows_M1*col_M1; ++i)
printf(" M1[%d] = (%f + i%f)\n", i , creal(M1[i]), cimag(M1[i])); printf("mutl_matrix_matrix_row_based: M1[%d] = (%f + i%f)\n", i , creal(M1[i]), cimag(M1[i]));
#endif #endif
cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, M0, lda, M1, ldb, &beta, Result, ldc); cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, M0, lda, M1, ldb, &beta, Result, ldc);
#ifdef DEBUG_PREPROC #ifdef DEBUG_PREPROC
for(i=0; i<rows_opA*col_opB; ++i) for(i=0; i<rows_opA*col_opB; ++i)
printf(" result[%d] = (%f + i%f)\n", i , creal(Result[i]), cimag(Result[i])); printf("mutl_matrix_matrix_row_based: result[%d] = (%f + i%f)\n", i , creal(Result[i]), cimag(Result[i]));
#endif #endif
} }
void mutl_matrix_matrix_col_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result ){ void mutl_matrix_matrix_col_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result ){
enum CBLAS_TRANSPOSE transa = CblasNoTrans; enum CBLAS_TRANSPOSE transa = CblasNoTrans;
enum CBLAS_TRANSPOSE transb = CblasNoTrans; enum CBLAS_TRANSPOSE transb = CblasNoTrans;
...@@ -239,21 +217,56 @@ void mutl_matrix_matrix_col_based(float complex* M0, float complex* M1, int rows ...@@ -239,21 +217,56 @@ void mutl_matrix_matrix_col_based(float complex* M0, float complex* M1, int rows
#ifdef DEBUG_PREPROC #ifdef DEBUG_PREPROC
int i = 0; int i = 0;
printf("rows_M0 %d, col_M0 %d, rows_M1 %d, col_M1 %d\n", rows_M0, col_M0, rows_M1, col_M1); printf("mutl_matrix_matrix_col_based: rows_M0 %d, col_M0 %d, rows_M1 %d, col_M1 %d\n", rows_M0, col_M0, rows_M1, col_M1);
for(i=0; i<rows_M0*col_M0; ++i)
printf(" rows_opA = %d, col_opB = %d, W_MMSE[%d] = (%f + i%f)\n", rows_opA, col_opB, i , creal(M0[i]), cimag(M0[i]));
for(i = 0; i < rows_M0*col_M0; ++i)
printf("mutl_matrix_matrix_col_based: rows_opA = %d, col_opB = %d, filter[%d] = (%f + i%f)\n", rows_opA, col_opB, i , creal(M0[i]), cimag(M0[i]));
for(i=0; i<rows_M1*col_M1; ++i) for(i = 0; i < rows_M1*col_M1; ++i)
printf(" M1[%d] = (%f + i%f)\n", i , creal(M1[i]), cimag(M1[i])); printf("mutl_matrix_matrix_col_based: M1[%d] = (%f + i%f)\n", i , creal(M1[i]), cimag(M1[i]));
#endif #endif
cblas_cgemm(CblasColMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, M0, lda, M1, ldb, &beta, Result, ldc); cblas_cgemm(CblasColMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, M0, lda, M1, ldb, &beta, Result, ldc);
#ifdef DEBUG_PREPROC #ifdef DEBUG_PREPROC
for(i=0; i<rows_opA*col_opB; ++i) for(i = 0; i < rows_opA*col_opB; ++i)
printf(" result[%d] = (%f + i%f)\n", i , creal(Result[i]), cimag(Result[i])); printf("mutl_matrix_matrix_col_based: result[%d] = (%f + i%f)\n", i , creal(Result[i]), cimag(Result[i]));
#endif
}
void mutl_scal_matrix_matrix_col_based(float *M0, float complex *M1, float alpha, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex *Result ){
enum CBLAS_TRANSPOSE transa = CblasNoTrans;
enum CBLAS_TRANSPOSE transb = CblasNoTrans;
float complex beta = 0.0;
int i;
float complex *D_0_complex = calloc(rows_M0*col_M0, sizeof(float complex));
for(i = 0; i < rows_M0*col_M0; ++i){
D_0_complex[i] = M0[i] + I*0.00001;
#ifdef DEBUG_PREPROC
printf("mutl_scal_matrix_matrix_col_based: D_0_complex[%d] = (%f, %f)\n", i , creal(D_0_complex[i]), cimag(D_0_complex[i]));
#endif
}
#ifdef DEBUG_PREPROC
printf("mutl_scal_matrix_matrix_col_based: alpha = %f\n", alpha);
for(i = 0; i < rows_M0*col_M0; ++i){
printf("mutl_scal_matrix_matrix_col_based M0[%d] = %f\n", i , M0[i]);
}
for(i = 0; i < rows_M1*col_M1; ++i)
printf("mutl_scal_matrix_matrix_col_based: M1[%d] = (%f + i%f)\n", i , creal(M1[i]), cimag(M1[i]));
#endif
cblas_cgemm(CblasColMajor, transa, transb, rows_M0, col_M1, col_M0, &alpha, D_0_complex, rows_M0, M1, col_M0, &beta, Result, rows_M0);
#ifdef DEBUG_PREPROC
for(i = 0; i < rows_M0*col_M1; ++i)
printf("mutl_scal_matrix_matrix_col_based: result[%d] = (%f + i%f)\n", i , creal(Result[i]), cimag(Result[i]));
#endif #endif
} }
...@@ -262,108 +275,154 @@ void mutl_matrix_matrix_col_based(float complex* M0, float complex* M1, int rows ...@@ -262,108 +275,154 @@ void mutl_matrix_matrix_col_based(float complex* M0, float complex* M1, int rows
void compute_MMSE(float complex* H, int order_H, float sigma2, float complex* W_MMSE) void compute_MMSE(float complex* H, int order_H, float sigma2, float complex* W_MMSE)
{ {
int N = order_H; int N = order_H;
float complex* H_hermH_sigmaI = malloc(N*N*sizeof(float complex)); float complex* H_hermH_sigmaI = calloc(N*N, sizeof(float complex));
float complex* H_herm = malloc(N*N*sizeof(float complex)); float complex* H_herm = calloc(N*N, sizeof(float complex));
H_hermH_plus_sigma2I(N, N, H, sigma2, H_hermH_sigmaI); H_hermH_plus_sigma2I(N, N, H, sigma2, H_hermH_sigmaI);
#ifdef DEBUG_PREPROC #ifdef DEBUG_PREPROC
int i =0; int i = 0;
for(i=0;i<N*N;i++) for(i = 0;i < N*N; ++i)
printf(" H_hermH_sigmaI[%d] = (%f + i%f)\n", i , creal(H_hermH_sigmaI[i]), cimag(H_hermH_sigmaI[i])); printf("compute_MMSE: H_hermH_sigmaI[%d] = (%f + i%f)\n", i , creal(H_hermH_sigmaI[i]), cimag(H_hermH_sigmaI[i]));
#endif #endif
conjugate_transpose (N, H, H_herm); //equals H_herm conjugate_transpose (N, N, H, H_herm); //equals H_herm
#ifdef DEBUG_PREPROC #ifdef DEBUG_PREPROC
for(i=0;i<N*N;i++) for(i = 0;i < N*N;i++)
printf(" H_herm[%d] = (%f + i%f)\n", i , creal(H_herm[i]), cimag(H_herm[i])); printf("compute_MMSE: H_herm[%d] = (%f + i%f)\n", i , creal(H_herm[i]), cimag(H_herm[i]));
#endif #endif
lin_eq_solver(N, H_hermH_sigmaI, H_herm, W_MMSE); lin_eq_solver(N, H_hermH_sigmaI, H_herm, W_MMSE);
#ifdef DEBUG_PREPROC #ifdef DEBUG_PREPROC
for(i=0;i<N*N;i++) for(i = 0;i < N*N; ++i)
printf(" W_MMSE[%d] = (%f + i%f)\n", i , creal(W_MMSE[i]), cimag(W_MMSE[i])); printf("compute_MMSE: W_MMSE[%d] = (%f + i%f)\n", i , creal(W_MMSE[i]), cimag(W_MMSE[i]));
#endif #endif
free(H_hermH_sigmaI); free(H_hermH_sigmaI);
free(H_herm); free(H_herm);
} }
#if 0 float sqrt_float(float x)
void compute_white_filter(float complex* H_re, {
int order_H, float sqrt_x = 0.0;
sqrt_x = (float)(sqrt((double)(x)));
return sqrt_x;
}
void compute_white_filter(float complex* H0_re,
float complex* H1_re,
float sigma2, float sigma2,
int n_rx,
int n_tx,
float complex* W_Wh_0_re, float complex* W_Wh_0_re,
float complex* W_Wh_1_re){ float complex* W_Wh_1_re){
int aatx, aarx, re; float sigma = 0.0;
int i,j; int i;
int M =n_rx;
int N = n_tx; float complex *R_corr_col_n_0_re = calloc(n_rx*n_tx, sizeof(float complex));
int sigma2=noise_power; float complex *R_corr_col_n_1_re = calloc(n_rx*n_tx, sizeof(float complex));
float complex *U_0_re = calloc(n_rx*n_tx, sizeof(float complex));
float complex *H0_re = malloc(n_rx*(n_tx>>2)*sizeof(float complex)); float complex *U_1_re = calloc(n_rx*n_tx, sizeof(float complex));
float complex *H1_re = malloc(n_rx*(n_tx>>2)*sizeof(float complex)); float complex *U_0_herm_re = calloc(n_rx*n_tx, sizeof(float complex));
float complex *R_corr_col_n_0_re = malloc(n_rx*n_tx*sizeof(float complex)); float complex *U_1_herm_re = calloc(n_rx*n_tx, sizeof(float complex));
float complex *R_corr_col_n_1_re = malloc(n_rx*n_tx*sizeof(float complex)); float *D_0_re = calloc(n_rx*n_tx, sizeof(float));
float complex *U_0_re = malloc(n_rx*n_tx*sizeof(float complex)); float *D_1_re = calloc(n_rx*n_tx, sizeof(float));
float complex *U_1_re = malloc(n_rx*n_tx*sizeof(float complex)); float *D_0_re_inv_sqrt = calloc(n_rx*n_tx, sizeof(float));
float complex *U_0_herm_re = malloc(n_rx*n_tx*sizeof(float complex)); float *D_1_re_inv_sqrt = calloc(n_rx*n_tx, sizeof(float));
float complex *U_1_herm_re = malloc(n_rx*n_tx*sizeof(float complex));
float complex *D_0_re = malloc(n_rx*n_tx*sizeof(float complex));
float complex *D_1_re = malloc(n_rx*n_tx*sizeof(float complex)); #ifdef DEBUG_PREPROC
float complex *W_Wh_0_re = malloc(n_rx*n_tx*sizeof(float complex)); printf("compute_white_filter: sigma2 = %f\n", sigma2);
float complex *W_Wh_1_re = malloc(n_rx*n_tx*sizeof(float complex)); for(i=0; i<n_rx*n_tx/2; i++){
printf("compute_white_filter: H1_re[%d] = (%f + i%f)\n", i , creal(H1_re[i]), cimag(H1_re[i]));
for (aatx=0; aatx<n_tx/2; aatx++){ printf("compute_white_filter: H0_re[%d] = (%f + i%f)\n", i , creal(H0_re[i]), cimag(H0_re[i]));
for (aarx=0; aarx<n_rx; aarx++) { }
H0_re[aatx*n_rx + aarx] = H_re[aatx*n_rx + aarx][re]; // H0 gets [0 1 2 3; 4,5,6,7].' coefficients of H #endif
H1_re[aatx*n_rx + aarx] = H_re[aatx*n_rx + aarx + 8][re]; // H1 gets [8 9 10 11; 12, 13, 14, 15].' coefficients of H
if (re == 0)
printf("ant %d, H_re = (%f + i%f) \n", aatx*n_rx + aarx, creal(H[aatx*n_rx + aarx][re]), cimag(H[aatx*n_rx + aarx][re]));
}
}
HH_herm_plus_sigma2I(n_rx, n_tx/2, H1_re, sigma2, R_corr_col_n_0_re);
HH_herm_plus_sigma2I(n_rx, n_tx/2, H0_re, sigma2, R_corr_col_n_1_re);
#ifdef DEBUG_PREPROC
for(i=0;i<n_rx*n_tx;i++){
printf("compute_white_filter: R_corr_col_n_0_re[%d] = (%f + i%f)\n", i , creal(R_corr_col_n_0_re[i]), cimag(R_corr_col_n_0_re[i]));
printf("compute_white_filter: R_corr_col_n_1_re[%d] = (%f + i%f)\n", i , creal(R_corr_col_n_1_re[i]), cimag(R_corr_col_n_1_re[i]));
}
//HH_herm_plus_sigma2I(n_rx, (n_tx>>2), H1_re, sigma2, R_corr_col_n_0_re); #endif
HH_herm_plus_sigma2I(n_rx, (n_tx>>2), H0_re, sigma2, R_corr_col_n_1_re);
eigen_vectors_values(n_rx, R_corr_col_n_0_re, U_0_re, D_0_re); eigen_vectors_values(n_rx, R_corr_col_n_0_re, U_0_re, D_0_re);
eigen_vectors_values(n_rx, R_corr_col_n_1_re, U_1_re, D_1_re); eigen_vectors_values(n_rx, R_corr_col_n_1_re, U_1_re, D_1_re);
transpose (n_rx, U_0_re, U_0_herm_re); #ifdef DEBUG_PREPROC
transpose (n_rx, U_1_re, U_1_herm_re); for(i=0;i<n_rx*n_tx;i++){
printf("compute_white_filter: U_0_re[%d] = (%f + i%f)\n", i , creal(U_0_re[i]), cimag(U_0_re[i]));
printf("compute_white_filter: D_0_re[%d] = (%f + i%f)\n", i , creal(D_0_re[i]), cimag(D_0_re[i]));
}
#endif
conjugate_transpose(n_rx, n_tx, U_0_re, U_0_herm_re);
conjugate_transpose(n_rx, n_tx, U_1_re, U_1_herm_re);
#ifdef DEBUG_PREPROC
for(i = 0;i < n_rx*n_tx; i++){
printf("compute_white_filter: U_0_herm_re[%d] = (%f + i%f)\n", i , creal(U_0_herm_re[i]), cimag(U_0_herm_re[i]));
}
#endif
sigma = (float)(sqrt((double)(sigma2))); sigma = (float)(sqrt((double)(sigma2)));
if (sigma <= 0.00001){
sigma = 0.00001;
}
/*The inverse of a diagonal matrix is obtained by replacing each element in the diagonal with its reciprocal. //The inverse of a diagonal matrix is obtained by replacing each element in the diagonal with //its reciprocal.
A square root of a diagonal matrix is given by the diagonal matrix, whose diagonal entries are just the square //A square root of a diagonal matrix is given by the diagonal matrix, whose diagonal entries are //just the square
roots of the original matrix.*/ //roots of the original matrix.
//printf ("This linear preprocessing is line %d.\n", __LINE__);
for (i = 0; i < n_rx*n_tx; i += (n_rx + 1)){
D_0_re_inv_sqrt[0] = sqrt_float(1/D_0_re_inv[0]); if (D_0_re[i] <= 0.00001){
D_0_re_inv_sqrt[5] = sqrt_float(1/D_0_re_inv[5]); D_0_re[i] = 0.00001;
D_0_re_inv_sqrt[10] = sqrt_float(1/D_0_re_inv[10]); }
D_0_re_inv_sqrt[15] = sqrt_float(1/D_0_re_inv[15]); if (D_1_re[i] <= 0.00001){
D_1_re[i] = 0.00001;
}
D_1_re_inv[0] = sqrt_float(1/D_1_re_inv[0]); D_0_re_inv_sqrt[i] = sqrt_float(1/D_0_re[i]);
D_1_re_inv[5] = sqrt_float(1/D_1_re_inv[5]); D_1_re_inv_sqrt[i] = sqrt_float(1/D_1_re[i]);
D_1_re_inv[10] = sqrt_float(1/D_1_re_inv[10]); }
D_1_re_inv[15] = sqrt_float(1/D_1_re_inv[15]);
now only to multiply
free(H0); #ifdef DEBUG_PREPROC
free(H1); for(i = 0;i <n_rx*n_tx; i++){
free(R_corr_col_n_0); printf("compute_white_filter: D_0_re_inv_sqrt[%d] = %f\n", i , D_0_re_inv_sqrt[i]);
free(R_corr_col_n_1); }
}
#endif #endif
float sqrt_float(float x, float sqrt_x)
{ mutl_scal_matrix_matrix_col_based(D_0_re_inv_sqrt, U_0_herm_re, sigma, n_rx, n_tx, n_rx, n_tx, W_Wh_0_re);
sqrt_x = (float)(sqrt((double)(x)));
return sqrt_x; #ifdef DEBUG_PREPROC
for(i = 0;i < n_rx*n_tx; i++){
printf("compute_white_filter: W_Wh_0_re[%d] = (%f + i%f)\n", i , creal(W_Wh_0_re[i]), cimag(W_Wh_0_re[i]));
}
#endif
mutl_scal_matrix_matrix_col_based(D_1_re_inv_sqrt, U_1_herm_re, sigma, n_rx, n_tx, n_rx, n_tx, W_Wh_1_re);
free(R_corr_col_n_0_re);
free(R_corr_col_n_1_re);
free(U_0_herm_re);
free(U_1_herm_re);
free(D_0_re_inv_sqrt);
free(D_1_re_inv_sqrt);
free(U_0_re);
free(U_1_re);
free(D_0_re);
free(D_1_re);
} }
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
/* FUNCTIONS FOR LINEAR PREPROCESSING: MMSE, WHITENNING, etc*/ /* FUNCTIONS FOR LINEAR PREPROCESSING: MMSE, WHITENNING, etc*/
void transpose(int N, float complex *A, float complex *Result); void transpose(int N, float complex *A, float complex *Result);
void conjugate_transpose(int N, float complex *A, float complex *Result); void conjugate_transpose (int rows_A, int col_A, float complex *A, float complex *Result);
void H_hermH_plus_sigma2I(int N, int M, float complex *A, float sigma2, float complex *Result); void H_hermH_plus_sigma2I(int N, int M, float complex *A, float sigma2, float complex *Result);
...@@ -26,9 +26,19 @@ void mutl_matrix_matrix_row_based(float complex* M0, float complex* M1, int rows ...@@ -26,9 +26,19 @@ void mutl_matrix_matrix_row_based(float complex* M0, float complex* M1, int rows
/* mutl_matrix_matrix_col_based performs multiplications matrix is column-oriented H[0], H[2]; H[1], H[3]*/ /* mutl_matrix_matrix_col_based performs multiplications matrix is column-oriented H[0], H[2]; H[1], H[3]*/
void mutl_matrix_matrix_col_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result ); void mutl_matrix_matrix_col_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result );
void mutl_scal_matrix_matrix_col_based(float complex* M0, float complex* M1, float complex alpha, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result);
void compute_MMSE(float complex* H, int order_H, float sigma2, float complex* W_MMSE); void compute_MMSE(float complex* H, int order_H, float sigma2, float complex* W_MMSE);
void compute_white_filter(float complex* H, int order_H, float sigma2, float complex* U_1, float complex* D_1); float sqrt_float(float x);
void compute_white_filter(float complex* H0_re,
float complex* H1_re,
float sigma2,
int n_rx,
int n_tx,
float complex* W_Wh_0_re,
float complex* W_Wh_1_re);
void mmse_processing_oai(LTE_UE_PDSCH *pdsch_vars, void mmse_processing_oai(LTE_UE_PDSCH *pdsch_vars,
LTE_DL_FRAME_PARMS *frame_parms, LTE_DL_FRAME_PARMS *frame_parms,
...@@ -57,38 +67,41 @@ void rxdataF_to_float(int32_t **rxdataF_ext, ...@@ -57,38 +67,41 @@ void rxdataF_to_float(int32_t **rxdataF_ext,
void chan_est_to_float(int32_t **dl_ch_estimates_ext, void chan_est_to_float(int32_t **dl_ch_estimates_ext,
float complex **dl_ch_estimates_ext_f, float complex **dl_ch_estimates_ext_f,
int n_tx, uint8_t n_tx,
int n_rx, uint8_t n_rx,
int length, int32_t length,
int start_point); int32_t start_point);
void float_to_chan_est(int32_t **dl_ch_estimates_ext,
float complex **dl_ch_estimates_ext_f,
int n_tx,
int n_rx,
int length,
int start_point);
void float_to_rxdataF(int32_t **rxdataF_ext,
float complex **rxdataF_f,
int n_tx,
int n_rx,
int length,
int start_point);
void mult_mmse_rxdataF(float complex** Wmmse, void float_to_chan_est(float complex **chan_est_flp,
float complex** rxdataF_ext_f, int32_t **result,
int n_tx, int n_tx,
int n_rx, int n_rx,
int length, int length,
int start_point); int start_point);
void mult_mmse_chan_est(float complex** Wmmse, void float_to_rxdataF(float complex **rxdataF_flp,
float complex** dl_ch_estimates_ext_f, int32_t **result,
int n_tx, uint8_t n_tx,
int n_rx, uint8_t n_rx,
int length, int32_t length,
int start_point); int32_t start_point);
void mult_filter_chan_est(float complex **W,
float complex **chan_est_flp,
float complex **result,
uint8_t n_tx,
uint8_t n_rx,
int32_t n_col_chan_est_flp,
int32_t length,
int32_t start_point);
void mult_filter_rxdataF(float complex **W,
float complex **rxdataF_flp,
float complex **result,
uint8_t n_tx,
uint8_t n_rx,
int32_t length,
int32_t start_point);
void mmse_processing_core(int32_t **rxdataF_ext, void mmse_processing_core(int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext, int32_t **dl_ch_estimates_ext,
...@@ -98,24 +111,27 @@ void mmse_processing_core(int32_t **rxdataF_ext, ...@@ -98,24 +111,27 @@ void mmse_processing_core(int32_t **rxdataF_ext,
int length, int length,
int start_point); int start_point);
void mmse_processing_core_flp(float complex** rxdataF_ext_flcpx, void mmse_processing_core_flp(float complex** rxdataF_flp,
float complex **H, float complex **chan_est_flp,
int32_t **rxdataF_ext, int32_t **rxdataF_filt_fp,
int32_t **dl_ch_estimates_ext, int32_t **chan_est_eff_fp,
float noise_power,
uint8_t n_tx,
uint8_t n_rx,
int32_t length,
int32_t start_point);
void whitening_processing_core_flp(float complex **rxdataF_flp,
float complex **chan_est_flp_0,
float complex **chan_est_flp_1,
int32_t **rxdataF_filt_fp_0,
int32_t **rxdataF_filt_fp_1,
int32_t **chan_est_eff_fp_0,
int32_t **chan_est_eff_fp_1,
float sigma2, float sigma2,
int n_tx, uint8_t n_tx,
int n_rx, uint8_t n_rx,
int length, int32_t length,
int start_point); int32_t start_point);
void whitening_processing_core_flp(float complex** rxdataF_ext_flcpx,
float complex **H,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
float sigma2,
int n_tx,
int n_rx,
int length,
int start_point);
float sqrt_float(float x, float sqrt_x);
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