carl  24.04
Computer ARithmetic Library
operations.h
Go to the documentation of this file.
1 /**
2  * @file adaption_cln/operations.h
3  * @ingroup cln
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 "typetraits.h"
18 #include <cassert>
19 #include <limits>
20 
21 namespace carl {
22 
23 inline bool is_zero(const cln::cl_I& n) {
24  return zerop(n);
25 }
26 
27 inline bool is_zero(const cln::cl_RA& n) {
28  return zerop(n);
29 }
30 
31 inline bool is_one(const cln::cl_I& n) {
32  return n == constant_one<cln::cl_I>::get();
33 }
34 
35 inline bool is_one(const cln::cl_RA& n) {
36  return n == constant_one<cln::cl_RA>::get();
37 }
38 
39 inline bool is_positive(const cln::cl_I& n) {
40  return n > constant_zero<cln::cl_RA>::get();
41 }
42 
43 inline bool is_positive(const cln::cl_RA& n) {
44  return n > constant_zero<cln::cl_RA>::get();
45 }
46 
47 inline bool is_negative(const cln::cl_I& n) {
49 }
50 
51 inline bool is_negative(const cln::cl_RA& n) {
53 }
54 
55 /**
56  * Extract the numerator from a fraction.
57  * @param n Fraction.
58  * @return Numerator.
59  */
60 inline cln::cl_I get_num(const cln::cl_RA& n) {
61  return cln::numerator(n);
62 }
63 
64 /**
65  * Extract the denominator from a fraction.
66  * @param n Fraction.
67  * @return Denominator.
68  */
69 inline cln::cl_I get_denom(const cln::cl_RA& n) {
70  return cln::denominator(n);
71 }
72 
73 /**
74  * Check if a number is integral.
75  * As cln::cl_I are always integral, this method returns true.
76  * @return true.
77  */
78 inline bool is_integer(const cln::cl_I& /*unused*/) {
79  return true;
80 }
81 
82 /**
83  * Check if a fraction is integral.
84  * @param n A fraction.
85  * @return true.
86  */
87 inline bool is_integer(const cln::cl_RA& n) {
88  return is_one(get_denom(n));
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 cln::cl_I& n) {
97  return cln::integer_length(n);
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 cln::cl_RA& n) {
105  return cln::integer_length(get_num(n)) + cln::integer_length(get_denom(n));
106 }
107 
108 /**
109  * Converts the given fraction to a double.
110  * @param n A fraction.
111  * @return Double.
112  */
113 inline double to_double(const cln::cl_RA& n) {
114  return cln::double_approx(n);
115 }
116 /**
117  * Converts the given integer to a double.
118  * @param n An integer.
119  * @return Double.
120  */
121 inline double to_double(const cln::cl_I& n) {
122  return cln::double_approx(n);
123 }
124 
125 template<typename Integer>
126 inline Integer to_int(const cln::cl_I& n);
127 template<typename Integer>
128 inline Integer to_int(const cln::cl_RA& n);
129 
130 template<>
131 inline sint to_int<sint>(const cln::cl_I& n) {
132  assert(n <= std::numeric_limits<sint>::max());
133  assert(n >= std::numeric_limits<sint>::min());
134  return cln::cl_I_to_long(n);
135 }
136 template<>
137 inline uint to_int<uint>(const cln::cl_I& n) {
138  assert(n <= std::numeric_limits<uint>::max());
139  assert(n >= std::numeric_limits<uint>::min());
140  return uint(cln::cl_I_to_long(n));
141 }
142 
143 
144 template<typename To, typename From>
145 inline To from_int(const From& n);
146 
147 template<>
148 inline cln::cl_I from_int(const uint& n) {
149  return cln::cl_I(n);
150 }
151 
152 template<>
153 inline cln::cl_I from_int(const sint& n) {
154  return cln::cl_I(n);
155 }
156 
157 template<>
158 inline cln::cl_RA from_int(const uint& n) {
159  return cln::cl_RA(n);
160 }
161 
162 template<>
163 inline cln::cl_RA from_int(const sint& n) {
164  return cln::cl_RA(n);
165 }
166 
167 /**
168  * Convert a fraction to an integer.
169  * This method assert, that the given fraction is an integer, i.e. that the denominator is one.
170  * @param n A fraction.
171  * @return An integer.
172  */
173 template<>
174 inline cln::cl_I to_int<cln::cl_I>(const cln::cl_RA& n) {
175  assert(is_integer(n));
176  return get_num(n);
177 }
178 template<>
179 inline sint to_int<sint>(const cln::cl_RA& n) {
180  return to_int<sint>(to_int<cln::cl_I>(n));
181 }
182 template<>
183 inline uint to_int<uint>(const cln::cl_RA& n) {
184  return to_int<uint>(to_int<cln::cl_I>(n));
185 }
186 
187 /**
188  * Convert a cln fraction to a cln long float.
189  * @param n A fraction.
190  * @return n as cln::cl_LF.
191  */
192 inline cln::cl_LF to_lf(const cln::cl_RA& n) {
193  return cln::cl_R_to_LF(n, std::max(cln::integer_length(cln::numerator(n)), cln::integer_length(cln::denominator(n))));
194 }
195 
196 static const cln::cl_RA ONE_DIVIDED_BY_10_TO_THE_POWER_OF_23 = cln::cl_RA(1)/cln::expt(cln::cl_RA(10), 23);
197 static const cln::cl_RA ONE_DIVIDED_BY_10_TO_THE_POWER_OF_52 = cln::cl_RA(1)/cln::expt(cln::cl_RA(10), 52);
198 
199 template<>
200 cln::cl_RA rationalize<cln::cl_RA>(double n);
201 
202 template<>
203 cln::cl_RA rationalize<cln::cl_RA>(float n);
204 
205 template<>
206 inline cln::cl_RA rationalize<cln::cl_RA>(int n) {
207  return cln::cl_RA(n);
208 }
209 
210 template<>
211 inline cln::cl_RA rationalize<cln::cl_RA>(uint n) {
212  return cln::cl_RA(n);
213 }
214 
215 template<>
216 inline cln::cl_RA rationalize<cln::cl_RA>(sint n) {
217  return cln::cl_RA(n);
218 }
219 
220 template<>
221 cln::cl_I parse<cln::cl_I>(const std::string& n);
222 
223 template<>
224 bool try_parse<cln::cl_I>(const std::string& n, cln::cl_I& res);
225 
226 template<>
227 cln::cl_RA parse<cln::cl_RA>(const std::string& n);
228 
229 template<>
230 bool try_parse<cln::cl_RA>(const std::string& n, cln::cl_RA& res);
231 
232 /**
233  * Get absolute value of an integer.
234  * @param n An integer.
235  * @return \f$|n|\f$.
236  */
237 inline cln::cl_I abs(const cln::cl_I& n) {
238  return cln::abs(n);
239 }
240 
241 /**
242  * Get absolute value of a fraction.
243  * @param n A fraction.
244  * @return \f$|n|\f$.
245  */
246 inline cln::cl_RA abs(const cln::cl_RA& n) {
247  return cln::abs(n);
248 }
249 
250 /**
251  * Round a fraction to next integer.
252  * @param n A fraction.
253  * @return The next integer.
254  */
255 inline cln::cl_I round(const cln::cl_RA& n) {
256  return cln::round1(n);
257 }
258 
259 /**
260  * Round an integer to next integer, that is do nothing.
261  * @param n An integer.
262  * @return The next integer.
263  */
264 inline cln::cl_I round(const cln::cl_I& n) {
265  return n;
266 }
267 
268 /**
269  * Round down a fraction.
270  * @param n A fraction.
271  * @return \f$\lfloor n \rfloor\f$.
272  */
273 inline cln::cl_I floor(const cln::cl_RA& n) {
274  return cln::floor1(n);
275 }
276 
277 /**
278  * Round down an integer.
279  * @param n An integer.
280  * @return \f$\lfloor n \rfloor\f$.
281  */
282 inline cln::cl_I floor(const cln::cl_I& n) {
283  return n;
284 }
285 
286 /**
287  * Round up a fraction.
288  * @param n A fraction.
289  * @return \f$\lceil n \rceil\f$.
290  */
291 inline cln::cl_I ceil(const cln::cl_RA& n) {
292  return cln::ceiling1(n);
293 }
294 
295 /**
296  * Round up an integer.
297  * @param n An integer.
298  * @return \f$\lceil n \rceil\f$.
299  */
300 inline cln::cl_I ceil(const cln::cl_I& n) {
301  return n;
302 }
303 
304 /**
305  * Calculate the greatest common divisor of two integers.
306  * @param a First argument.
307  * @param b Second argument.
308  * @return Gcd of a and b.
309  */
310 inline cln::cl_I gcd(const cln::cl_I& a, const cln::cl_I& b) {
311  return cln::gcd(a,b);
312 }
313 
314 /**
315  * Calculate the greatest common divisor of two integers.
316  * Stores the result in the first argument.
317  * @param a First argument.
318  * @param b Second argument.
319  * @return Updated a.
320  */
321 inline cln::cl_I& gcd_assign(cln::cl_I& a, const cln::cl_I& b) {
322  a = cln::gcd(a,b);
323  return a;
324 }
325 
326 inline void divide(const cln::cl_I& dividend, const cln::cl_I& divisor, cln::cl_I& quotient, cln::cl_I& remainder) {
327  cln::cl_I_div_t res = cln::floor2(dividend, divisor);
328  quotient = res.quotient;
329  remainder = res.remainder;
330 }
331 
332 /**
333  * Calculate the greatest common divisor of two fractions.
334  * Stores the result in the first argument.
335  * Asserts that the arguments are integral.
336  * @param a First argument.
337  * @param b Second argument.
338  * @return Updated a.
339  */
340 inline cln::cl_RA& gcd_assign(cln::cl_RA& a, const cln::cl_RA& b) {
342  return a;
343 }
344 
345 /**
346  * Calculate the greatest common divisor of two fractions.
347  * Asserts that the arguments are integral.
348  * @param a First argument.
349  * @param b Second argument.
350  * @return Gcd of a and b.
351  */
352 inline cln::cl_RA gcd(const cln::cl_RA& a, const cln::cl_RA& b) {
354 }
355 
356 /**
357  * Calculate the least common multiple of two integers.
358  * @param a First argument.
359  * @param b Second argument.
360  * @return Lcm of a and b.
361  */
362 inline cln::cl_I lcm(const cln::cl_I& a, const cln::cl_I& b) {
363  return cln::lcm(a,b);
364 }
365 
366 /**
367  * Calculate the least common multiple of two fractions.
368  * Asserts that the arguments are integral.
369  * @param a First argument.
370  * @param b Second argument.
371  * @return Lcm of a and b.
372  */
373 inline cln::cl_RA lcm(const cln::cl_RA& a, const cln::cl_RA& b) {
374  assert( carl::is_integer( a ) );
375  assert( carl::is_integer( b ) );
376  return cln::lcm(carl::get_num(a),carl::get_num(b));
377 }
378 
379 /**
380  * Calculate the power of some fraction to some positive integer.
381  * @param basis Basis.
382  * @param exp Exponent.
383  * @return \f$n^e\f$
384  */
385 template<>
386 inline cln::cl_RA pow(const cln::cl_RA& basis, std::size_t exp) {
387  return cln::expt(basis, int(exp));
388 }
389 
390 inline cln::cl_RA log(const cln::cl_RA& n) {
391  return cln::rationalize(cln::realpart(cln::log(n)));
392 }
393 inline cln::cl_RA log10(const cln::cl_RA& n) {
394  return cln::rationalize(cln::realpart(cln::log(n, 10)));
395 }
396 
397 inline cln::cl_RA sin(const cln::cl_RA& n) {
398  return cln::rationalize(cln::sin(n));
399 }
400 
401 inline cln::cl_RA cos(const cln::cl_RA& n) {
402  return cln::rationalize(cln::cos(n));
403 }
404 
405 /**
406  * Calculate the square root of a fraction if possible.
407  *
408  * @param a The fraction to calculate the square root for.
409  * @param b A reference to the rational, in which the result is stored.
410  * @return true, if the number to calculate the square root for is a square;
411  * false, otherwise.
412  */
413 bool sqrt_exact(const cln::cl_RA& a, cln::cl_RA& b);
414 
415 cln::cl_RA sqrt(const cln::cl_RA& a);
416 
417 /**
418  * Calculate the square root of a fraction.
419  *
420  * If we are able to find a an \f$x\f$ such that \f$x\f$ is the exact root of \f$a\f$, \f$(x,x)\f$ is returned.
421  * If we can not find such a number (note that such a number might not even exist), \f$(x,y)\f$ is returned with \f$ x < \sqrt{a} < y \f$.
422  * Note that we try to find bounds that are very close to the actual square root. If a small representation is more important than a small interval, sqrt_fast should be used.
423  * @param a A fraction.
424  * @return Interval containing the square root of a.
425  */
426 std::pair<cln::cl_RA, cln::cl_RA> sqrt_safe(const cln::cl_RA& a);
427 
428 /**
429  * Compute square root in a fast but less precise way.
430  * Use cln::sqrt() to obtain an approximation. If the result is rational, i.e. the result is exact, use this result.
431  * Otherwise use the nearest integers as bounds on the square root.
432  * @param a Some number.
433  * @return [x,x] if sqrt(a) = x is rational, otherwise [y,z] for y,z integer and y < sqrt(a) < z.
434  */
435 std::pair<cln::cl_RA, cln::cl_RA> sqrt_fast(const cln::cl_RA& a);
436 
437 std::pair<cln::cl_RA, cln::cl_RA> root_safe(const cln::cl_RA& a, uint n);
438 
439 /**
440  * Calculate the remainder of the integer division.
441  * @param a First argument.
442  * @param b Second argument.
443  * @return \f$a \% b\f$.
444  */
445 inline cln::cl_I mod(const cln::cl_I& a, const cln::cl_I& b) {
446  return cln::rem(a, b);
447 }
448 
449 /**
450  * Divide two fractions.
451  * @param a First argument.
452  * @param b Second argument.
453  * @return \f$ a / b \f$.
454  */
455 inline cln::cl_RA div(const cln::cl_RA& a, const cln::cl_RA& b) {
456  return (a / b);
457 }
458 
459 /**
460  * Divide two integers.
461  * Asserts that the remainder is zero.
462  * @param a First argument.
463  * @param b Second argument.
464  * @return \f$ a / b \f$.
465  */
466 inline cln::cl_I div(const cln::cl_I& a, const cln::cl_I& b) {
467  assert(cln::mod(a, b) == 0);
468  return cln::exquo(a, b);
469 }
470 
471 /**
472  * Divide two fractions.
473  * Stores the result in the first argument.
474  * @param a First argument.
475  * @param b Second argument.
476  * @return \f$ a / b \f$.
477  */
478 inline cln::cl_RA& div_assign(cln::cl_RA& a, const cln::cl_RA& b) {
479  a /= b;
480  return a;
481 }
482 
483 /**
484  * Divide two integers.
485  * Asserts that the remainder is zero.
486  * Stores the result in the first argument.
487  * @param a First argument.
488  * @param b Second argument.
489  * @return \f$ a / b \f$.
490  */
491 inline cln::cl_I& div_assign(cln::cl_I& a, const cln::cl_I& b) {
492  assert(cln::mod(a,b) == 0);
493  a = cln::exquo(a, b);
494  return a;
495 }
496 
497 /**
498  * Divide two fractions.
499  * @param a First argument.
500  * @param b Second argument.
501  * @return \f$ a / b \f$.
502  */
503 inline cln::cl_RA quotient(const cln::cl_RA& a, const cln::cl_RA& b)
504 {
505  return a / b;
506 }
507 /**
508  * Divide two integers.
509  * Discards the remainder of the division.
510  * @param a First argument.
511  * @param b Second argument.
512  * @return \f$ a / b \f$.
513  */
514 inline cln::cl_I quotient(const cln::cl_I& a, const cln::cl_I& b)
515 {
516  return cln::exquo(a - cln::rem(a, b), b);
517 }
518 
519 
520 /**
521  * Calculate the remainder of the integer division.
522  * @param a First argument.
523  * @param b Second argument.
524  * @return \f$a \% b\f$.
525  */
526 inline cln::cl_I remainder(const cln::cl_I& a, const cln::cl_I& b) {
527  return cln::rem(a, b);
528 }
529 
530 
531 /**
532  * Divide two integers.
533  * Discards the remainder of the division.
534  * @param a First argument.
535  * @param b Second argument.
536  * @return \f$ a / b \f$.
537  */
538 inline cln::cl_I operator/(const cln::cl_I& a, const cln::cl_I& b)
539 {
540  return quotient(a,b);
541 }
542 inline cln::cl_I operator/(const cln::cl_I& lhs, const int& rhs) {
543  return lhs / cln::cl_I(rhs);
544 }
545 
546 inline cln::cl_RA reciprocal(const cln::cl_RA& a) {
547  return cln::recip(a);
548 }
549 
550 std::string toString(const cln::cl_RA& _number, bool _infix=true);
551 
552 std::string toString(const cln::cl_I& _number, bool _infix=true);
553 
554 }
mpz_class Integer
carl is the main namespace for the library.
sint mod(sint n, sint m)
Definition: operations.h:134
double rationalize(double n)
Definition: operations.h:98
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
bool sqrt_exact(const cln::cl_RA &a, cln::cl_RA &b)
Calculate the square root of a fraction if possible.
static const cln::cl_RA ONE_DIVIDED_BY_10_TO_THE_POWER_OF_23
Definition: operations.h:196
double abs(double n)
Definition: operations.h:127
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
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
cln::cl_LF to_lf(const cln::cl_RA &n)
Convert a cln fraction to a cln long float.
Definition: operations.h:192
static const cln::cl_RA ONE_DIVIDED_BY_10_TO_THE_POWER_OF_52
Definition: operations.h:197
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
mpq_class gcd(const mpq_class &a, const mpq_class &b)
Definition: operations.h:311
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
mpq_class lcm(const mpq_class &a, const mpq_class &b)
Definition: operations.h:349
sint to_int< sint >(const cln::cl_I &n)
Definition: operations.h:131
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 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
Interval< Number > pow(const Interval< Number > &i, Integer exp)
Definition: Power.h:11
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