function [gn,En,bn,b_bar_check,margin]=MALC(P,SNRmfb,Ex_bar,b_bar,Ntot,gap) % % EE379C 2001-2002 Spring % % Levin Campello's Method % % P is the pulse response % SNRmfb is the SNRmfb in dB % Ex_bar is the normalized energy % Ntot is the total number of real/complex subchannels, Ntot>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^(SNRmfb/10)); gap=10^(gap/10); % initialization En=zeros(1,Ntot/2+1); bn=zeros(1,Ntot/2+1); gn=zeros(1,Ntot/2+1); Hn = zeros(1,Ntot/2+1); decision_table=zeros(1,Ntot/2+1); % subchannel center frequencies f=0:1/Ntot:1/2; % find Hn vector for i=1:length(P) Hn=Hn+P(i)*exp(j*2*pi*f*(i-1)); % This value will be different depending if P represents % P(1) + P(2)*D^-1 + .... or P(1) + P(2)*D^+1...., % but we'll get same gn, thus same waterfilling result. % (Note that both have the same magnitude response!) end % find gn vector gn=abs(Hn).^2/Noise_var; %debugging purpose %plot(gn) %%%%%%%%%%%%%%%%%%%%%%% % Now do LC % %%%%%%%%%%%%%%%%%%%%%%% %initialization %used energy so far E_so_far=0; %decision table - QAM and PAM decision_table(2:Ntot/2)=2*gap./gn(2:Ntot/2); if gn(1) ~= 0 decision_table(1)=3*gap/gn(1); else decision_table(1)=inf; end if gn(Ntot/2+1) ~=0 decision_table(Ntot/2+1)=3*gap/gn(Ntot/2+1); else decision_table(Ntot/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) >= Ntot*b_bar break; else En(index)=En(index)+y; bn(index)=bn(index)+1; if (index ==1 | index == Ntot/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/Ntot*(sum(bn)); % check margin margin=10*log10(Ntot*Ex_bar/sum(En)); %>> [gn,En,bn,b_bar_check,margin]=MALC([1 0.9],10,1,1,8,0) % %gn = % % 19.9448 17.0320 10.0000 2.9680 0.0552 % % %En = % % 0.7521 0.8220 0.6000 0.6739 0 % % %bn = % % 2 3 2 1 0 % % %b_bar_check = % % 1 % % %margin = % % 4.4856