carl  24.04
Computer ARithmetic Library
operations.h
Go to the documentation of this file.
1 /**
2  * @file adaption_gmpxx/operations.h
3  * @ingroup gmpxx
4  * @author Gereon Kremer <gereon.kremer@cs.rwth-aachen.de>
5  * @author Sebastian Junges
6  *
7  * @warning This file should never be included directly but only via operations.h
8  */
9 
10 #pragma once
11 
12 #ifndef INCLUDED_FROM_NUMBERS_H
13 static_assert(false, "This file may only be included indirectly by numbers.h");
14 #endif
15 
17 #include "include.h"
18 #include "typetraits.h"
19 
20 #include <climits>
21 #include <cmath>
22 #include <cstddef>
23 #include <iostream>
24 #include <sstream>
25 #include <vector>
26 
27 namespace carl {
28 
29 
30 /**
31  * Informational functions
32  *
33  * The following functions return informations about the given numbers.
34  */
35 inline bool is_zero(const mpz_class& n) {
36  return constant_zero<mpz_class>::get() == n;
37 }
38 
39 inline bool is_zero(const mpq_class& n) {
40  return constant_zero<mpz_class>::get() == n;
41 }
42 
43 inline bool is_one(const mpz_class& n) {
44  return constant_one<mpz_class>::get() == n;
45 }
46 
47 inline bool is_one(const mpq_class& n) {
48  return constant_one<mpz_class>::get() == n;
49 }
50 
51 inline bool is_positive(const mpz_class& n) {
52  return n > constant_zero<mpz_class>::get();
53 }
54 
55 inline bool is_positive(const mpq_class& n) {
56  return n > constant_zero<mpq_class>::get();
57 }
58 
59 inline bool is_negative(const mpz_class& n) {
61 }
62 
63 inline bool is_negative(const mpq_class& n) {
65 }
66 
67 inline mpz_class get_num(const mpq_class& n) {
68  return n.get_num();
69 }
70 
71 inline mpz_class get_num(const mpz_class& n) {
72  return n;
73 }
74 
75 inline mpz_class get_denom(const mpq_class& n) {
76  return n.get_den();
77 }
78 
79 inline mpz_class get_denom(const mpz_class& n) {
80  return n;
81 }
82 
83 inline bool is_integer(const mpq_class& n) {
84  return 0 != mpz_divisible_p(n.get_num_mpz_t(), n.get_den_mpz_t());
85 }
86 
87 inline bool is_integer(const mpz_class& /*unused*/) {
88  return true;
89 }
90 
91 /**
92  * Get the bit size of the representation of a integer.
93  * @param n An integer.
94  * @return Bit size of n.
95  */
96 inline std::size_t bitsize(const mpz_class& n) {
97  return mpz_sizeinbase(n.__get_mp(),2);
98 }
99 /**
100  * Get the bit size of the representation of a fraction.
101  * @param n A fraction.
102  * @return Bit size of n.
103  */
104 inline std::size_t bitsize(const mpq_class& n) {
105  return mpz_sizeinbase(get_num(n).__get_mp(),2) + mpz_sizeinbase(get_denom(n).__get_mp(),2);
106 }
107 
108 /**
109  * Conversion functions
110  *
111  * The following function convert types to other types.
112  */
113 
114 inline double to_double(const mpq_class& n) {
115  return n.get_d();
116 }
117 inline double to_double(const mpz_class& n) {
118  return n.get_d();
119 }
120 
121 template<typename Integer>
122 inline Integer to_int(const mpz_class& n);
123 
124 template<>
125 inline sint to_int<sint>(const mpz_class& n) {
126  assert(n <= std::numeric_limits<signed long>::max());
127  assert(n >= std::numeric_limits<signed long>::min());
128  return mpz_get_si(n.get_mpz_t());
129 }
130 template<>
131 inline uint to_int<uint>(const mpz_class& n) {
132  assert(n <= std::numeric_limits<unsigned long>::max());
133  assert(n >= std::numeric_limits<unsigned long>::min());
134  return mpz_get_ui(n.get_mpz_t());
135 }
136 
137 template<typename Integer>
138 inline Integer to_int(const mpq_class& n);
139 
140 /**
141  * Convert a fraction to an integer.
142  * This method assert, that the given fraction is an integer, i.e. that the denominator is one.
143  * @param n A fraction.
144  * @return An integer.
145  */
146 template<>
147 inline mpz_class to_int<mpz_class>(const mpq_class& n) {
148  assert(is_integer(n));
149  return get_num(n);
150 }
151 
152 template<typename To, typename From>
153 inline To from_int(const From& n);
154 
155 template<>
156 inline mpz_class from_int(const uint& n) {
157  mpz_class res;
158  mpz_set_ui(res.get_mpz_t(), n);
159  return res;
160  //assert(n <= std::numeric_limits<unsigned long>::max());
161  //assert(n >= std::numeric_limits<unsigned long>::min());
162  //return mpz_class(static_cast<unsigned long>(n));
163 }
164 
165 template<>
166 inline mpz_class from_int(const sint& n) {
167  mpz_class res;
168  mpz_set_si(res.get_mpz_t(), n);
169  return res;
170  //assert(n <= std::numeric_limits<signed long>::max());
171  //assert(n >= std::numeric_limits<signed long>::min());
172  //return mpz_class(static_cast<signed long>(n));
173 }
174 
175 template<>
176 inline mpq_class from_int(const uint& n) {
177  return from_int<mpz_class>(n);
178 }
179 
180 template<>
181 inline mpq_class from_int(const sint& n) {
182  return from_int<mpz_class>(n);
183 }
184 
185 /**
186  * Convert a fraction to an unsigned.
187  * @param n A fraction.
188  * @return n as unsigned.
189  */
190 template<>
191 inline sint to_int<sint>(const mpq_class& n) {
192  return to_int<sint>(to_int<mpz_class>(n));
193 }
194 template<>
195 inline uint to_int<uint>(const mpq_class& n) {
196  return to_int<uint>(to_int<mpz_class>(n));
197 }
198 
199 template<typename T>
201 
202 template<>
203 inline mpq_class rationalize<mpq_class>(float n) {
204  assert(!std::isinf(n) && !std::isnan(n));
205  return mpq_class(n);
206 }
207 
208 template<>
209 inline mpq_class rationalize<mpq_class>(double n) {
210  assert(!std::isinf(n) && !std::isnan(n));
211  return mpq_class(n);
212 }
213 
214 template<>
215 inline mpq_class rationalize<mpq_class>(int n) {
216  return mpq_class(n);
217 }
218 
219 template<>
220 inline mpq_class rationalize<mpq_class>(uint n) {
221  return mpq_class(static_cast<unsigned long>(n));
222 }
223 
224 template<>
225 inline mpq_class rationalize<mpq_class>(sint n) {
226  return mpq_class(static_cast<signed long>(n));
227 }
228 
229 template<>
231  return n;
232 }
233 
234 template<>
235 mpz_class parse<mpz_class>(const std::string& n);
236 
237 template<>
238 bool try_parse<mpz_class>(const std::string& n, mpz_class& res);
239 
240 template<>
241 mpq_class parse<mpq_class>(const std::string& n);
242 
243 template<>
244 bool try_parse<mpq_class>(const std::string& n, mpq_class& res);
245 
246 /**
247  * Basic Operators
248  *
249  * The following functions implement simple operations on the given numbers.
250  */
251 
252 inline mpz_class abs(const mpz_class& n) {
253  mpz_class res;
254  mpz_abs(res.get_mpz_t(), n.get_mpz_t());
255  return res;
256 }
257 
258 inline mpq_class abs(const mpq_class& n) {
259  mpq_class res;
260  mpq_abs(res.get_mpq_t(), n.get_mpq_t());
261  return res;
262 }
263 
264 inline mpz_class round(const mpq_class& n) {
265  if (is_zero(mpz_class(n.get_num_mpz_t()))) return carl::constant_zero<mpz_class>::get();
266  mpz_class res;
267  mpz_class rem;
268  mpz_fdiv_qr(res.get_mpz_t(), rem.get_mpz_t(), n.get_num_mpz_t(), n.get_den_mpz_t());
269  rem *= 2;
270  if (rem >= get_denom(n)) ++res;
271  return res;
272 }
273 
274 inline mpz_class round(const mpz_class& n) {
275  return n;
276 }
277 
278 inline mpz_class floor(const mpq_class& n) {
279  if (is_zero(mpz_class(n.get_num_mpz_t()))) return carl::constant_zero<mpz_class>::get();
280  mpz_class res;
281  mpz_fdiv_q(res.get_mpz_t(), n.get_num_mpz_t(), n.get_den_mpz_t());
282  return res;
283 }
284 
285 inline mpz_class floor(const mpz_class& n) {
286  return n;
287 }
288 
289 inline mpz_class ceil(const mpq_class& n) {
290  if (is_zero(mpz_class(n.get_num_mpz_t()))) return carl::constant_zero<mpz_class>::get();
291  mpz_class res;
292  mpz_cdiv_q(res.get_mpz_t(), n.get_num_mpz_t(), n.get_den_mpz_t());
293  return res;
294 }
295 inline mpz_class ceil(const mpz_class& n) {
296  return n;
297 }
298 
299 inline mpz_class gcd(const mpz_class& a, const mpz_class& b) {
300  mpz_class res;
301  mpz_gcd(res.get_mpz_t(), a.get_mpz_t(), b.get_mpz_t());
302  return res;
303 }
304 
305 inline mpz_class lcm(const mpz_class& a, const mpz_class& b) {
306  mpz_class res;
307  mpz_lcm(res.get_mpz_t(), a.get_mpz_t(), b.get_mpz_t());
308  return res;
309 }
310 
311 inline mpq_class gcd(const mpq_class& a, const mpq_class& b) {
312  mpz_class resNum;
313  mpz_gcd(resNum.get_mpz_t(), get_num(a).get_mpz_t(), get_num(b).get_mpz_t());
314  mpz_class resDen;
315  mpz_lcm(resDen.get_mpz_t(), get_denom(a).get_mpz_t(), get_denom(b).get_mpz_t());
316  mpq_class resqNum;
317  mpq_set_z(resqNum.get_mpq_t(), resNum.get_mpz_t());
318  mpq_class resqDen;
319  mpq_set_z(resqDen.get_mpq_t(), resDen.get_mpz_t());
320  mpq_class res;
321  mpq_div(res.get_mpq_t(), resqNum.get_mpq_t(), resqDen.get_mpq_t());
322  return res;
323 }
324 
325 /**
326  * Calculate the greatest common divisor of two integers.
327  * Stores the result in the first argument.
328  * @param a First argument.
329  * @param b Second argument.
330  * @return Updated a.
331  */
332 inline mpz_class& gcd_assign(mpz_class& a, const mpz_class& b) {
333  a = carl::gcd(a,b);
334  return a;
335 }
336 
337 /**
338  * Calculate the greatest common divisor of two integers.
339  * Stores the result in the first argument.
340  * @param a First argument.
341  * @param b Second argument.
342  * @return Updated a.
343  */
344 inline mpq_class& gcd_assign(mpq_class& a, const mpq_class& b) {
345  a = carl::gcd(a,b);
346  return a;
347 }
348 
349 inline mpq_class lcm(const mpq_class& a, const mpq_class& b) {
350  mpz_class resNum;
351  mpz_lcm(resNum.get_mpz_t(), get_num(a).get_mpz_t(), get_num(b).get_mpz_t());
352  mpz_class resDen;
353  mpz_gcd(resDen.get_mpz_t(), get_denom(a).get_mpz_t(), get_denom(b).get_mpz_t());
354  mpq_class resqNum;
355  mpq_set_z(resqNum.get_mpq_t(), resNum.get_mpz_t());
356  mpq_class resqDen;
357  mpq_set_z(resqDen.get_mpq_t(), resDen.get_mpz_t());
358  mpq_class res;
359  mpq_div(res.get_mpq_t(), resqNum.get_mpq_t(), resqDen.get_mpq_t());
360  return res;
361 }
362 
363 inline mpq_class log(const mpq_class& n) {
364  return carl::rationalize<mpq_class>(std::log(mpq_class(n).get_d()));
365 }
366 inline mpq_class log10(const mpq_class& n) {
367  return carl::rationalize<mpq_class>(std::log10(mpq_class(n).get_d()));
368 }
369 
370 inline mpq_class sin(const mpq_class& n) {
371  return carl::rationalize<mpq_class>(std::sin(mpq_class(n).get_d()));
372 }
373 
374 inline mpq_class cos(const mpq_class& n) {
375  return carl::rationalize<mpq_class>(std::cos(mpq_class(n).get_d()));
376 }
377 
378 template<>
379 inline mpz_class pow(const mpz_class& basis, std::size_t exp) {
380  mpz_class res;
381  mpz_pow_ui(res.get_mpz_t(), basis.get_mpz_t(), exp);
382  return res;
383 }
384 
385 template<>
386 inline mpq_class pow(const mpq_class& basis, std::size_t exp) {
387  mpz_class den = basis.get_den();
388  mpz_class powDen;
389  mpz_pow_ui(powDen.get_mpz_t(), den.get_mpz_t(), exp);
390  mpz_class num = basis.get_num();
391  mpz_class powNum;
392  mpz_pow_ui(powNum.get_mpz_t(), num.get_mpz_t(), exp);
393  mpq_class resNum;
394  mpq_set_z(resNum.get_mpq_t(), powNum.get_mpz_t());
395  mpq_class resDen;
396  mpq_set_z(resDen.get_mpq_t(), powDen.get_mpz_t());
397  mpq_class res;
398  mpq_div(res.get_mpq_t(), resNum.get_mpq_t(), resDen.get_mpq_t());
399  return res;
400 }
401 
402 /**
403  * Calculate the square root of a fraction if possible.
404  *
405  * @param a The fraction to calculate the square root for.
406  * @param b A reference to the rational, in which the result is stored.
407  * @return true, if the number to calculate the square root for is a square;
408  * false, otherwise.
409  */
410 bool sqrt_exact(const mpq_class& a, mpq_class& b);
411 
412 mpq_class sqrt(const mpq_class& a);
413 
414 std::pair<mpq_class,mpq_class> sqrt_safe(const mpq_class& a);
415 
416 /**
417  * Calculate the nth root of a fraction.
418  * The precise result is contained in the resulting interval.
419  */
420 std::pair<mpq_class,mpq_class> root_safe(const mpq_class& a, uint n);
421 
422 /**
423  * Compute square root in a fast but less precise way.
424  * Use cln::sqrt() to obtain an approximation. If the result is rational, i.e. the result is exact, use this result.
425  * Otherwise use the nearest integers as bounds on the square root.
426  * @param a Some number.
427  * @return [x,x] if sqrt(a) = x is rational, otherwise [y,z] for y,z integer and y < sqrt(a) < z.
428  */
429 std::pair<mpq_class,mpq_class> sqrt_fast(const mpq_class& a);
430 
431 inline mpz_class mod(const mpz_class& n, const mpz_class& m) {
432  // TODO: In order to have the same result as division of native signed integer we have to
433  // make it that complicated, as mpz_mod always returns positive integer. Maybe there is a better way.
434  mpz_class res;
435  mpz_mod(res.get_mpz_t(), abs(n).get_mpz_t(), m.get_mpz_t());
436  return is_negative(n) ? mpz_class(-res) : res;
437 }
438 
439 inline mpz_class remainder(const mpz_class& n, const mpz_class& m) {
440  return mod(n,m);
441 }
442 
443 inline mpz_class quotient(const mpz_class& n, const mpz_class& d)
444 {
445  // TODO: In order to have the same result as division of native signed integer we have to
446  // make it that complicated, as mpz_div does round differently. Maybe there is a better way.
447  mpz_class res;
448  mpz_div(res.get_mpz_t(), abs(n).get_mpz_t(), abs(d).get_mpz_t());
449  return is_negative(n) == is_negative(d) ? res : mpz_class(-res);
450 }
451 
452 inline mpz_class operator/(const mpz_class& n, const mpz_class& d)
453 {
454  return quotient(n,d);
455 }
456 
457 inline mpq_class quotient(const mpq_class& n, const mpq_class& d)
458 {
459  mpq_class res;
460  mpq_div(res.get_mpq_t(), n.get_mpq_t(), d.get_mpq_t());
461  return res;
462 }
463 
464 inline mpq_class operator/(const mpq_class& n, const mpq_class& d)
465 {
466  return quotient(n,d);
467 }
468 
469 inline void divide(const mpz_class& dividend, const mpz_class& divisor, mpz_class& quotient, mpz_class& remainder) {
470  mpz_divmod(quotient.get_mpz_t(), remainder.get_mpz_t(), dividend.get_mpz_t(), divisor.get_mpz_t());
471 }
472 
473 /**
474  * Divide two fractions.
475  * @param a First argument.
476  * @param b Second argument.
477  * @return \f$ a / b \f$.
478  */
479 inline mpq_class div(const mpq_class& a, const mpq_class& b) {
480  return carl::quotient(a,b);
481 }
482 
483 /**
484  * Divide two integers.
485  * Asserts that the remainder is zero.
486  * @param a First argument.
487  * @param b Second argument.
488  * @return \f$ a / b \f$.
489  */
490 inline mpz_class div(const mpz_class& a, const mpz_class& b) {
491  assert(carl::mod(a, b) == 0);
492  return carl::quotient(a, b);
493 }
494 
495 /**
496  * Divide two integers.
497  * Asserts that the remainder is zero.
498  * Stores the result in the first argument.
499  * @param a First argument.
500  * @param b Second argument.
501  * @return \f$ a / b \f$.
502  */
503 inline mpz_class& div_assign(mpz_class& a, const mpz_class& b) {
504  a = carl::quotient(a, b);
505  return a;
506 }
507 /**
508  * Divide two integers.
509  * Asserts that the remainder is zero.
510  * Stores the result in the first argument.
511  * @param a First argument.
512  * @param b Second argument.
513  * @return \f$ a / b \f$.
514  */
515 inline mpq_class& div_assign(mpq_class& a, const mpq_class& b) {
516  a = carl::quotient(a, b);
517  return a;
518 }
519 
520 inline mpq_class reciprocal(const mpq_class& a) {
521  mpq_class res;
522  mpq_inv(res.get_mpq_t(), a.get_mpq_t());
523  return res;
524 }
525 
526 inline mpq_class operator *(const mpq_class& lhs, const mpq_class& rhs)
527 {
528  mpq_class res;
529  mpq_mul(res.get_mpq_t(), lhs.get_mpq_t(), rhs.get_mpq_t());
530  return res;
531 }
532 
533 std::string toString(const mpq_class& _number, bool _infix=true);
534 
535 std::string toString(const mpz_class& _number, bool _infix=true);
536 
537 }
mpz_class Integer
carl is the main namespace for the library.
T rationalize(const PreventConversion< mpq_class > &)
Interval< Number > ceil(const Interval< Number > &_in)
Method which returns the next larger integer of the passed number or the number itself,...
Definition: Interval.h:1535
std::uint64_t uint
Definition: numbers.h:16
Interval< Number > operator/(const Interval< Number > &lhs, const Number &rhs)
Operator for the division of an interval and a number.
Definition: operators.h:453
std::pair< cln::cl_RA, cln::cl_RA > sqrt_fast(const cln::cl_RA &a)
Compute square root in a fast but less precise way.
double sin(double in)
Definition: operations.h:153
std::string toString(Relation r)
Definition: Relation.h:73
Interval< Number > abs(const Interval< Number > &_in)
Method which returns the absolute value of the passed number.
Definition: Interval.h:1511
bool is_positive(const cln::cl_I &n)
Definition: operations.h:39
Interval< Number > floor(const Interval< Number > &_in)
Method which returns the next smaller integer of this number or the number itself,...
Definition: Interval.h:1523
Interval< Number > quotient(const Interval< Number > &_lhs, const Interval< Number > &_rhs)
Implements the division with remainder.
Definition: Interval.h:1488
mpq_class rationalize< mpq_class >(float n)
Definition: operations.h:203
bool sqrt_exact(const cln::cl_RA &a, cln::cl_RA &b)
Calculate the square root of a fraction if possible.
cln::cl_I mod(const cln::cl_I &a, const cln::cl_I &b)
Calculate the remainder of the integer division.
Definition: operations.h:445
std::pair< cln::cl_RA, cln::cl_RA > root_safe(const cln::cl_RA &a, uint n)
cln::cl_RA reciprocal(const cln::cl_RA &a)
Definition: operations.h:546
cln::cl_I gcd(const cln::cl_I &a, const cln::cl_I &b)
Calculate the greatest common divisor of two integers.
Definition: operations.h:310
Interval< Number > exp(const Interval< Number > &i)
Definition: Exponential.h:10
cln::cl_RA log10(const cln::cl_RA &n)
Definition: operations.h:393
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
Definition: Interval.h:1453
Interval< Number > operator*(const Interval< Number > &lhs, const Interval< Number > &rhs)
Operator for the multiplication of two intervals.
Definition: operators.h:386
Integer to_int(const Interval< Number > &_floatInterval)
Casts the Interval to an arbitrary integer type which has a constructor for a native int.
Definition: Interval.h:1500
cln::cl_I get_num(const cln::cl_RA &n)
Extract the numerator from a fraction.
Definition: operations.h:60
Interval< Number > cos(const Interval< Number > &i)
Definition: Trigonometry.h:22
Interval< Number > sqrt(const Interval< Number > &i)
Definition: Power.h:51
uint to_int< uint >(const cln::cl_I &n)
Definition: operations.h:137
void divide(const cln::cl_I &dividend, const cln::cl_I &divisor, cln::cl_I &quotient, cln::cl_I &remainder)
Definition: operations.h:326
bool try_parse< mpq_class >(const std::string &n, mpq_class &res)
Definition: operations.cpp:171
Interval< Number > div(const Interval< Number > &_lhs, const Interval< Number > &_rhs)
Implements the division which assumes that there is no remainder.
Definition: Interval.h:1476
cln::cl_RA & div_assign(cln::cl_RA &a, const cln::cl_RA &b)
Divide two fractions.
Definition: operations.h:478
Interval< Number > log(const Interval< Number > &i)
Definition: Exponential.h:22
bool is_integer(const Interval< Number > &n)
Definition: Interval.h:1445
bool is_negative(const cln::cl_I &n)
Definition: operations.h:47
cln::cl_I get_denom(const cln::cl_RA &n)
Extract the denominator from a fraction.
Definition: operations.h:69
double to_double(const cln::cl_RA &n)
Converts the given fraction to a double.
Definition: operations.h:113
cln::cl_I lcm(const cln::cl_I &a, const cln::cl_I &b)
Calculate the least common multiple of two integers.
Definition: operations.h:362
cln::cl_I round(const cln::cl_RA &n)
Round a fraction to next integer.
Definition: operations.h:255
std::int64_t sint
Definition: numbers.h:17
Interval< Number > sin(const Interval< Number > &i)
Definition: Trigonometry.h:10
mpz_class parse< mpz_class >(const std::string &n)
Definition: operations.cpp:150
std::pair< cln::cl_RA, cln::cl_RA > sqrt_safe(const cln::cl_RA &a)
Calculate the square root of a fraction.
double log(double in)
Definition: operations.h:177
sint to_int< sint >(const cln::cl_I &n)
Definition: operations.h:131
mpz_class to_int< mpz_class >(const mpq_class &n)
Convert a fraction to an integer.
Definition: operations.h:147
std::size_t bitsize(const cln::cl_I &n)
Get the bit size of the representation of a integer.
Definition: operations.h:96
cln::cl_I remainder(const cln::cl_I &a, const cln::cl_I &b)
Calculate the remainder of the integer division.
Definition: operations.h:526
double log10(double in)
Definition: operations.h:180
double cos(double in)
Definition: operations.h:157
To from_int(const From &n)
cln::cl_I & gcd_assign(cln::cl_I &a, const cln::cl_I &b)
Calculate the greatest common divisor of two integers.
Definition: operations.h:321
bool try_parse< mpz_class >(const std::string &n, mpz_class &res)
Definition: operations.cpp:158
Interval< Number > pow(const Interval< Number > &i, Integer exp)
Definition: Power.h:11
mpq_class parse< mpq_class >(const std::string &n)
Definition: operations.cpp:163
bool is_one(const Interval< Number > &i)
Check if this interval is a point-interval containing 1.
Definition: Interval.h:1462
auto & get(const std::string &name)
static const T & get()
Definition: constants.h:42
static const T & get()
Definition: constants.h:51