复数(Complex)类及FFT的C++实现

===○专业造轮子===

因为一些原因需要额外编写傅里叶变换(Fourier Transform)的实现代码,

而傅里叶变换需要复数的支持,因此额外编写了一个复数类。


首先是复数(Complex)类的设计,很简单,数据域只有实部和虚部,为了方便外部操作,

将数据设置为公开访问,大致如下

classComplex

{

public:

    Complex();

    Complex(double re,double im);

    // operator +,-,*,/,= etc.

    double real;  // 实部

    double imag;  // 虚部

  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
以下是基于DIT(Divide in Time)算法的FFT(Fast Fourier Transform)的C++实现: ```cpp #include <bits/stdc++.h> using namespace std; const int N = 1 << 20; const double PI = acos(-1.0); struct Complex { double real, imag; Complex operator+(const Complex &rhs) const { return {real + rhs.real, imag + rhs.imag}; } Complex operator-(const Complex &rhs) const { return {real - rhs.real, imag - rhs.imag}; } Complex operator*(const Complex &rhs) const { return {real * rhs.real - imag * rhs.imag, real * rhs.imag + imag * rhs.real}; } } a[N], b[N], c[N], d[N]; int rev[N]; void FFT(Complex *a, int n, int inv) { for (int i = 0; i < n; ++i) { if (i < rev[i]) { swap(a[i], a[rev[i]]); } } for (int i = 2; i <= n; i <<= 1) { Complex wn = {cos(2 * PI / i), sin(2 * PI / i) * inv}; for (int j = 0; j < n; j += i) { Complex w = {1, 0}; for (int k = j; k < j + (i >> 1); ++k) { Complex x = a[k], y = w * a[k + (i >> 1)]; a[k] = x + y, a[k + (i >> 1)] = x - y; w = w * wn; } } } if (inv == -1) { for (int i = 0; i < n; ++i) { a[i].real /= n, a[i].imag /= n; } } } int main() { int n = 1, m = 1; while (n <= 100000) { n <<= 1; } for (int i = 0; i < n; ++i) { rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? n >> 1 : 0); } for (int i = 0; i < m; ++i) { scanf("%lf", &a[i].real); } FFT(a, n, 1); for (int i = 0; i < n; ++i) { b[i] = a[i] * a[i]; } FFT(b, n, -1); for (int i = 0; i < m; ++i) { printf("%.0f ", b[i].real); } return 0; } ``` 其中,`Complex`结构体表示复数,`FFT`函数为DIT-FFT算法的实现,`rev`数组为反转映射数组,`n`为最终计算的序列长度,`m`为输入序列的长度,`a`为输入序列,`b`为结果序列。该代码实现了对输入序列进行FFT变换后,计算其平方序列的逆变换,得到了平方序列。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值