Mathcad到Matlab - 白噪声,fft和NPS测试

时间:2014-12-12 17:54:42

标签: matlab fft noise spectrum mathcad

我试图在Matlab中编写简单函数来计算和绘制噪声功率谱(NPS)。首先,我想测试我从老师那里得到的算法是否合适。这是(它是在mathcad中制作的)

enter image description here

所以我试着将它复制粘贴到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)后看起来更好。

1 个答案:

答案 0 :(得分:2)

它不起作用的主要原因是由于MathCad和MATLAB之间的FFT缩放因子。使用MathCad时,额外缩放因子为1/sqrt(N),而MATLAB 包含此缩放因子。因此,如果您想模拟使用MathCad看到的结果,则需要将FFT结果乘以此缩放系数。

另外,我对您的代码提出了一些建议:

  1. 我们可以完全使这个矢量化没有任何循环
  2. fftrandn等函数可以对矩阵进行操作,您可以将该函数专门应用于一个特定维度。
  3. 请注意,我已使用泊松随机噪声(来自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的参数指定为第三个参数的原因。

    这是我在运行上述代码时得到的结果:

    enter image description here


    你看到它徘徊在1500左右的平均值,这是我们所期望的,因为我们从泊松随机分布中得到lambda=1500。如果你真的想让图表看起来像你的老师,那么将y轴的限制从0更改为2000,如下所示:

    ylim([0 2000]);
    

    我们得到:

    enter image description here