function [gn,En,bn,b_bar_check,margin]=DMTLCma(P,SNRrcvr,Ex_bar,b_bar,N,gap) % % EE379C 2008 Spring % % Levin Campello's Method for margin-adaptive % % P is the pulse response % SNRrcvr is the channel output SNR in dB for i.i.d. inputs % Ex_bar is the normalized energy % N is the total number of real/complex subchannels, N>2 % gap is the gap in dB % b_bar is the bit rate % gn is channel gain % En is the energy in the nth subchannel (PAM or QAM) % bn is the bit in the nth subchannel (PAM or QAM) % b_bar_check is the bit rate for checking - this should be equal to b_bar % margin is the margin % The first bin and the last bin is PAM, the rest of them are QAM. % dB into normal scale Noise_var=Ex_bar*(norm(P)^2)/(10^(SNRrcvr/10)); gap=10^(gap/10); nu=length(P)-1; % initialization En=zeros(1,N/2+1); bn=zeros(1,N/2+1); gn=zeros(1,N/2+1); Hn = zeros(1,N/2+1); decision_table=zeros(1,N/2+1); % subchannel center frequencies f=0:1/N:1/2; % find Hn vector for i=1:length(P) Hn=Hn+P(i)*exp(j*2*pi*f*(i-1)); end % find gn vector gn=abs(Hn).^2/Noise_var; %debugging purpose %plot(gn) %%%%%%%%%%%%%%%%%%%%%%% % Margin Adaptive LC % %%%%%%%%%%%%%%%%%%%%%%% %initialization %used energy so far E_so_far=0; %decision table - QAM and PAM decision_table(2:N/2)=2*gap./gn(2:N/2); % gap-formula based incremental energies if gn(1) ~= 0 decision_table(1)=3*gap/gn(1); else decision_table(1)=inf; end if gn(N/2+1) ~=0 decision_table(N/2+1)=3*gap/gn(N/2+1); else decision_table(N/2+1)=inf; end %decision_table: debugging purpose while(1) [y,index]=min(decision_table); E_so_far=E_so_far+y; if sum(bn) >= (N+nu)*b_bar break; else En(index)=En(index)+y; bn(index)=bn(index)+1; if (index ==1 | index == N/2+1) decision_table(index)=4*decision_table(index); else decision_table(index)=2*decision_table(index); end end end % calculate b_bar b_bar_check=1/(N+nu)*(sum(bn)); % check margin margin=10*log10(N*Ex_bar/sum(En));