Ejemplo n.º 1
0
void BigIntegerStrassen::FastFourierTransform(vcomp &vect, bool invert){
    //static long double PI = 3.14159265358979323846;
    static long double PI = 3.14159265358979323846264338327950288419716939937510L;
    
    ll n = (ll)vect.size();
    if (n == 1)  return;

    vcomp vect0(n / 2), vect1(n / 2);
    for (ll i = 0, j = 0; i<n; i += 2, ++j){
        vect0[j] = vect[i];
        vect1[j] = vect[i + 1];
    }

    FastFourierTransform(vect0, invert);
    FastFourierTransform(vect1, invert);

    long double ang = 2 * PI / n * (invert ? -1 : 1);
    std::complex<long double> w(1), wn(cos(ang), sin(ang));
    for (ll i = 0; i < n / 2; ++i) {
        vect[i] = vect0[i] + w * vect1[i];
        vect[i + n / 2] = vect0[i] - w * vect1[i];
        if (invert){
            vect[i] /= 2;
            vect[i + n / 2] /= 2;
        }
        w *= wn;
    }

}
Ejemplo n.º 2
0
void BigIntegerStrassen::Multiply(const BigIntegerStrassen &right_number){
    vcomp fa(number.begin(), number.end());
    auto right_arr = right_number.ToArray();
    vcomp fb(right_arr.begin(), right_arr.end());

    ll n = 1;
    while (n < std::max(number.size(), right_arr.size())) n <<= 1;
    n <<= 1;

    fa.resize(n);
    fb.resize(n);

    FastFourierTransform(fa, false);
    FastFourierTransform(fb, false);

    for (ll i = 0; i < n; i++) fa[i] *= fb[i];
    FastFourierTransform(fa, true);
    
    number.resize(n);
    ll carry = 0;
    for (ll i = 0; i < n; i++){
        carry += ll(fa[i].real() + 0.5);
        number[i] = carry % base;
        carry /= base;
    }

    while (number.size() && number.back() == 0) number.pop_back();

}
Ejemplo n.º 3
0
void FastFourierTransform(ComplexNumber x[], ComplexNumber X[], int N, int s) {
	
	ComplexNumber t;
	ComplexNumber intermediate_complex_number, intermediate_product;
	
	if (N == 1) {
		
		X[0] = x[0];
		
	}
	
	else {
		
		FastFourierTransform(x, X, N / 2, 2 * s);
		
		FastFourierTransform(x + s, X + N / 2, N / 2, 2 * s);
		
		for (int k = 0; k < N / 2; k++) {
			
			t = X[k];
			
			intermediate_complex_number = NewComplexNumber(1.0, -2.0 * PI * (float)k / (float) N, 1);
			
			intermediate_product = MultiplyComplexNumbers(intermediate_complex_number, X[k + N/2]);
			
			X[k] = AddComplexNumbers(t, intermediate_product);
			X[k + N/2] = SubtractComplexNumbers(t, intermediate_product);
			
		}
		
	}
	
}
TEST( FastFourierTransformTest, Inversible ) {
    Polynomial<std::complex<double>> p = { { 1, 0 }, { 2, 3 }, { 4, 5 }, { 3, 5 } };
    auto q = FastFourierTransform( p, false );
    auto r = FastFourierTransform( q, true );
    EXPECT_EQ( p, r );
}