Single-tap equalization of the demodulated FBMC-OQAM symbols. function [ x, B ] = FBMC_OQAM_EqualizerSingleTap( z, C, criterion, Para ) function [ x, B ] = FBMC_OQAM_EqualizerSingleTap( z, C, criterion, Para, B ) The function works for MIMO and SISO systems. Input arguments: z: demodulated FBMC-OQAM symbols. Size: matrix [Para.nSubcarriers, N] if Para.N_R == 1, multidimensional array [Para.N_R, Para.nSubcarriers, N] if Para.N_R > 1. C: channel impulse response. Multidimensional array [Para.N_R, Para.N_T, ~]. criterion: determines the criterion to use. Several options are possible: 'ZF': zero forcing. Error if Para.N_R < Para.N_T. 'MMSE': minimum mean squared error. Error if Para.N_R < Para.N_T. 'MF': matched filter. Error if Para.N_R < Para.N_T. 'Specific': the specific equalizing matrices given in the function argument B should be provided and will be used for equalization. Argument C is not regarded. 'ZF_opt_freq_selec': as opposed to conventional 'ZF', does not assume channel frequency flatness at the subcarrier level and takes into account derivatives of channel frequency response. Follows the design of [1]. 'MMSE_opt_freq_selec': as opposed to conventional 'MMSE', does not assume channel frequency flatness at the subcarrier level and takes into account derivatives of channel frequency response. Follows the design of [1]. Para: structure containing the modulation parameters. B: the equalizing matrices at each subcarrier should be provided if 'Specific' equalizer type is chosen. If not chosen, the matrix B is disregarded. Size: vector [Para.nSubcarriers ,1] if Para.N_T == 1 and multi- dimensional array [Para.S, Para.N_R, Para.nSubcarriers] otherwise. Ouput arguments: x: equalized symbols. Size: matrix [Para.nSubcarriers, N] if Para.S == 1, multidimensional array [para.S, Para.nSubcarriers, N] if Para.S > 1. B: equalizing matrices used at each subcarrier. Size: vector [Para.nSubcarriers ,1] if Para.N_T == 1 and multidimensional array [Para.S, Para.N_R, Para.nSubcarriers] otherwise. References: [1] F. Rottenberg, X. Mestre, F. Horlin and J. Louveaux, "Single-Tap Precoders and Decoders for Multi-User MIMO FBMC-OQAM under Strong Channel Frequency Selectivity," IEEE Transactions on Signal Processing, 2017, vol. 65, no. 3, pp. 587-600.
0001 function [ x, B ] = FBMC_OQAM_EqualizerSingleTap( z, C, criterion, Para, B ) 0002 % Single-tap equalization of the demodulated FBMC-OQAM symbols. 0003 % 0004 % function [ x, B ] = FBMC_OQAM_EqualizerSingleTap( z, C, criterion, Para ) 0005 % function [ x, B ] = FBMC_OQAM_EqualizerSingleTap( z, C, criterion, Para, B ) 0006 % 0007 % The function works for MIMO and SISO systems. 0008 % 0009 % Input arguments: 0010 % 0011 % z: demodulated FBMC-OQAM symbols. Size: matrix [Para.nSubcarriers, N] if 0012 % Para.N_R == 1, multidimensional array [Para.N_R, Para.nSubcarriers, N] 0013 % if Para.N_R > 1. 0014 % 0015 % C: channel impulse response. Multidimensional array [Para.N_R, Para.N_T, ~]. 0016 % 0017 % criterion: determines the criterion to use. Several options are 0018 % possible: 0019 % 0020 % 'ZF': zero forcing. Error if Para.N_R < Para.N_T. 0021 % 0022 % 'MMSE': minimum mean squared error. Error if Para.N_R < Para.N_T. 0023 % 0024 % 'MF': matched filter. Error if Para.N_R < Para.N_T. 0025 % 0026 % 'Specific': the specific equalizing matrices given in the function 0027 % argument B should be provided and will be used for equalization. 0028 % Argument C is not regarded. 0029 % 0030 % 'ZF_opt_freq_selec': as opposed to conventional 'ZF', does not 0031 % assume channel frequency flatness at the subcarrier level and takes 0032 % into account derivatives of channel frequency response. Follows the 0033 % design of [1]. 0034 % 0035 % 'MMSE_opt_freq_selec': as opposed to conventional 'MMSE', does not 0036 % assume channel frequency flatness at the subcarrier level and takes 0037 % into account derivatives of channel frequency response. Follows the 0038 % design of [1]. 0039 % 0040 % Para: structure containing the modulation parameters. 0041 % 0042 % B: the equalizing matrices at each subcarrier should be provided if 0043 % 'Specific' equalizer type is chosen. If not chosen, the matrix B is 0044 % disregarded. Size: vector [Para.nSubcarriers ,1] if Para.N_T == 1 and multi- 0045 % dimensional array [Para.S, Para.N_R, Para.nSubcarriers] otherwise. 0046 % 0047 % Ouput arguments: 0048 % 0049 % x: equalized symbols. Size: matrix [Para.nSubcarriers, N] if Para.S == 1, 0050 % multidimensional array [para.S, Para.nSubcarriers, N] if Para.S > 1. 0051 % 0052 % B: equalizing matrices used at each subcarrier. Size: vector 0053 % [Para.nSubcarriers ,1] if Para.N_T == 1 and multidimensional array [Para.S, 0054 % Para.N_R, Para.nSubcarriers] otherwise. 0055 % 0056 % References: [1] F. Rottenberg, X. Mestre, F. Horlin and J. Louveaux, 0057 % "Single-Tap Precoders and Decoders for Multi-User MIMO FBMC-OQAM under 0058 % Strong Channel Frequency Selectivity," IEEE Transactions on Signal 0059 % Processing, 2017, vol. 65, no. 3, pp. 587-600. 0060 % 0061 0062 % This file is part of WaveComBox: www.wavecombox.com and is distributed under the terms of the MIT license. See accompanying LICENSE file. 0063 % Original author: François Rottenberg, May 4, 2018. 0064 % Contributors: 0065 % Change log: 0066 0067 M=Para.nSubcarriers/2; 0068 0069 if Para.N_R==1 0070 N=length(z(1,:)); 0071 else 0072 N=length(z(1,1,:)); 0073 end 0074 0075 if Para.N_R==1 && Para.N_T==1 0076 H=fft(squeeze(C),2*M); 0077 x=zeros(2*M,N); 0078 0079 switch criterion 0080 case 'ZF' 0081 B=1./H; 0082 case 'MMSE' 0083 % Noise power 0084 Es_N0=10.^(Para.Es_N0_dB/10); 0085 B=conj(H)./(abs(H).^2+1/Es_N0); 0086 case 'MF' 0087 B=1./H; 0088 case 'Specific' 0089 if exist('B','var')==0 0090 error('Argument missing "B" for equalizer type "Specific"') 0091 end 0092 case 'MMSE_opt_freq_selec' 0093 L=length(C(1,1,:)); 0094 H_1=-sqrt(-1)*fft((0:L-1).*squeeze(C).',2*M).'; 0095 H_2=-fft((0:L-1).^2.*squeeze(C).',2*M).'; 0096 Es_N0=10.^(Para.Es_N0_dB/10); 0097 eta_tilde=ComputeEtaTilde(Para); 0098 B=(conj(H)+eta_tilde*conj(H_2))./( abs(H).^2+2*eta_tilde*abs(H_1).^2+eta_tilde*(H.*conj(H_2)+H_2.*conj(H))+1/Es_N0); 0099 case 'ZF_opt_freq_selec' 0100 B=1./H; 0101 otherwise 0102 error('Equalizer type not existing') 0103 end 0104 for m=Para.ActiveSubcarriers 0105 x(m,:)=B(m).*z(m,:); 0106 end 0107 else 0108 0109 H=zeros(Para.N_R,Para.N_T,2*M); 0110 for index_N_R=1:Para.N_R 0111 for index_N_T=1:Para.N_T 0112 H(index_N_R,index_N_T,:)=fft(squeeze(C(index_N_R,index_N_T,:)),2*M).'; 0113 end 0114 end 0115 x=zeros(Para.S,2*M,N); 0116 switch criterion 0117 case 'ZF' 0118 if Para.N_T>Para.N_R 0119 error('Error: N_T>N_R') 0120 end 0121 B=zeros(Para.S, Para.N_R, 2*M); 0122 for m=Para.ActiveSubcarriers 0123 H_m=H(:,:,m); 0124 B(:,:,m)=(H_m'*H_m)\H(:,:,m)'; 0125 for l=1:N 0126 x(:,m,l)=B(:,:,m)*z(:,m,l); 0127 end 0128 end 0129 case 'MMSE' 0130 if Para.N_T>Para.N_R 0131 error('Error: N_T>N_R') 0132 end 0133 B=zeros(Para.S, Para.N_R, 2*M); 0134 for m=Para.ActiveSubcarriers 0135 % Noise power 0136 Es_N0=10.^(Para.Es_N0_dB/10); 0137 H_m=H(:,:,m); 0138 B(:,:,m)=eye(Para.N_T,Para.N_T)/(H_m'*H_m+1/Es_N0*Para.N_T*eye(Para.N_T,Para.N_T))*H_m'; 0139 for l=1:N 0140 x(:,m,l)=B(:,:,m)*z(:,m,l); 0141 end 0142 end 0143 case 'MF' 0144 if Para.N_T>Para.N_R 0145 error('Error: N_T>N_R') 0146 end 0147 B=zeros(Para.S, Para.N_R, 2*M); 0148 for m=Para.ActiveSubcarriers 0149 H_m=H(:,:,m); 0150 B(:,:,m)= (diag(diag(H_m'*H_m)))\H_m'; 0151 for l=1:N 0152 x(:,m,l)=B(:,:,m)*z(:,m,l); 0153 end 0154 end 0155 case 'ZF_opt_freq_selec' 0156 if Para.N_T>Para.N_R 0157 error('Error: N_T>N_R') 0158 end 0159 eta_tilde=ComputeEtaTilde(Para); 0160 Es_N0=10.^(Para.Es_N0_dB/10); 0161 H_1=zeros(Para.N_R,Para.N_T,2*M); 0162 L=length(C(1,1,:)); 0163 for index_N_R=1:Para.N_R 0164 for index_N_T=1:Para.N_T 0165 H_1(index_N_R,index_N_T,:)=-sqrt(-1)*fft((0:L-1).*squeeze(C(index_N_R,index_N_T,:)).',2*M).'; 0166 end 0167 end 0168 for m=Para.ActiveSubcarriers 0169 H_m=H(:,:,m); 0170 H1_m=H_1(:,:,m); 0171 Gram_inv=eye(Para.N_T,Para.N_T)/(H_m'*H_m); 0172 P_plus=eye(Para.N_R,Para.N_R)-H_m*Gram_inv*H_m'; 0173 H_plus=Gram_inv*H_m'; 0174 B_tilde_P_plus=-H_plus*H1_m/(H1_m'*P_plus*H1_m+1/Es_N0*Para.N_T/eta_tilde*eye(Para.N_T,Para.N_T))*H1_m'*P_plus; 0175 B(:,:,m)=(H_plus+B_tilde_P_plus); 0176 for l=1:N 0177 x(:,m,l)=B(:,:,m)*z(:,m,l); 0178 end 0179 end 0180 case 'MMSE_opt_freq_selec' 0181 if Para.N_T>Para.N_R 0182 error('Error: N_T>N_R') 0183 end 0184 eta_tilde=ComputeEtaTilde(Para); 0185 Es_N0=10.^(Para.Es_N0_dB/10); 0186 H_1=zeros(Para.N_R,Para.N_T,2*M); 0187 H_2=zeros(Para.N_R,Para.N_T,2*M); 0188 L=length(C(1,1,:)); 0189 for index_N_R=1:Para.N_R 0190 for index_N_T=1:Para.N_T 0191 H_1(index_N_R,index_N_T,:)=-sqrt(-1)*fft((0:L-1).*squeeze(C(index_N_R,index_N_T,:)).',2*M).'; 0192 H_2(index_N_R,index_N_T,:)=-fft((0:L-1).^2.*squeeze(C(index_N_R,index_N_T,:)).',2*M).'; 0193 end 0194 end 0195 for m=Para.ActiveSubcarriers 0196 H_m=H(:,:,m); 0197 H1_m=H_1(:,:,m); 0198 H2_m=H_2(:,:,m); 0199 B(:,:,m)=(H_m'+eta_tilde*H2_m')/(H_m*H_m'+2*eta_tilde*(H1_m*H1_m')+eta_tilde*(H_m*H2_m'+H2_m*H_m')+1/Es_N0*Para.N_T*eye(Para.N_R,Para.N_R)); 0200 for l=1:N 0201 x(:,m,l)=B(:,:,m)*z(:,m,l); 0202 end 0203 end 0204 0205 case 'Specific' 0206 if exist('B','var')==0 0207 error('Argument missing "B" for equalizer type "Specific"') 0208 end 0209 if Para.N_R==1 0210 for m=Para.ActiveSubcarriers 0211 for l=1:N 0212 x(:,m,l)=B(:,:,m)*z(m,l); 0213 end 0214 end 0215 else 0216 for m=Para.ActiveSubcarriers 0217 for l=1:N 0218 x(:,m,l)=B(:,:,m)*z(:,m,l); 0219 end 0220 end 0221 end 0222 otherwise 0223 error('Equalizer type not existing') 0224 end 0225 if Para.S==1 0226 x=squeeze(x); 0227 end 0228 0229 0230 end 0231 0232 0233 0234 0235 0236 0237 0238 0239 0240 0241 0242 0243 0244 0245 0246 end 0247