0001 function [d_tilde, A, B ]=FBMC_OQAM_PreEqualizerSingleTap( d, C, criterion, Para )
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 if Para.N_R==1 && Para.N_T==1
0068 H=fft(squeeze(C),Para.nSubcarriers);
0069 switch criterion
0070 case 'ZF'
0071 A_tilde=1./H;
0072 xi=abs(A_tilde);
0073 A=A_tilde./xi;
0074 B=xi;
0075 case 'MMSE'
0076
0077 Es_N0=10.^(Para.Es_N0_dB/10);
0078 A_tilde=conj(H)./(abs(H).^2+1/Es_N0);
0079 xi=abs(A_tilde);
0080 A=A_tilde./xi;
0081 B=xi;
0082 case 'MF'
0083 A_tilde=1./H;
0084 xi=abs(A_tilde);
0085 A=A_tilde./xi;
0086 B=xi;
0087 case 'SVD'
0088 A_tilde=1./H;
0089 xi=abs(A_tilde);
0090 A=A_tilde./xi;
0091 B=xi;
0092 case 'ZF_opt_freq_selec'
0093 A_tilde=1./H;
0094 xi=abs(A_tilde);
0095 A=A_tilde./xi;
0096 B=xi;
0097 case 'MMSE_opt_freq_selec'
0098 L=length(C(1,1,:));
0099 H_1=-sqrt(-1)*fft((0:L-1).*squeeze(C).',Para.nSubcarriers).';
0100 H_2=-fft((0:L-1).^2.*squeeze(C).',Para.nSubcarriers).';
0101 Es_N0=10.^(Para.Es_N0_dB/10);
0102 eta_tilde=ComputeEtaTilde(Para);
0103
0104 X_inv=1./(abs(H).^2+eta_tilde*(conj(H).*H_2+conj(H_2).*H)+2*eta_tilde*abs(H_1).^2+1/Es_N0);
0105 psi=-1./(real(abs(H).^2.*X_inv)).*imag(H.*X_inv.*(conj(H)+eta_tilde.*conj(H_2)));
0106 A_tilde=X_inv.*(1j*conj(H).*psi+conj(H)+eta_tilde.*conj(H_2));
0107 xi=abs(A_tilde);
0108 A=A_tilde./xi;
0109 B=xi;
0110 otherwise
0111 error('Equalizer type not existing')
0112 end
0113 d_tilde=zeros(Para.nSubcarriers, 2*Para.Ns);
0114 for m=Para.ActiveSubcarriers
0115 d_tilde(m,:)=A(m).*d(m,:);
0116 end
0117 else
0118 H=zeros(Para.N_R,Para.N_T,Para.nSubcarriers);
0119 for index_N_R=1:Para.N_R
0120 for index_N_T=1:Para.N_T
0121 H(index_N_R,index_N_T,:)=fft(squeeze(C(index_N_R,index_N_T,:)),Para.nSubcarriers).';
0122 end
0123 end
0124 B=zeros(Para.S, Para.N_R, Para.nSubcarriers);
0125 A=zeros(Para.N_T, Para.S, Para.nSubcarriers);
0126 switch criterion
0127 case 'ZF'
0128 if Para.N_R>Para.N_T
0129 error('Error: N_R>N_T')
0130 end
0131 for m=Para.ActiveSubcarriers
0132 H_m=H(:,:,m);
0133 Gram_inv=eye(Para.N_R,Para.N_R)/(H_m*H_m');
0134 xi=sqrt(trace(Gram_inv)/Para.S);
0135 A(:,:,m)=H_m'*Gram_inv.*(1/xi);
0136 B(:,:,m)=xi*eye(Para.N_R,Para.N_R);
0137 end
0138
0139 case 'MMSE'
0140 if Para.N_R>Para.N_T
0141 error('Error: N_R>N_T')
0142 end
0143 for m=Para.ActiveSubcarriers
0144
0145 Es_N0=10.^(Para.Es_N0_dB/10);
0146 H_m=H(:,:,m);
0147 A_tilde=(H_m'*H_m+1/Es_N0*Para.N_R*eye(Para.N_T,Para.N_T))\H_m';
0148 xi=sqrt(trace(A_tilde*A_tilde')/Para.S);
0149 A(:,:,m)=A_tilde.*(1/xi);
0150 B(:,:,m)=xi*eye(Para.N_R,Para.N_R);
0151 end
0152 case 'MF'
0153 if Para.N_R>Para.N_T
0154 error('Error: N_R>N_T')
0155 end
0156 for m=Para.ActiveSubcarriers
0157 H_m=H(:,:,m);
0158 A_tilde=H_m'/(diag(diag(H_m*H_m')));
0159 xi=sqrt(trace(A_tilde*A_tilde')/Para.S);
0160 A(:,:,m)=A_tilde.*(1/xi);
0161 B(:,:,m)=xi*eye(Para.N_R,Para.N_R);
0162 end
0163 case 'SVD'
0164 for m=Para.ActiveSubcarriers
0165 if Para.S>min(Para.N_T, Para.N_R)
0166 error('Error: S>min(N_T,N_R)')
0167 end
0168 H_m=H(:,:,m);
0169 [U,S,V] = svd(H_m);
0170 A_tilde=V(:,1:Para.S);
0171 xi=sqrt(trace(A_tilde*A_tilde')/Para.S);
0172 A(:,:,m)=A_tilde.*(1/xi);
0173 B(:,:,m)=((H_m*A(:,:,m))'*(H_m*A(:,:,m)) )\((H_m*A(:,:,m))');
0174 end
0175 case 'ZF_opt_freq_selec'
0176 if Para.N_R>Para.N_T
0177 error('Error: N_R>N_T')
0178 end
0179 Es_N0=10.^(Para.Es_N0_dB/10);
0180 eta_tilde=ComputeEtaTilde(Para);
0181 H_1=zeros(Para.N_R,Para.N_T,Para.nSubcarriers);
0182 L=length(C(1,1,:));
0183 for index_N_R=1:Para.N_R
0184 for index_N_T=1:Para.N_T
0185 H_1(index_N_R,index_N_T,:)=-sqrt(-1)*fft((0:L-1).*squeeze(C(index_N_R,index_N_T,:)).',Para.nSubcarriers).';
0186 end
0187 end
0188 for m=Para.ActiveSubcarriers
0189 H_m=H(:,:,m);
0190 H1_m=H_1(:,:,m);
0191 Gram_inv=eye(Para.N_R,Para.N_R)/(H_m*H_m');
0192 P_plus=eye(Para.N_T,Para.N_T)-H_m'*Gram_inv*H_m;
0193 H_plus=H_m'*Gram_inv;
0194 P_plus_A2=-P_plus*H1_m'/(H1_m*P_plus*H1_m'+1/Es_N0*Para.N_R/eta_tilde*eye(Para.N_R,Para.N_R))*H1_m*H_plus;
0195 A_tilde=( H_plus+P_plus_A2 );
0196 xi=sqrt(trace(A_tilde*A_tilde')/Para.S);
0197 A(:,:,m)=A_tilde.*(1/xi);
0198 B(:,:,m)=xi*eye(Para.N_R,Para.N_R);
0199 end
0200 case 'MMSE_opt_freq_selec'
0201 if Para.N_R>Para.N_T
0202 error('Error: N_R>N_T')
0203 end
0204 Es_N0=10.^(Para.Es_N0_dB/10);
0205 eta_tilde=ComputeEtaTilde(Para);
0206 H_1=zeros(Para.N_R,Para.N_T,Para.nSubcarriers);
0207 H_2=zeros(Para.N_R,Para.N_T,Para.nSubcarriers);
0208 L=length(C(1,1,:));
0209 for index_N_R=1:Para.N_R
0210 for index_N_T=1:Para.N_T
0211 H_1(index_N_R,index_N_T,:)=-sqrt(-1)*fft((0:L-1).*squeeze(C(index_N_R,index_N_T,:)).',Para.nSubcarriers).';
0212 H_2(index_N_R,index_N_T,:)=-fft((0:L-1).^2.*squeeze(C(index_N_R,index_N_T,:)).',Para.nSubcarriers).';
0213 end
0214 end
0215 for m=Para.ActiveSubcarriers
0216 H_m=H(:,:,m);
0217 H1=H_1(:,:,m);
0218 H2=H_2(:,:,m);
0219 X_inv=eye(Para.N_T,Para.N_T)/(H_m'*H_m+eta_tilde*(H_m'*H2+H2'*H_m)+2*eta_tilde*(H1'*H1)+1/Es_N0*Para.N_R*eye(Para.N_T,Para.N_T));
0220 psi=-inv(real(H_m*X_inv*H_m'))*imag(H_m*X_inv*(H_m'+eta_tilde*H2'));
0221 A_tilde=X_inv*(1j*H_m'*psi+H_m'+eta_tilde*H2');
0222 xi=sqrt(trace(A_tilde*A_tilde')/Para.S);
0223 A(:,:,m)=A_tilde.*(1/xi);
0224 B(:,:,m)=xi*eye(Para.N_R,Para.N_R);
0225 end
0226
0227 otherwise
0228 error('Equalizer type not existing')
0229 end
0230 d_tilde=zeros(Para.N_T,Para.nSubcarriers, 2*Para.Ns);
0231 if Para.S==1
0232 for m=Para.ActiveSubcarriers
0233 for l=1:2*Para.Ns
0234 d_tilde(:,m,l)=A(:,:,m)*d(m,l);
0235 end
0236 end
0237 else
0238 for m=Para.ActiveSubcarriers
0239 for l=1:2*Para.Ns
0240 d_tilde(:,m,l)=A(:,:,m)*d(:,m,l);
0241 end
0242 end
0243 end
0244 if Para.N_T==1
0245 d_tilde=squeeze(d_tilde);
0246 end
0247
0248
0249 end
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265 end
0266