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 }