00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 #ifndef __MMX__MATRIX_COMPLEX__HPP
00014 #define __MMX__MATRIX_COMPLEX__HPP
00015 #include <algebramix/matrix.hpp>
00016 #include <numerix/complex.hpp>
00017 #include <numerix/integer.hpp>
00018 
00019 namespace mmx {
00020 #define TMPL template<typename C>
00021 #define Complex complex<C>
00022 
00023 
00024 
00025 
00026 
00027 template<typename V>
00028 struct matrix_complex: public V {
00029   typedef typename V::Vec Vec;
00030   typedef typename V::Naive Naive;
00031   typedef typename V::Positive Positive;
00032   typedef matrix_complex<typename V::No_simd> No_simd;
00033   typedef matrix_complex<typename V::No_thread> No_thread;
00034   typedef matrix_complex<typename V::No_scaled> No_scaled;
00035 };
00036 
00037 template<typename F, typename V, typename W>
00038 struct implementation<F,V,matrix_complex<W> >:
00039   public implementation<F,V,W> {};
00040 
00041 TMPL
00042 struct matrix_variant_helper<Complex > {
00043   typedef typename matrix_variant_helper<C>::MV CMV;
00044   typedef matrix_complex<CMV> MV;
00045 };
00046 
00047 STMPL
00048 struct matrix_variant_helper<complex<generic> > {
00049   typedef matrix_naive MV;
00050 };
00051 
00052 
00053 
00054 
00055 
00056 template<typename V, typename CV>
00057 struct implementation<matrix_multiply,V,matrix_complex<CV> >:
00058   public implementation<matrix_linear,V>
00059 {
00060   typedef implementation<vector_linear,CV> Vec_C;
00061   typedef implementation<matrix_multiply,CV> Mat_C;
00062 
00063 TMPL static inline void
00064 mul (Complex* dest, const Complex* s1, const Complex* s2,
00065      nat r, nat l, nat c)
00066 {
00067   nat n1 = r*l, spc1= aligned_size<C,CV> (n1);
00068   nat n2 = l*c, spc2= aligned_size<C,CV> (n2);
00069   nat nd = r*c, spcd= aligned_size<C,CV> (nd);
00070   nat spc= 2*spc1 + 2*spc2 + 3*spcd;
00071   C* real_x1= mmx_new<C> (spc);
00072   C* imag_x1= real_x1 + spc1;
00073   C* real_x2= imag_x1 + spc1;
00074   C* imag_x2= real_x2 + spc2;
00075   C* real_d = imag_x2 + spc2;
00076   C* imag_d = real_d  + spcd;
00077   C* temp_d = imag_d  + spcd;
00078 
00079   Vec_C::half_copy (real_x1, (C*) ((void*) s1), n1);
00080   Vec_C::half_copy (imag_x1, ((C*) ((void*) s1)) + 1, n1);
00081   Vec_C::half_copy (real_x2, (C*) ((void*) s2), n2);
00082   Vec_C::half_copy (imag_x2, ((C*) ((void*) s2)) + 1, n2);
00083   
00084   
00085   Mat_C::mul (real_d, real_x1, real_x2, r, l, c);
00086   
00087   
00088   
00089   Mat_C::mul (temp_d, imag_x1, imag_x2, r, l, c);
00090   
00091   Vec_C::add (real_x1, imag_x1, n1);
00092   Vec_C::add (real_x2, imag_x2, n2);
00093   
00094   
00095   Mat_C::mul (imag_d, real_x1, real_x2, r, l, c);
00096   
00097   Vec_C::sub (imag_d, real_d, nd);
00098   Vec_C::sub (imag_d, temp_d, nd);
00099   Vec_C::sub (real_d, temp_d, nd);
00100   Vec_C::double_copy ((C*) ((void*) dest), real_d, nd);
00101   Vec_C::double_copy (((C*) ((void*) dest)) + 1, imag_d, nd);
00102 
00103   mmx_delete<C> (real_x1, spc);
00104 }
00105 
00106 }; 
00107 
00108 #undef TMPL
00109 #undef Complex
00110 } 
00111 #endif //__MMX__MATRIX_COMPLEX__HPP