我试图在Matlab中编写简单函数来计算和绘制噪声功率谱(NPS)。首先,我想测试我从老师那里得到的算法是否合适。这是(它是在mathcad中制作的)
所以我试着将它复制粘贴到Matlab脚本中,最后得到了这段代码:
clear all;
clc;
N=1000;
O=1024;
mn=zeros(N,O);
n0=1500;
s=sqrt(n0);
W=zeros(N,O/2);
W1=zeros(N,O);
for k=1:N
for l=1:O
mn(k,l)=n0+round(sin(randn)*s);
end
end
for k=1:N
for l=1:O
mn(k,l)=mn(k,l)-n0;
end
end
for k=1:N
W1(k,:)=fft(mn(k,:));
end
for k=1:N
for l=1:O/2
W(k,l)=W1(k,l);
end
end
NPS1=(abs(W)).^2;
NPS2=sum(NPS1);
NPS=(1/N)*NPS2;
plot(NPS);
我没有使用Poisson分布,而且我已经切换了row-columnd索引,但这不重要(对吧?)。问题是我的情节中的数值比预期值高出400倍。
以下是它的样子:
我试图找到我做错了什么,但经过一段时间的测试后,我又回到了原点......我唯一担心的就是Matlab fft函数的工作方式与Mathcad中使用的函数不同(不能完全告诉我完全理解它)。 任何善良的灵魂都可以告诉我它是否与fft功能有关?或者我只是盲目的假人谁不能看到他犯的愚蠢错误? 干杯,抱歉我的英语不好。
[编辑]
经过一段时间后,我的老师让我检查这种方法是否与相关(有点)噪声一起工作,因为它在(再次)mathcad中起作用。 相关后,其NPS应该是“下降”。在更高的频率。问题是它没有。我用来测试它的代码如下所示:
clear all;
clc;
N=1000;
mn = poissrnd(N, N, N);
dataw=zeros(N);
for k=1:N ## loop used for my teacher's correlation method
for l=1:N
if l>1 && l<N
dataw(k,l)=dataw(k,l)+mn(k,l)*0.5+mn(k,l-1)*0.25+mn(k,l+1)*0.25;
elseif l==1
dataw(k,l)=dataw(k,l)+mn(k,l)*0.75+mn(k,l+1)*0.25;
else
dataw(k,l)=dataw(k,l)+mn(k,l)*0.75+mn(k,l-1)*0.25;
end
end
end
dataw = dataw - mean(dataw(:));
W1 = (1/sqrt(N))*fft(dataw, [], 1);
NPS1=(abs(W1)).^2;
NPS2=sum(NPS1);
NPS=(1/N)*NPS2;
plot(NPS);
我对由rayryeng修复的代码所做的唯一更改是使噪声矩阵为正方形(1000x1000),使得平均值为1000并使用整个变换向量W1而不是其“半”&#39 ;。 我知道它确实对我的老师有用,但它不适合我...还有其他关于matlab fft的东西我是否被忽略了,或者它是相关方法&#39;我用过吗?
在几次快速更改之后添加它在Mathcad中的样子(一些细微差别,但总体而言,它显示了我应该得到的效果)。它切断了扫描的开始,但它与我在这篇文章的开头所提出的完全相同。
[EDIT2]
Nvm,这只是fft功能中的一个维度问题。将其更改为fft(dataw,[],2)后看起来更好。
答案 0 :(得分:2)
它不起作用的主要原因是由于MathCad和MATLAB之间的FFT缩放因子。使用MathCad时,额外缩放因子为1/sqrt(N)
,而MATLAB 不包含此缩放因子。因此,如果您想模拟使用MathCad看到的结果,则需要将FFT结果乘以此缩放系数。
另外,我对您的代码提出了一些建议:
fft
和randn
等函数可以对矩阵进行操作,您可以将该函数专门应用于一个特定维度。 请注意,我已使用泊松随机噪声(来自poissrnd
)替换了您的随机噪声分布,以便我可以模仿您老师看到的结果。
基本上,您的代码可以替换为:
clear all;
clc;
N=1000;
O=1024;
n0=1500;
s=sqrt(n0);
%mn = round(sin(randn(N,O)*s));
mn = poissrnd(n0, N, O); %// CHANGE
mn = mn - mean(mn(:)); %// Remove mean
W1 = (1/sqrt(N))*fft(mn, [], 1); %// CHANGE FROM ABOVE
W = W1(:,1:O/2);
NPS1=(abs(W)).^2;
NPS2=sum(NPS1);
NPS=(1/N)*NPS2;
plot(NPS);
请注意,在生成随机数据时,您已经添加了平均值1500 ...仅在不对偏移数据进行任何处理的情况下再次从中减去1500。我刚从您的代码中删除了正弦舍入随机噪声。我已将该代码注释掉,因为我现在无论如何都没有运行。另请注意,randn
可以包含行数和列数,以便您可以生成随机矩阵值。此外,fft
可以对行或列进行操作,并将该维度中的每个信号视为1D信号。在这种情况下,您希望对每个列进行操作并对行进行处理,这就是我们将1
的参数指定为第三个参数的原因。
这是我在运行上述代码时得到的结果:
你看到它徘徊在1500左右的平均值,这是我们所期望的,因为我们从泊松随机分布中得到lambda=1500
。如果你真的想让图表看起来像你的老师,那么将y轴的限制从0更改为2000,如下所示:
ylim([0 2000]);
我们得到: