当前位置:文档之家› MATLAB编程如何不用for循环

MATLAB编程如何不用for循环

MATLAB编程如何不用for循环--以DFT变换矩阵为例
缘起:大家都知道MATLAB中用for循环编写的代码执行起来效率不高,如何用矩阵和向量的运算提升效率对每一个用matlab的人来说都是很有必要的,但是此项功夫高手一般不愿意给初学者讲,此功夫是高手和低手的分水岭,高手们更是拿此功夫在初学者面前炫耀。

本人当初怀着很恭敬的心向高手请教,高手笑笑说这要我自己编。

出于让后来人受益,帮助和我一样无助的求知者。

本人今天话了一天时间将此问题研究下,并且将代码毫无保留的公布出来。

希望大家能够受益,阿弥陀佛!
上述W矩阵的第一列代表直流成分,第二列到最后一列是信号的交流成分,可以看出倍频关系!我以前不知道DFT 可以通过矩阵表示。

注意matlab中dftmtx实现上述W矩阵的时候没有用1/sqrt(N) 进行归一化!可以通过dftmtx(2)验证,没有1/sqrt(2)。

例1 DFT matrix 是Hermitian的
Nfft = 8; xn=rand(1,Nfft);
y=dftmtx(Nfft)*xn.' %结果是个列向量y=dftmtx(Nfft)*x.' 和y=fft(x,Nfft)是等价的
y = xn*dftmtx(Nfft) %结果是个行向量
y=fft(xn,Nfft) %结果是个行向量
%dft变换公式,n代表时域采样点,k代表频域采样点
Y(k)=sum(x.*exp(-j*2*pi*n*k))
相应的,dftmtx(Nfft)产生的矩阵中,第k行,n列元素=exp(-j*2*pi*k*n/Nfft),与x.'相乘正好对应fft变换后的每个频点值。

例1:双重循环求DFT
N = 8; x=rand(1,N);
for k=0:N-1
sum=0; % 注意每个X(k)的值不应该受上次计算的影响
for m=0:N-1
w=exp(-j*2*pi/N.*m.*k); %DFT matrix 的每一行的元素是不同的
sum=sum+x(m+1).*w; % 这个循环实际上是计算DFT matrix的每一行与信号x的内积
end
X(k+1)=sum; %Matlab下标从1开始
end
% 注意X 是个行向量,是个数组,我以前不知道X(k)的循环赋值的结果是个行向量
y=fft(x,N) %验证
例2:单循环求DFT
%% x 是行向量的Version,结果X也是行向量
N = 8; x=rand(1,N); m=0:N-1;
sum=0;
for k=0:N-1 %核心思想是内积运算:x躺着,后面的必须站着
X(k+1)= x*exp(-j*2*pi/N.*m'.*k) ; % 以前这样的表达物理含义是不明确的--> X(k+1)= x*exp(-j*2*pi/N.*m.*k).' ; end
y=fft(x,N) %验证
%% x 是列向量的Version,结果X是行向量,fft(x)的结果是列向量
N = 8; x=rand(1,N)'; m=0:N-1;
sum=0;
for k=0:N-1 % 核心思想是内积运算:x躺着,后面的必须站着
X(k+1)= exp(-j*2*pi/N.*m.*k)*x ; % 以前这样的表达物理含义是不明确的--> X(k+1)= x*exp(-j*2*pi/N.*m.*k).' ; end
y=fft(x,N) %验证结果y是个列向量,X是y的转置。

因为X按下标赋值的结果是个行向量!
例3:不用循环求DFT
%% x 是行向量的Version,结果X也是行向量
N = 8; xn=rand(1,N); %一次去掉2个循环,不要试图一次去掉一个
n=[0:1:N-1];
k=[0:1:N-1];
WN=exp(-j*2*pi/N);
nk=n'*k; %看看如何不用for循环来实现,向量的外积N-by-1 multiply 1-by-N
WNnk=WN.^nk; %WNnk就是dftmtx(8),dftmtx原来是这样构造的
Xk=xn*WNnk; % 究竟nk这个向量外径是n'*k还是k'*n要看内积在哪一维执行
y=fft(xn,N) %验证
%% x 是列向量的Version,结果X也是列向量
N = 8; xn=rand(1,N)'; %一次去掉2个循环,不要试图一次去掉一个
n=[0:1:N-1];
k=[0:1:N-1];
WN=exp(-j*2*pi/N);
nk=k'*n; %看看如何不用for循环来实现,向量的外积N-by-1 multiply 1-by-N
WNnk=WN.^nk; %WNnk就是dftmtx(8),dftmtx原来是这样构造的
Xk=WNnk*xn; % 究竟nk这个向量外径是n'*k还是k'*n要看内积在哪一维执行
y=fft(xn,N) %验证
--------------------------------------------------------------------------------------------
自相关矩阵
做信道矩阵相关时,假设信道频域相关矩阵R_ff,时域相关矩阵为R_tt,Nfft,那么
R_ff=dftmtx(Nfft)*R_tt*dftmtx(Nfft)'
时域相关矩阵R_tt=h*h',t
频域相关矩阵R_ff=H*H'=dftmtx(Nfft)*h*(dftmtx(Nfft)*h)'=dftmtx(Nfft)*h*h'*dftmtx(Nfft)=dftmtx(Nfft)*R_tt*dftmtx(Nff)
均值就是直流分量
方差就是交流功率
自相关在零时刻的值是平均功率。

相关主题