function [gn,en_bar,bn_bar,Nstar,b_bar_check,margin]=DMTma(P,SNRrcvr,Ex_bar,b_bar,N,gap) % EE379C 2008 Spring, % J. Cioffi - thanks to Seong Taek Chung % % P is the pulse response where v=length(P) -1 % SNRrcvr is the SNR (in dB) at te receiver input if the input is i.i.d % b_bar is the target normalized bit rate % Ex_bar is the normalized energy % N is the total number of real/complex subchannels, N>2 % gap is the gap in dB % % gn is the vector of channel gains % en_bar is the vector of energy/dim for all subchannels % bn_bar is the vector of bit/dim for all subchannels % Nstar is the number of used subchannel % 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); bn=zeros(1,N); gn=zeros(1,N); Hn = zeros(1,N); % subchannel center frequencies f=-1/2+1/N: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; %%%%%%%%%%%%%%%%%%%%%%% % MA waterfilling % %%%%%%%%%%%%%%%%%%%%%%% %sort [gn_sorted, Index]=sort(gn); % sort gain, and get Index gn_sorted = fliplr(gn_sorted);% flip left/right to get the largest % gain in leftside Index = fliplr(Index); % also flip index num_zero_gn = length(find(gn_sorted == 0)); %number of zero gain subchannels Nstar=N - num_zero_gn; % Number of used channels, % start from N - (number of zero gain subchannels) b=(N+nu)*b_bar; Klog2tilde=2*b-(1/log(2))*sum(log(gn_sorted)); while(1) Klog2=(1/Nstar)*Klog2tilde + log(gap)/log(2); En_min=2^(Klog2)-gap/gn_sorted(Nstar); % En_min occurs in the worst channel if (En_min<0) Klog2tilde=Klog2tilde+(1/log(2))*log(gn_sorted(Nstar)); Nstar=Nstar-1; % If negative En, continue with less channels else break; % If all En positive, done. end end K=2^(Klog2); En=K-gap./gn_sorted(1:Nstar); % Calculate En Bn=.5*log2(K*gn_sorted(1:Nstar)/gap); % Calculate bn bn(Index(1:Nstar))=Bn; % return values in original index en(Index(1:Nstar))=En; % return values in original index en_bar=en; bn_bar=bn; % calculate b_bar b_bar_check=1/(N+nu)*(sum(bn)); %calculate margin margin=10*log10(N*Ex_bar/sum(en));