algebramix_doc 0.3
|
00001 00002 /****************************************************************************** 00003 * MODULE : polynomial_complex.hpp 00004 * DESCRIPTION: Complex multiplication of polynomials 00005 * COPYRIGHT : (C) 2007 Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 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 * Variant for complex polynomials 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 * Complex multiplication 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 }; // implementation<polynomial_multiply,V,polynomial_complex<CV> > 00126 00127 #undef TMPL 00128 } // namespace mmx 00129 #endif //__MMX__POLYNOMIAL_COMPLEX__HPP