Home > WaveComBox > Toolbox > CP_OFDM > ChannelPreEqualization > OFDM_PreEqualizerSingleTap.m

OFDM_PreEqualizerSingleTap

PURPOSE ^

Pre-equalizes data symbols d and returns corresponding pre-equalizing and

SYNOPSIS ^

function [d_tilde, A, B ]=OFDM_PreEqualizerSingleTap( d, C, criterion, Para )

DESCRIPTION ^

 Pre-equalizes data symbols d and returns corresponding pre-equalizing and
 required equalizing matrices.

 function [d_tilde, A, B ]=OFDM_PreEqualizerSingleTap( d, C,
 equalizer_type, Para )

 The function works for SISO and MIMO systems.

 Input arguments:

   d: data symbols to pre-equalize. Size: matrix [Para.nSubcarriers, Ns] if Para.S == 1,
   multidimensional array [para.S, Para.nSubcarriers, Ns] if Para.S > 1.  

   C: channel impulse response. Multidimensional array [Para.N_R, Para.N_T, ~].

   criterion: determines the design 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.

       'SVD': singular value decomposition. Precode by S right singular
       vector of the channel frequency response corresponding to largest
       singular values.

   Para: structure containing the modulation parameters.

 Outputs arguments:

   d_tilde: pre-equalized data symbols. Size: matrix [Para.nSubcarriers, Ns] if
   Para.N_T == 1, multidimensional array [para.N_T, Para.nSubcarriers, Ns] if
   Para.N_T > 1.

   A: used pre-equalizing matrices at each subcarrier. Size: vector [Para.nSubcarriers, 1]
   if Para.N_T == Para.N_R == 1 and multidimensional array
   [Para.T,Para.S,Para.nSubcarriers] otherwise

   B: required equalizing matrices at each subcarrier. Size: vector [Para.nSubcarriers, 1]
   if Para.N_T == Para.N_R == 1 and multidimensional array [Para.S,Para.N_R,Para.nSubcarriers] otherwise

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [d_tilde, A, B ]=OFDM_PreEqualizerSingleTap( d, C, criterion, Para )
0002 % Pre-equalizes data symbols d and returns corresponding pre-equalizing and
0003 % required equalizing matrices.
0004 %
0005 % function [d_tilde, A, B ]=OFDM_PreEqualizerSingleTap( d, C,
0006 % equalizer_type, Para )
0007 %
0008 % The function works for SISO and MIMO systems.
0009 %
0010 % Input arguments:
0011 %
0012 %   d: data symbols to pre-equalize. Size: matrix [Para.nSubcarriers, Ns] if Para.S == 1,
0013 %   multidimensional array [para.S, Para.nSubcarriers, Ns] if Para.S > 1.
0014 %
0015 %   C: channel impulse response. Multidimensional array [Para.N_R, Para.N_T, ~].
0016 %
0017 %   criterion: determines the design criterion to use.
0018 %   Several options are 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 %       'SVD': singular value decomposition. Precode by S right singular
0027 %       vector of the channel frequency response corresponding to largest
0028 %       singular values.
0029 %
0030 %   Para: structure containing the modulation parameters.
0031 %
0032 % Outputs arguments:
0033 %
0034 %   d_tilde: pre-equalized data symbols. Size: matrix [Para.nSubcarriers, Ns] if
0035 %   Para.N_T == 1, multidimensional array [para.N_T, Para.nSubcarriers, Ns] if
0036 %   Para.N_T > 1.
0037 %
0038 %   A: used pre-equalizing matrices at each subcarrier. Size: vector [Para.nSubcarriers, 1]
0039 %   if Para.N_T == Para.N_R == 1 and multidimensional array
0040 %   [Para.T,Para.S,Para.nSubcarriers] otherwise
0041 %
0042 %   B: required equalizing matrices at each subcarrier. Size: vector [Para.nSubcarriers, 1]
0043 %   if Para.N_T == Para.N_R == 1 and multidimensional array [Para.S,Para.N_R,Para.nSubcarriers] otherwise
0044 
0045 % This file is part of WaveComBox: www.wavecombox.com and is distributed under the terms of the MIT license. See accompanying LICENSE file.
0046 % Original author: François Rottenberg, May 3, 2018.
0047 % Contributors:
0048 % Change log:
0049 
0050 if Para.N_R==1 && Para.N_T==1
0051     if Para.S>1
0052         error('Error: S>min(N_T,N_R)')
0053     end
0054     H=fft(squeeze(C),Para.nSubcarriers);
0055     switch criterion
0056         case 'ZF'
0057             A_tilde=1./H;
0058             xi=abs(A_tilde);
0059             A=A_tilde./xi;
0060             B=xi;
0061         case 'MMSE'
0062             % Noise power
0063             Es_N0=10.^(Para.Es_N0_dB/10);
0064             A_tilde=conj(H)./(abs(H).^2+1/Es_N0);
0065             xi=abs(A_tilde);
0066             A=A_tilde./xi;
0067             B=xi;
0068         case 'MF'
0069             A_tilde=1./H;
0070             xi=abs(A_tilde);
0071             A=A_tilde./xi;
0072             B=xi;
0073         case 'SVD'
0074             A_tilde=1./H;
0075             xi=abs(A_tilde);
0076             A=A_tilde./xi;
0077             B=xi;
0078         otherwise
0079             error('Equalizer type not existing')
0080     end
0081     d_tilde=zeros(Para.nSubcarriers, (Para.Ns+Para.PreambleLength));
0082     for m=Para.ActiveSubcarriers
0083         d_tilde(m,:)=A(m).*d(m,:);
0084     end
0085 else    
0086     H=zeros(Para.N_R,Para.N_T,Para.nSubcarriers);
0087     for index_N_R=1:Para.N_R
0088         for index_N_T=1:Para.N_T
0089             H(index_N_R,index_N_T,:)=fft(squeeze(C(index_N_R,index_N_T,:)),Para.nSubcarriers).';
0090         end
0091     end
0092     B=zeros(Para.S, Para.N_R, Para.nSubcarriers);
0093     A=zeros(Para.N_T, Para.S, Para.nSubcarriers);
0094     switch criterion
0095         case 'ZF'
0096             if Para.N_R>Para.N_T
0097                 error('Error: N_R>N_T')
0098             end
0099             for m=Para.ActiveSubcarriers
0100                 H_m=H(:,:,m);
0101                 Gram_inv=eye(Para.N_R,Para.N_R)/(H_m*H_m');
0102                 xi=sqrt(trace(Gram_inv)/Para.S);
0103                 A(:,:,m)=H_m'*Gram_inv.*(1/xi);
0104                 B(:,:,m)=xi*eye(Para.N_R,Para.N_R);
0105             end
0106             
0107         case 'MMSE'
0108             if Para.N_R>Para.N_T
0109                 error('Error: N_R>N_T')
0110             end
0111             for m=Para.ActiveSubcarriers
0112                 % Noise power
0113                 Es_N0=10.^(Para.Es_N0_dB/10);
0114                 H_m=H(:,:,m);
0115                 A_tilde=(H_m'*H_m+1/Es_N0*Para.N_R*eye(Para.N_T,Para.N_T))\H_m';
0116                 xi=sqrt(trace(A_tilde*A_tilde')/Para.S);
0117                 A(:,:,m)=A_tilde.*(1/xi);
0118                 B(:,:,m)=xi*eye(Para.N_R,Para.N_R);
0119             end            
0120         case 'MF'
0121             if Para.N_R>Para.N_T
0122                 error('Error: N_R>N_T')
0123             end
0124             for m=Para.ActiveSubcarriers
0125                 H_m=H(:,:,m);
0126                 A_tilde=H_m'/(diag(diag(H_m*H_m')));                
0127                 xi=sqrt(trace(A_tilde*A_tilde')/Para.S);
0128                 A(:,:,m)=A_tilde.*(1/xi);
0129                 B(:,:,m)=xi*eye(Para.N_R,Para.N_R);
0130             end
0131         case 'SVD'
0132             for m=Para.ActiveSubcarriers
0133                 if Para.S>min(Para.N_T, Para.N_R)
0134                     error('Error: S>min(N_T,N_R)')
0135                 end
0136                 H_m=H(:,:,m);
0137                 [~,~,V] = svd(H_m);
0138                 A_tilde=V(:,1:Para.S);          
0139                 xi=sqrt(trace(A_tilde*A_tilde')/Para.S);
0140                 A(:,:,m)=A_tilde.*(1/xi);
0141                 B(:,:,m)=((H_m*A(:,:,m))'*(H_m*A(:,:,m)) )\((H_m*A(:,:,m))');
0142             end
0143             
0144         otherwise
0145             error('Equalizer type not existing')
0146     end
0147     d_tilde=zeros(Para.N_T,Para.nSubcarriers, (Para.Ns+Para.PreambleLength));
0148     if Para.S==1
0149         for m=Para.ActiveSubcarriers
0150             for l=1:(Para.Ns+Para.PreambleLength)
0151                 d_tilde(:,m,l)=A(:,:,m)*d(m,l);
0152             end
0153         end
0154     else
0155         for m=Para.ActiveSubcarriers
0156             for l=1:(Para.Ns+Para.PreambleLength)
0157                 d_tilde(:,m,l)=A(:,:,m)*d(:,m,l);
0158             end
0159         end
0160     end
0161     if Para.N_T==1
0162         d_tilde=squeeze(d_tilde);
0163     end
0164     
0165     
0166 end
0167 
0168 
0169 
0170 
0171 end
0172

Generated on Mon 14-Oct-2019 13:48:34 by m2html © 2005