00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX__POLYNOMIAL_COMPLEX__HPP
00014 #define __MMX__POLYNOMIAL_COMPLEX__HPP
00015 #include <algebramix/polynomial.hpp>
00016 #include <algebramix/polynomial_dicho.hpp>
00017 #include <numerix/complex.hpp>
00018
00019 namespace mmx {
00020 #define TMPL template<typename C>
00021
00022
00023
00024
00025
00026 template<typename V>
00027 struct polynomial_complex {
00028 typedef typename V::Vec Vec;
00029 typedef typename V::Naive Naive;
00030 typedef typename V::Positive Positive;
00031 typedef polynomial_complex<typename V::No_simd> No_simd;
00032 typedef polynomial_complex<typename V::No_thread> No_thread;
00033 typedef polynomial_complex<typename V::No_scaled> No_scaled;
00034 };
00035
00036 template<typename F, typename V, typename W>
00037 struct implementation<F,V,polynomial_complex<W> >:
00038 public implementation<F,V,W> {};
00039
00040 template<typename C>
00041 struct polynomial_variant_helper<complex<C> > {
00042 typedef typename Polynomial_variant(C) CPV;
00043 typedef polynomial_complex<CPV> PV;
00044 };
00045
00046
00047
00048
00049
00050 template<typename V, typename CV>
00051 struct implementation<polynomial_multiply,V,polynomial_complex<CV> >:
00052 public implementation<polynomial_linear,V>
00053 {
00054 typedef implementation<vector_linear,CV> Vec_C;
00055 typedef implementation<polynomial_multiply,CV> Pol_C;
00056
00057 TMPL static inline void
00058 mul (complex<C>* dest, const complex<C>* s1, const complex<C>* s2,
00059 nat n1, nat n2)
00060 {
00061 nat nd = n1 + n2 - 1;
00062 nat spc1 = aligned_size<C,CV> (n1);
00063 nat spc2 = aligned_size<C,CV> (n2);
00064 nat spcd = aligned_size<C,CV> (nd);
00065 nat spc = 5 * (spc1 + spc2);
00066 C* real_x1= mmx_new<C> (spc);
00067 C* imag_x1= real_x1 + spc1;
00068 C* real_x2= imag_x1 + spc1;
00069 C* imag_x2= real_x2 + spc2;
00070 C* real_d = imag_x2 + spc2;
00071 C* imag_d = real_d + spcd;
00072 C* temp_d = imag_d + spcd;
00073
00074 Vec_C::half_copy (real_x1, (C*) ((void*) s1), n1);
00075 Vec_C::half_copy (imag_x1, ((C*) ((void*) s1)) + 1, n1);
00076 Vec_C::half_copy (real_x2, (C*) ((void*) s2), n2);
00077 Vec_C::half_copy (imag_x2, ((C*) ((void*) s2)) + 1, n2);
00078 Pol_C::mul (real_d, real_x1, real_x2, n1, n2);
00079 Pol_C::mul (temp_d , imag_x1, imag_x2, n1, n2);
00080 Pol_C::add (real_x1, imag_x1, n1);
00081 Pol_C::add (real_x2, imag_x2, n2);
00082 Pol_C::mul (imag_d, real_x1, real_x2, n1, n2);
00083 Pol_C::sub (imag_d, real_d, nd);
00084 Pol_C::sub (imag_d, temp_d, nd);
00085 Pol_C::sub (real_d, temp_d, nd);
00086 Vec_C::double_copy ((C*) ((void*) dest), real_d, nd);
00087 Vec_C::double_copy (((C*) ((void*) dest)) + 1, imag_d, nd);
00088
00089 mmx_delete<C> (real_x1, spc);
00090 }
00091
00092 TMPL static inline void
00093 square (complex<C>* dest, const complex<C>* s1, nat n1) {
00094 nat nd = n1 + n1 - 1;
00095 nat spc1 = aligned_size<C,CV> (n1);
00096 nat spcd = aligned_size<C,CV> (nd);
00097 nat spc = 8 * spc1;
00098 C* real_x1= mmx_new<C> (spc);
00099 C* imag_x1= real_x1 + spc1;
00100 C* real_d = imag_x1 + spc1;
00101 C* imag_d = real_d + spcd;
00102 C* temp_d = imag_d + spcd;
00103
00104 Vec_C::half_copy (real_x1, (C*) ((void*) s1), n1);
00105 Vec_C::half_copy (imag_x1, ((C*) ((void*) s1)) + 1, n1);
00106 Pol_C::square (real_d, real_x1, n1);
00107 Pol_C::square (temp_d, imag_x1, n1);
00108 Pol_C::add (real_x1, imag_x1, n1);
00109 Pol_C::square (imag_d, real_x1, n1);
00110 Pol_C::sub (imag_d, real_d, nd);
00111 Pol_C::sub (imag_d, temp_d, nd);
00112 Pol_C::sub (real_d, temp_d, nd);
00113 Vec_C::double_copy ((C*) ((void*) dest), real_d, nd);
00114 Vec_C::double_copy (((C*) ((void*) dest)) + 1, imag_d, nd);
00115
00116 mmx_delete<C> (real_x1, spc);
00117 }
00118
00119 TMPL static inline void
00120 tmul (C* dest, const C* s1, const C* s2, nat n1, nat n2) {
00121 (void) dest; (void) s1; (void) s2; (void) n1; (void) n2;
00122 ERROR ("transposed complexified multiplication not implemented");
00123 }
00124
00125 };
00126
00127 #undef TMPL
00128 }
00129 #endif //__MMX__POLYNOMIAL_COMPLEX__HPP