MATLAB(ofdm注水算法odfmwaterfilling)

注水算法matlab函数:

function[shanonCapacity powerAllocated] = ofdmwaterfilling(nSubChannel,totalPower,channelStateInformation,bandwidth,noiseDensity); 

%为了使频率选择性信道的容量最大化,注水算法被使用,OFDM调制把总带宽分配成了
%n个子信道,如果正确的循环前缀被添加到每个OFDM模型的末端,那么大部分的子信道
%都能让其经历平衰落。注水算法就实现了把更多的功率分配给有好状态的信道,不给信道状态不好的(有深度衰落)的信道分配功率。

%参数设置
nSubChannel             = 16; 
totalPower              = 1e-5;      
channelStateInformation = random('rayleigh',1/0.6552,1,nSubChannel); %瑞利分布是一个均值为0,方差为σ^2的平稳窄带高斯过程
bandwidth               = 1e6;           
noiseDensity            = 1e-11;  %噪声密度 

subchannelNoise=noiseDensity*bandwidth/nSubChannel;
carrierToNoiseRatio =channelStateInformation.^2/subchannelNoise;   
initPowerAllo=(totalPower + sum(1./carrierToNoiseRatio))/nSubChannel-1./carrierToNoiseRatio; 

%在这个阶段,公式一的最优化结果就会导致一些子信道被分配了少功率,
%在接下来的阶段,这些信道会被消除,然后继续这种算法,把多余的功率分
%配给其他信道。
 while(length(find(initPowerAllo < 0 )) > 0 ) 
      negIndex       = initPowerAllo <= 0; 
      posIndex       = find(initPowerAllo >  0); 
      nSubchannelRem = length(posIndex); 
      initPowerAllo(negIndex) = 0; 
      CnrRem         = carrierToNoiseRatio(posIndex); 
      powerAlloTemp  = (totalPower + sum(1./CnrRem))/nSubchannelRem - 1./CnrRem; 
      initPowerAllo(posIndex) = powerAlloTemp; 
 end 
 %计算信道容量
powerAllocated = initPowerAllo';         
shanonCapacity = bandwidth/nSubChannel*sum(log2(1 + initPowerAllo.*carrierToNoiseRatio)); 
%绘直方图
    f1 = figure(1); 
    clf; 
    set(f1,'Color',[1 1 1]); 
    bar((initPowerAllo +1./carrierToNoiseRatio),1,'r') 
    hold on;
    bar(1./carrierToNoiseRatio,1); 
    xlabel('subchannel indices'); 
    title('Water filling algorithm') 
    legend('amount of power allocated to each subchannel', 'Noise to Carrier Ratio') 

下面我们举一个实例来应用此算法,首先我们要知道注水算法的初衷:保留正数,负数置零。

下面是主程序:

N=16;
H=100;
L=2000;
ro=80;
p=linspace(100000,100000,N);
q=linspace(100000,100000,N);
x=linspace(0,2000,N);
y=linspace(500,500,N);
rsr=ro./(H^2+x.^2+y.^2);
rrd=ro./(H^2+(L-x).^2+y.^2);  
la=linspace(1/16,1/16,N);
u=linspace(0.0001,0.0001,N);
for t=1:1:1000
b=linspace(0,0,N);
for n=1:1:N-1 
    for i=n+1:1:N
     b(n)=b(n)+la(i);
    end
end
v=linspace(0,0,N); 
for n=2:1:N
    for i=n:1:N  
    v(n)=1-(v(n)+la(i));
    end
end

[Ps]=WF1(p,b,rsr);
[Pr]=WF1(q,v,rrd);
[Rr]=WF3(q,v,rrd);
la=la-u.*(sum(log2(1+Ps.*rsr))-sum(Rr));
disp(la)
end

下面是注水子程序:

function[Ps]=WF1(p,b,rsr)
Ps=p.*b-1./(rsr);
while(~isempty(find(Ps<0, 1)))
    IndexN= Ps<=0;
    IndexP= Ps>0;
    Ps(IndexN)=0;
    pT=p(IndexP);
    bT=b(IndexP);
    rsnT=rsr(IndexP);
    PsT=pT.*bT-1./(rsnT);
    Ps(IndexP)=PsT;
end
end

function[Pr]=WF2(q,v,rrd)
Pr=q.*v-1./(rrd);
while(~isempty(find(Pr<0, 1)))
    IndexN= Pr<=0;
    IndexP= Pr>0;
    Pr(IndexN)=0;
    qT=q(IndexP);
    vT=v(IndexP);
    rrdT=rsn(IndexP);
    PrT=qT.*vT-1./(rrdT);
    Pr(IndexP)=PrT;
end

function[Rr]=WF3(q,v,rrd)
Rr=log2(q.*v.*rrd);
while(~isempty(find(Rr<0, 1)))
    IndexN= Rr<=0;
    IndexP= Rr>0;
    Rr(IndexN)=0;
    qT=q(IndexP);
    vT=v(IndexP);
    rrdT=rrd(IndexP);
    RrT=log2(qT.*vT.*rrdT);
    Rr(IndexP)=RrT;
end
end


你可能感兴趣的:(matlab)