首页 > 其他分享 >快速傅里叶变换

快速傅里叶变换

时间:2022-10-11 23:32:46浏览次数:68  
标签:comx http 变换 傅里叶 FFT len int ans 快速


快速傅里叶变换不能三言两语能解释清楚,自己看了一些资料,仍不敢说完全掌握了。
快速傅里叶变换 (FFT)的作用及解释:


​http://blog.jobbole.com/70549/​

编程实现:

​http://wenku.baidu.com/link?url=Ntpg6kmz98PiLYCo4ymYCNDEQ2iziPIaq4sCqhbxLuZ16ONotUgwLvJ0q8AG-mpTlpoCFr-M7dkf0iZ7tnws45W8Z-JD2g_0VgoSblbU4jK###​



大神们的博客:

​http://blog.miskcoo.com/2015/04/polynomial-multiplication-and-fast-fourier-transform#i-15​

卷积是两个变量在某范围内相乘后求和的结果。如果卷积的变量是序列x(n)和h(n),则卷积的结果




快速傅里叶变换_fft

,其中星号*表示卷积。


多项式乘法就可被FFT高效解决。



快速傅里叶变换提供了一种新的视觉,从不同的角度看待问题,让复杂问题简单化。把数字统统放到复数域内,由单位复根W的三大特性,对称性,可约性,周期性实现普通离散变换效率上的飞跃。


复根:


快速傅里叶变换_#include_02


对称性奇偶分类,分治处理,此外


周期性:


快速傅里叶变换_卷积_03


可约性:


快速傅里叶变换_卷积_04

  


帮助减少了运算量。



快速傅里叶变换解决问题的过程可以说就是先将函数表达变成点值关系,进行运算,再转成系数表示。



A * B Problem Plus
​​​http://acm.hdu.edu.cn/showproblem.php?pid=1402​


Calculate A * B. 数据很大


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N=5e5+10;
const double PI=acos(-1.0);
struct comx{ // 复数
double r,i;
comx(double r=0.0,double i=0.0){
this->r=r;
this->i=i;
}
comx operator +(const comx x){
return comx(r+x.r,i+x.i);
}
comx operator -(const comx x){
return comx(r-x.r,i-x.i);
}
comx operator *(const comx x){
return comx(r*x.r-i*x.i,r*x.i+i*x.r);
}
};
// 倒位序·雷德算法 100 --> 001
void Rader(comx F[],int len){
int j=len/2;
for(int i=1;i<len-1;i++){
if(i<j) swap(F[i],F[j]);
int k=len>>1;
while(j>=k){
j-=k;
k>>=1;
}
if(j<k) j+=k;
}
}
// FFT 快速傅里叶变换
void FFT(comx F[],int len,int f){
Rader(F,len); // 倒位序 奇偶分类
for(int i=2;i<=len;i<<=1){ // 分治
comx I(cos(-f*2*PI/i),sin(-f*2*PI/i));
for(int j=0;j<len;j+=i){
comx w(1,0); // 旋转因子
for(int k=j;k<j+i/2;k++){
comx u=F[k];
comx t=w*F[k+i/2];
F[k]=u+t;
F[k+i/2]=u-t; //蝴蝶
w=w*I;
}
}
}
if(f==-1) {
for(int i=0;i<len;i++) F[i].r/=len;
}
}
// 卷积
void Conv(comx a[],comx b[],int len){
FFT(a,len,1); // DFT 变成点值
FFT(b,len,1);
for(int i=0;i<len;i++) a[i]=a[i]*b[i];
FFT(a,len,-1); // IDFT 变回关系式
}

char str1[N],str2[N];
comx a[N],b[N];
int ans[N],len;

int main()
{
while(~scanf("%s%s",str1,str2)){
int len1=strlen(str1),len2=strlen(str2);
len=1;
while(len<2*len1 || len<2*len2) len<<=1;
int i;
for(i=0;i<len1;i++){ //大数存入两个复数数组中
a[i].r=str1[len1-1-i]-'0';
a[i].i=0;
}
while(i<len){
a[i].r=a[i].i=0;
i++;
}
for(i=0;i<len2;i++){
b[i].r=str2[len2-1-i]-'0';
b[i].i=0;
}
while(i<len){
b[i].r=b[i].i=0;
i++;
}
Conv(a,b,len);
for(i=0;i<len;i++) ans[i]=a[i].r+0.5; //四舍五入
for(i=0;i<len;i++){
ans[i+1]+=ans[i]/10; //高精度处理
ans[i]%=10;
}
int length=0;
for(i=len-1;i>=0;i--){
if(ans[i]) {
length=i;
break;
}
}
for(i=length;i>=0;i--) printf("%d",ans[i]);
printf("\n");
}
return 0;
}


拓展:
将卷积部分改成单纯的求和,即成为高精度求和


求和 (前提是两个大数均是非负数):


void Conv(comx a[],comx b[],int len){
FFT(a,len,1); // DFT 变成点值
FFT(b,len,1);
for(int i=0;i<len;i++) a[i]=a[i]+b[i];
FFT(a,len,-1); // IDFT 变回关系式
}



但是不能拓展成为高精度减法:

void Conv(comx a[],comx b[],int len){
FFT(a,len,1); // DFT 变成点值
FFT(b,len,1);
for(int i=0;i<len;i++) a[i]=a[i]-b[i];
FFT(a,len,-1); // IDFT 变回关系式
}


POJ 2389 Bull Math


​http://poj.org/problem?id=2389​


普通的大数乘法。我就是试试FFT。。。


和上题差不多,数组大小改一下就能过



1028 大数乘法 V2


​http://www.51nod.com/onlineJudge/questionCode.html#​​!problemId=1028


也是大数乘法


FFT用于多项式乘法,当数据很大时,其优势体现的更加明显,普通的计算过程为O(n^2),但是FFT可以做到O(nlogn).




标签:comx,http,变换,傅里叶,FFT,len,int,ans,快速
From: https://blog.51cto.com/u_15746559/5748430

相关文章

  • 如何快速学习Go的切片和数组数据类型
    本文已收录​​如何快速学习Go的struct数据类型​​。涵盖PHP、JavaScript、Linux、Golang、MySQL、Redis和开源工具等等相关内容。什么是数组数组是属于同一类型的元素的集......
  • 草图?不管黑猫白猫,能快速、有效把你的设计理念讲清楚才行
    下午我被叫去参加“合作服务商资金安全解决方案”项目的codereview。对程序实现逻辑上存疑。简单听他们了解了一下需求逻辑。然后,果然发现逻辑有疏漏。为了表达清楚我的意......
  • pyspider 安装 和 快速开始
     From:官方文档---快速开始:​​http://docs.pyspider.org/en/latest/Quickstart/​​pyspidergithub地址:​​https://github.com/binux/pyspider​​pyspider官方文档:......
  • 快速排序
    首先我们要对一组数据进行排序:在数组中选一个基准数(通常为数组第一个,黄圈圈标记了);将数组中小于基准数的数据移到基准数左边,大于基准数的移到右边,怎么移动,后面说;......
  • 如何将手机便签里的照片和视频,快速保存到电脑?
    对于不少职场人士来说,日常使用频率较高的电子设备就是手机和电脑了,并且在办公时,有时候还需要把手机中的照片和视频批量保存到电脑中使用。那么如何将手机里的照片和视频,快......
  • java Spring Cloud 全环境 简明快速 精准 详解 视频课程 -专题视频课程
    Maven下SpringCloud全环境—10645人已学习课程介绍        本课程介绍SpringCloud+maven+Eureka+zuul+微服务+客户端+feign+hystrix+ribbon+config负载均衡......
  • 前段 HTML5/CSS+jquery +javascript 13天 短期快速 从基础 入门到实战精通 项目实战-
    HTML5/CSS+jquery+javascript13天从基础入门到实战精通项目实战—14780人已学习课程介绍        1.前端技术总体介绍htmlcssjqueryjavascript2.编辑第......
  • Git项目管理快速入门
    Git是什么Git的理解:Git是目前世界上最先进的分布式版本控制系统(没有之一),用于敏捷高效地处理任何或小或大的项目。简单理解就是代码管理工具。使用Git一般处于以下3......
  • Class 2 基于ECS快速搭建Docker环境
    title:Class2基于ECS快速搭建Docker环境excerpt:云上实践云上成长ECS7天实践训练营tags:[阿里云,在家学习,ECS,docker,进阶班]categories:[学习,阿里......
  • 面试官:如何快速定位慢SQL
    开启慢查询日志在项目中我们会经常遇到慢查询,当我们遇到慢查询的时候一般都要开启慢查询日志,并且分析慢查询日志,找到慢sql,然后用explain来分析系统变量MySQL和慢查询相关的......