intalg.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002     
00003     intalg.hpp -- Algorithm for integers and "integer-like" structures.
00004 
00005     Этот файл является частью библиотеки Arageli.
00006 
00007     Some functions in this file are part of Anna Bestaeva degree work 2006.
00008     They have been integrated into Arageli by Sergey Lyalin.
00009 
00010     Copyright (C) Nikolai Yu. Zolotykh, 1999--2006
00011     Copyright (C) Sergey S. Lyalin, 2005--2006
00012     Copyright (C) Aleksey Bader, 2005--2006
00013     Copyright (C) Anna Bestaeva, 2006
00014 
00015     University of Nizhni Novgorod, Russia
00016 
00017 *****************************************************************************/
00018 
00019 #ifndef _ARAGELI_intalg_hpp_
00020 #define _ARAGELI_intalg_hpp_
00021 
00022 #include "config.hpp"
00023 
00024 #include <cmath>
00025 
00026 #include "exception.hpp"
00027 #include "type_traits.hpp"
00028 #include "factory.hpp"
00029 #include "cmp.hpp"
00030 #include "gcd.hpp"
00031 #include "powerest.hpp"
00032 
00033 #include "std_import.hpp"
00034 
00035 
00036 namespace Arageli
00037 {
00038 
00039 
00041 
00042 template <typename T, typename T_factory>
00043 inline T inverse_mod (const T& a, const T& m, const T_factory& tfctr)
00044 {
00045     ARAGELI_ASSERT_0(is_positive(a));
00046     ARAGELI_ASSERT_0(m >= 2);
00047 
00048     T u, v;
00049     T r = euclid_bezout(a, m, u, v, tfctr);
00050     ARAGELI_ASSERT_0(is_unit(r));
00051     return is_negative(u) ? u + m : u;
00052 }
00053 
00054 
00056 
00057 template <typename T>
00058 inline T inverse_mod (const T& a, const T& n)
00059 { return inverse_mod(a, n, factory<T>()); }
00060 
00061 
00063 
00064 template <typename T, typename I, typename T_factory>
00065 T power_mod (T a, I n, const T& m, const T_factory& tfctr);
00066 
00068 
00069 template <typename T, typename I>
00070 inline T power_mod (const T& a, const I& n, const T& m)
00071 { return power_mod(a, n, m, factory<T>()); }
00072 
00073 
00074 namespace _Internal
00075 {
00076 
00077 // WARNING! The following functions are here temporary
00078 // tail their functionality will be clear.
00079 // TODO: Understand what these functions do and give more complicated names.
00080 // Then move into Arageli namespace directly.
00081     
00082 //ф-я возвращает с: gcd(a + cb, N) = gcd(a, b, N), 0 <= c <= 2(logN)^1.5
00083 //предпологается, что a, b, N - целые, N > 0, gcd(a, b) = 1
00084 template <typename T> 
00085 T conditioner (const T& a, const T& b, const T& N);
00086 
00087 //ф-я возвращает либо  с: gcd(a + cb, N) = gcd(a, b, N), 0 <= c <= 2(logN)^1.5
00088 //               либо -1, если было увеличено кол-во элементов в разложении числа N
00089 // d  - разложение числа N на взаимно простые множители
00090 template <typename T, typename V>
00091 T conditioner (const T& _a, const T& _b, const T& N, V &d);
00092 
00093 }
00094 
00095 
00096 // WARNING! STRANGE FUNCTION
00097 // TODO: Document!
00098 template <typename T1, typename T2, typename T3>
00099 T3 mod (const T1& a, const T2& b, const T3& d)
00100 { return mod(a*div_mod(unit(a), b, d), d);} // WARNING! div_mod(unit(a), b, d) is inverse of b modulo d
00101 
00102 
00104 template <typename T1, typename T2>
00105 inline T2 mod (const T1& a, const T2& b)
00106 { return prrem(a, b); }
00107 
00108 
00110 template <typename T1, typename T2, typename T3>
00111 T3 div_mod (const T1& a, const T2& b, const T3& d);
00112 
00113 
00115 
00116 template <typename T1, typename T2, typename T3>
00117 inline T3 rem_mod (const T1& a, const T2& b, const T3& d)
00118 { return prrem(a, gcd(b, d)); }
00119 
00120 
00122 template <typename T1, typename T2>
00123 inline T2 ann (const T1& a, const T2& n)
00124 { return n/gcd(a, n);}
00125 
00126 
00127 // TODO: Document it!
00128 template <typename T1, typename T2, typename T3>
00129 T3 quo_mod (const T1& a, const T2& b, const T3& d);
00130 
00131 // TODO: Document it!
00132 template <typename T>
00133 T split (const T& a, const T& d);
00134 
00135 
00136 // TODO: Document it!
00137 template <typename T>
00138 T stab (const T& a, const T& b, const T& N);
00139 
00140 
00141 // TODO: Document it!
00142 template <typename T>
00143 T split_stab (const T& a, const T& b, const T& N);
00144 
00145 
00146 // TODO: Document it and check name conflicts!
00147 // Maybe more complicated name will be better.
00148 template <typename T>
00149 T unit (const T& a, const T& N);
00150 
00151 
00152 // TODO: Document it!
00153 template <typename T>
00154 inline T stab (const T& a, const T& b, const T& N, const T& d)
00155 { return stab(a, b, gcd(d, N)); }
00156 
00157 
00158 // TODO: Document it!
00159 template <typename T>
00160 inline T split_stab (const T& a, const T& b, const T& N, const T& d)
00161 { return split_stab(a, b, gcd(d, N)); }
00162 
00163 
00164 // TODO: Document it!
00165 template <typename T>
00166 T split_mod (const T& a, const T& d);
00167 
00168 
00169 // TODO: Document it!
00170 template <typename T>
00171 T stab_mod (const T& a, const T& b, const T& N);
00172 
00173 
00174 // TODO: Document it!
00175 template <typename T>
00176 inline T stab_mod (const T& a, const T& b, const T& N, const T& d)
00177 { return stab_mod(a, b, gcd(d, N)); }
00178 
00179 
00181 template<typename T>
00182 bool is_invertible_mod (const T& a, const T& N);
00183 
00184 
00186 template <typename T>
00187 inline std::size_t nbits (const T& a)
00188 { return nbits(a, factory<T>()); }
00189 
00190 
00192 template <typename T, typename T_factory>
00193 std::size_t nbits(T a, const T_factory& tfctr);
00194 
00195 
00197 
00198 template <typename T, typename T_factory>
00199 T factorial_successive_multiplication (T a, const T_factory& tfctr);
00200 
00202 template <typename T>
00203 inline T factorial_successive_multiplication (const T& a)
00204 { return factorial_successive_multiplication(a, factory<T>()); }
00205 
00206 
00208 template <typename T, typename T_factory>
00209 T factorial_even_odd_multiplication (T a, const T_factory& tfctr);
00210 
00212 template <typename T>
00213 inline T factorial_even_odd_multiplication (const T& a)
00214 { return factorial_even_odd_multiplication(a, factory<T>()); }
00215 
00216 
00218 template <typename T, typename T_factory>
00219 inline T factorial (const T& a, const T_factory& tfctr)
00220 { return factorial_even_odd_multiplication(a, tfctr); }
00221 
00223 template <typename T>
00224 inline T factorial (const T& a)
00225 { return factorial(a, factory<T>()); }
00226 
00227 
00228 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00230 
00232 
00234 
00235 template <typename T, typename T_factory>
00236 int jacobi (T a, T n, const T_factory& tfctr);
00237 
00238 
00240 
00241 template <typename T>
00242 inline int jacobi (const T& a, const T& n)
00243 { return jacobi(a, n, factory<T>()); }
00244 
00245 
00247 
00249 
00251 template <typename T>
00252 T intsqrt (const T& a);
00253 
00255 
00257 template <typename T, typename TT>
00258 T sqrt_mod_shenks (const T& a, const T& n, const TT& tt);
00259 
00260 
00262 
00264 template <typename T>
00265 inline T sqrt_mod_shenks (const T& a, const T& n)
00266 { return sqrt_mod_shenks(a, n, type_traits<T>()); }
00267 
00268 
00270 
00273 //  Requirement: a is positive. */
00274 //template <typename T>
00275 //inline T intsqrt (const T& a)
00276 //{ return intsqrt(a, type_traits<T>()); }
00277 //
00280 //  Requirement: 0 <= a < n, n is prime and n = 1 (mod 4). */
00281 //template <typename T>
00282 //T sqrt_mod_shenks (const T& a, const T& n, const TT& tt);
00283 //
00284 //
00287 //  Requirement: 0 <= a < n, n is prime and n = 1 (mod 4). */
00288 //template <typename T>
00289 //inline T sqrt_mod_shenks (const T& a, const T& n)
00290 //{ return sqrt_mod_shenks(a, n, type_traits<T>()); }
00291 //
00292 //
00295 //  Requirement: 0 <= a < n, n is prime. */
00296 //template <typename T>
00297 //T sqrt_mod (const T& a, const T& n, const TT& tt);
00298 //
00299 //
00302 //  Requirement: 0 <= a < n, n is prime. */
00303 //template <typename T>
00304 //inline T sqrt_mod (const T& a, const T& n)
00305 //{ return sqrt_mod(a, n, type_traits<T>()); }
00306 
00308 
00309 } // namespace Arageli
00310 
00311 
00312 namespace std
00313 {
00314 
00315 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00317 
00319 
00320 inline char sqrt (char a) { return Arageli::intsqrt(a); }
00321 inline unsigned char sqrt (unsigned char a) { return Arageli::intsqrt(a); }
00322 inline signed char sqrt (signed char a) { return Arageli::intsqrt(a); }
00323 inline unsigned short sqrt (unsigned short a) { return Arageli::intsqrt(a); }
00324 inline signed short sqrt (signed short a) { return Arageli::intsqrt(a); }
00325 inline unsigned int sqrt (unsigned int a) { return Arageli::intsqrt(a); }
00326 inline signed int sqrt (signed int a) { return Arageli::intsqrt(a); }
00327 inline unsigned long sqrt (unsigned long a) { return Arageli::intsqrt(a); }
00328 inline signed long sqrt (signed long a) { return Arageli::intsqrt(a); }
00329 
00330 #ifdef ARAGELI_INT64_SUPPORT
00331     inline unsigned __int64 sqrt (unsigned __int64 a) { return Arageli::intsqrt(a); }
00332     inline signed __int64 sqrt (signed __int64 a) { return Arageli::intsqrt(a); }
00333 #endif
00334 
00335 #ifdef ARAGELI_LONG_LONG_SUPPORT
00336     inline unsigned long long sqrt (unsigned long long a) { return Arageli::intsqrt(a); }
00337     inline signed long long sqrt (signed long long a) { return Arageli::intsqrt(a); }
00338 #endif
00339 
00341 
00342 
00343 }
00344 
00345 
00346 #ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
00347     #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_INTALG
00348     #include "intalg.cpp"
00349     #undef  ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_INTALG
00350 #endif
00351 
00352 
00353 #endif  //  #ifndef _ARAGELI_intalg_hpp_

Generated on Thu Aug 31 17:38:06 2006 for Arageli by  doxygen 1.4.7