利用傅里叶变换求信号波动性

最近在研究如何分析一维曲线的波动情况。如何定义波动见仁见智。我先定义什么叫完美的波动。

事实上,我可以认为正弦/余弦函数即为完美的波动。如果我将正弦/余弦的波动性定义为1,那么其它曲线越与正余弦函数相似,其波动性越接近于1,反之越接近于0。事实上,傅里叶变换即可近似地做到这一点。下面是我的尝试。

import numpy as np
import matplotlib.pyplot as plt

A = 1       # A为振幅。我们希望波动性与振幅无关
n = 2       # 基频倍数。我们希望波动性与波动周期也无关
t = np.linspace(0, 2*np.pi, 1000)
x = A * np.sin(n*t)

plt.plot(t, x, 'b-')
plt.show()

请添加图片描述

def my_fft(x):
    """
    计算信号的傅里叶变化,返回其能量谱
    :param x: 信号
    :return: 能量谱
    """
    half_ppv = (np.max(x) - np.min(x))/2
    fourier_transform = np.fft.rfft(x)
    power_specturm =np.abs(fourier_transform)/len(x)/half_ppv  # 注意要除以信号长度以及幅值
    id = np.argmax(power_specturm)
    print(f"最大频谱能量位置:{id}, 最大频谱能量为:{power_specturm[id]}")
    plt.plot(power_specturm)
    plt.show()
    return power_specturm

y = my_fft(x)
最大频谱能量位置:2, 最大频谱能量为:0.4997471913220719

请添加图片描述

可以看到,最大频谱所处的位置为2(从0开始计数), 这对应了基频倍数。可以看到此时的最大频谱能量为0.5。由于我们希望波动性为1,因此定义波动性为:

def wave_coeff(x) -> float:
    return 2*np.max(my_fft(x))

wc = wave_coeff(x)
print(f"wave coeff: {wc:.2f}")
最大频谱能量位置:2, 最大频谱能量为:0.4997471913220719

请添加图片描述

wave coeff: 1.00

下面来验证,幅值A和基频倍数n是否对波动性没有影响。

A = 3
n = 2
x = A * np.sin(n*t)
wc = wave_coeff(x)
print(f"wave coeff: {wc:.2f}")
最大频谱能量位置:2, 最大频谱能量为:0.4997471913220718

请添加图片描述

wave coeff: 1.00
A = 2
n = 3
x = A * np.sin(n*t)
wc = wave_coeff(x)
print(f"wave coeff: {wc:.2f}")
最大频谱能量位置:3, 最大频谱能量为:0.4997480067898512

请添加图片描述
wave coeff: 1.00

可以看到,最大频谱能量的位置发生了变化,但是最大频谱能量没有发生变化;波动系数也未发生变化。

源码链接:https://github.com/zhongcheng0519/algorithm-fundamental/blob/main/fourier1d.ipynb

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值