function [separated_data]=coherent_ZF_receiver(received_signal,H,code_name,rate,num_code)
%HELP: coherent_ZF_receiver
%
%Perform Zero Forcing equalization for sapce time coded signal
%
%Input: - received signal
% - channel matrix: H
% - code_name: The code name ('Alamouti','OSTBC3',...)
% - code_rate: The code rate ('1','1/2',...)
% - num_code: The code number (1,2,...)
%
%Output: - separated data
%
%Reference:
%
%[1]E.G. Larsson,P.Stoica. "Space-time block coding for wireless
%communications", Cambridge Press,2003
%
%Programmed by V. Choqueuse (vincent.choqueuse@gmail.com)
%% extract space time block coding information
Rendement=str2num(rate);
[nb_emitters,code_length]=size(space_time_coding(0,code_name,rate,num_code,1));
nb_symbols_block=code_length*str2num(rate);
%% Extract coding matrices
G=zeros(2*nb_emitters*code_length,2*nb_symbols_block);
for indice=1:nb_symbols_block
real_part=zeros(1,nb_symbols_block);
real_part(indice)=1;
imag_part=zeros(1,nb_symbols_block);
imag_part(indice)=i;
Ak=space_time_coding(real_part,code_name,rate,num_code)';
Bk=space_time_coding(imag_part,code_name,rate,num_code)';
Akt=Ak(:);
Bkt=Bk(:);
G(:,indice)=[real(Akt);imag(Akt)]; %for real part
G(:,indice+nb_symbols_block)=[real(Bkt);imag(Bkt)]; %for imag part
end
%% rewritting the received symbol into a vector form
[nb_receiver,N] = size(received_signal);
Nb_bloc=N/code_length;
for indice=1:Nb_bloc
Xv=received_signal(:,(indice-1)*code_length+1:indice*code_length)';
xv_tilde(:,indice)=[real(Xv(:));imag(Xv(:))];
end
W_tilde=[kron(real(H),eye(code_length)) kron(imag(H),eye(code_length));...
-kron(imag(H),eye(code_length)) kron(real(H),eye(code_length))];
%% Zero forcing receiver
separated_data=[eye(nb_symbols_block) i*eye(nb_symbols_block)]*pinv(W_tilde*G)*xv_tilde;