00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX__MATRIX_MODULAR__HPP
00014 #define __MMX__MATRIX_MODULAR__HPP
00015 #include <numerix/modular.hpp>
00016 #include <algebramix/matrix_int.hpp>
00017 #include <algebramix/matrix_integer.hpp>
00018
00019 namespace mmx {
00020 #define TMPL template<typename C, typename V1, typename V2>
00021 #define Modulus modulus<C,V1>
00022 #define Modular modular<Modulus,V2>
00023
00024
00025
00026
00027
00028 template<typename V>
00029 struct matrix_modular: public V {
00030 typedef typename V::Vec Vec;
00031 typedef typename V::Naive Naive;
00032 typedef matrix_modular<V> Positive;
00033 typedef matrix_modular<typename V::No_simd> No_simd;
00034 typedef matrix_modular<typename V::No_thread> No_thread;
00035 typedef matrix_modular<typename V::No_scaled> No_scaled;
00036 };
00037
00038 template<typename F, typename V, typename W>
00039 struct implementation<F,V,matrix_modular<W> >:
00040 public implementation<F,V,W> {};
00041
00042 TMPL
00043 struct matrix_variant_helper<Modular > {
00044 typedef matrix_naive Naive;
00045 typedef matrix_unrolled<8,Naive> Unrolled;
00046 typedef matrix_simd<8,8,Unrolled> Simd;
00047 typedef matrix_modular<Unrolled> MV;
00048 };
00049
00050
00051
00052
00053
00054 template<typename V, typename MV>
00055 struct implementation<matrix_multiply_base,V,matrix_modular<MV> >:
00056 public implementation<matrix_linear,V>
00057 {
00058 typedef implementation<matrix_multiply,MV> Mat;
00059
00060
00061 template<typename Op, typename D, typename S1, typename S2>
00062 static inline void
00063 mul (D* d, const S1* s1, const S2* s2,
00064 nat r, nat rr, nat l, nat ll, nat c, nat cc)
00065 {
00066 Mat::template mul<Op> (d, s1, s2, r, rr, l, ll, c, cc);
00067 }
00068
00069
00070 template<typename Op, typename C, typename V1, typename V2>
00071 static inline void
00072 mul (Modular* d, const Modular* s1, const Modular* s2,
00073 nat r, nat rr, nat l, nat ll, nat c, nat cc)
00074 {
00075 typedef Lift_type(Modular) D;
00076 typedef typename Matrix_variant(D) W;
00077 typedef implementation<matrix_multiply,W> Mat_D;
00078 nat len_1= aligned_size<D,V> (r * l);
00079 nat len_2= aligned_size<D,V> (l * c);
00080 nat len_d= aligned_size<D,V> (r * c);
00081 nat spc = len_1 + len_2 + len_d;
00082 D* x1= mmx_new<D> (spc);
00083 D* x2= x1 + len_1;
00084 D* xd= x2 + len_2;
00085 Mat_D::template mat_unary_stride<lift_op, D, Modular>
00086 (x1, Mat_D::index (1, 0, r, l) , Mat_D::index (0, 1, r, l),
00087 s1, Mat ::index (1, 0, rr, ll), Mat ::index (0, 1, rr, ll), r, l);
00088 Mat_D::template mat_unary_stride<lift_op, D, Modular>
00089 (x2, Mat_D::index (1, 0, l, c) , Mat_D::index (0, 1, l, c),
00090 s2, Mat ::index (1, 0, ll, cc), Mat ::index (0, 1, ll, cc), l, c);
00091 Mat_D::template mul<Op> (xd, x1, x2, r, r, l, l, c, c);
00092 Mat_D::template mat_unary_stride<project_op>
00093 (d , Mat ::index (1, 0, rr, cc), Mat ::index (0, 1, rr, cc),
00094 xd, Mat_D::index (1, 0, r, c) , Mat_D::index (0, 1, r, c), r, c);
00095 mmx_delete<D> (x1, spc);
00096 }
00097 };
00098
00099 #undef TMPL
00100 #undef Modulus
00101 #undef Modular
00102 }
00103
00104 #endif //__MMX__MATRIX_MODULAR__HPP