algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/polynomial_complex.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines