www.gusucode.com > LTE仿真Matlab源码 > LTE_tx_precoding.m

    function [precode_y, UE, D, W, U] = LTE_tx_precoding(LTE_params, layer_x, UE, AtPorts, codebook_index, RI, CDD,rb_numbers)
% Precoding according to 3GPP TS 36.211-820, Section 6.3.4 page 37
% TODO: reorganize this huge tree so it more readable. Check whether
% something can be precalculated and stored 
% Author: Stefan Schwarz, sschwarz@nt.tuwien.ac.at
% (c) 2009 by INTHFT
% www.nt.tuwien.ac.at
d = 0;

if (AtPorts ~= 1)   % for 1 transmit antenna no precoding is used (precoding matrix = 1)
    if (UE.mode == 2) % transmit diversity, Section 6.3.4.3
        if (AtPorts == 2)
            c = length(layer_x(1,:));
            precode_y = zeros(2,2*c);   
            X =1/sqrt(2)*[1,0,1i,0;0,-1,0,1i;0,1,0,1i;1,0,-1i,0]*[real(layer_x(1,:));real(layer_x(2,:));...
                imag(layer_x(1,:));imag(layer_x(2,:))];
            precode_y(1,1:2:2*c-1)=X(1,:); 
            precode_y(2,1:2:2*c-1)=X(2,:);
            precode_y(1,2:2:2*c)=X(3,:); 
            precode_y(2,2:2:2*c)=X(4,:);
            D = 0;  % these matrices are needed in the receiver for undoing the precoding 
            W = 0;
            U = 0;
        else
            c = length(layer_x(1,:));
            precode_y = zeros(4,4*c); % NOTE: cleanup
            Z = [1,0,0,0,1i,0,0,0;0,0,0,0,0,0,0,0;0,-1,0,0,0,1i,0,0;0,0,0,0,0,0,0,0;0,1,0,0,0,1i,0,0;...
                0,0,0,0,0,0,0,0;1,0,0,0,-1i,0,0,0;0,0,0,0,0,0,0,0;0,0,0,0,0,0,0,0;0,0,1,0,0,0,1i,0;...
                0,0,0,0,0,0,0,0;0,0,0,-1,0,0,0,1i;0,0,0,0,0,0,0,0;0,0,0,1,0,0,0,1i;0,0,0,0,0,0,0,0;...
                0,0,1,0,0,0,-1i,0];
            X =1/sqrt(2)*Z*[real(layer_x(1,:));real(layer_x(2,:));real(layer_x(3,:));real(layer_x(4,:));...
                imag(layer_x(1,:));imag(layer_x(2,:));imag(layer_x(3,:));imag(layer_x(4,:))];
            precode_y(1,1:4:4*c-3)=X(1,:); 
            precode_y(2,1:4:4*c-3)=X(2,:);
            precode_y(3,1:4:4*c-3)=X(3,:); 
            precode_y(4,1:4:4*c-3)=X(4,:);
            precode_y(1,2:4:4*c-2)=X(5,:); 
            precode_y(2,2:4:4*c-2)=X(6,:);
            precode_y(3,2:4:4*c-2)=X(7,:); 
            precode_y(4,2:4:4*c-2)=X(8,:);
            precode_y(1,3:4:4*c-1)=X(9,:); 
            precode_y(2,3:4:4*c-1)=X(10,:);
            precode_y(3,3:4:4*c-1)=X(11,:); 
            precode_y(4,3:4:4*c-1)=X(12,:);
            precode_y(1,4:4:4*c)=X(13,:); 
            precode_y(2,4:4:4*c)=X(14,:);
            precode_y(3,4:4:4*c)=X(15,:); 
            precode_y(4,4:4:4*c)=X(16,:);
            D = 0;
            W = 0;
            U = 0;
        end
    else    % spatial multiplexing
        
        if (AtPorts == 2)   % precoding matrix according to Table 6.3.4.2.3-1
            switch codebook_index
                case 0
                    if (RI == 2)
                        W=1/sqrt(2)*[1,0;0,1];
                    else
                        W = [1;0];
                    end
                case 1
                    if (RI == 2)
                        W=1/(2)*[1,1;1,-1];
                    else
                        W = [0;1];
                    end
                case 2
                    if (RI == 2)
                        W=1/(2)*[1,1;1i,-1i];
                    else
                        W = 1/sqrt(2)*[1;1];
                    end
                case 3
                    if (RI == 2)
                        error('codebook index not supported');
                    else
                        W = 1/sqrt(2)*[1;-1];
                    end
                case 4
                    if (RI == 2)
                        error('codebook index not supported');
                    else
                        W = 1/sqrt(2)*[1;1i];
                    end
                case 5
                    if (RI == 2)
                        error('codebook index not supported');
                    else
                        W = 1/sqrt(2)*[1;-1i];
                    end
                otherwise
                    error('codebook index not supported');
            end
        else % precoding matrix according to Table 6.3.4.2.3-2
            for i = 1:length(codebook_index)    % for open loop spatial multiplexing 
                                                % codebook_index = [12,13,14,15]
                                                % see 3GPP TS 36.213-820, Section 7.1.3 
                                                % NOTE: store this in some pre-stored variable
                switch codebook_index(i)
                    case 0
                        u= [1;-1;-1;-1];
                    case 1
                        u= [1;-1i;1;1i];
                    case 2
                        u= [1;1;-1;1];
                    case 3
                        u= [1;1i;1;-1i];
                    case 4
                        u= [1;(-1-1i)/sqrt(2); -1i;(1-1i)/sqrt(2)];
                    case 5
                        u= [1;(1-1i)/sqrt(2); 1i;(-1-1i)/sqrt(2)];
                    case 6
                        u= [1;(1+1i)/sqrt(2); -1i;(-1+1i)/sqrt(2)];
                    case 7
                        u= [1;(-1+1i)/sqrt(2); 1i;(1+1i)/sqrt(2)];
                    case 8
                        u= [1;-1;1;1];
                    case 9
                        u= [1;-1i;-1;-1i];
                    case 10
                        u= [1;1;1;-1];
                    case 11
                        u= [1;1i;-1;1i];
                    case 12
                        u= [1;-1;-1;1];
                    case 13
                        u= [1;-1;1;-1];
                    case 14
                        u= [1;1;-1;-1];
                    case 15
                        u= [1;1;1;1];
                    otherwise
                        error('codebook index not supported');
                end
                W1 = diag(ones(1,4))-2*u*u'/(u'*u);
                switch RI  
                    case 1
                        W = W1(:,1);
                    case 2
                        switch codebook_index(i)
                            case {0,4,5,9}
                                W(:,:,i) = W1(:,[1 4])/sqrt(2);
                            case {1,2,3,8,12,15}
                                W(:,:,i) = W1(:,[1 2])/sqrt(2);
                            otherwise
                                W(:,:,i) = W1(:,[1 3])/sqrt(2);
                        end
                    case 3
                        switch codebook_index(i)
                            case {0,4,5,8}
                                W(:,:,i) = W1(:,[1 2 4])/sqrt(3);
                            case {1,2,3,10,12,13,14,15}
                                W(:,:,i) = W1(:,[1 2 3])/sqrt(3);
                            otherwise
                                W(:,:,i) = W1(:,[1 3 4])/sqrt(3);
                        end
                    case 4
                        switch codebook_index(i)
                            case {0,1,4,5,8,9,12,15}
                                W(:,:,i) = W1(:,[1 2 3 4])/2;
                            case {6,7,10,11,13}
                                W(:,:,i) = W1(:,[1 3 2 4])/2;
                            otherwise
                                W(:,:,i) = W1(:,[3 2 1 4])/2;
                        end
                    otherwise
                        error('RI not supported');
                end
            end
        end
        switch CDD  % cyclic delay diversity, precoding according to Section 6.3.4.2
            case 0  % zero delay CDD
                D = diag(ones(1,AtPorts));  
                precode_y = D*W*layer_x;
                U = 0;
            case 1  % small delay CDD 
                eta = [128 256 512 1024 2048];
                index = find((eta-LTE_params.Nrb*LTE_params.Nsc*ones(1,5))>=0);
                n = eta(index(1));
                D = zeros(LTE_params.Nsc*length(rb_numbers),AtPorts);
                vec = [];
                for ii = 1:length(rb_numbers)
                    if(rb_numbers(ii) > LTE_params.Nrb)
                        vec =[vec;((rb_numbers(ii)-LTE_params.Nrb-1)*LTE_params.Nsc+1:(rb_numbers(ii)-LTE_params.Nrb)*LTE_params.Nsc).'];
                    else
                        vec =[vec;((rb_numbers(ii)-1)*LTE_params.Nsc+1:rb_numbers(ii)*LTE_params.Nsc).']; 
                    end
                end
                switch AtPorts 
                    case 2
                        d = 2/n;
                        D(:,1)=1;
                        D(:,2) = exp(-1i*2*pi*d*vec);
                    case 4
                        d = 1/n;
                        D(:,1)=1;
                        D(:,2) = exp(-1i*2*pi*d*vec);
                        D(:,3) = exp(-1i*2*pi*d*vec*2);
                        D(:,4) = exp(-1i*2*pi*d*vec*3);
                end
                precode_y = W*layer_x;
                U = 0;
            case 2  % large delay CDD
                switch RI
                    case 1
                        precode_y = W*layer_x;
                        D =0;
                    case 2
                        U = 1/sqrt(2)*[1,1;1,exp(-1i*pi)];
                        D = [1,0;0,exp(-1i*pi)];
                           if (AtPorts ==2)    % faster encoding (for 2 Antennaports W is not dependent on the time index)
                            precodey1= W*D*U*layer_x(:,1:2:end);
                            precodey2= W*D^2*U*layer_x(:,2:2:end);
                            ende = floor(length(layer_x)/2);
                            precode_y = reshape([precodey1(:,1:ende);precodey2(:,1:ende)],AtPorts,[]);
                            if (length(precodey1)>ende)
                                precode_y=[precode_y,precodey1(:,end)]; 
                            end
                           end
                    case 3
                        U = 1/sqrt(3)*[1,1,1;1,exp(-1i*2*pi/3),exp(-1i*4*pi/3);1,exp(-1i*4*pi/3),exp(-1i*8*pi/3)];
                        D = [1,0,0;0,exp(-1i*2*pi/3),0;0,0,exp(-1i*4*pi/3)];
                    case 4
                        U = 1/2*[1,1,1,1;1,exp(-1i*2*pi/4),exp(-1i*4*pi/4),exp(-1i*6*pi/4);...
                            1,exp(-1i*4*pi/4),exp(-1i*8*pi/4),exp(-1i*12*pi/4);...
                            1,exp(-1i*6*pi/4),exp(-1i*12*pi/4),exp(-1i*18*pi/4)];
                        D = [1,0,0,0;0,exp(-1i*2*pi/4),0,0;0,0,exp(-1i*4*pi/4),0;0,0,0,exp(-1i*6*pi/4)];
                    otherwise
                        error('RI not supported');
                end
                if (RI > 1 && AtPorts == 4) % slower encoding version (if W is time dependent)
                    l = 1:length(layer_x);
                    k = mod(floor((l-1)/RI),4)+1;
                    p = mod(l-1,RI)+1;
                    for i = 1:l(end)
                       precode_y(:,i) = W(:,:,k(i))*D^(p(i))*U*layer_x(:,i);
                    end
                end
            otherwise
                    error('CDD not supported');          
        end
    end
else        % single Antenna Port (SISO)
    precode_y = layer_x;
    UE.CDD = 0; % no CDD for single antenna transmission
    W=1;
    D=1;
    U = 1;
end
%figure(2)
%plot(precode_y,'x');