0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

看完學(xué)會(huì)速傅立葉變換FFT

jf_78858299 ? 來(lái)源:ACM算法日常 ? 作者: Xiejiadong ? 2023-05-05 09:48 ? 次閱讀

FFT 即快速傅立葉變換。在很多計(jì)算機(jī)領(lǐng)域都用用處,例如數(shù)字圖像處理、計(jì)算機(jī)網(wǎng)絡(luò)。但他在算法競(jìng)賽中主要是用于多項(xiàng)式和生成函數(shù)相關(guān)的題目。

多項(xiàng)式

表達(dá)方式

簡(jiǎn)介

  • 系數(shù)表達(dá)式,即。
  • 坐標(biāo)形式。每一個(gè)坐標(biāo)用表示。顯然,為了能夠表示一個(gè)確定的多項(xiàng)式,需要個(gè)不同的坐標(biāo)來(lái)表示。

比較

  • 對(duì)于系數(shù)表示,多項(xiàng)式加法的時(shí)間復(fù)雜度是,多項(xiàng)式乘法的時(shí)間復(fù)雜度是。
  • 對(duì)于點(diǎn)值表示,多項(xiàng)式加法的時(shí)間復(fù)雜度同樣是,但是乘法的時(shí)間復(fù)雜度就是(因?yàn)槎囗?xiàng)式乘法以后最高項(xiàng)次數(shù)為,我們只需要個(gè)坐標(biāo)表示)。

思考

這樣一來(lái),我們就有一個(gè)想法,多項(xiàng)式乘法,是不是可以利用坐標(biāo)表示做多項(xiàng)式乘法特別快這點(diǎn)來(lái)優(yōu)化算法。

于是需要解決的最大的問(wèn)題就是,多項(xiàng)式兩種表示方法之間的互相轉(zhuǎn)換。

求值樸素做法的時(shí)間復(fù)雜度是,即隨便選取一個(gè)值帶入,暴力計(jì)算。

差值樸素的做法時(shí)間復(fù)雜度是,即根據(jù)坐標(biāo)進(jìn)行高斯消元。

在介紹 FFT 之前,得先學(xué)習(xí) DFT (離散傅里葉變換)算法。

DFT

由于對(duì)一個(gè)多項(xiàng)式的點(diǎn)值表達(dá)式的取是任意的,所以好的取法可能會(huì)使一個(gè)算法產(chǎn)生本質(zhì)性的蛻變。

我們選取次單位復(fù)根作為來(lái)取值。

單位復(fù)根

,這個(gè)方程的復(fù)數(shù)根為次單位根。

單位的個(gè)單位根分別為。

個(gè)單位根在復(fù)平面的坐標(biāo)表示為,我們將這個(gè)記為。在復(fù)平面上形象的表示的話,就是下圖:

圖片

單位根在多項(xiàng)式的應(yīng)用

我們將個(gè)單位根帶入多項(xiàng)式可以得到個(gè)因變量結(jié)果,記為。

我們將個(gè)單位根的倒數(shù)作為自變量帶入由作為系數(shù)的多項(xiàng)式,可以得到。

而當(dāng)?shù)臅r(shí)候,它為,其余時(shí)候,它為(通過(guò)等比數(shù)列求和)。于是有。

于是可以發(fā)現(xiàn),將個(gè)單位根的倒數(shù)帶入變換后的多項(xiàng)式,可以得到原來(lái)的多項(xiàng)式。

這樣一來(lái),我們利用個(gè)單位根的性質(zhì),完成了多項(xiàng)式兩種表示方式之間的轉(zhuǎn)換。

DFT算法

有了的取值,我們就可以得到的取值了。

。

直接暴力計(jì)算,兩個(gè)方向轉(zhuǎn)換的時(shí)間復(fù)雜均為。

FFT

那么 FFT 算法是如何優(yōu)化計(jì)算這一過(guò)程的?利用分治。

我們把一個(gè)多項(xiàng)式的計(jì)算分為偶數(shù)項(xiàng)的計(jì)算和奇數(shù)項(xiàng)的計(jì)算:

也就是說(shuō), FFT 的思想就是不斷得把一個(gè)多項(xiàng)式拆分成奇數(shù)多項(xiàng)式和偶數(shù)多項(xiàng)式,然后合并兩個(gè)多項(xiàng)式的信息。

也就是說(shuō),如果我們已經(jīng)得到了和,我們只需要就可以得到了。

每次都能把多項(xiàng)式的長(zhǎng)度減小一半,于是時(shí)間復(fù)雜度就是。

模版

C++ 是自帶了復(fù)數(shù) stl 的,即:

#include

但是常數(shù)大,跑得慢,不如自己重載的好。

  • 下面的模版必須要保證是的整數(shù)次冪。
typedef double LD;
const LD PI = acos(-1);
struct C {
    LD r, i;
    C(LD r = 0, LD i = 0): r(r), i(i) {}
};
C operator + (const C& a, const C& b) {
    return C(a.r + b.r, a.i + b.i);
}
C operator - (const C& a, const C& b) {
    return C(a.r - b.r, a.i - b.i);
}
C operator * (const C& a, const C& b) {
    return C(a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r);
}

void FFT(C x[], int n, int p) {
    for (int i = 0, t = 0; i < n; ++i) {
        if (i > t) swap(x[i], x[t]);
        for (int j = n >> 1; (t ^= j) < j; j >>= 1);
    }
    for (int h = 2; h <= n; h <<= 1) {
        C wn(cos(p * 2 * PI / h), sin(p * 2 * PI / h));
        for (int i = 0; i < n; i += h) {
            C w(1, 0), u;
            for (int j = i, k = h >> 1; j < i + k; ++j) {
                u = x[j + k] * w;
                x[j + k] = x[j] - u;
                x[j] = x[j] + u;
                w = w * wn;
            }
        }
    }
    if (p == -1)
        FOR (i, 0, n)
            x[i].r /= n;
}

void conv(C a[], C b[], int n) {
    FFT(a, n, 1);
    FFT(b, n, 1);
    FOR (i, 0, n)
        a[i] = a[i] * b[i];
    FFT(a, n, -1);
}

例題

A * B II

https://acm.ecnu.edu.cn/problem/3007/

大整數(shù)相乘。

把每一位都看成是多項(xiàng)式其中一項(xiàng)的系數(shù),那么大數(shù)最后的結(jié)果也就是多項(xiàng)式乘法系數(shù)的結(jié)果。

要進(jìn)位處理。

Hnoi2017 禮物

顯然是要計(jì)算的最小值,其中$0≤x

展開(kāi)這個(gè)式子,

除了,其他的和與相關(guān)的項(xiàng)都可以在的時(shí)間內(nèi)算出了

那么配個(gè)方,就可以求出最小值了,而是固定的

現(xiàn)在的問(wèn)題就是求,我們可以用FFT來(lái)解決

如果我們把多項(xiàng)式倒置,我們就能發(fā)現(xiàn)式子的和的下標(biāo)和可以相同,我們可以利用多項(xiàng)式乘法同時(shí)算出卷積。

設(shè),那么,這樣就可以用FFT算出來(lái)了

總的時(shí)間復(fù)雜度

#include
#define inf 0x3fffffff
using namespace std;

typedef double LD;
const LD PI=acos(-1);
struct C
{
    LD r,i;
    C(LD r=0,LD i=0):r(r),i(i){}
};
C operator + (const C& a, const C& b){
    return C(a.r+b.r,a.i+b.i);
}
C operator - (const C& a, const C& b){
    return C(a.r-b.r,a.i-b.i);
}
C operator * (const C& a, const C& b){
    return C(a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r);
}
 
void FFT(C x[],int n,int p)
{
    for (int i=0,t=0;i
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 圖像處理
    +關(guān)注

    關(guān)注

    27

    文章

    1275

    瀏覽量

    56577
  • FFT
    FFT
    +關(guān)注

    關(guān)注

    15

    文章

    433

    瀏覽量

    59256
  • 計(jì)算機(jī)網(wǎng)絡(luò)

    關(guān)注

    3

    文章

    335

    瀏覽量

    22101
  • 傅立葉變換
    +關(guān)注

    關(guān)注

    3

    文章

    99

    瀏覽量

    32333
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    快速傅立葉變換(FFT)算法實(shí)驗(yàn)

    本帖最后由 mr.pengyongche 于 2013-4-30 02:23 編輯 快速傅立葉變換(FFT)算法實(shí)驗(yàn)一、摘
    發(fā)表于 12-21 10:54

    如何使用快速傅立葉變換FFT)的8590 C/E/L系列頻譜分析儀中的FFT函數(shù)?

    本產(chǎn)品說(shuō)明說(shuō)明了如何使用快速傅立葉變換FFT)的8590 C/E/L系列頻譜分析儀中的FFT函數(shù)。FFT通過(guò)提供智能用戶(hù)界面簡(jiǎn)化了AM分析
    發(fā)表于 04-04 16:50

    淺懂示波器FFT快速傅立葉變換功能及運(yùn)用

    大多數(shù)示波器上都有個(gè)FFT功能,也叫快速傅立葉變換,但很多人不了解這個(gè)功能是做什么用的,百度以后又會(huì)遇到各種各樣的高數(shù)公式,看的一頭霧水,遂而放棄這塊知識(shí)。我們來(lái)看百度百科的解釋?zhuān)?b class='flag-5'>FFT
    發(fā)表于 01-14 17:00

    示波器FFT快速傅立葉變換不會(huì)用?看完這篇帖子,我徹底悟了

    大多數(shù)示波器上都有個(gè)FFT功能,也叫快速傅立葉變換,但很多人不了解這個(gè)功能是做什么用的,百度以后又會(huì)遇到滿屏的高數(shù)公式,看得一頭霧水,繼而以放棄告終。先來(lái)看看百度百科對(duì)FFT的解釋?zhuān)?/div>
    發(fā)表于 09-22 13:42

    快速傅立葉變換開(kāi)發(fā)指南

    快速傅立葉變換開(kāi)發(fā)指南:The Xilinx® LogiCORE™ IP Fast Fourier Transform (FFT) is a computationally
    發(fā)表于 12-31 15:19 ?35次下載

    快速傅立葉變換FFT)的Nios II實(shí)現(xiàn)

    快速傅立葉變換FFT)的Nios II實(shí)現(xiàn) 隨著數(shù)字電子技術(shù)的發(fā)展,數(shù)字信號(hào)處理的理論和技術(shù)廣泛地應(yīng)用于通訊、語(yǔ)音處理、計(jì)算機(jī)和多媒體等領(lǐng)域??焖俑道锶~
    發(fā)表于 02-09 09:38 ?81次下載

    基于FPGA的快速傅立葉變換

    摘要:在對(duì)FFT(快速傅立葉變換)算法進(jìn)行研究的基礎(chǔ)上,描述了用FPGA實(shí)現(xiàn)FFT的方法,并對(duì)其中的整體結(jié)構(gòu)、蝶形單元及性能等進(jìn)行了分析。
    發(fā)表于 06-20 14:13 ?1095次閱讀

    1024點(diǎn)FFT快速傅立葉變換

    Xilinx FPGA工程例子源碼:1024點(diǎn)FFT快速傅立葉變換
    發(fā)表于 06-07 14:13 ?33次下載

    Xilinx 的IP:1024點(diǎn)FFT快速傅立葉變換

    Xilinx FPGA工程例子源碼:Xilinx 的IP:1024點(diǎn)FFT快速傅立葉變換
    發(fā)表于 06-07 15:07 ?51次下載

    DSP進(jìn)行浮點(diǎn)快速傅立葉變換剖析

    前言本文目的是演示如何使用STM32F30x 內(nèi)部的DSP 進(jìn)行浮點(diǎn)快速傅立葉變換FFT),為聯(lián)系實(shí)際應(yīng)用
    的頭像 發(fā)表于 09-18 06:44 ?9436次閱讀

    簡(jiǎn)述FPGA的快速傅立葉變換

    摘要:在對(duì)FFT(快速傅立葉變換)算法進(jìn)行研究的基礎(chǔ)上,描述了用FPGA實(shí)現(xiàn)FFT的方法,并對(duì)其中的整體結(jié)構(gòu)、蝶形單元及性能等進(jìn)行了分析。 傅立葉
    的頭像 發(fā)表于 05-27 11:21 ?2206次閱讀
    簡(jiǎn)述FPGA的快速<b class='flag-5'>傅立葉</b><b class='flag-5'>變換</b>

    傅立葉變換是怎么變換傅立葉的理解

    關(guān)于傅立葉變換,無(wú)論是書(shū)本還是在網(wǎng)上可以很容易找到關(guān)于傅立葉變換的描述,但是大都讓人很難理解太過(guò)抽象,盡是一些讓人看了就望而生畏的公式的羅列。 要理解
    的頭像 發(fā)表于 08-25 11:25 ?4775次閱讀

    我印象中的快速傅里葉變換 (FFT)

    首先,FFT是離散傅立葉變換 (DFT) 的快速算法,那么說(shuō)到FFT,我們自然要先講清楚傅立葉變換
    的頭像 發(fā)表于 05-05 09:57 ?1122次閱讀
    我印象中的快速傅里葉<b class='flag-5'>變換</b> (<b class='flag-5'>FFT</b>)

    淺懂示波器FFT快速傅立葉變換功能及運(yùn)用

    大多數(shù)示波器上都有個(gè)FFT功能,也叫快速傅立葉變換,但很多人不了解這個(gè)功能是做什么用的,百度以后又會(huì)遇到各種各樣的高數(shù)公式,看的一頭霧水,遂而放棄這塊知識(shí)。我們來(lái)看百度百科的解釋?zhuān)?b class='flag-5'>FFT
    的頭像 發(fā)表于 11-08 15:01 ?6462次閱讀
    淺懂示波器<b class='flag-5'>FFT</b>快速<b class='flag-5'>傅立葉</b><b class='flag-5'>變換</b>功能及運(yùn)用

    如何使用SBench 6對(duì)數(shù)字化儀采集信號(hào)進(jìn)行處理?(三)——快速傅立葉變換FFT

    上一篇文章介紹了德思特SBench 6的平均運(yùn)算功能。本章將繼續(xù)為大家介紹SBench 6的快速傅立葉變換FFT)。
    的頭像 發(fā)表于 01-23 10:38 ?540次閱讀
    如何使用SBench 6對(duì)數(shù)字化儀采集信號(hào)進(jìn)行處理?(三)——快速<b class='flag-5'>傅立葉</b><b class='flag-5'>變換</b>(<b class='flag-5'>FFT</b>)