FFT 和改变频率以及矢量化 FOR 循环

发布于 2024-10-29 08:07:56 字数 1644 浏览 1 评论 0原文

FFT 和改变频率以及矢量化循环

问候所有

我可以增加和减少频率 使用 fft 和傅里叶级数扩展 FOR 循环组合的信号 下面的代码 但如果信号/阵列太大,它就会变得非常 很慢(1x44100 的数组大约需要 2 分钟才能完成)我确定 它与 for 循环有关,但是 我不太确定如何对其进行矢量化以提高性能。请注意,这将用于长度为 3 到 6 分钟的音频信号。 1x44100 数组只有一秒钟,大约需要 2 分钟才能完成

任何建议

%create signal
clear all, clc,clf,tic
x= linspace(0,2*pi,44100)';

%Used in exporting to ycalc audio file make sure in sync with above
freq_orig=1;
freq_new=4
vertoff=0;
vertoffConj=0;
vertoffInv=0;
vertoffInvConj=0;
phaseshift=(0)*pi/180 ; %can use mod to limit to 180 degrees

y=sin(freq_orig*(x));
[size_r,size_c]=size(y);

N=size_r; %to test make 50
T=2*pi;
dt=T/N;
t=linspace(0,T-dt,N)';
phase = 0;
f0 = 1/T; % Exactly, one period

y=(y/max(abs(y))*.8)/2; %make the max amplitude here
C = fft(y)/N; % No semicolon to display output


A = real(C);
B = imag(C)*-1; %I needed to multiply by -1 to get the correct sign

% Single-Sided (f >= 0)
An = [A(1); 2*A(2:round(N/2)); A(round(N/2)+1)]; 
Bn = [B(1); 2*B(2:round(N/2)); B(round(N/2)+1)];

pmax=N/2;
ycalc=zeros(N,1); %preallocating space for ycalc
w=0;

for p=2:pmax
               %
       %%1 step) re-create signal using equation
        ycalc=ycalc+An(p)*cos(freq_new*(p-1).*t-phaseshift)
+Bn(p)*sin(freq_new*(p-1).*t-phaseshift)+(vertoff/pmax);
        w=w+(360/(pmax-1)); %used to create phaseshift
        phaseshift=w;

end;

fprintf('\n- Completed in %4.4fsec or %4.4fmins\n',toc,toc/60);

subplot(2,1,1), plot(y),title('Orginal Signal');
subplot(2,1,2),plot(ycalc),title('FFT new signal');

如果有人想查看输出,这是一张绘图的图片,这是正确的 FOR 循环真的很慢

在此处输入图像描述

FFT and changing frequency and vectorizing for loop

Greetings All

I can increase and decrease the frequency of a
signal using the combination of fft and a Fourier series expansion FOR loop in
the code below
but if the signal/array is to large it becomes extremely
slow (an array that's 1x44100 takes about 2 mins to complete) I'm sure
it has to do with the for loop but
I'm not exactly sure how to vectorize it to improve performance. Please note that this will be used with audio signals that are 3 to 6 mins long. The 1x44100 array is only a second and it takes about 2 mins to complete

Any recommendations

%create signal
clear all, clc,clf,tic
x= linspace(0,2*pi,44100)';

%Used in exporting to ycalc audio file make sure in sync with above
freq_orig=1;
freq_new=4
vertoff=0;
vertoffConj=0;
vertoffInv=0;
vertoffInvConj=0;
phaseshift=(0)*pi/180 ; %can use mod to limit to 180 degrees

y=sin(freq_orig*(x));
[size_r,size_c]=size(y);

N=size_r; %to test make 50
T=2*pi;
dt=T/N;
t=linspace(0,T-dt,N)';
phase = 0;
f0 = 1/T; % Exactly, one period

y=(y/max(abs(y))*.8)/2; %make the max amplitude here
C = fft(y)/N; % No semicolon to display output


A = real(C);
B = imag(C)*-1; %I needed to multiply by -1 to get the correct sign

% Single-Sided (f >= 0)
An = [A(1); 2*A(2:round(N/2)); A(round(N/2)+1)]; 
Bn = [B(1); 2*B(2:round(N/2)); B(round(N/2)+1)];

pmax=N/2;
ycalc=zeros(N,1); %preallocating space for ycalc
w=0;

for p=2:pmax
               %
       %%1 step) re-create signal using equation
        ycalc=ycalc+An(p)*cos(freq_new*(p-1).*t-phaseshift)
+Bn(p)*sin(freq_new*(p-1).*t-phaseshift)+(vertoff/pmax);
        w=w+(360/(pmax-1)); %used to create phaseshift
        phaseshift=w;

end;

fprintf('\n- Completed in %4.4fsec or %4.4fmins\n',toc,toc/60);

subplot(2,1,1), plot(y),title('Orginal Signal');
subplot(2,1,2),plot(ycalc),title('FFT new signal');

Here's a pic of the plot if some one wants to see the output, which is correct the FOR loop is just really really slow

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

对岸观火 2024-11-05 08:07:56

看起来好像您基本上是在频域中向上移动信号,然后您的“级数扩展”只是在移动版本上实现逆 DFT。正如您所看到的,简单的 iDFT 将会非常慢。尝试将整个循环更改为对 ifft 的调用,您应该能够获得巨大的加速。

It appears as though you are basically shifting the signal upwards in the frequency domain, and then your "series expansion" is simply implementing the inverse DFT on the shifted version. As you have seen, the naive iDFT is going to be exceedingly slow. Try changing that entire loop into a call to ifft, and you should be able to get a tremendous speedup.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文