LAL: Linear Arrangement Library 21.07.01
A library focused on algorithms on linear arrangements of graphs.
Loading...
Searching...
No Matches
rational.hpp
1/*********************************************************************
2 *
3 * Linear Arrangement Library - A library that implements a collection
4 * algorithms for linear arrangments of graphs.
5 *
6 * Copyright (C) 2019 - 2021
7 *
8 * This file is part of Linear Arrangement Library. To see the full code
9 * visit the webpage:
10 * https://github.com/lluisalemanypuig/linear-arrangement-library.git
11 *
12 * Linear Arrangement Library is free software: you can redistribute it
13 * and/or modify it under the terms of the GNU Affero General Public License
14 * as published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * Linear Arrangement Library is distributed in the hope that it will be
18 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Affero General Public License for more details.
21 *
22 * You should have received a copy of the GNU Affero General Public License
23 * along with Linear Arrangement Library. If not, see <http://www.gnu.org/licenses/>.
24 *
25 * Contact:
26 *
27 * LluĂ­s Alemany Puig (lalemany@cs.upc.edu)
28 * LARCA (Laboratory for Relational Algorithmics, Complexity and Learning)
29 * CQL (Complexity and Quantitative Linguistics Lab)
30 * Jordi Girona St 1-3, Campus Nord UPC, 08034 Barcelona. CATALONIA, SPAIN
31 * Webpage: https://cqllab.upc.edu/people/lalemany/
32 *
33 * Ramon Ferrer i Cancho (rferrericancho@cs.upc.edu)
34 * LARCA (Laboratory for Relational Algorithmics, Complexity and Learning)
35 * CQL (Complexity and Quantitative Linguistics Lab)
36 * Office S124, Omega building
37 * Jordi Girona St 1-3, Campus Nord UPC, 08034 Barcelona. CATALONIA, SPAIN
38 * Webpage: https://cqllab.upc.edu/people/rferrericancho/
39 *
40 ********************************************************************/
41
42#pragma once
43
44// C includes
45#include <gmp.h>
46
47// C++ includes
48#include <cstdint>
49#include <string>
50
51// lal includes
52#include <lal/numeric/integer.hpp>
53
54namespace lal {
55namespace numeric {
56
63class rational {
64public:
65 /* CONSTRUCTORS */
66
68 rational() noexcept { mpq_init(m_val); }
74 rational(int64_t n, uint64_t d = 1) noexcept
75 { mpq_init(m_val); set_si(n, d); }
81 rational(const integer& n, const integer& d = 1) noexcept
82 { mpq_init(m_val); set_integer(n, d); }
87 rational(const std::string& s) noexcept
88 { mpq_init(m_val); set_str(s); }
93 rational(const rational& r) noexcept
94 { mpq_init(m_val); mpq_set(m_val, r.m_val); }
95#ifndef SWIG
100 rational(integer&& v) noexcept;
106 rational(integer&& n, integer&& d) noexcept;
111 rational(rational&& r) noexcept;
112#endif
114 ~rational() noexcept { mpq_clear(m_val); }
115
116 /* SETTERS */
117
123 inline void set_si(int64_t n, uint64_t d = 1) noexcept {
124 if (not is_initialized()) { mpq_init(m_val); }
125 mpq_set_si(m_val, n, d);
126 mpq_canonicalize(m_val);
127 m_initialized = true;
128 }
134 inline void set_ui(uint64_t n, uint64_t d = 1) noexcept {
135 if (not is_initialized()) { mpq_init(m_val); }
136 mpq_set_ui(m_val, n, d);
137 mpq_canonicalize(m_val);
138 m_initialized = true;
139 }
144 inline void set_str(const std::string& s) noexcept {
145 if (not is_initialized()) { mpq_init(m_val); }
146 mpq_set_str(m_val, s.c_str(), 10);
147 mpq_canonicalize(m_val);
148 m_initialized = true;
149 }
155 inline void set_integer(const integer& n, const integer& d) noexcept {
156 if (not is_initialized()) { mpq_init(m_val); }
157 mpq_set_num(m_val, n.get_raw_value());
158 mpq_set_den(m_val, d.get_raw_value());
159 mpq_canonicalize(m_val);
160 m_initialized = true;
161 }
166 inline void set_rational(const rational& r) noexcept {
167 if (not is_initialized()) { mpq_init(m_val); }
168 mpq_set(m_val, r.m_val);
169 }
170
177 inline void invert() noexcept { mpq_inv(m_val, m_val); }
178
179 /* OPERATORS */
180
181 // -- ASSIGNMENT
182
187 inline rational& operator= (int64_t i) noexcept
188 { set_si(i); return *this; }
193 inline rational& operator= (const std::string& s) noexcept
194 { set_str(s); return *this; }
199 inline rational& operator= (const integer& i) noexcept
200 { set_integer(i, 1); return *this; }
205 inline rational& operator= (const rational& r) noexcept
206 { set_rational(r); return *this; }
207#ifndef SWIG
218#endif
219
220 // -- EQUALITY
221
226 inline bool operator== (int64_t i) const noexcept
227 { rational r(i); return mpq_equal(m_val, r.m_val) != 0; }
228#ifndef SWIG
234 inline friend bool operator== (int64_t i, const rational& r) noexcept
235 { return r == i; }
236#endif
241 inline bool operator== (const integer& i) const noexcept
242 { rational r(i); return mpq_equal(m_val, r.m_val) != 0; }
243#ifndef SWIG
249 inline friend bool operator== (const integer& i, const rational& r) noexcept
250 { return r == i; }
251#endif
256 inline bool operator== (const rational& r) const noexcept
257 { return mpq_equal(m_val, r.m_val) != 0; }
258
259 // -- NON-EQUALITY
260
265 inline bool operator!= (int64_t i) const noexcept
266 { return not (*this == i); }
267#ifndef SWIG
273 inline friend bool operator!= (int64_t i, const rational& r) noexcept
274 { return r != i; }
275#endif
280 inline bool operator!= (const integer& i) const noexcept
281 { return not (*this == i); }
282#ifndef SWIG
288 inline friend bool operator!= (const integer& i, const rational& r) noexcept
289 { return r != i; }
290#endif
295 inline bool operator!= (const rational& r) const noexcept
296 { return not (*this == r); }
297
298 // -- LESS THAN
299
304 inline bool operator< (int64_t i) const noexcept
305 { rational r(i); return mpq_cmp(m_val, r.m_val) < 0; }
306#ifndef SWIG
312 inline friend bool operator< (int64_t i, const rational& r) noexcept
313 { return r > i; }
314#endif
319 inline bool operator< (const integer& i) const noexcept
320 { rational r(i); return mpq_cmp(m_val, r.m_val) < 0; }
321#ifndef SWIG
327 inline friend bool operator< (const integer& i, const rational& r) noexcept
328 { return r > i; }
329#endif
334 inline bool operator< (const rational& r) const noexcept
335 { return mpq_cmp(m_val, r.m_val) < 0; }
336
337 // -- LESS THAN OR EQUAL TO
338
343 inline bool operator<= (int64_t i) const noexcept
344 { rational r(i); return mpq_cmp(m_val, r.m_val) <= 0; }
345#ifndef SWIG
351 inline friend bool operator<= (int64_t i, const rational& r) noexcept
352 { return r >= i; }
353#endif
358 inline bool operator<= (const integer& i) const noexcept
359 { rational r(i); return mpq_cmp(m_val, r.m_val) <= 0; }
360#ifndef SWIG
366 inline friend bool operator<= (const integer& i, const rational& r) noexcept
367 { return r >= i; }
368#endif
373 inline bool operator<= (const rational& r) const noexcept
374 { return mpq_cmp(m_val, r.m_val) <= 0; }
375
376 // -- GREATER THAN
377
382 inline bool operator> (int64_t i) const noexcept
383 { rational r(i); return mpq_cmp(m_val, r.m_val) > 0; }
384#ifndef SWIG
390 inline friend bool operator> (int64_t i, const rational& r) noexcept
391 { return r < i; }
392#endif
397 inline bool operator> (const integer& i) const noexcept
398 { rational r(i); return mpq_cmp(m_val, r.m_val) > 0; }
399#ifndef SWIG
405 inline friend bool operator> (const integer& i, const rational& r) noexcept
406 { return r < i; }
407#endif
412 inline bool operator> (const rational& r) const noexcept
413 { return mpq_cmp(m_val, r.m_val) > 0; }
414
415 // -- GREATER THAN OR EQUAL TO
416
421 inline bool operator>= (int64_t i) const noexcept
422 { rational r(i); return mpq_cmp(m_val, r.m_val) >= 0; }
423#ifndef SWIG
429 inline friend bool operator>= (int64_t i, const rational& r) noexcept
430 { return r <= i; }
431#endif
436 inline bool operator>= (const integer& i) const noexcept
437 { rational r(i); return mpq_cmp(m_val, r.m_val) >= 0; }
438#ifndef SWIG
444 inline friend bool operator>= (const integer& i, const rational& r) noexcept
445 { return r <= i; }
446#endif
451 inline bool operator>= (const rational& r) const noexcept
452 { return mpq_cmp(m_val, r.m_val) >= 0; }
453
454 // -- ADDITION
455
460 inline rational operator+ (int64_t i) const noexcept
461 { rational r(*this); r += i; return r; }
462#ifndef SWIG
468 inline friend rational operator+ (int64_t i, const rational& r) noexcept
469 { return r + i; }
470#endif
475 inline rational operator+ (const integer& i) const noexcept
476 { rational r(*this); r += i; return r; }
477#ifndef SWIG
483 inline friend rational operator+ (const integer& i, const rational& r) noexcept
484 { return r + i; }
485#endif
490 inline rational operator+ (const rational& r) const noexcept
491 { rational k(*this); k += r; return k; }
492
497 inline rational& operator+= (int64_t i) noexcept
498 { rational r(i); mpq_add(m_val, m_val, r.m_val); return *this; }
503 inline rational& operator+= (const integer& i) noexcept
504 { rational r(i); mpq_add(m_val, m_val, r.m_val); return *this; }
509 inline rational& operator+= (const rational& r) noexcept
510 { mpq_add(m_val, m_val, r.m_val); return *this; }
511
512 // -- SUBSTRACTION
513
515 inline rational operator- () const noexcept
516 { rational r(*this); mpq_neg(r.m_val, r.m_val); return r; }
521 inline rational operator- (int64_t i) const noexcept
522 { rational r(*this); r -= i; return r; }
523#ifndef SWIG
529 inline friend rational operator- (int64_t i, const rational& r) noexcept
530 { return -r + i; }
531#endif
536 inline rational operator- (const integer& i) const noexcept
537 { rational r(*this); r -= i; return r; }
538#ifndef SWIG
544 inline friend rational operator- (const integer& i, const rational& r) noexcept
545 { return -r + i; }
546#endif
551 inline rational operator- (const rational& r) const noexcept
552 { rational k(*this); k -= r; return k; }
553
558 inline rational& operator-= (int64_t i) noexcept
559 { rational r(i); mpq_sub(m_val, m_val, r.m_val); return *this; }
564 inline rational& operator-= (const integer& i) noexcept
565 { rational r(i); mpq_sub(m_val, m_val, r.m_val); return *this; }
570 inline rational& operator-= (const rational& r) noexcept
571 { mpq_sub(m_val, m_val, r.m_val); return *this; }
572
573 // -- MULTIPLICATION
574
579 inline rational operator* (int64_t i) const noexcept
580 { rational r(*this); r *= i; return r; }
581#ifndef SWIG
587 inline friend rational operator* (int64_t i, const rational& r) noexcept
588 { return r*i; }
589#endif
594 inline rational operator* (const integer& i) const noexcept
595 { rational r(*this); r *= i; return r; }
596#ifndef SWIG
602 inline friend rational operator* (const integer& i, const rational& r) noexcept
603 { return r*i; }
604#endif
609 inline rational operator* (const rational& r) const noexcept
610 { rational k(*this); k *= r; return k; }
611
616 inline rational& operator*= (int64_t i) noexcept
617 { rational r(i); mpq_mul(m_val, m_val, r.m_val); return *this; }
622 inline rational& operator*= (const integer& i) noexcept
623 { rational r(i); mpq_mul(m_val, m_val, r.m_val); return *this; }
628 inline rational& operator*= (const rational& r) noexcept
629 { mpq_mul(m_val, m_val, r.m_val); return *this; }
630
631 // -- DIVISION
632
637 inline rational operator/ (int64_t i) const noexcept
638 { rational r(*this); r /= i; return r; }
639#ifndef SWIG
645 inline friend rational operator/ (int64_t i, const rational& r) noexcept
646 { rational inv(r); inv.invert(); return inv*i; }
647#endif
648
653 inline rational operator/ (const integer& i) const noexcept
654 { rational r(*this); r /= i; return r; }
659 inline rational operator/ (const rational& r) const noexcept
660 { rational k(*this); k /= r; return k; }
661
666 rational& operator/= (int64_t i) noexcept;
671 rational& operator/= (const integer& i) noexcept;
676 rational& operator/= (const rational& r) noexcept;
677
678 // -- EXPONENTIATION
679
684 rational pow(uint64_t i) const noexcept;
689 rational pow(const integer& i) const noexcept;
690
695 rational& powt(uint64_t i) noexcept;
700 rational& powt(const integer& i) noexcept;
701
702 /* GETTERS */
703
705 inline bool is_initialized() const noexcept { return m_initialized; }
707 inline int32_t get_sign() const noexcept { return mpq_sgn(m_val); }
708
710 size_t bytes() const noexcept;
711
712 /* CONVERTERS */
713
721 inline integer to_integer() const noexcept {
722 integer i;
723 as_integer(i);
724 return i;
725 }
733 void as_integer(integer& i) const noexcept;
734
736 inline double to_double() const noexcept { return mpq_get_d(m_val); }
738 inline void as_double(double& d) const noexcept { d = mpq_get_d(m_val); }
739
741 inline std::string to_string() const noexcept {
742 std::string k;
743 as_string(k);
744 return k;
745 }
747 inline void as_string(std::string& s) const noexcept {
748 char *buf = nullptr;
749 buf = mpq_get_str(buf, 10, m_val);
750 s = std::string(buf);
751 free(buf);
752 }
753
755 inline integer get_numerator() const noexcept {
756 mpz_t numerator;
757 mpz_init(numerator);
758 mpq_get_num(numerator, m_val);
759 return integer(std::move(numerator));
760 }
761
763 inline integer get_denominator() const noexcept {
764 mpz_t denominator;
765 mpz_init(denominator);
766 mpq_get_den(denominator, m_val);
767 return integer(std::move(denominator));
768 }
769
770 /* OTHERS */
771
781 void swap(rational& r) noexcept { mpq_swap(m_val, r.m_val); }
782
783#ifndef SWIG
789 friend void swap(rational& r1, rational& r2) noexcept { r1.swap(r2); }
790#endif
791
792private:
794 mpq_t m_val;
796 bool m_initialized = true;
797};
798
800inline rational rational_from_ui(uint64_t n, uint64_t d = 1) noexcept {
801 rational R;
802 R.set_ui(n, d);
803 return R;
804}
805
806} // -- namespace numeric
807} // -- namespace lal
Arbitrary precision integer.
Definition integer.hpp:60
Exact rational number.
Definition rational.hpp:63
rational pow(const integer &i) const noexcept
Exponentiation operator.
rational(integer &&n, integer &&d) noexcept
Move constructor with numerator and denominator.
friend bool operator>(int64_t i, const rational &r) noexcept
Greater than operator.
Definition rational.hpp:390
void swap(rational &r) noexcept
Swaps the value of this rational with rational r's value.
Definition rational.hpp:781
void set_si(int64_t n, uint64_t d=1) noexcept
Overwrites the value of this rational with .
Definition rational.hpp:123
void set_str(const std::string &s) noexcept
Overwrites the value in the string s.
Definition rational.hpp:144
bool is_initialized() const noexcept
Returns whether this object is initialised or not.
Definition rational.hpp:705
rational(integer &&v) noexcept
Move constructor.
std::string to_string() const noexcept
Converts this integer to a string.
Definition rational.hpp:741
void set_integer(const integer &n, const integer &d) noexcept
Overwrites the value of this rational with the value .
Definition rational.hpp:155
rational & operator+=(int64_t i) noexcept
Addition operator.
Definition rational.hpp:497
int32_t get_sign() const noexcept
Returns the sign of this rational.
Definition rational.hpp:707
rational(int64_t n, uint64_t d=1) noexcept
Constructor with numerator and denominator.
Definition rational.hpp:74
rational & operator-=(int64_t i) noexcept
Substraction operator.
Definition rational.hpp:558
friend rational operator/(int64_t i, const rational &r) noexcept
Division operator.
Definition rational.hpp:645
friend rational operator+(int64_t i, const rational &r) noexcept
Addition operator.
Definition rational.hpp:468
void as_double(double &d) const noexcept
Converts this rational to a double-precision floating-point value.
Definition rational.hpp:738
rational(const std::string &s) noexcept
Constructor with string.
Definition rational.hpp:87
size_t bytes() const noexcept
Returns the amount of bytes this integer occupies.
void as_string(std::string &s) const noexcept
Converts this integer to a string.
Definition rational.hpp:747
rational(const rational &r) noexcept
Copy constructor.
Definition rational.hpp:93
rational pow(uint64_t i) const noexcept
Exponentiation operator.
rational & operator/=(int64_t i) noexcept
Division operator.
rational & operator*=(int64_t i) noexcept
Multiplication operator.
Definition rational.hpp:616
rational & powt(const integer &i) noexcept
Exponentiation operator.
rational operator-() const noexcept
Substraction unary operator.
Definition rational.hpp:515
rational() noexcept
Empty constructor.
Definition rational.hpp:68
void as_integer(integer &i) const noexcept
Converts this rational to an integer value.
void set_rational(const rational &r) noexcept
Overwrites the value of this rational with the value .
Definition rational.hpp:166
void set_ui(uint64_t n, uint64_t d=1) noexcept
Overwrites the value of this rational with .
Definition rational.hpp:134
friend bool operator!=(int64_t i, const rational &r) noexcept
Non-equality operator.
Definition rational.hpp:273
friend bool operator<=(int64_t i, const rational &r) noexcept
Less than or equal to operator.
Definition rational.hpp:351
integer get_denominator() const noexcept
Returns the denominator of this rational number.
Definition rational.hpp:763
bool m_initialized
Is this rational initialised?
Definition rational.hpp:796
integer to_integer() const noexcept
Converts this rational to an integer value.
Definition rational.hpp:721
rational(rational &&r) noexcept
Move constructor.
rational & powt(uint64_t i) noexcept
Exponentiation operator.
friend bool operator>=(int64_t i, const rational &r) noexcept
Greater than or equal to operator.
Definition rational.hpp:429
void invert() noexcept
Changes numerator and denominator.
Definition rational.hpp:177
friend void swap(rational &r1, rational &r2) noexcept
Swaps two rationals.
Definition rational.hpp:789
friend bool operator<(int64_t i, const rational &r) noexcept
Less than operator.
Definition rational.hpp:312
rational & operator=(int64_t i) noexcept
Assignment operator.
Definition rational.hpp:187
double to_double() const noexcept
Converts this rational to a double-precision floating-point value.
Definition rational.hpp:736
rational(const integer &n, const integer &d=1) noexcept
Constructor with numerator and denominator.
Definition rational.hpp:81
integer get_numerator() const noexcept
Returns the numerator of this rational number.
Definition rational.hpp:755
friend bool operator==(int64_t i, const rational &r) noexcept
Equality operator.
Definition rational.hpp:234
~rational() noexcept
Destructor.
Definition rational.hpp:114
mpq_t m_val
Structure from GMP storing the rational's value.
Definition rational.hpp:794
friend rational operator*(int64_t i, const rational &r) noexcept
Multiplication operator.
Definition rational.hpp:587
rational rational_from_ui(uint64_t n, uint64_t d=1) noexcept
Make a rational value from two 64-bit unsigned integers.
Definition rational.hpp:800
Main namespace of the library.
Definition definitions.hpp:48