00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX_KRONECKER_MODULAR_INT_HPP
00014 #define __MMX_KRONECKER_MODULAR_INT_HPP
00015 #include <basix/vector.hpp>
00016 #include <numerix/modular_int.hpp>
00017 #include <algebramix/kronecker_int.hpp>
00018
00019 namespace mmx {
00020
00021
00022
00023
00024
00025 #define DECLARE_HELPER(I) \
00026 void decode_kronecker_mod (I* dest, nat n, xnat bits, \
00027 const integer& src, const I& p); \
00028 void mul_kronecker_mod (I* dest, const I* src1, nat n1, \
00029 const I* src2, nat n2, const I& p); \
00030 void square_kronecker_mod (I* dest, const I* src1, nat n1, const I& p);
00031 DECLARE_HELPER(signed char)
00032 DECLARE_HELPER(unsigned char)
00033 DECLARE_HELPER(short int)
00034 DECLARE_HELPER(unsigned short int)
00035 DECLARE_HELPER(int)
00036 DECLARE_HELPER(unsigned int)
00037 DECLARE_HELPER(long int)
00038 DECLARE_HELPER(unsigned long int)
00039 DECLARE_HELPER(long long int)
00040 DECLARE_HELPER(unsigned long long int)
00041 #undef DECLARE_HELPER
00042
00043
00044
00045
00046
00047 #define TMPL template<typename I, typename MoV, typename MaV>
00048 #define C modular<modulus<I,MoV>,MaV>
00049
00050 TMPL inline void
00051 mul_kronecker (C* dest, const C* s1, nat n1, const C* s2, nat n2) {
00052 mul_kronecker_mod ((I*) (void*) dest,
00053 (const I*) (const void*) s1, n1,
00054 (const I*) (const void*) s2, n2,
00055 * C::get_modulus());
00056 }
00057
00058 TMPL inline void
00059 square_kronecker (C* dest, const C* s, nat n) {
00060 square_kronecker_mod ((I*) (void*) dest,
00061 (const I*) (const void*) s, n,
00062 * C::get_modulus());
00063 }
00064
00065 #undef C
00066 #undef TMPL
00067
00068 #define TMPL template<typename I, typename MoV>
00069 #define C modular<modulus<I,MoV>,modular_local>
00070
00071 TMPL inline void
00072 mul_kronecker (C* dest, const C* s1, const C* s2, nat n1, nat n2) {
00073 nat l1= default_aligned_size<I> (n1), l2= default_aligned_size<I> (n2);
00074 nat spc= l1 + l2 + default_aligned_size<I> (n1 + n2 - 1);
00075 I* t1= mmx_new<I> (spc); I* t2= t1 + l1, * r= t1 + l1 + l2;
00076 for (nat i= 0; i < n1; i++) t1[i]= * s1[i];
00077 for (nat i= 0; i < n2; i++) t2[i]= * s2[i];
00078 I p= * get_modulus (s1[0]);
00079 mul_kronecker_mod (r, t1, n1, t2, n2, p);
00080 for (nat i= 0; i < n1 + n2 - 1; i++) dest[i]= C (* r[i], p, true);
00081 mmx_delete<I> (t1, spc);
00082 }
00083
00084 TMPL inline void
00085 square_kronecker (C* dest, const C* s, nat n) {
00086 nat ls= default_aligned_size<I> (n);
00087 nat spc= ls + default_aligned_size<I> (2 * n - 1);
00088 I* t= mmx_new<I> (spc), * r= t + ls;
00089 for (nat i= 0; i < n; i++) t[i]= * s[i];
00090 I p= * get_modulus (s[0]);
00091 square_kronecker_mod (r, t, n, p);
00092 for (nat i= 0; i < 2 * n - 1; i++) dest[i]= C (* r[i], p, true);
00093 mmx_delete<I> (t, spc);
00094 }
00095
00096 #undef C
00097 #undef TMPL
00098 }
00099 #endif // __MMX_KRONECKER_MODULAR_INT_HPP