├── AIC.m
├── CSM_CSS.m
├── CSM_TCT.m
├── IMUSIC (frequency Bin) with random phase in same B.svg
├── IMUSIC (frequency Bin) with random phase.svg
├── IMUSIC on each frequency.png
├── IMUSIC(weighted).png
├── IMUSIC-LFM.png
├── IMUSIC.m
├── IMUSIC.png
├── IMUSIC_LFM.m
├── MUSIC.m
├── README.md
├── TCT method in optimal frequency.png
├── TOPS.m
├── Wideband Signal Spectrum(freqBin).png
└── temp.png
/AIC.m:
--------------------------------------------------------------------------------
1 | function sourceNum = AIC(snapshots, sensorNum, eigVals)
2 | %---sourceNum: the number of sources using AIC method---%
3 | %---snapshots: the number of snapshots------------------%
4 | %---sensorNum: the number of array elements-------------%
5 | %---eigVals: eigen values with descendant sort--------%
6 | t = inf;
7 | for sourceNum = 1: sensorNum - 1
8 | num = 0;
9 | den = 1;
10 | for iter = sourceNum + 1: sensorNum
11 | num = num + eigVals(iter);
12 | den = den * eigVals(iter);
13 | end
14 | Lambda = (num/(sensorNum - sourceNum)) / den^(1/(sensorNum - sourceNum));
15 | etrpy = 2*snapshots*(sensorNum - sourceNum)*log(Lambda) + ...
16 | 2*sourceNum*(2*sensorNum - sourceNum); % AIC entropy
17 | %-------find minimum loss entropy----------------%
18 | if etrpy > t
19 | break;
20 | else
21 | t = etrpy;
22 | end
23 | end
24 | sourceNum = sourceNum - 1; % fix n
25 | end
--------------------------------------------------------------------------------
/CSM_CSS.m:
--------------------------------------------------------------------------------
1 | function [theta, spectrum] = CSM_CSS()
2 | SNR = 15;
3 | sensorNum = 8;
4 | theta_S = [-10; 0];
5 | sourceNum = length(theta_S);
6 | %----Signal bandwidth: 4MHz, center freq: 10MHz fs: 8e6-----%
7 | f_begin = 8e6;
8 | f_end = 12e6;
9 | bandwidth = f_end - f_begin;
10 | fs = 2*bandwidth;
11 | narrowBandwidth = 1e2;
12 | narrowBandNum = bandwidth/narrowBandwidth;
13 |
14 | freqSnapshots = 200;
15 | nFFT = 64;
16 |
17 |
18 | c = 3e8;
19 | Ts = 1/fs;
20 | snapshots = freqSnapshots*nFFT;
21 | Ns = Ts*(0: snapshots - 1);
22 | margin = (c/f_end)/2;
23 | distance = margin*(0: sensorNum - 1)';
24 |
25 | receivedData = zeros(sensorNum, snapshots);
26 | manifoldMat = zeros(sensorNum, sourceNum);
27 | signalCovMat = [1, 0; 0, 1];
28 | for bandNum = 1: narrowBandNum
29 | f = f_begin + (bandNum - 1)*narrowBandwidth;
30 | signalAmp = mvnrnd(zeros(sourceNum, 1), signalCovMat, snapshots).';
31 | signalMat = [exp(1j*2*pi*f*Ns); exp(1j*2*pi*f*Ns)].*signalAmp;
32 | for col = 1: sourceNum
33 | manifoldMat(:, col) = exp(-1j*2*pi*f*((distance*sind(theta_S(col)))/c));
34 | end
35 | receivedData = receivedData + manifoldMat*signalMat;
36 | end
37 | receivedData = awgn(receivedData, SNR, 'measured');
38 |
39 | dataSet = zeros(sensorNum, freqSnapshots, nFFT);
40 | for slice = 1: freqSnapshots
41 | dataSlice = receivedData(:, (slice - 1)*nFFT + 1: slice*nFFT);
42 | for eachSensor = 1: sensorNum
43 | dataSet(eachSensor, slice, :) = fft(dataSlice(eachSensor, :), nFFT);
44 | end
45 | end
46 |
47 | preEstTheta = theta_S + 0.25*randn();
48 | %---------form tansform matrix-------%
49 | focusFreq = (f_begin + f_end)/2;
50 | % auxiAngles = [-25; -20; -15; 10; 15; 20];
51 | % focusAuxiManifoldMat = zeros(sensorNum, length(auxiAngles));
52 | % freqBinManifoldMat = zeros(sensorNum, length(auxiAngles));
53 | transMat = zeros(sensorNum, sensorNum, nFFT);
54 | preManifoldMat = zeros(sensorNum, sourceNum);
55 | noiseCovMat = zeros(sensorNum, sensorNum);
56 | for col = 1: sourceNum
57 | manifoldMat(:, col) = exp(-1j*2*pi*focusFreq*((distance*sind(preEstTheta(col)))/c));
58 | end
59 | % for col = 1: length(auxiAngles)
60 | % focusAuxiManifoldMat(:, col) = exp(-1j*2*pi*focusFreq*((distance*sind(auxiAngles(col)))/c));
61 | % end
62 | for freqPos = 1: nFFT
63 | if freqPos <= nFFT/2
64 | f = fs + (freqPos - 1)*fs/nFFT;
65 | else
66 | f = (f_end + bandwidth) - (freqPos - 1)*fs/nFFT;
67 | end
68 | for col = 1: sourceNum
69 | preManifoldMat(:, col) = exp(-1j*2*pi*f*((distance*sind(preEstTheta(col)))/c));
70 | end
71 | tempMatB = [zeros(sourceNum, sensorNum - sourceNum); eye(sensorNum - sourceNum)];
72 | transMat(:, :, freqPos) = [manifoldMat, tempMatB]*pinv([preManifoldMat, tempMatB]);
73 | % for col = 1: length(auxiAngles)
74 | % freqBinManifoldMat(:, col) = exp(-1j*2*pi*f*((distance*sind(auxiAngles(col)))/c));
75 | % end
76 | % transMat(:, :, freqPos) = [manifoldMat, focusAuxiManifoldMat]*pinv([preManifoldMat, freqBinManifoldMat]);
77 | noiseCovMat = noiseCovMat + transMat(:, :, freqPos)*transMat(:, :, freqPos)';
78 | end
79 |
80 | %--------prewhite noise covariance matrix--------%
81 | upperMat = chol(noiseCovMat);
82 |
83 | %--------form transformed covarince matrix-------%
84 | transCovMat = zeros(sensorNum, sensorNum);
85 | for freqPos = 1: nFFT
86 | data = dataSet(:, :, freqPos);
87 | covMat = (data*data')/size(data, 2);
88 | transCovMat = transCovMat + transMat(:, :, freqPos)*covMat*transMat(:, :, freqPos)';
89 | end
90 | transCovMat = pinv(upperMat')*transCovMat*pinv(upperMat);
91 |
92 | %-------MUSIC---------%
93 | [theta, spectrum] = MUSIC(transCovMat, focusFreq, sourceNum, sensorNum, margin);
94 | end
--------------------------------------------------------------------------------
/CSM_TCT.m:
--------------------------------------------------------------------------------
1 | function [theta, spectrum] = CSM_TCT()
2 | SNR = 15;
3 | sensorNum = 8;
4 | theta_S = [-10; 0];
5 | sourceNum = length(theta_S);
6 | %----Signal bandwidth: 4MHz, center freq: 10MHz fs: 8e6-----%
7 | f_begin = 8e6;
8 | f_end = 12e6;
9 | bandwidth = f_end - f_begin;
10 | fs = 2*bandwidth;
11 | narrowBandwidth = 1e2;
12 | narrowBandNum = bandwidth/narrowBandwidth;
13 |
14 | freqSnapshots = 100;
15 | nFFT = 64;
16 |
17 |
18 | c = 3e8;
19 | Ts = 1/fs;
20 | snapshots = freqSnapshots*nFFT;
21 | Ns = Ts*(0: snapshots - 1);
22 | margin = (c/f_end)/2;
23 | distance = margin*(0: sensorNum - 1)';
24 |
25 | receivedData = zeros(sensorNum, snapshots);
26 | manifoldMat = zeros(sensorNum, sourceNum);
27 | signalCovMat = [1, 0.99; 0.99, 1];
28 | for bandNum = 1: narrowBandNum
29 | f = f_begin + (bandNum - 1)*narrowBandwidth;
30 | signalAmp = mvnrnd(zeros(sourceNum, 1), signalCovMat, snapshots).';
31 | signalMat = [exp(1j*2*pi*f*Ns); exp(1j*2*pi*f*Ns)].*signalAmp;
32 | for col = 1: sourceNum
33 | manifoldMat(:, col) = exp(-1j*2*pi*f*((distance*sind(theta_S(col)))/c));
34 | end
35 | receivedData = receivedData + manifoldMat*signalMat;
36 | end
37 | receivedData = awgn(receivedData, SNR, 'measured');
38 |
39 | dataSet = zeros(sensorNum, freqSnapshots, nFFT);
40 | for slice = 1: freqSnapshots
41 | dataSlice = receivedData(:, (slice - 1)*nFFT + 1: slice*nFFT);
42 | for eachSensor = 1: sensorNum
43 | dataSet(eachSensor, slice, :) = fft(dataSlice(eachSensor, :), nFFT);
44 | end
45 | end
46 |
47 | preEstTheta = theta_S + 0.25*randn();
48 | estManifold = zeros(sensorNum, sourceNum);
49 | focusFreqSignalCorreMat = 0;
50 | singularValsSum = 0;
51 | %------form signal correlation matrices and manifold in each frequency bin------%
52 | for freqPos = 1: nFFT
53 | if freqPos <= nFFT/2
54 | f = fs + (freqPos - 1)*fs/nFFT;
55 | else
56 | f = (f_end + bandwidth) - (freqPos - 1)*fs/nFFT;
57 | end
58 | data = dataSet(:, :, freqPos);
59 | covMat = (data*data')/size(data, 2);
60 | [~, eigenVals] = eig(covMat);
61 | eigenVals = diag(eigenVals);
62 | noisePower = min(eigenVals);
63 | cleanedData = covMat - noisePower*eye(sensorNum);
64 | singularValsSum = singularValsSum + svd(cleanedData);
65 | for col = 1: sourceNum
66 | estManifold(:, col) = exp(-1j*2*pi*f*((distance*sind(preEstTheta(col)))/c));
67 | end
68 | signalCorreMat = pinv(estManifold'*estManifold)*estManifold'*cleanedData*estManifold*pinv(estManifold'*estManifold);
69 | focusFreqSignalCorreMat = focusFreqSignalCorreMat + signalCorreMat;
70 | end
71 | focusFreqSignalCorreMat = focusFreqSignalCorreMat/nFFT;
72 | %------form focus matrices------%
73 | focusFreq = (f_begin + f_end)/2;
74 | focusManifold = zeros(sensorNum, sourceNum);
75 | % cost = inf;
76 | % for freqPos = 1: nFFT/2
77 | % f = fs + (freqPos - 1)*fs/nFFT;
78 | % for col = 1: sourceNum
79 | % focusManifold(:, col) = exp(-1j*2*pi*f*((distance*sind(preEstTheta(col)))/c));
80 | % end
81 | % focusData = focusManifold*focusFreqSignalCorreMat*focusManifold';
82 | % thisCost = sum(abs(svd(focusData) - singularValsSum/nFFT).^2);
83 | % if thisCost < cost
84 | % focusFreq = f;
85 | % cost = thisCost;
86 | % end
87 | % end
88 | for col = 1: sourceNum
89 | focusManifold(:, col) = exp(-1j*2*pi*focusFreq*((distance*sind(preEstTheta(col)))/c));
90 | end
91 | focusData = focusManifold*focusFreqSignalCorreMat*focusManifold';
92 | [focusEigSubspace, eigenVals] = eig(focusData);
93 | eigenVals = diag(eigenVals);
94 | [~, index] = sort(eigenVals, 'descend');
95 | focusEigSubspace = focusEigSubspace(:, index);
96 |
97 | covMat_TCT = 0;
98 | for freqPos = 1: nFFT
99 | data = dataSet(:, :, freqPos);
100 | covMat = (data*data')/size(data, 2);
101 | [~, eigenVals] = eig(covMat);
102 | eigenVals = diag(eigenVals);
103 | noisePower = min(eigenVals);
104 | cleanedData = covMat - noisePower*eye(sensorNum);
105 | [eigSubspace, eigenVals] = eig(cleanedData);
106 | eigenVals = diag(eigenVals);
107 | [~, index] = sort(eigenVals, 'descend');
108 | eigSubspace = eigSubspace(:, index);
109 | transMat = focusEigSubspace*eigSubspace';
110 | covMat_TCT = covMat_TCT + transMat*cleanedData*transMat';
111 | end
112 | covMat_TCT = covMat_TCT/nFFT;
113 |
114 | %-------MUSIC---------%
115 | [theta, spectrum] = MUSIC(covMat_TCT, focusFreq, sourceNum, sensorNum, margin);
116 | end
--------------------------------------------------------------------------------
/IMUSIC (frequency Bin) with random phase in same B.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
230 |
--------------------------------------------------------------------------------
/IMUSIC (frequency Bin) with random phase.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
230 |
--------------------------------------------------------------------------------
/IMUSIC on each frequency.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unive3sal/DOA-estimation/cfefbdbeb6c7a8dc6ea5da3bfb7592f925f930bb/IMUSIC on each frequency.png
--------------------------------------------------------------------------------
/IMUSIC(weighted).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unive3sal/DOA-estimation/cfefbdbeb6c7a8dc6ea5da3bfb7592f925f930bb/IMUSIC(weighted).png
--------------------------------------------------------------------------------
/IMUSIC-LFM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unive3sal/DOA-estimation/cfefbdbeb6c7a8dc6ea5da3bfb7592f925f930bb/IMUSIC-LFM.png
--------------------------------------------------------------------------------
/IMUSIC.m:
--------------------------------------------------------------------------------
1 | SNR = 15;
2 | sensorNum = 8;
3 | theta_S = [-15, 5];
4 | sourceNum = length(theta_S);
5 |
6 | f_begin = [600, 1000];
7 | f_end = [1400, 1400];
8 | fc = 1000;
9 | bandwidth = f_end - f_begin;
10 | fs = 2*max(bandwidth);
11 | narrowBandwidth = 1;
12 | narrowBandNum = bandwidth/narrowBandwidth;
13 |
14 | freqSnapshots = 100;
15 | nFFT = 256;
16 | snapshots = freqSnapshots*nFFT;
17 | Ts = (1/fs)*(0: snapshots - 1)' + 0.005;
18 |
19 | c = 3e8;
20 | margin = (c/max(f_end))/2;
21 |
22 | test = 0;
23 |
24 | receivedData = zeros(sensorNum, snapshots);
25 | for n = 1: sourceNum
26 | for bandNum = 1: narrowBandNum(n)
27 | f = f_begin(n) + (bandNum - 1)*narrowBandwidth;
28 | steerVec = exp(-1j*2*pi*f*((margin*(0: sensorNum - 1)'*sind(theta_S(n))/c)));
29 | signalVec = exp(1j*2*pi*(f*Ts' + rand()));
30 | test = test + signalVec;
31 | receivedData = receivedData + steerVec*signalVec;
32 | end
33 | end
34 |
35 | receivedData = awgn(receivedData, SNR, 'measured');
36 | receivedData = receivedData.*exp(-1j*2*pi*fc*Ts');
37 | test = test.*exp(-1j*2*pi*fc*Ts');
38 |
39 | dataSet = zeros(sensorNum, freqSnapshots, nFFT);
40 | for slice = 1: freqSnapshots
41 | dataSlice = receivedData(:, (slice - 1)*nFFT + 1: slice*nFFT);
42 | dataSlice = fft(dataSlice, nFFT, 2);
43 | dataSet(:, slice, :) = dataSlice;
44 | end
45 |
46 | theta = (-30: 0.1: 30)';
47 | spectrum = zeros(size(theta));
48 | for freqBin = 1: nFFT
49 | if freqBin <= nFFT/2
50 | f = fc + (freqBin - 1)*fs/nFFT;
51 | else
52 | f = (fc - fs) + (freqBin - 1)*fs/nFFT;
53 | end
54 | data = dataSet(:, :, freqBin);
55 | covMat = data*data'/freqSnapshots;
56 | [eigVecs, eigVals] = eig(covMat);
57 | eigVals = diag(eigVals);
58 | [eigVals, index] = sort(eigVals);
59 | sourceNum = AIC(freqSnapshots, sensorNum, flip(eigVals));
60 | noiseSubspace = eigVecs(:, index(1: sensorNum - sourceNum));
61 | for n = 1: length(theta)
62 | steerVec = exp(-1j*2*pi*f*(margin*(0: sensorNum - 1)'*sind(theta(n)))/c);
63 | spectrum(n) = spectrum(n) + (steerVec'*steerVec)./...
64 | (steerVec'*(noiseSubspace*noiseSubspace')*steerVec);
65 | end
66 | end
67 | spectrum = spectrum./nFFT;
68 |
69 | plot(theta, 10*log10(abs(spectrum)/max(abs(spectrum))))
70 | grid on
71 | hold on
72 | for n = 1: length(theta_S)
73 | plot([theta_S(n), theta_S(n)], get(gca, 'YLim'), '--r')
74 | end
75 | hold off
76 | set(gca, 'XTICK', -30: 5: 30)
77 | xlabel('angle/degree')
78 | ylabel('spectrum/dB')
79 | title('IMUSIC')
--------------------------------------------------------------------------------
/IMUSIC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unive3sal/DOA-estimation/cfefbdbeb6c7a8dc6ea5da3bfb7592f925f930bb/IMUSIC.png
--------------------------------------------------------------------------------
/IMUSIC_LFM.m:
--------------------------------------------------------------------------------
1 | SNR = 15;
2 | sensorNum = 8;
3 | theta_S = [-15, 5];
4 | sourceNum = length(theta_S);
5 |
6 | f_begin = [600e6, 1000e6];
7 | f_end = [1400e6, 1400e6];
8 | fc = 1000e6;
9 | bandwidth = f_end - f_begin;
10 | fs = 2*max(bandwidth);
11 |
12 | freqSnapshots = 100;
13 | nFFT = 256;
14 | snapshots = freqSnapshots*nFFT;
15 | Ts = (1/fs)*(0: snapshots - 1)' + 0.005;
16 |
17 | c = 3e8;
18 | margin = (c/max(f_end))/2;
19 |
20 | receivedData = zeros(sensorNum, snapshots);
21 | for m = 1: sensorNum
22 | for n = 1: sourceNum
23 | delay = (m - 1)*margin*sind(theta_S(n))/c;
24 | k = bandwidth(n)/Ts(end);
25 | % signal = exp(1j*2*pi*(f_begin(n)*Ts + (1/2)*k*Ts.^2));
26 | receivedData(m, :) = receivedData(m, :) + exp(1j*2*pi*(f_begin(n)*(Ts - delay) + ...
27 | (1/2)*k*(Ts - delay).^2)).';
28 | end
29 | end
30 | receivedData = awgn(receivedData, SNR, 'measured');
31 | receivedData = receivedData.*exp(-1j*2*pi*fc*Ts');
32 |
33 | dataSet = zeros(sensorNum, freqSnapshots, nFFT);
34 | for slice = 1: freqSnapshots
35 | dataSlice = receivedData(:, (slice - 1)*nFFT + 1: slice*nFFT);
36 | dataSlice = fft(dataSlice, nFFT, 2);
37 | dataSet(:, slice, :) = dataSlice;
38 | end
39 |
40 | theta = (-30: 0.1: 30)';
41 | spectrum = zeros(size(theta));
42 | for freqBin = 1: nFFT
43 | if freqBin <= nFFT/2
44 | f = fc + (freqBin - 1)*fs/nFFT;
45 | else
46 | f = (fc - fs) + (freqBin - 1)*fs/nFFT;
47 | end
48 | data = dataSet(:, :, freqBin);
49 | covMat = data*data'/freqSnapshots;
50 | [eigVecs, eigVals] = eig(covMat);
51 | eigVals = diag(eigVals);
52 | [eigVals, index] = sort(eigVals);
53 | sourceNum = AIC(freqSnapshots, sensorNum, flip(eigVals));
54 | noiseSubspace = eigVecs(:, index(1: sensorNum - sourceNum));
55 | for n = 1: length(theta)
56 | steerVec = exp(-1j*2*pi*f*(margin*(0: sensorNum - 1)'*sind(theta(n)))/c);
57 | spectrum(n) = spectrum(n) + ...
58 | (steerVec'*steerVec)/(steerVec'*(noiseSubspace*noiseSubspace')*steerVec);
59 | end
60 | end
61 | spectrum = spectrum/nFFT;
62 |
63 | plot(theta, 10*log10(abs(spectrum)/max(abs(spectrum))))
64 | grid on
65 | hold on
66 | for n = 1: length(theta_S)
67 | plot([theta_S(n), theta_S(n)], get(gca, 'YLim'), '--r')
68 | end
69 | hold off
70 | set(gca, 'XTICK', -30: 5: 30)
71 | xlabel('angle/degree')
72 | ylabel('spectrum/dB')
73 | title('IMUSIC-LFM')
--------------------------------------------------------------------------------
/MUSIC.m:
--------------------------------------------------------------------------------
1 | function [theta, spectrum] = MUSIC(data, f, sourceNum, sensorNum, margin)
2 | %---@Input: data (x = As + n)------%
3 | %---@ f: frequency (Hz)---%
4 | %---@ sourceNum: number of sources---%
5 | %---@ sensorNum: number of sensors---%
6 | %---@Output: spectrum of MUSIC--%
7 | covMat = (data*data')/size(data, 2); % Covariance matrix
8 | [eigenVec, eigenVals] = eig(covMat); % Eigen factorization
9 | eigenVals = diag(eigenVals);
10 | [~, index] = sort(eigenVals);
11 | noiseSubspace = eigenVec(:, index(1: sensorNum - sourceNum));
12 |
13 | theta = (-30: 0.1: 30)';
14 | spectrum = zeros(length(theta), 1);
15 | c = 3e8;
16 | % margin = (c/f)/2; % Let distance between 2 adjacent sensors equal to wavelength/2
17 | for itr = 1: length(theta)
18 | steeringVec = exp(-1j*2*pi*f*(margin*(0: sensorNum - 1)'*sind(theta(itr)))/c);
19 | spectrum(itr) = (steeringVec'*steeringVec)/(steeringVec'*(noiseSubspace*noiseSubspace')*steeringVec);
20 | end
21 | end
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DOA-estimation
2 | DOA estimation source code
3 | http://dengyuhao.org/
--------------------------------------------------------------------------------
/TCT method in optimal frequency.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unive3sal/DOA-estimation/cfefbdbeb6c7a8dc6ea5da3bfb7592f925f930bb/TCT method in optimal frequency.png
--------------------------------------------------------------------------------
/TOPS.m:
--------------------------------------------------------------------------------
1 | function [theta, spectrum] = TOPS()
2 | SNR = 15;
3 | sensorNum = 8;
4 | theta_S = [-20; 13];
5 | sourceNum = length(theta_S);
6 | %----Signal bandwidth: 4MHz, center freq: 10MHz fs: 8e6-----%
7 | f_begin = 8e6;
8 | f_end = 12e6;
9 | fc = (f_begin + f_end)/2;
10 | bandwidth = f_end - f_begin;
11 | fs = 2*bandwidth;
12 | narrowBandwidth = 1e2;
13 | narrowBandNum = bandwidth/narrowBandwidth;
14 |
15 | freqSnapshots = 100;
16 | nFFT = 64;
17 |
18 |
19 | c = 3e8;
20 | Ts = 1/fs;
21 | snapshots = freqSnapshots*nFFT;
22 | Ns = Ts*(0: snapshots - 1);
23 | margin = (c/f_end)/2;
24 | distance = margin*(0: sensorNum - 1)';
25 |
26 | receivedData = zeros(sensorNum, snapshots);
27 | manifoldMat = zeros(sensorNum, sourceNum);
28 | for bandNum = 1: narrowBandNum
29 | f = f_begin + (bandNum - 1)*narrowBandwidth;
30 | signalMat = [exp(-1j*2*pi*f*Ns); exp(-1j*2*pi*f*Ns)];
31 | for col = 1: sourceNum
32 | manifoldMat(:, col) = exp(-1j*2*pi*f*((distance*sind(theta_S(col)))/c));
33 | end
34 | receivedData = receivedData + manifoldMat*signalMat;
35 | end
36 | receivedData = awgn(receivedData, SNR, 'measured');
37 | receivedData = receivedData.*exp(-1j*2*pi*fc*Ns);
38 |
39 | dataSet = zeros(sensorNum, freqSnapshots, nFFT);
40 | for slice = 1: freqSnapshots
41 | dataSlice = receivedData(:, (slice - 1)*nFFT + 1: slice*nFFT);
42 | dataSlice = fft(dataSlice, nFFT, 2);
43 | dataSet(:, slice, :) = dataSlice;
44 | end
45 |
46 | theta = (-30: 0.1: 30)';
47 | spectrum = zeros(size(theta));
48 | data = dataSet(:, :, 1);
49 | covMat = (data*data')/size(data, 2);
50 | [eigenVec, eigenVals] = eig(covMat); % Eigen factorization
51 | eigenVals = diag(eigenVals);
52 | [~, index] = sort(eigenVals, 'descend');
53 | signalSubspace = eigenVec(:, index(1: sourceNum));
54 | for itr = 1: length(theta)
55 | estimator = [];
56 | for freqPos = 2: nFFT
57 | data = dataSet(:, :, freqPos);
58 | covMat = (data*data')/size(data, 2);
59 | [eigenVec, eigenVals] = eig(covMat); % Eigen factorization
60 | eigenVals = diag(eigenVals);
61 | [~, index] = sort(eigenVals, 'ascend');
62 | noiseSubspace = eigenVec(:, index(1: sensorNum - sourceNum));
63 |
64 | if freqPos <= nFFT/2
65 | f = fc + (freqPos - 1)*fs/nFFT;
66 | else
67 | f = (fc - fs) + (freqPos - 1)*fs/nFFT;
68 | end
69 | deltaF = f - fc;
70 | steeringVec = exp(-1j*2*pi*deltaF*(margin*(0: sensorNum - 1)'*sind(theta(itr)))/c);
71 | unitaryMat = diag(steeringVec);
72 | projectionMat = eye(sensorNum) - pinv(steeringVec'*steeringVec)*(steeringVec*steeringVec');
73 | tempMatU = projectionMat*unitaryMat*signalSubspace;
74 | estimator = [estimator, tempMatU'*noiseSubspace];
75 | end
76 | singularVals = svd(estimator);
77 | spectrum(itr) = 1/(singularVals(end));
78 |
79 | end
80 |
81 | end
--------------------------------------------------------------------------------
/Wideband Signal Spectrum(freqBin).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unive3sal/DOA-estimation/cfefbdbeb6c7a8dc6ea5da3bfb7592f925f930bb/Wideband Signal Spectrum(freqBin).png
--------------------------------------------------------------------------------
/temp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unive3sal/DOA-estimation/cfefbdbeb6c7a8dc6ea5da3bfb7592f925f930bb/temp.png
--------------------------------------------------------------------------------