技术背景

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

    集群及分布式定时任务中间件MEE_TIMED 转载请著名出处:https://www.cnblogs.com/funnyzpc/p/18312521 MEE_TIMED一套开源的定时任务中间件,MEE ...

  2. 深入理解Spring Boot:Bean管理、原理解析与Maven高级应用

    深入理解Spring Boot:Bean管理.原理解析与Maven高级应用 前言 大家好,今天我们来聊聊Spring Boot的核心内容,包括Bean管理.Spring Boot的工作原理以及Mave ...

  3. selenium高亮显示定位到的页面元素

    from selenium import webdriver import unittest,time def highLightElement(driver,element): #封装好的高亮显示页 ...

  4. Python 实现行为驱动开发 (BDD) 自动化测试详解

    ​ 在当今的软件开发领域,行为驱动开发(Behavior Driven Development,BDD)作为一种新兴的测试方法,逐渐受到越来越多开发者的关注和青睐.Python作为一门功能强大且易于使 ...

  5. docker 容器挂载技术

    创建和使用桥接网络 docker network create --driver bridge --subnet 192.168.13.0/24 --gateway 192.168.13.1 mqyn ...

  6. 遗传算法和神经网络融合算法:GA-BP算法流程图

    相关: https://d.wanfangdata.com.cn/periodical/sxgcxb202109004

  7. Regardless of the outcome of the Russia-Ukraine war, how can Ukraine avoid paying the weapon fees to the United States after the war?

    According to the agreement between the Ukrainian government and the United States, regardless of the ...

  8. 深度学习需要float64精度吗 —— 为什么各大深度学习框架均不支持float64的深度学习运算呢 —— 商用NVIDIA显卡的float64性能是否多余呢

    首先要知道这么几个事实,也是交代一下本文要讨论的问题的背景: 各大深度学习框架均支持float64类型的简单运算,但是均不支持float64的深度学习的运算操作: 作为深度学习运行的加速设备,各种GP ...

  9. 【转载】 PyTorch下训练数据小文件转大文件读写(附有各种存储格式对比)

      版权声明:本文为CSDN博主「Liekkas Kono」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明.原文链接: https://blog.csdn.net/s ...

  10. [COCI2013-2014#6] KRUŽNICE 题解

    前言 题目链接:洛谷. 题目分析 显然,手模样例发现答案分为以下几个贡献: 所有圆外面的那个大平面,贡献为 \(1\). 每个圆至少被分成一部分,贡献为 \(n\). 如果有一个圆被"拦腰截 ...