├── Bayesian_DSP2018.m ├── README.md ├── main.m └── signal.m /Bayesian_DSP2018.m: -------------------------------------------------------------------------------- 1 | function [Pm,search_area]=Bayesian_DSP2018_paper(X,Snap,resolution,position,etc) 2 | search_area=[-90:resolution:90]; 3 | Rx=X*X'/Snap; 4 | Y=Rx(:); 5 | [M2,T]=size(Y); 6 | M=sqrt(M2); 7 | K_hat=length(search_area); 8 | reslu=search_area(2)-search_area(1); 9 | In=eye(M); 10 | In=In(:); 11 | pos_all=round(log(kron(exp(-position),exp(position)))); 12 | W=kron(Rx.',Rx)/Snap; 13 | W_sq=sqrtm(inv(W)); 14 | Y=W_sq*Y; 15 | 16 | %% Initialization 17 | d=0.01; 18 | maxiter=300; 19 | tol=1e-5; 20 | beta0=1; 21 | delta=ones(K_hat+1,1); 22 | a_search=search_area*pi/180; 23 | A=exp(-1i*pi*pos_all'*sin(a_search)); 24 | B=-1i*pi*pos_all'*cos(a_search).*A; 25 | A_w=W_sq*A; 26 | B_w=W_sq*B; 27 | I_w= W_sq* In; 28 | Phi=[A_w, I_w]; 29 | V_temp= 1/beta0*eye(M2) + Phi *diag(delta) * Phi'; 30 | Sigma = diag(delta) -diag(delta) * Phi' * (V_temp\Phi) * diag(delta); 31 | mu = beta0*Sigma * Phi' * Y; 32 | 33 | converged = false; 34 | iter = 0; 35 | while (~converged) || iter<=100 36 | 37 | iter = iter + 1; 38 | delta_last = delta; 39 | %% Calculate mu and Sigma 40 | V_temp= 1/beta0*eye(M2) + Phi *diag(delta) * Phi'; 41 | Sigma = diag(delta) -diag(delta) * Phi' * (V_temp\Phi) * diag(delta); 42 | mu = beta0*(Sigma * (Phi' * Y)); 43 | 44 | %% Update delta 45 | temp=sum( mu.*conj(mu), 2) + T*real(diag(Sigma)); 46 | delta= ( -T+ sqrt( T^2 + 4*d* real(temp) ) ) / ( 2*d ); 47 | 48 | %% Stopping criteria 49 | erro=norm(delta - delta_last)/norm(delta_last); 50 | if erro < tol || iter >= maxiter 51 | converged = true; 52 | end 53 | 54 | %% Grid refinement 55 | [~, idx] = sort(delta(1:end-1), 'descend'); 56 | idx = idx(1:etc); 57 | BHB = B_w' * B_w; 58 | P = real(conj(BHB(idx,idx)) .* (mu(idx,:) * mu(idx,:)' + Sigma(idx,idx))); 59 | v = real(diag(conj(mu(idx))) * B_w(:,idx)' * (Y - A_w * mu(1:end-1)-mu(end)*I_w))... 60 | - real(diag(B_w(:,idx)' * A_w * Sigma(1:end-1,idx)) + diag(Sigma(idx,K_hat+1))*B_w(:,idx).'*conj(I_w)); 61 | eigP=svd(P); 62 | if eigP(end)/eigP(1)>1e-5 63 | temp1 = P \ v; 64 | else 65 | temp1=v./diag(P); 66 | end 67 | temp2=temp1'*180/pi; 68 | if iter<100 69 | ind_small=find(abs(temp2)reslu); 73 | temp2(ind_large)=sign(temp2(ind_large))*reslu/100; 74 | angle_cand=search_area(idx) + temp2; 75 | search_area(idx)=angle_cand; 76 | % for iii=1:etc 77 | % if angle_cand(iii)>= search_mid_left(idx(iii)) && (angle_cand(iii) <= search_mid_right(idx(iii))) 78 | % search_area(idx(iii))=angle_cand(iii); 79 | % end 80 | % end 81 | A_ect=exp(-1i*pi*pos_all'*sin(search_area(idx)*pi/180)); 82 | B_ect=-1i*pi*pos_all'*cos(search_area(idx)*pi/180).*A_ect; 83 | A_w(:,idx) =W_sq*A_ect; 84 | B_w(:,idx) =W_sq*B_ect; 85 | Phi(:,idx)= A_w(:,idx); 86 | 87 | end 88 | Pm=delta(1:end-1); 89 | % [search_area,sort_s]=sort(search_area); 90 | % Pm=Pm(sort_s); 91 | % insert=(search_area(1:end-1)+search_area(2:end))/2; 92 | % search_area_2=zeros(length(search_area)*2-1,1); 93 | % search_area_2(1:2:end)=search_area; 94 | % search_area_2(2:2:end)=insert; 95 | % Pm_2=zeros(length(Pm)*2-1,1); 96 | % Pm_2(1:2:end)=Pm; 97 | % search_area=search_area_2; 98 | % Pm=Pm_2; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SBL_nested 2 | Matlab codes for the paper: Chen, Fangfang, Jisheng Dai, Nan Hu, and Zhongfu Ye. "Sparse Bayesian learning for off-grid DOA estimation with nested arrays." Digital Signal Processing 82 (2018): 187-193. 3 | -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | clear; 2 | close all; 3 | % randn('seed',0); 4 | % rand('seed',0); 5 | 6 | Snap=200; % Number of snapshots 7 | SNR = 0; % SNR 8 | M1=2; 9 | M2=2; 10 | M=M1+M2; % Number of element nested array 11 | position=[0:M1 [2:M2]*(M1+1)-1]; 12 | resolution=3; % grid interval 13 | etc=M2*(M1); % Maximum number of active grid points 14 | 15 | %% generate the signal 16 | True_DOAs=10*rand(1,2) + [-30,10]; 17 | N_alpha=length(True_DOAs); 18 | [X]=signal(M,position,True_DOAs,SNR, Snap); 19 | 20 | %% the proposed method 21 | [Pm_our,search_area_our]=Bayesian_DSP2018(X,Snap,resolution,position,etc); 22 | figure; stem(search_area_our,Pm_our) 23 | -------------------------------------------------------------------------------- /signal.m: -------------------------------------------------------------------------------- 1 | function [X]=signal(M,position,True_DOAs,SNR,Snap) 2 | 3 | N_theta=length(True_DOAs); 4 | A=exp(-1i*pi*position'*sin(True_DOAs*pi/180)); 5 | Pow=sqrt(( (10).^(SNR/10) )/2); 6 | S=Pow*(randn(N_theta,Snap)+1i*randn(N_theta,Snap)); 7 | noise=sqrt(1/2)*(randn(M,Snap)+1i*randn(M,Snap)); 8 | X=A*S+noise; 9 | --------------------------------------------------------------------------------