技术背景

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

Python实现多维傅里叶变换的更多相关文章

  1. Day1 老男孩python自动化运维课程学习笔记

    2017年1月7日老男孩python自动化运维课程正式开课 第一天学习内容: 上午 1.python语言的基本介绍 python语言是一门解释型的语言,与1989年的圣诞节期间,吉多·范罗苏姆为了在阿 ...

  2. python自动化运维学习第一天--day1

    学习python自动化运维第一天自己总结的作业 所使用到知识:json模块,用于数据转化sys.exit 用于中断循环退出程序字符串格式化.format字典.文件打开读写with open(file, ...

  3. 有关python下二维码识别用法及识别率对比分析

    最近项目中用到二维码图片识别,在python下二维码识别,目前主要有三个模块:zbar .zbarlight.zxing. 1.三个模块的用法: #-*-coding=utf-8-*- import ...

  4. 从Scratch到Python——Python生成二维码

    # Python利用pyqrcode模块生成二维码 import pyqrcode import sys number = pyqrcode.create('从Scratch到Python--Pyth ...

  5. python常用运维脚本实例

    转载  file是一个类,使用file('file_name', 'r+')这种方式打开文件,返回一个file对象,以写模式打开文件不存在则会被创建.但是更推荐使用内置函数open()来打开一个文件 ...

  6. 转:python常用运维脚本实例

    python常用运维脚本实例 转载  file是一个类,使用file('file_name', 'r+')这种方式打开文件,返回一个file对象,以写模式打开文件不存在则会被创建.但是更推荐使用内置函 ...

  7. python常用运维脚本实例【转】

    file是一个类,使用file('file_name', 'r+')这种方式打开文件,返回一个file对象,以写模式打开文件不存在则会被创建.但是更推荐使用内置函数open()来打开一个文件 . 首先 ...

  8. 【目录】Python自动化运维

    目录:Python自动化运维笔记 Python自动化运维 - day2 - 数据类型 Python自动化运维 - day3 - 函数part1 Python自动化运维 - day4 - 函数Part2 ...

  9. python自动化运维篇

    1-1 Python运维-课程简介及基础 1-2 Python运维-自动化运维脚本编写 2-1 Python自动化运维-Ansible教程-Ansible介绍 2-2 Python自动化运维-Ansi ...

  10. 用python生成二维码

    Python生成二维码,可以使用qrcode模块, github地址 我是搬运工 首先安装, 因为打算生成好再展示出来,所以用到Pillow模块 pip install qrcode pip inst ...

随机推荐

  1. SUM-ACM,3月24-3-31周报

    两场天梯赛和一场atcoder. 主要错误知识点在于字符串的处理和并查集的掌握不够,不懂灵活运用. 第一场pta天梯赛 7-5 6翻了 一道字符串的题,我只拿了14分.我不熟悉一个点,f(i,0,s. ...

  2. Goutte爬虫

    安装 composer require fabpot/goutte:4.0

  3. 是否可以在线创建ios证书

    生成苹果证书,假如使用官方的教程去生成,非常麻烦,因为它需要使用苹果mac电脑去生成,而且生成的流程还要对苹果电脑的证书导入和导出比较熟. 因此,生成苹果ios证书,不建议使用官方的方法去生成,少走弯 ...

  4. 将txt转化为csv的方法和遇到问题

    一.无法修改扩展名步骤如下 二.转换之后所有数据都挤在第一列 win10系统修改文件扩展名只需4部,打开我的电脑->查看->选择->查看->取消勾选(已知隐藏文件的扩展名)-& ...

  5. 家庭局域网中电脑唤醒 —— WOL远程唤醒(python实现)

    相关: https://blog.csdn.net/hih30250/article/details/136342258 在WOL介绍里说过WOL数据包的最简格式是由6个字节的255和目标计算机的48 ...

  6. 家中局域网搭建nas后的一些体验 —— NAS的速率究竟如何计算

    NAS局域网,使用的路由器的有线端口为1000Mbps,无线WiFi速率860Mbps,不过由于不知道是不是因为电脑WiFi接收器型号老旧还是路由器WiFi协议或天线老旧(电脑和路由器均不支持WiFi ...

  7. NVIDIA 2024 GTC大会提出的数字孪生技术 —— 工厂3D仿真与AI大模型结合

    地址: https://www.youtube.com/watch?v=JQdyzQdMRS0 Fusing Real-Time AI With Digital Twins 使用NVIDIA的3D仿真 ...

  8. 【转载】Ubuntu20.04安装Bazel

    原文地址: https://zhuanlan.zhihu.com/p/311406177 ====================================== sudo apt install ...

  9. 使用tensorbaoardx报错——Descriptors cannot not be created directly. If this call came from a _pb2.py file, your generated code is out of date and must be regenerated with protoc >= 3.19.0.

    运行代码报错: from tensorboardX import SummaryWriter 报错内容: 发生异常: TypeError Descriptors cannot not be creat ...

  10. 如何在 Recovery 中启用应用

    如果因为禁用了某个应用手机无法开机,那么你需要这个方法来救命 https://xdaforums.com/t/enable-or-disable-apps-directly-from-the-file ...