
% NOTA: in aula ho sbagliato Eb/N0 rispetto all'SNR!
%
function hamming_benchmark

	% frame da quanti byte?
	BYTES = 1500;

	% intervallo di rapporto SNR da valutare
	Eb_N0_dB = 0:0.25:20;
	Eb_N0 = 10.^(Eb_N0_dB/10);

	% probabilità di errore del sistema non codificato
	Pe_BPSK_unc = Q(sqrt(2*Eb_N0));

	% sistema codificato con codice di Hamming
	NmK = 3;
	N = 2^NmK - 1;
	K = N - NmK;
	R = K/N;
	
	% probabilità di errore del sistema codificato (PRIMA
	% DELLA DECODIFICA)
	Pe_BPSK_R = Q(sqrt(2*R*Eb_N0));
	
	% probabilità di errore del sistema codificato (DOPO
	% LA DECODIFICA)
	Pc_BPSK_Hamming = (1-Pe_BPSK_R).^N + ...
		N * Pe_BPSK_R .* (1-Pe_BPSK_R).^(N-1);
	Pe_BPSK_Hamming = 1 - Pc_BPSK_Hamming;
	
	% diagramma delle probabilità di errore in scala
	% semilogaritmica
	subplot(2,1,1)
	
	hold off
	semilogy(Eb_N0_dB,1-(1-Pe_BPSK_unc).^(BYTES*8))
	set(gca,'YLim',[1e-6 1])
	set(gca,'XLim',[0 20])
	hold on
	semilogy(Eb_N0_dB,1-(1-Pe_BPSK_R).^ceil(BYTES*8/R),'r')
	semilogy(Eb_N0_dB,1-(1-Pe_BPSK_Hamming).^ceil(BYTES*8/K),'m')
	
	% etichette agli assi, griglia e range da rappresentare
	xlabel('E_b/N_0 [dB]');
	ylabel('P(e)');
	grid on
	
	SNR_dB = -3:0.25:17;
	SNR = 10.^(SNR_dB/10);
	p_BSC = Q(sqrt(SNR));
	
	% probabilità di consegna corretta del sistema non codificato
	% (coincide col throughput)
	pC_unc = (1-p_BSC).^(BYTES*8);
	
	% probabilità di corretta decisione sulla parola
	pC_word = (1-p_BSC).^N + N * p_BSC .* (1-p_BSC).^(N-1);
	pC_frame_Hamming = pC_word.^ceil(BYTES*8/K);
	
	% diagramma della capacità del canale AWGN,
	% dell'informazione mutua e del throughput in funzione
	% del rapporto SNR
	subplot(2,1,2)
	
	hold off
	plot(SNR_dB,0.5*log2(1+SNR),'k:');
	hold on
	plot(SNR_dB,1-H(p_BSC),'k');
	plot(SNR_dB,pC_unc,'b')
	plot(SNR_dB,pC_frame_Hamming*R,'m')
	
	xlabel('SNR [dB]');
	ylabel('bit/channel use');
	grid on
	set(gca,'YLim',[0,1])
	set(gca,'XLim',[-3 17])
end

% Q(x) = Pr{ N(0,1) > x }
function val = Q(x)
	val = 0.5*erfc(x/sqrt(2));
end

% entropia di una sorgente binaria
function val = H(p)
	val = -p.*log2(p) - (1-p).*log2(1-p);
end
