从R中的离散傅里叶变换重构信号
我试图在R中复制下图:(改编自) 该图的基本概念是显示DFT的前几个分量,绘制在时域中,然后仅使用这些分量(X')相对于原始数据(X)在时域中显示重构波。我想稍微修改上图,使所有显示的线都覆盖在一个绘图上 我一直在尝试用60Hz采样的一些真实数据来调整这个数字。例如:从R中的离散傅里叶变换重构信号,r,fft,R,Fft,我试图在R中复制下图:(改编自) 该图的基本概念是显示DFT的前几个分量,绘制在时域中,然后仅使用这些分量(X')相对于原始数据(X)在时域中显示重构波。我想稍微修改上图,使所有显示的线都覆盖在一个绘图上 我一直在尝试用60Hz采样的一些真实数据来调整这个数字。例如: ## 3 second sample where: time is in seconds and var is the variable of interest temp = data.frame(time=seq(from=0
## 3 second sample where: time is in seconds and var is the variable of interest
temp = data.frame(time=seq(from=0,to=3,by=1/60),
var = c(0.054,0.054,0.054,0.072,0.072,0.072,0.072,0.09,0.09,0.108,0.126,0.126,
0.126,0.126,0.126,0.144,0.144,0.144,0.144,0.144,0.162,0.162,0.144,0.126,
0.126,0.108,0.144,0.162,0.18,0.162,0.126,0.126,0.108,0.108,0.126,0.144,
0.162,0.144,0.144,0.144,0.144,0.162,0.162,0.126,0.108,0.09,0.09,0.072,
0.054,0.054,0.054,0.036,0.036,0.018,0.018,0.018,0.018,0,0.018,0,
0,0,-0.018,0,0,0,-0.018,0,-0.018,-0.018,0,-0.018,
-0.018,-0.018,-0.018,-0.036,-0.036,-0.054,-0.054,-0.072,-0.072,-0.072,-0.072,-0.072,
-0.09,-0.09,-0.108,-0.126,-0.126,-0.126,-0.144,-0.144,-0.144,-0.162,-0.162,-0.18,
-0.162,-0.162,-0.162,-0.162,-0.144,-0.144,-0.144,-0.126,-0.126,-0.108,-0.108,-0.09,
-0.072,-0.054,-0.036,-0.018,0,0,0,0,0.018,0.018,0.036,0.054,
0.054,0.054,0.054,0.054,0.054,0.054,0.054,0.054,0.054,0.072,0.054,0.072,
0.072,0.072,0.072,0.072,0.072,0.054,0.054,0.054,0.036,0.036,0.036,0.036,
0.036,0.054,0.054,0.072,0.09,0.072,0.036,0.036,0.018,0.018,0.018,0.018,
0.036,0.036,0.036,0.036,0.018,0,-0.018,-0.018,-0.018,-0.018,-0.018,0,
-0.018,-0.036,-0.036,-0.018,-0.018,-0.018,-0.036,0,0,-0.018,-0.018,-0.018,-0.018))
##plot the original data
ggplot(temp, aes(x=time, y=var))+geom_line()
我相信我可以使用fft()
最终实现这个目标,但是从fft()
的输出到我的目标的飞跃有点不清楚
我意识到这个问题有点类似于:但是我对上面特定数据的实际代码更感兴趣
请注意,我对时间序列分析相对较新,因此,如果您能提供w.r.t.将fft()的输出置于上下文中的任何清晰信息,或者您能推荐的能够有效完成此任务的任何软件包,我们将不胜感激
谢谢你Matlab是你最好的工具,具体功能就是fft()。要使用它,首先确定时域数据的几个基本参数: 1,持续时间(T),等于3s 2,采样间隔T_s,等于1/60 s 3,频域旋转fs,等于两个相邻傅里叶基之间的频率差。您可以根据自己的需要定义f_。然而,最小可能的f_s等于1/T=0.333 Hz。因此,如果您想要更好的频域旋转(更小的fs),则需要更长的时域数据 4,最大频率f_M,根据香农抽样理论,它等于1/(2T_s)=30 5,DFT长度N,等于2*f_M/f_s 然后找出你想要用来近似数据的四个傅里叶基的具体频率。例如,3、6、9和12赫兹。因此f_s=3 Hz。然后N=2*f_M/f_s=20 您的Matlab代码如下所示:
var=[0.054,0.054,0.054 ...]; % input all your data points here
f_full=fft(var,20); % Do 20-point fft
f_useful=f_full(2:5); % You are interested with the lowest four frequencies except DC
这里f_有用包含四个傅里叶基的四个复系数。要重建var,请执行以下操作:
% Generate basis functions
dt=0:1/60:3;
df=[3:3:12];
basis1=exp(1j*2*pi*df(1)*dt);
basis2=exp(1j*2*pi*df(2)*dt);
basis3=exp(1j*2*pi*df(3)*dt);
basis4=exp(1j*2*pi*df(4)*dt);
% Reconstruct var
var_recon=basis1*f_useful(1)+...
basis2*f_useful(2)+...
basis3*f_useful(3)+...
basis4*f_useful(4);
var_recon=real(var_recon);
% Plot both curves
figure;
plot(var);
hold on;
plot(var_recon);
将此代码改编为您的论文:)改编我自己的文章。我认为它仍然与Python中的相关
我不是这方面的专家,但有一些有用的例子可以分享 保留的傅里叶分量越多,模拟原始信号的距离就越近 这个例子展示了当你保持10,20,…最多n个组件时会发生什么。假设
x
和y
是您的数据向量
import numpy
from matplotlib import pyplot as plt
n = len(y)
COMPONENTS = [10, 20, n]
for c in COMPONENTS:
colors = numpy.linspace(start=100, stop=255, num=c)
for i in range(c):
Y = numpy.fft.fft(y)
numpy.put(Y, range(i+1, n), 0.0)
ifft = numpy.fft.ifft(Y)
plt.plot(x, ifft, color=plt.cm.Reds(int(colors[i])), alpha=.70)
plt.title("First {c} fourier components".format(c=c))
plt.plot(x,y, label="Original dataset", linewidth=2.0)
plt.grid(linestyle='dashed')
plt.legend()
plt.show()
对于本书的数据集,保留最多4、10和n个组件:
对于数据集,最多保留4、10和n个组件:
谢谢,丹尼尔,这很有帮助。