00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <numerix/floating.hpp>
00014 #include <numerix/complex.hpp>
00015 #include <algebramix/fft_naive.hpp>
00016 #include <algebramix/polynomial_tft.hpp>
00017
00018 namespace mmx {
00019
00020 #ifdef ACCURATE_ROOTS
00021 complex<double>
00022 primitive_root_helper<complex<double> >::op (nat n, nat i, const format<complex<double> >&) {
00023 nat old= mmx_bit_precision;
00024 mmx_bit_precision= 64;
00025 format<complex<floating<> > > ffm;
00026 complex<floating<> > zf= primitive_root<complex<floating<> > > (n, i, ffm);
00027 complex<double> zd (as_double (Re (zf)), as_double (Im (zf)));
00028 mmx_bit_precision= old;
00029 return zd;
00030 }
00031 #endif // ACCURATE_ROOTS
00032
00033 void
00034 fft_mul (double* dest, const double* s1, const double *s2, nat n1, nat n2) {
00035 typedef polynomial_dicho<
00036 polynomial_tft<
00037 polynomial_karatsuba<
00038 polynomial_naive> > > PV;
00039 typedef implementation<vector_linear,PV> Vec;
00040 typedef implementation<polynomial_multiply,PV> Pol;
00041
00042
00043 nat nd = n1 + n2 - 1;
00044 nat spc= n1 + n2 + nd;
00045 complex<double>* m1= mmx_new<complex<double> > (spc);
00046 complex<double>* m2= m1 + n1;
00047 complex<double>* md= m2 + n2;
00048 Vec::cast (m1, s1, n1);
00049 Vec::cast (m2, s2, n2);
00050 Pol::mul (md, m1, m2, n1, n2);
00051 Vec::vec_unary<Re_op> (dest, md, nd);
00052 mmx_delete<complex<double> > (m1, spc);
00053
00054 }
00055
00056 }