00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <numerix/integer.hpp>
00014 namespace mmx {
00015
00016
00017
00018
00019
00020 #if !defined(__GNU_MP__)
00021 template<typename I> static inline void
00022 encode_kronecker_int (integer& dest, const I* src, nat n, xnat bits) {
00023 if (n == 0) dest= 0;
00024 else if (n == 1) dest= src[0];
00025 else {
00026 nat h= n>>1;
00027 integer aux;
00028 encode_kronecker_int (aux , src+h, n-h, bits);
00029 encode_kronecker_int (dest, src , h , bits);
00030 dest += (aux << (h*bits));
00031 }
00032 }
00033
00034 #define IMPLEMENTATION_HELPER(I) \
00035 void \
00036 encode_kronecker (integer& dest, const I* src, nat n, xnat bits) { \
00037 encode_kronecker_int (dest, src, n, bits); }
00038 IMPLEMENTATION_HELPER (unsigned char)
00039 IMPLEMENTATION_HELPER (unsigned short)
00040 IMPLEMENTATION_HELPER (unsigned int)
00041 IMPLEMENTATION_HELPER (unsigned long int)
00042 IMPLEMENTATION_HELPER (unsigned long long int)
00043 IMPLEMENTATION_HELPER (signed char)
00044 IMPLEMENTATION_HELPER (short int)
00045 IMPLEMENTATION_HELPER (int)
00046 IMPLEMENTATION_HELPER (long int)
00047 IMPLEMENTATION_HELPER (long long int)
00048 #undef IMPLEMENTATION_HELPER
00049
00050 template<typename I> static inline void
00051 decode_kronecker_int (I* dest, nat n, xnat bits, const integer& src) {
00052 static const integer mask= (integer (1) << (8 * sizeof (I))) - 1;
00053 if (n == 0);
00054 else if (n == 1)
00055 dest[0]= src > 0 ? as<I> (src & mask) : - as<I> ((-src) & mask);
00056 else if (src > 0) {
00057 nat h= n>>1;
00058 integer aux= src >> (h*bits);
00059 if (src[h*bits-1]) aux += 1;
00060 decode_kronecker (dest+h, n-h, bits, aux);
00061 aux= src - (aux << (h*bits));
00062 decode_kronecker (dest, h, bits, aux);
00063 }
00064 else {
00065 integer bis= -src;
00066 nat h= n>>1;
00067 integer aux= bis >> (h*bits);
00068 if (bis[h*bits-1]) aux += 1;
00069 decode_kronecker (dest+h, n-h, bits, -aux);
00070 aux= bis - (aux << (h*bits));
00071 decode_kronecker (dest, h, bits, -aux);
00072 }
00073 }
00074
00075 template<typename I> static inline void
00076 decode_kronecker_uint (I* dest, nat n, xnat bits, const integer& src) {
00077 if (n == 0);
00078 else if (n == 1) dest[0]= as<I> (src);
00079 else {
00080 nat h= n>>1;
00081 integer aux= src >> (h*bits);
00082 decode_kronecker_int (dest+h, n-h, bits, aux);
00083 aux= src - (aux << (h*bits));
00084 decode_kronecker_int (dest, h, bits, aux);
00085 }
00086 }
00087
00088 #define IMPLEMENTATION_HELPER(I) \
00089 void \
00090 decode_kronecker (I* dest, nat n, xnat bits, const integer& src) { \
00091 decode_kronecker_uint (dest, n, bits, src); }
00092 IMPLEMENTATION_HELPER (unsigned char)
00093 IMPLEMENTATION_HELPER (unsigned short int)
00094 IMPLEMENTATION_HELPER (unsigned int)
00095 IMPLEMENTATION_HELPER (unsigned long int)
00096 IMPLEMENTATION_HELPER (unsigned long long int)
00097 #undef IMPLEMENTATION_HELPER
00098
00099 #define IMPLEMENTATION_HELPER(I) \
00100 void \
00101 decode_kronecker (I* dest, nat n, xnat bits, const integer& src) { \
00102 decode_kronecker_int (dest, n, bits, src); }
00103 IMPLEMENTATION_HELPER (signed char)
00104 IMPLEMENTATION_HELPER (short int)
00105 IMPLEMENTATION_HELPER (int)
00106 IMPLEMENTATION_HELPER (long int)
00107 IMPLEMENTATION_HELPER (long long int)
00108 #undef IMPLEMENTATION_HELPER
00109
00110 #else
00111
00112
00113
00114
00115
00116 #define DECLARE_HELPER(I) \
00117 void mpz_encode_kronecker (mpz_t dest, const I* src, \
00118 unsigned long n, unsigned long bits); \
00119 void mpz_decode_kronecker (I* dest, unsigned long n, \
00120 unsigned long bits, const mpz_t src);
00121 DECLARE_HELPER(unsigned char)
00122 DECLARE_HELPER(unsigned short)
00123 DECLARE_HELPER(unsigned int)
00124 DECLARE_HELPER(unsigned long int)
00125 DECLARE_HELPER(unsigned long long int)
00126 #undef DECLARE_HELPER
00127
00128 #define IMPLEMENTATION_HELPER(I) \
00129 void encode_kronecker (integer& dest, \
00130 const I* src, nat n, xnat bits) { \
00131 typedef unsigned_of_helper<I>::type U; \
00132 mpz_encode_kronecker (*dest, (const U*) (const I*) src, \
00133 (unsigned long) n, \
00134 (unsigned long) bits); } \
00135 void decode_kronecker (I* dest, nat n, xnat bits, \
00136 const integer& src) { \
00137 typedef unsigned_of_helper<I>::type U; \
00138 mpz_decode_kronecker ((U*) (void*) dest, (unsigned long) n, \
00139 (unsigned long) bits, *src); }
00140 IMPLEMENTATION_HELPER(signed char)
00141 IMPLEMENTATION_HELPER(unsigned char)
00142 IMPLEMENTATION_HELPER(short int)
00143 IMPLEMENTATION_HELPER(unsigned short)
00144 IMPLEMENTATION_HELPER(int)
00145 IMPLEMENTATION_HELPER(unsigned int)
00146 IMPLEMENTATION_HELPER(long int)
00147 IMPLEMENTATION_HELPER(unsigned long int)
00148 IMPLEMENTATION_HELPER(long long int)
00149 IMPLEMENTATION_HELPER(unsigned long long int)
00150 #undef IMPLEMENTATION_HELPER
00151
00152 #endif // __GNU_MP__
00153
00154
00155
00156
00157
00158 template<typename I> static inline void
00159 mul_kronecker_int (I* dest,
00160 const I* src1, nat n1,
00161 const I* src2, nat n2)
00162 {
00163 if (n1 == 0 && n2 == 0) return;
00164 for (nat i= 0; i < n1 + n2 - 1; i++) dest[i]= 0;
00165 while (n1 > 0 && src1[n1-1] == 0) n1--;
00166 while (n2 > 0 && src2[n2-1] == 0) n2--;
00167 if (n1 == 0 || n2 == 0) return;
00168
00169 xnat bits= 16 * sizeof (I) + bit_size (min (n1, n2));
00170 integer aux1, aux2;
00171 encode_kronecker (aux1, src1, n1, bits);
00172 encode_kronecker (aux2, src2, n2, bits);
00173 integer aux= aux1 * aux2;
00174 decode_kronecker (dest, n1+n2-1, bits, aux);
00175 }
00176
00177 #define IMPLEMENTATION_HELPER(I) \
00178 void \
00179 mul_kronecker (I* dest, const I* src1, nat n1, const I* src2, nat n2) { \
00180 mul_kronecker_int (dest, src1, n1, src2, n2); }
00181 IMPLEMENTATION_HELPER (signed char)
00182 IMPLEMENTATION_HELPER (unsigned char)
00183 IMPLEMENTATION_HELPER (signed short int)
00184 IMPLEMENTATION_HELPER (unsigned short int)
00185 IMPLEMENTATION_HELPER (int)
00186 IMPLEMENTATION_HELPER (unsigned int)
00187 IMPLEMENTATION_HELPER (long int)
00188 IMPLEMENTATION_HELPER (unsigned long int)
00189 IMPLEMENTATION_HELPER (long long int)
00190 IMPLEMENTATION_HELPER (unsigned long long int)
00191 #undef IMPLEMENTATION_HELPER
00192
00193 template<typename I> static inline void
00194 square_kronecker_int (I* dest, const I* src, nat n) {
00195 if (n == 0) return;
00196 for (nat i= 0; i < 2 * n - 1; i++) dest[i]= 0;
00197 while (n > 0 && src[n-1] == 0) n--;
00198 if (n == 0) return;
00199 if (n == 1) { dest[0]= square (src[0]); return; }
00200
00201 xnat bits= 16 * sizeof (I) + bit_size (n);
00202 integer aux1;
00203 encode_kronecker (aux1, src, n, bits);
00204 integer aux= square (aux1);
00205 decode_kronecker (dest, 2*n - 1, bits, aux);
00206 }
00207
00208 #define IMPLEMENTATION_HELPER(I) \
00209 void \
00210 square_kronecker (I* dest, const I* src, nat n) { \
00211 square_kronecker_int (dest, src, n); }
00212 IMPLEMENTATION_HELPER (signed char)
00213 IMPLEMENTATION_HELPER (unsigned char)
00214 IMPLEMENTATION_HELPER (signed short int)
00215 IMPLEMENTATION_HELPER (unsigned short int)
00216 IMPLEMENTATION_HELPER (int)
00217 IMPLEMENTATION_HELPER (unsigned int)
00218 IMPLEMENTATION_HELPER (long int)
00219 IMPLEMENTATION_HELPER (unsigned long int)
00220 IMPLEMENTATION_HELPER (long long int)
00221 IMPLEMENTATION_HELPER (unsigned long long int)
00222 #undef IMPLEMENTATION_HELPER
00223
00224 }