计算物理专题:傅里叶变换与快速傅里叶变换

计算物理专题:傅里叶变换与快速傅里叶变换

  • 傅里叶变换提供一个全新的角度去观察和描述问题,如在量子力学中,动量与坐标表象之间的变换就是傅里叶变换。傅里叶变换同意可以用在数据处理等领域。
  • 1965年,Cooley 和 Tukey 提出了快速傅里叶算法,将计算一个N点变换的工作量由N^2 降低至 N log_2N

傅里叶变换(FT)

  • 一个波形的傅里叶变换就是把这个波形分解成多个不同频率的正弦波之和。设h(t) 是一个给定的波形,其傅里叶积分为 : H(f) = \int_{-\infty}^{+\infty} h(t) exp(-i 2\pi f t)dt 
  • 傅里叶变换的逆变换 h(t) = \int_{-\infty}^{+\infty} H(f) exp(i2\pi f t)df
  • 傅里叶变换例题:

\begin{matrix} h(t)=\left\{\begin{matrix} A &(|t|\leq T_0) \\ 0 &(|t|>T_0) \end{matrix}\right.\\ \\ H(f)=\int_{-T_0}^{T_0}Ae^{-i2\pi ft}dt\\ =\frac{A}{\pi T_0}sin(2\pi fT_0) \end{matrix}(1)

\begin{matrix} h(t)=Acos(2\pi f_0 t)\\ H(f)=\frac{A}{2}(\delta(f-f_0)+\delta(f+f_0)) \end{matrix}(2)

离散傅里叶变换(DFT)

  • discrete_fourier_transform
  • 在计算机上做傅里叶变换必须对傅里叶变换做离散化处理。离散傅里叶变换一般视作抽样后的波形的连续傅里叶变换
  • 设函数 f(x) 在区间 0<= x <= 2\pi 上N个等分点 2\pi l/N 处的值已知,用已知周期为2\pi 的函数exp(ikx)的线性组合做 f(x) 在此区间上的三角插值函数,f(x) = \sum_{k=0}^{N-1} F_k exp(ikx)
    • 并且 f(2\pi l/N) = \sum_{k=0}^{N-1} F_k exp(i2\pi kl/N),F_k 一般为一个复数
  • 离散傅里叶变换一般具有两个性质

\begin{matrix} \sum_{k=0}^{N-1}e^{ik2\pi/N}e^{-ik2\pi/N}=N \\ \sum_{k=0}^{N-1}e^{ijk2\pi/N}e^{-ilk2\pi/N}=0(l\neq j) \end{matrix}

  • 离散傅里叶变换有公式如下:

F_k=\frac{1}{N}\sum_{l=0}^{N-1}f(2l\pi/N)e^{-ikl2\pi/N}

离散傅里叶变换的Python 实现

import numpy as npdef DFT(x,threshold=False):N = len(x)FKR = np.zeros(N)FKI = np.zeros(N)for k in range(N):Fk_r,Fk_i = 0.0,0.0for l in range(N):angle = 2 * np.pi * k * l / NFk_r += x[l] * np.cos(angle)Fk_i -= x[l] * np.sin(angle)FKR[k] = Fk_rFKI[k] = Fk_iif threshold:for i in range(N):if abs(FKR[i])<threshold:FKR[i] = 0.0FKR[i] = round(FKR[i],5)if abs(FKI[i])<threshold:FKI[i] = 0.0FKI[i] = round(FKI[i],5)return FKR,FKI#testing
threshold = 1e-5# sin(x) example:
N = 10
X = [np.sin(i*2*np.pi/N) for i in range(N)]
FKR,FKI = DFT(X,threshold = 1e-5)#standard output
for i in range(len(FKR)):print(f"FK[{i}] = {FKR[i]} + {FKI[i]}j")

快速傅里叶变换(FFT)

  • 注意到F_k表达式中exp(-ikl2\pi /N)的周期性,就会发先这N个F_k 中N^2个不同的项中只有N个是不同的,即:1,exp[-i2\pi/N],exp[-i4\pi/N]......
  • 快速傅里叶算法将各项先按 exp[-ik2\pi/N]归类与合并同类项,从而将操作数从N^2 减少到 Nlog_2 N 

  • 设 N = 2^k(pos int) ,令 W = exp(-i2\pi/N) ,则W^N = 1,若记:f_l = f(2\pi l/N)/N
  • 则离散傅里叶变换的两个性质可以改写为:  

F_j = \sum_{l=0}^{N-1}f_lW^{jl}(j=0,1,...,N-1) 

\begin{matrix} F_{2j_1}=\sum_{l=0}^{N/2-1}(f_l+f_{l+N/2})(W^2)^{j_1l}\\ F_{2j_1+1}=\sum_{l=0}^{N/2-1}(f_l-f_{l+N/2})W^l(W^2)^{j_1l} \end{matrix}

快速傅里叶变换的Python实现

import numpy as npdef FFT(x):N = len(x)assert (N&(N-1))==0,f"{N} is not a power of 2"if N <= 1:return xeven = FFT(x[0::2])odd  = FFT(x[1::2])T = [np.exp(-2j * np.pi * k/N) * odd[k] for k in range(N//2)]return [even[k] + T[k] for k in range(N//2)] + [even[k] - T[k] for k in range(N//2)]# example
Num = 16
x = [np.sin(j*2*np.pi/Num) for j in range(Num)]
result = FFT(x)FKR = [np.real(c) for c in result]
FKI = [np.imag(c) for c in result]

快速傅里叶变换的C语言实现

#include <stdio.h>
#include <math.h>#define PI 3.14159265358979struct Complex 
{double real;double imag;
};void FFT(struct Complex x[], int N)
{if (N <= 1)return ;struct Complex even[N/2], odd[N/2];for (int i = 0; i < N/2; i++) {even[i] = x[2*i];odd[i] = x[2*i + 1];}FFT(even,N/2);FFT(odd, N/2);for (int k = 0; k < N/2; k++) {double angle = -2 * PI * k / N;        x[k].real = even[k].real + cos(angle) * odd[k].real + sin(angle) * odd[k].imag;x[k].imag = even[k].imag + cos(angle) * odd[k].imag - sin(angle) * odd[k].real;x[k + N/2].real = even[k].real - cos(angle) * odd[k].real + sin(angle) * odd[k].imag;x[k + N/2].imag = even[k].imag - cos(angle) * odd[k].imag - sin(angle) * odd[k].real;}
}int main()
{int N = 8;struct Complex x[N] = {{1,0}, {0,0}, {1,0},{0,0}, {1,0}, {0,0}, {1,0}, {0,0}};FFT(x,N);printf("FFT result:\n");for (int i = 0; i < N; i++) {printf("FK[%d] = %.2f + %.2f i\n",i,x[i].real,x[i].imag);}
}
  • 在编程中最复杂的就是处理复数的问题,一般使用新的struct 或者只能开动脑筋了用多个列表代替了,那样肯定会更加复杂和头晕。

傅里叶变换的应用举例

振荡频率的处理

import numpy as np
import matplotlib.pyplot as pltFs = 1000   #采样率
T = 1 / Fs  #采样间隔
L = 1000    #数据长度A1 = 1
A2 = 2
A3 = 40f1 = 50
f2 = 120
f3 = 400t = np.arange(0,L)*T  # 时间序列
data = A1 * np.sin(2*np.pi * f1 *t) +\A2 * np.sin(2*np.pi * f2 *t) +\A3 * np.sin(2*np.pi * f3 *t)#FFT变换
fft_result = np.fft.fft(data)
#频率轴
frequencies = np.fft.fftfreq(len(data),T)N = len(frequencies)
N = N //2
frequencies = frequencies[:N]
fft_result = fft_result[:N]
Norm = np.linalg.norm(np.abs(fft_result))
fft_result = np.abs(fft_result)/Normplt.plot(frequencies,fft_result)
plt.xlabel("Frequency(Hz)")
plt.ylabel("Amplitude(normalized)")
plt.pause(0.01)Nmax = 3
max_indices = np.argsort(fft_result)[::-1][:Nmax]
# 对应的频率和幅度比例
main_frequencies = frequencies[max_indices]
main_amplitudes = fft_result[max_indices]
main_amplitudes = [i/min(main_amplitudes) for i in main_amplitudes]
print("主要频率:", main_frequencies)
print("对应幅度比例:", main_amplitudes)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/4889.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF中的Behavior及Behavior在MVVM模式下的应用

WPF中的Behavior及Behavior在MVVM模式下的应用 在WPF中&#xff0c;Behaviors&#xff08;行为&#xff09;是一种可重用的组件&#xff0c;可以附加到任何UI元素上&#xff0c;以添加特定的交互行为或功能。Behaviors可以通过附加属性或附加行为的方式来实现。 Behavior并不…

大厂月入3w+,失业焦虑折磨着我

大家好&#xff0c;这里是程序员晚枫&#xff0c;小红书也叫这个名字。 周末和一位老朋友聚会&#xff0c;聊了聊一个很现实的收入问题&#xff0c;巧合的是&#xff1a;他的焦虑&#xff0c;竟然和月薪5k的我一模一样。 今天给大家分享一下。 1、外人看来&#xff0c;让人羡…

在 Linux 中配置 IPv4 和 IPv6 地址详解

概要 IPv4和IPv6是Internet上常用的两种IP地址协议。在Linux系统中&#xff0c;您可以通过配置网络接口来设置IPv4和IPv6地址。本文将详细介绍如何在Linux中配置IPv4和IPv6地址。 步骤 1&#xff1a;确定网络接口 在开始配置IP地址之前&#xff0c;您需要确定要配置的网络接口…

吴恩达ChatGPT《LangChain for LLM Application Development》笔记

基于 LangChain 的 LLM 应用开发 1. 介绍 现在&#xff0c;使用 Prompt 可以快速开发一个应用程序&#xff0c;但是一个应用程序可能需要多次写Prompt&#xff0c;并对 LLM 的输出结果进行解析。因此&#xff0c;需要编写很多胶水代码。 Harrison Chase 创建的 LangChain 框…

初步认识Java垃圾回收算法

GCRoot指被栈上直接或间接引用的对象&#xff0c;或被本地方法栈直接或间接引用的对象&#xff0c;或被方法区引用的对象。 被引用的对象是不能被删除的。 如果对象跟GCRoot并没有直接或间接相连的关系&#xff0c;那么这些对象就可以被删除了。 标记-清理&#xff1a;将需要删…

基于FPGA的RC滤波器设计实现

目录 简介&#xff1a; 传递函数 FPGA代码实现 总结 简介&#xff1a; RC滤波器的特性基本情况介绍 RC一阶低通滤波介绍&#xff1b;RC滤波器电路简单&#xff0c;抗干扰性强&#xff0c;有较好的低频性能&#xff0c;并且选用标准的阻容元件易得&#xff0c;所以在工程测…

GAMES101 笔记 Lecture08 Shading 2(Shading, Pipeline and Texture Mapping)

目录 Specular Term(高光项)Ambient Term(环境光照项)Blinn-Phong Reflection ModelShading Frequencies(着色频率)Shade each triangle(flat shading)在每个三角形上进行着色Shade each vertex (Gouraud shading)(顶点着色)Shade each pixel (Phong shading)Defining Per-Vert…

ES基本操作(JavaAPI篇)

引入jar包依赖 <dependencies><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.8.0</version></dependency><!-- es客户端 --><dependency><groupI…

Loadrunner怎么实现MD5加密

目录 前言&#xff1a; 1、写一个md5.h文件&#xff0c;将其放入脚本路径下 2、在globals.h中加入#include “md5.h” 3、在Action中写脚本&#xff0c;脚本示例如下&#xff1a; 前言&#xff1a; 在 LoadRunner 中实现 MD5 加密可以通过使用 LoadRunner 提供的函数来完成…

【FPGA零基础学习之旅#9】状态机基础知识

&#x1f389;欢迎来到FPGA专栏~状态机基础知识 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;FPGA学习之旅 文章作者技术和水平有限&#xff0c;如果文中出现错误&#xff0c;希望大家能指正…

macOS Ventura 13.5beta4(22G5059d)发布

系统介绍 黑果魏叔 6 月 28 日消息&#xff0c;苹果今日向 Mac 电脑用户推送了 macOS 13.5 开发者预览版 Beta 4 更新&#xff08;内部版本号&#xff1a;22G5059d&#xff09;&#xff0c;本次更新距离上次发布隔了 12 天。 macOS Ventura 带来了台前调度、连续互通相机、F…

TypeScript ~ 掌握基本类型 ②

作者 : SYFStrive 博客首页 : HomePage &#x1f4dc;&#xff1a; TypeScript ~ TS &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f4cc;&#xff1a;觉得文章不错可以点点关注 &…