algebramix_doc 0.3
|
00001 00002 /****************************************************************************** 00003 * MODULE : kronecker_modular_int.hpp 00004 * DESCRIPTION: Kronecker tranforms for modular integers 00005 * COPYRIGHT : (C) 2009 Joris van der Hoeven and Gregoire Lecerf 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_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 * Low level Kronecker multiplication for modular ints 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 * Standard routines 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 } // namespace mmx 00099 #endif // __MMX_KRONECKER_MODULAR_INT_HPP