首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

Python实现多维傅里叶变换

编程知识
2024年09月26日 10:04

技术背景

在前面一篇文章中,我们介绍了一维离散傅里叶变换和快速傅里叶变换的基本原理和简单的代码实现。本文补充一个多维傅里叶变换的场景,以及简单的Python实现。

二维傅里叶变换

首先回顾一下上一篇文章中介绍的一维傅里叶变换与逆傅里叶变换的形式:

\[y_k=\sum_{n=0}^{N-1}x_ne^{-j\frac{2\pi nk}{N}},0\leq k\leq N-1\\ x_n=\frac{1}{N}\sum_{k=0}^{N-1}y_ke^{j\frac{2\pi nk}{N}},0\leq n\leq N-1 \]

那么首先我们通过前面一篇文章中的简单DFT实现来理解一下一维傅里叶变换的物理图像:

import numpy as np

def dft(x):
    y = np.zeros_like(x, dtype=np.complex64)
    N = x.shape[0]
    for k in range(N):
        y[k] = np.sum(x * np.exp(-1j*2*np.pi*k*np.arange(N)/N))
    return y

我们先不讨论时域和频域的概念,这里只有输入x和输出y,那么每一点的y的数据,都是通过一系列的参数矢量与x矢量的内积。换句话说,x上的每一个数据点都对y的每一个数据点有贡献,这个贡献的大小通过傅里叶变换的参数来给定:

那么高维傅里叶变换,其实就是按顺序在每个维度上做内积:

对应的代数形式为:

\[y_{k_1,k_2}=\sum_{n_2=0}^{D-1}e^{-j\frac{2\pi n_2k_2}{D}}\sum_{n_1=0}^{N-1}x_{n_1,n_2}e^{-j\frac{2\pi n_1k_1}{N}},0\leq k_1,k_2\leq N-1\\ x_{n_1,n_2}=\frac{1}{D}\sum_{k_2=0}^{D-1}e^{j\frac{2\pi n_2k_2}{D}}\frac{1}{N}\sum_{k_1=0}^{N-1}y_{k_1,k_2}e^{j\frac{2\pi n_1k_1}{N}},0\leq n_1,n_2\leq N-1 \]

至于更高维度的傅里叶变换,就是继续增加求和的维度。也有一种常见的写法是采用归一化的矢量内积形式:

\[y_{\vec{k}}=\sum_{\vec{n}}e^{-2j\pi\vec{k}\cdot\vec{n}}x_{\vec{n}} \]

至于FFT的形式,只是对其中的特定维度进行分解,这里不做更多分析,可以直接看一下多维DFT的一个简单实现。

Python代码实现

这里使用Python实现一个最简单的二维傅里叶变换和逆傅里叶变换,没有经过任何的优化:

import numpy as np

def dftn(x):
    y = np.zeros_like(x, dtype=np.complex64)
    N = x.shape[0]
    D = x.shape[1]
    for k1 in range(N):
        for k2 in range(D):
            for n1 in range(N):
                for n2 in range(D):
                    y[k1][k2] += np.exp(-2j*np.pi*(k2*n2)/D)* np.exp(-2j*np.pi*(k1*n1)/N) * x[n1][n2]
    return y

def idftn(y):
    x = np.zeros_like(y, dtype=np.complex64)
    N = y.shape[0]
    D = y.shape[1]
    for n1 in range(N):
        for n2 in range(D):
            for k1 in range(N):
                for k2 in range(D):
                    x[n1][n2] += np.exp(2j*np.pi*(k2*n2)/D) * np.exp(2j*np.pi*(k1*n1)/N) * y[k1][k2] / N / D
    return x

N = 16
x = np.random.random((N, 3)).astype(np.float32)
y0 = dftn(x)
y1 = np.fft.fft2(x)
x0 = idftn(y1)
x1 = np.fft.ifft2(y0)
print (np.allclose(y0, y1))
print (np.allclose(x0, x1))
# True
# True

经过和numpy中实现方式的对比,两边结果一致。

总结概要

继前一篇文章中的一维傅里叶变换,本文介绍了多维傅里叶变换的物理图像和基本原理,并附带了Python简单实现。并将Python的计算结果与Numpy中已经实现的二维傅里叶变换的结果进行对比。

版权声明

本文首发链接为:https://www.cnblogs.com/dechinphy/p/fftn.html

作者ID:DechinPhy

更多原著文章:https://www.cnblogs.com/dechinphy/

请博主喝咖啡:https://www.cnblogs.com/dechinphy/gallery/image/379634.html

From:https://www.cnblogs.com/dechinphy/p/18432936/fftn
本文地址: http://www.shuzixingkong.net/article/2311
0评论
提交 加载更多评论
其他文章 ShiftAddAug:基于乘法算子训练的最新无乘法网络方案 | CVPR'24
不包含乘法的运算符,如移位和加法,因其与硬件的兼容性而日益受到重视。然而,采用这些运算符的神经网络(NNs)通常表现出比具有相同结构的传统NNs更低的准确性。ShiftAddAug利用成本较高的乘法来增强高效但功能较弱的无乘法运算符,从而在没有任何推理开销的情况下提高性能。将一个ShiftAdd小型
ShiftAddAug:基于乘法算子训练的最新无乘法网络方案 | CVPR'24 ShiftAddAug:基于乘法算子训练的最新无乘法网络方案 | CVPR'24 ShiftAddAug:基于乘法算子训练的最新无乘法网络方案 | CVPR'24
数据结构 - 数组
学习数组,需掌握其ADT定义。数组为同类型元素序列,具固定长度、连续内存、类型相同、索引从0起等特性。通过ADT定义数组,实现类包含内存管理和长度字段,支持初始化、获取/设置元素、插入/删除及释放内存等操作。掌握数据结构需理解其定义并实现。
数据结构 - 数组 数据结构 - 数组
logisim学习感想(持续更新)
状态机类型 存在两种类型的状态机,分别为mealy型状态机和moore型状态机,在实验中,二者的大体实现如下: 其中从输入到输出的连线只有mealy状态机才有,而moore型则无此线。 区分两种类型的状态机的方法 mealy的输出由输入和当前状态决定;moore的输出只由当前状态决定 具体体现在时序
logisim学习感想(持续更新) logisim学习感想(持续更新) logisim学习感想(持续更新)
IDEA如何查看每一行代码的提交记录(人员,时间)
前言 我们在使用IDEA开发时,一般需要使用git来管理我们的代码,而且大家协同开发。 有时候,我们在开发的时候,经常需要看一下当前的代码时谁开发的,除了看类上面的作者外,更精细的方式是看每一行代码的提交记录。 那么,我们该怎么查看呢? 如何查看 首先,我们需要保证我们的代码是有git来管理的。 然
IDEA如何查看每一行代码的提交记录(人员,时间) IDEA如何查看每一行代码的提交记录(人员,时间) IDEA如何查看每一行代码的提交记录(人员,时间)
对 LLM 工具使用进行统一
我们为 LLM 确立了一个跨模型的 统一工具调用 API。有了它,你就可以在不同的模型上使用相同的代码,在 Mistral、Cohere、NousResearch 或 Llama 等模型间自由切换,而无需或很少需要根据模型更改工具调用相关的代码。此外,我们还在 transformers 中新增了一些
如何创建一个Java游戏客户端
本文简要介绍了Java如何创建一个游戏客户端,本文介绍了创建一个完整的Java游戏客户端示例是一个相对复杂的任务,因为它通常涉及图形用户界面(GUI)、事件处理、游戏逻辑等多个方面。为了简化,我将提供一个基于Java Swing的简单游戏客户端示例:一个简易的“猜数字”游戏。这个游戏将随机生成一个1
.NET 工具库高效生成 PDF 文档
前言 QuestPDF 是一个开源 .NET 库,用于生成 PDF 文档。使用了C# Fluent API方式可简化开发、减少错误并提高工作效率。利用它可以轻松生成 PDF 报告、发票、导出文件等。 项目介绍 QuestPDF 是一个革命性的开源 .NET 库,它彻底改变了我们生成 PDF 文档的方
.NET 工具库高效生成 PDF 文档 .NET 工具库高效生成 PDF 文档 .NET 工具库高效生成 PDF 文档
三大硬核方式揭秘:Java如何与底层硬件和工业设备轻松通信!
大家好,我是V哥,程序员聊天真是三句不到离不开技术啊,这不前两天跟一个哥们吃饭,他是我好多年前的学员了,一直保持着联系,现在都李总了,在做工业互联网相关的项目,真是只要 Java 学得好,能干一辈子,卷死的是那些半吊子。 感谢李总给我分享了工业互联网项目的事情,收获很多,今天的内容来聊一聊 Java