30 #ifndef __MATH_TOOLS_H__
31 #define __MATH_TOOLS_H__
36 #ifdef _USE_LOCAL_GMP_
62 template <
typename Type>
63 typename std::enable_if<std::is_unsigned<Type>::value, Type>::type
67 << (
sizeof(Type) * 8 -
75 if (n >= root + place) {
93 template <
typename Type>
94 typename std::enable_if<std::is_unsigned<Type>::value, Type>::type
101 << (
sizeof(Type) * 8 -
110 if (n >= root + place) {
129 template <
typename Type>
130 vector<typename std::enable_if<std::is_unsigned<Type>::value, Type>::type>
133 static vector<vector<Type>> divisors_(
134 vector<vector<Type>>(60, vector<Type>(0)));
135 static vector<vector<Type>> divisors_nonTrivialOnly_(
136 vector<vector<Type>>(60, vector<Type>(0)));
139 if (nonTrivialOnly && divisors_nonTrivialOnly_[n - 1].size())
140 return divisors_nonTrivialOnly_[n - 1];
142 if (!nonTrivialOnly && divisors_[n - 1].size())
143 return divisors_[n - 1];
147 static vector<vector<Type>> divisors_ = vector<vector<Type>>(
149 vector<Type>({1, 2}),
150 vector<Type>({1, 3}),
151 vector<Type>({1, 2, 4}),
152 vector<Type>({1, 5}),
153 vector<Type>({1, 2, 3, 6}),
154 vector<Type>({1, 7}),
155 vector<Type>({1, 2, 4, 8}),
156 vector<Type>({1, 3, 9}),
157 vector<Type>({1, 2, 5, 10}),
158 vector<Type>({1, 11}),
159 vector<Type>({1, 2, 3, 4, 6, 12}),
160 vector<Type>({1, 13}),
161 vector<Type>({1, 2, 7, 14}),
162 vector<Type>({1, 3, 5, 15}),
163 vector<Type>({1, 2, 4, 8, 16}),
164 vector<Type>({1, 17}),
165 vector<Type>({1, 2, 3, 6, 9, 18}),
166 vector<Type>({1, 19}),
167 vector<Type>({1, 2, 4, 5, 10, 20}),
168 vector<Type>({1, 3, 7, 21}),
169 vector<Type>({1, 2, 11, 22}),
170 vector<Type>({1, 23}),
171 vector<Type>({1, 2, 3, 4, 6, 8, 12, 24}),
172 vector<Type>({1, 5, 25}),
173 vector<Type>({1, 2, 13, 26}),
174 vector<Type>({1, 3, 9, 27}),
175 vector<Type>({1, 2, 4, 7, 14, 28}),
176 vector<Type>({1, 29}),
177 vector<Type>({1, 2, 3, 5, 6, 10, 15, 30}),
178 vector<Type>({1, 31}),
179 vector<Type>({1, 2, 4, 8, 16, 32}),
180 vector<Type>({1, 3, 11, 33}),
181 vector<Type>({1, 2, 17, 34}),
182 vector<Type>({1, 5, 7, 35}),
183 vector<Type>({1, 2, 3, 4, 6, 9, 12, 18, 36}),
184 vector<Type>({1, 37}),
185 vector<Type>({1, 2, 19, 38}),
186 vector<Type>({1, 3, 13, 39}),
187 vector<Type>({1, 2, 4, 5, 8, 10, 20, 40}),
188 vector<Type>({1, 41}),
189 vector<Type>({1, 2, 3, 6, 7, 14, 21, 42}),
190 vector<Type>({1, 43}),
191 vector<Type>({1, 2, 4, 11, 22, 44}),
192 vector<Type>({1, 3, 5, 9, 15, 45}),
193 vector<Type>({1, 2, 23, 46}),
194 vector<Type>({1, 47}),
195 vector<Type>({1, 2, 3, 4, 6, 8, 12, 16, 24, 48}),
196 vector<Type>({1, 7, 49}),
197 vector<Type>({1, 2, 5, 10, 25, 50}),
198 vector<Type>({1, 3, 17, 51}),
199 vector<Type>({1, 2, 4, 13, 26, 52}),
200 vector<Type>({1, 53}),
201 vector<Type>({1, 2, 3, 6, 9, 18, 27, 54}),
202 vector<Type>({1, 5, 11, 55}),
203 vector<Type>({1, 2, 4, 7, 8, 14, 28, 56}),
204 vector<Type>({1, 3, 19, 57}),
205 vector<Type>({1, 2, 29, 58}),
206 vector<Type>({1, 59}),
207 vector<Type>({1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60})});
208 static vector<vector<Type>> divisors_nonTrivialOnly_ =
209 vector<vector<Type>>({vector<Type>(0),
214 vector<Type>({2, 3}),
216 vector<Type>({2, 4}),
218 vector<Type>({2, 5}),
220 vector<Type>({2, 3, 4, 6}),
222 vector<Type>({2, 7}),
223 vector<Type>({3, 5}),
224 vector<Type>({2, 4, 8}),
226 vector<Type>({2, 3, 6, 9}),
228 vector<Type>({2, 4, 5, 10}),
229 vector<Type>({3, 7}),
230 vector<Type>({2, 11}),
232 vector<Type>({2, 3, 4, 6, 8, 12}),
234 vector<Type>({2, 13}),
235 vector<Type>({3, 9}),
236 vector<Type>({2, 4, 7, 14}),
238 vector<Type>({2, 3, 5, 6, 10, 15}),
240 vector<Type>({2, 4, 8, 16}),
241 vector<Type>({3, 11}),
242 vector<Type>({2, 17}),
243 vector<Type>({5, 7}),
244 vector<Type>({2, 3, 4, 6, 9, 12, 18}),
246 vector<Type>({2, 19}),
247 vector<Type>({3, 13}),
248 vector<Type>({2, 4, 5, 8, 10, 20}),
250 vector<Type>({2, 3, 6, 7, 14, 21}),
252 vector<Type>({2, 4, 11, 22}),
253 vector<Type>({3, 5, 9, 15}),
254 vector<Type>({2, 23}),
256 vector<Type>({2, 3, 4, 6, 8, 12, 16, 24}),
258 vector<Type>({2, 5, 10, 25}),
259 vector<Type>({3, 17}),
260 vector<Type>({2, 4, 13, 26}),
262 vector<Type>({2, 3, 6, 9, 18, 27}),
263 vector<Type>({5, 11}),
264 vector<Type>({2, 4, 7, 8, 14, 28}),
265 vector<Type>({3, 19}),
266 vector<Type>({2, 29}),
268 vector<Type>({2, 3, 4, 5, 6, 10, 12, 15, 20, 30})});
272 return divisors_nonTrivialOnly_[n - 1];
274 return divisors_[n - 1];
278 vector<Type> divisors;
280 if (!nonTrivialOnly) {
281 divisors.push_back(1);
282 divisors.push_back(n);
286 for (Type i(2); i <= max; i++) {
289 divisors.push_back(i);
291 divisors.push_back(temp);
297 divisors_nonTrivialOnly_[n - 1] = iDivisors;
299 divisors_[n - 1] = iDivisors;
312 template <
typename Type>
313 typename std::enable_if<std::is_unsigned<Type>::value, Type>::type
316 unsigned int r = u % v;
348 Type nWork(n < 0 ? -n : n);
352 return vector<Type>();
362 for (
unsigned int i(1); i < 1229 && nWork > 1; i++) {
372 Type iDivisor(10007);
374 if (!(nWork % iDivisor)) {
375 primes.push_back(iDivisor);
378 while (!(nWork % iDivisor))
394 template <
typename Type>
395 typename std::enable_if<std::is_unsigned<Type>::value,
396 map<Type, unsigned int>>::type
398 map<Type, unsigned int> primes;
401 return map<Type, unsigned int>();
413 for (
unsigned int i(1); i < 1229 && n > 1; i++) {
425 Type iDivisor(10007);
427 if (!(n % iDivisor)) {
428 primes[iDivisor] = 1;
431 while (!(n % iDivisor)) {
450 Type nWork(n > 0 ? n : -n), res(1), square;
455 for (
unsigned int i(0); i < 1229 && nWork > 1; i++) {
458 while (nWork % square == 0)
467 Type iDivisor(10007);
469 square = iDivisor * iDivisor;
471 while (nWork % square == 0)
474 if (nWork % iDivisor == 0) {
482 return (n < 0 ? -res : res);
492 template <
typename Type>
493 inline Type
ceilQuotient(
const Type &numerator,
const Type &denominator) {
494 return ((numerator % denominator) ? numerator / denominator + 1
495 : numerator / denominator);
506 template <
typename Type>
507 typename std::enable_if<std::is_unsigned<Type>::value, Type>::type
511 while (denominator * (tRes + 1) * (tRes + 1) <= numerator)
518 const mpz_class &denominator);
520 const mpz_class &denominator);
530 template <
typename Type>
531 typename std::enable_if<std::is_unsigned<Type>::value, Type>::type
536 Type tRes((numerator % denominator) != 0 ? numerator / denominator + 1
537 : numerator / denominator);
540 while (numerator <= denominator * (tRes - 1) * (tRes - 1))
type ugcd(type u, type v)
Definition: mpz_rational.cpp:25