FFT

bool inverse = false ;

inline Complex omega ( const int& n, const int& k )  {
    if ( ! inverse ) return Complex ( cos ( 2 * PI / n * k ), sin ( 2 * PI / n * k ) ) ;
    return Complex ( cos ( 2 * PI / n * k ), sin ( 2 * PI / n * k ) ).conj ( ) ;
}

inline void fft ( Complex *a, const int& n )  {
    if ( n == 1 ) return ;

    static Complex buf [N] ;
    
    const int m = n >> 1 ;
    
    for ( int i = 0 ; i < m ; ++ i )  {
        buf [i] = a [i << 1] ;
        buf [i + m] = a [i << 1 | 1] ;
    }
    
    memcpy ( a, buf, sizeof ( int ) * ( n + 1 ) ) ;

    Complex *a1 = a, *a2 = a + m;
    fft ( a1, m ) ;
    fft ( a2, m ) ;

    for ( int i = 0 ; i < m ; ++ i )  {
        Complex t = omega ( n, i ) ;
        buf [i] = a1 [i] + t * a2 [i] ;
        buf [i + m] = a1 [i] - t * a2 [i] ;
    }
    
    memcpy ( a, buf, sizeof ( int ) * ( n + 1 ) ) ;
}
struct FastFourierTransform  {
    Complex omega [N], omegaInverse [N] ;

    void init ( const int& n )  {
        for ( int i = 0 ; i < n ; ++ i )  {
            omega [i] = Complex ( cos ( 2 * PI / n * i), sin ( 2 * PI / n * i ) ) ;
            omegaInverse [i] = omega [i].conj ( ) ;
        }
    }

    void transform ( Complex *a, const int& n, const Complex* omega ) {
        for ( int i = 0, j = 0 ; i < n ; ++ i )  {
		if ( i > j )  std :: swap ( a [i], a [j] ) ;
		for( int l = n >> 1 ; ( j ^= l ) < l ; l >>= 1 ) ;
	}

        for ( int l = 2 ; l <= n ; l <<= 1 )  {
            int m = l / 2;
            for ( Complex *p = a ; p != a + n ; p += l )  {
                for ( int i = 0 ; i < m ; ++ i )  {
                    Complex t = omega [n / l * i] * p [m + i] ;
                    p [m + i] = p [i] - t ;
                    p [i] += t ;
                }
            }
        }
    }

    void dft ( Complex *a, const int& n )  {
        transform ( a, n, omega ) ;
    }

    void idft ( Complex *a, const int& n )  {
        transform ( a, n, omegaInverse ) ;
        for ( int i = 0 ; i < n ; ++ i ) a [i] /= n ;
    }
} fft ;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值