% ###############################################################################
% ##  Loesung: Verkettete Codes                                                ##
% ##---------------------------------------------------------------------------##
% ##  Aufgabe 9.3.2) Parallele Verkettung zweier Faltungscodes                 ##
% ##---------------------------------------------------------------------------##
% ##  benoetigte Matlab-Dateien: lparallel.m, parallelconcat.m,                ##
% ##                             pb_unionbound_awgn.m,iowef_block_conv.m       ##
% ###############################################################################

clear all;
close all;

disp('Aufgrund der Simulation kann die Berechnung sehr lange dauern...');
ant=input('Soll ein vorhandener Arbeitsbereich für Aufgabe 9.3.2 geladen werden (j/n)? ','s');
if ant=='j'
   disp('Arbeitsbereich a9_3_2.mat geladen');
   file=1;
   load results/a9_3_2;
elseif ant=='n'
   disp('Arbeitsbereich nicht geladen - simuliere neu!');
   file=0;
end;

%allgemeine Parameter
% Faltungscodes (oktale Darstellung)
Lc   = 3;
n    = 2;
k    = 1;

% Rekursiver Code mit rekursivem Polynom 5
G1   = [1;7];
R1   = [0;5];

% Rekursiver Code mit rekursivem Polynom 7
G2 = [1;5];
R2 = [0;7];

EbN0 = 0:0.5:10;

% ##############################################################
% #####Aufgabenteil a) IOWEF der Teil- und des Turbocodes  #####
% ##############################################################

disp('Aufgabenteil a) IOWEF der Teil- und des Turbocodes');

if (~file)
   % IOWEF von Teilcode 1 bestimmen 
   dmax = 200;
   lmax = 100;
   wmax = 98;
   P    = [3;3]; 
   A1   = iowef_block_conv(Lc,n,k,G1,R1,dmax,lmax,wmax,P);
   N    = 100; 
end   
   % effektive Distanz
   disp('effektive Distanz von Code 1');
   d_eff1 = min(find(A1(3,:))) * 2 - 2
   
if(~file)
   % IOWEF des Turbo-Codes bestimmen 
   A1p100   = parallelconcat(A1,A1,N,'IOWEF');
   N        = 200; 
   A1p200   = parallelconcat(A1,A1,N,'IOWEF');
   N        = 400; 
   A1p400   = parallelconcat(A1,A1,N,'IOWEF');
   N        = 800; 
   A1p800   = parallelconcat(A1,A1,N,'IOWEF');
   N        = 1600; 
   A1p1600  = parallelconcat(A1,A1,N,'IOWEF');
   
   % Koeffizienten cd bestimmen
   [w,d] = size(A1);
   cd1   = [1:(w-1)] * A1(2:w,2:d) / 98;
   [w,d] = size(A1p100);
   cd1_100 = [1:(w-1)] * A1p100(2:w,2:d) / 98;
   [w,d] = size(A1p200);
   cd1_200 = [1:(w-1)] * A1p200(2:w,2:d) / 198;
   [w,d] = size(A1p400);
   cd1_400 = [1:(w-1)] * A1p400(2:w,2:d) / 398;
   [w,d] = size(A1p800);
   cd1_800 = [1:(w-1)] * A1p800(2:w,2:d) / 798;
   [w,d] = size(A1p1600);
   cd1_1600 = [1:(w-1)] * A1p1600(2:w,2:d) / 1598;
end   

figure('name', 'Parallele Verkettung von RSC-Codes', 'numbertitle', 'off'); 
%subplot(121);
gh=semilogy(1:length(cd1),cd1,'k:*',1:length(cd1_100),cd1_100,'k:o',1:length(cd1_200),cd1_200,'k:x',...
   1:length(cd1_400),cd1_400,'k:s',1:length(cd1_800),cd1_800,'k:v',1:length(cd1_1600),cd1_1600,'k:^');
%set(gh,'linewidth',1.5,'markersize',8);
grid on;
axis([0 30 10^-10 10^15]);
set(gca,'fontname','times','fontsize',15);
xlabel('x');
ylabel('y');
set(gca,'ytick',[10^-5 10^-0 10^5 10^10 10^15 ],'xtick',[0 5 10 15 20 25 30]);
set(gcf,'PaperPosition',[2 5 4.7 3.4]);
title('t');
legend('Teilcode','Lpi=100','Lpi=200','Lpi=400','Lpi=800','Lpi=1600',2);
%xlabel('d \rightarrow');
%ylabel('c_d \rightarrow');
%title('a) Parallele Verkettung von RSC-Codes (5)');
print -deps b9_3_6a

disp('Weiter mit beliebiger Taste');
%pause;
   
% ##########################################################
% #####Aufgabenteil b) Rueckkopplung von Generator g1  #####
% ##########################################################

disp(sprintf('\nAufgabenteil b) Rueckkopplung von Generator g1'));

if(~file)   % b) IOWEF von Teilcode 2 bestimmen 
   dmax = 200;
   lmax = 100;
   wmax = 98;
   P    = [3;3]; 
   A2   = iowef_block_conv(Lc,n,k,G2,R2,dmax,lmax,wmax,P);
   N    = 100; 
   pb2  = pb_unionbound_awgn(EbN0,A2,N*2,N-(Lc-1));
end   
   % effektive Distanz
   disp('effektive Distanz von Code 2');
   d_eff2 = min(find(A2(3,:))) * 2 - 2
   
   if(~file)
   % IOWEF des Turbo-Codes bestimmen 
   A2p100 = parallelconcat(A2,A2,N,'IOWEF');
   N       = 200; 
   A2p200  = parallelconcat(A2,A2,N,'IOWEF');
   N       = 400; 
   A2p400  = parallelconcat(A2,A2,N,'IOWEF');
   N       = 800; 
   A2p800  = parallelconcat(A2,A2,N,'IOWEF');
   N        = 1600; 
   A2p1600  = parallelconcat(A2,A2,N,'IOWEF');
   
   % Koeffizienten cd bestimmen
   [w,d] = size(A2);
   cd2   = [1:(w-1)] * A2(2:w,2:d) / 98;
   [w,d] = size(A2p100);
   cd2_100 = [1:(w-1)] * A2p100(2:w,2:d) / 98;
   [w,d] = size(A2p200);
   cd2_200 = [1:(w-1)] * A2p200(2:w,2:d) / 198;
   [w,d] = size(A2p400);
   cd2_400 = [1:(w-1)] * A2p400(2:w,2:d) / 398;
   [w,d] = size(A2p800);
   cd2_800 = [1:(w-1)] * A2p800(2:w,2:d) / 798;
   [w,d] = size(A2p1600);
   cd2_1600 = [1:(w-1)] * A2p1600(2:w,2:d) / 1598;
end

%subplot(122);
figure;
gh=semilogy(1:length(cd2),cd2,'k:*',1:length(cd2_100),cd2_100,'k:o',1:length(cd2_200),cd2_200,'k:x',...
   1:length(cd2_400),cd2_400,'k:s',1:length(cd2_800),cd2_800,'k:v',1:length(cd2_1600),cd2_1600,'k:^');
%set(gh,'linewidth',1.5,'markersize',8);
grid on;
axis([0 30 10^-10 10^15]);
set(gca,'fontname','times','fontsize',15);
xlabel('x');
ylabel('y');
set(gca,'ytick',[10^-5 10^-0 10^5 10^10 10^15 ],'xtick',[0 5 10 15 20 25 30]);
set(gcf,'PaperPosition',[2 5 4.7 3.4]);
title('t');
legend('Teilcode','Lpi=100','Lpi=200','Lpi=400','Lpi=800','Lpi=1600',2);
%xlabel('d \rightarrow');
%ylabel('c_d \rightarrow');
%title('b) Parallele Verkettung von RSC-Codes (7)');
print -deps b9_3_6b

disp('Weiter mit beliebiger Taste');
%pause;
  
      
% ###########################################################
% #####Aufgabenteil c) Abschaetzung der Bitfehlerraten  #####
% #####################################################ä#####

disp(sprintf('\nAufgabenteil c) Abschaetzung der Bitfehlerraten'));
if(~file)
   pb1  = pb_unionbound_awgn(EbN0,A1,200,100-(Lc-1));
   pb1p100 = pb_unionbound_awgn(EbN0,A1p100,100*3,100-(Lc-1));
   pb1p200 = pb_unionbound_awgn(EbN0,A1p200,200*3,200-(Lc-1));
   pb1p400 = pb_unionbound_awgn(EbN0,A1p400,400*3,400-(Lc-1));
   pb1p800 = pb_unionbound_awgn(EbN0,A1p800,800*3,800-(Lc-1));
   pb1p1600 = pb_unionbound_awgn(EbN0,A1p1600,1600*3,1600-(Lc-1));
   
   pb2p100 = pb_unionbound_awgn(EbN0,A2p100,100*3,100-(Lc-1));
   pb2p200 = pb_unionbound_awgn(EbN0,A2p200,200*3,200-(Lc-1));
   pb2p400 = pb_unionbound_awgn(EbN0,A2p400,400*3,400-(Lc-1));
   pb2p800 = pb_unionbound_awgn(EbN0,A2p800,800*3,800-(Lc-1));
   pb2p1600 = pb_unionbound_awgn(EbN0,A2p1600,1600*3,1600-(Lc-1));
   
end

figure('name', 'Union-Bound Abschaetzung', 'numbertitle', 'off'); 
%subplot(121);
gh=semilogy(EbN0,pb1,'k-',EbN0,pb1p100,'k-o',EbN0,pb1p200,'k-x',EbN0,pb1p400,'k-d',...
   EbN0,pb1p800,'k-v',EbN0,pb1p1600,'k-^');
%set(gh,'linewidth',1.5,'markersize',8);
grid on;
axis([0 10 10^-15 1]);
set(gca,'fontname','times','fontsize',15);
xlabel('x');
ylabel('y');
set(gca,'ytick',[10^-15 10^-10 10^-5 10^0],'xtick',[0 2 4 6 8 10]);
set(gcf,'PaperPosition',[2 5 4.7 3.4]);
title('t');
legend('Teilcode','Lpi=100','Lpi=200','Lpi=400','Lpi=800','Lpi=1600');
%xlabel('E_b/N_0 in dB \rightarrow');
%ylabel('P_b \rightarrow');
%title('a) Parallele Verkettung von RSC-Codes (5)');
print -deps b9_3_7a

%subplot(122);
figure
gh=semilogy(EbN0,pb2,'k-',EbN0,pb2p100,'k-o',EbN0,pb2p200,'k-x',EbN0,pb2p400,'k-d',...
   EbN0,pb2p800,'k-v',EbN0,pb2p1600,'k-^');
%set(gh,'linewidth',1.5,'markersize',8);
grid on;
axis([0 10 10^-15 1])
set(gca,'fontname','times','fontsize',15);
xlabel('x');
ylabel('y');
set(gca,'ytick',[10^-15 10^-10 10^-5 10^0],'xtick',[0 2 4 6 8 10]);
set(gcf,'PaperPosition',[2 5 4.7 3.4]);
title('t');
legend('Teilcode','Lpi=100','Lpi=200','Lpi=400','Lpi=800','Lpi=1600');
%xlabel('E_b/N_0 in dB \rightarrow');
%ylabel('P_b \rightarrow');
%title('b) Parallele Verkettung von RSC-Codes (7)');
print -deps b9_3_7b

disp('Weiter mit beliebiger Taste');
%pause;

% ###########################################################
% #####Aufgabenteil d) BER fuer punktierten Turbo-Code  #####
% ###########################################################

disp(sprintf('\nAufgabenteil d) BER fuer punktierten Turbo-Code'));

if(~file)
   N    = 400; 
   dmax = 200;
   lmax = 100;
   wmax = 98;
   
   % Rate 1/2
   P1   = [3;1]; 
   A1   = iowef_block_conv(Lc,n,k,G2,R2,dmax,lmax,wmax,P1);
   P2   = [1;3]; 
   A2   = iowef_block_conv(Lc,n,k,G2,R2,dmax,lmax,wmax,P2);
   
   A2p400_1  = parallelconcat(A1,A2,N,'IOWEF');
   pb2p400_1 = pb_unionbound_awgn(EbN0,A2p400_1,N*2,N-(Lc-1));
   
   % Rate 2/3
   P1   = [3;1;1;1]; 
   A1   = iowef_block_conv(Lc,n,k,G2,R2,dmax,lmax,wmax,P1);
   P2   = [1;1;3;1]; 
   A2   = iowef_block_conv(Lc,n,k,G2,R2,dmax,lmax,wmax,P2);
   A2p400_2  = parallelconcat(A1,A2,N,'IOWEF');
   pb2p400_2 = pb_unionbound_awgn(EbN0,A2p400_2,N*3/2,N-(Lc-1));
   
   % Rate 3/4
   P1   = [3;1;1;1;1;1]; 
   A1   = iowef_block_conv(Lc,n,k,G2,R2,dmax,lmax,wmax,P1);
   P2   = [1;1;1;3;1;1]; 
   A2   = iowef_block_conv(Lc,n,k,G2,R2,dmax,lmax,wmax,P2);
   A2p400_3  = parallelconcat(A1,A2,N,'IOWEF');
   pb2p400_3 = pb_unionbound_awgn(EbN0,A2p400_3,N*4/3,N-(Lc-1));
   
end

% Mindestdistanzen
disp('Mindestdistanz Code 1')
dminUI = min(find(sum(A1p100(:,2:40))))

disp('Mindestdistanz Code 2')
dminUI = min(find(sum(A2p100(:,2:40))))

figure('name', 'Punktierter Turbo-Code', 'numbertitle', 'off'); 
gh=semilogy(EbN0,pb2p400,'k-',EbN0,pb2p400_1,'k-x',EbN0,pb2p400_2,'k-d',EbN0,pb2p400_3,'k-v');
%set(gh,'linewidth',1.5,'markersize',8);
grid on;
axis([0 10 10^-15 1])
set(gca,'fontname','times','fontsize',13);
xlabel('x');
ylabel('y');
set(gca,'ytick',[10^-15 10^-10 10^-5 10^0],'xtick',[0 2 4 6 8 10]);
set(gcf,'PaperPosition',[2 5 4.7 3.4]);
title('t');
legend('Rc=1/3','Rc=1/2','Rc=2/3','Rc=3/4');
%xlabel('E_b/N_0 in dB \rightarrow');
%ylabel('P_b \rightarrow');
%title('Punktierung von paralleler Verkettung');
print -deps b9_3_8

disp('Ende von Aufgabe 9.3.2');
