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