LAL: Linear Arrangement Library 23.01.00
A library focused on algorithms on linear arrangements of graphs.
Loading...
Searching...
No Matches
utils.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 - 2023
7 *
8 * This file is part of Linear Arrangement Library. The full code is available
9 * at:
10 * https://github.com/LAL-project/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 <cstdint>
46
47// gmp includes
48#include <gmp.h>
49
50namespace lal {
51namespace detail {
52
53/* Other arithmetic operations */
54
66inline
67void mpz_pow_mpz(mpz_t& r, const mpz_t& b, const mpz_t& e) noexcept {
68 if (mpz_fits_ulong_p(e)) {
69 mpz_pow_ui(r, b, mpz_get_ui(e));
70 return;
71 }
72
73 if (mpz_even_p(e)) {
74 // r = (b^(e/2))^2
75
76 mpz_t e_half;
77 mpz_init(e_half);
78
79 // e_half = e/2
80 mpz_div_ui(e_half, e, 2);
81
82 // r = b^(e/2)
83 mpz_pow_mpz(r, b, e_half);
84
85 // r = (b^(e/2))^2 = b^e
86 mpz_mul(r, r, r);
87 mpz_clear(e_half);
88 return;
89 }
90
91 // r = (b^(e - 1))*b
92
93 mpz_t e_minus_one;
94 mpz_init(e_minus_one);
95 // e_minus_one = e - 1
96 mpz_sub_ui(e_minus_one, e, 1);
97
98 // r = b^(e - 1)
99 mpz_pow_mpz(r, b, e_minus_one);
100
101 // r = (b^(e - 1))*b = b^e
102 mpz_mul(r, r, b);
103 mpz_clear(e_minus_one);
104}
105
113inline
114void mpz_divide_mpq(mpq_t& r, const mpz_t& k) noexcept {
115 mpz_t b;
116 mpz_init(b);
117
118 mpq_get_den(b, r); // r = a/b
119
120 mpz_mul(b, b, k); // b <- b*k
121
122 mpq_set_den(r, b); // r <- a/(b*k)
123 mpq_canonicalize(r);
124
125 mpz_clear(b);
126}
127
135inline
136void mpq_divide_mpq(mpq_t& num, const mpq_t& den) noexcept {
137 mpz_t a, b, c, d;
138 mpz_inits(a, b, c, d, nullptr);
139
140 mpq_get_num(a, num); // num = a/b
141 mpq_get_den(b, num);
142 mpq_get_num(c, den); // den = c/d
143 mpq_get_den(d, den);
144
145 mpz_mul(a, a, d);
146 mpz_mul(b, b, c);
147
148 mpq_set_num(num, a);
149 mpq_set_den(num, b);
150 mpq_canonicalize(num);
151
152 mpz_clears(a, b, c, d, nullptr);
153}
154
162inline
163void operate_power(mpq_t& r, uint64_t p) noexcept {
164 if (p == 0) {
165 mpq_set_si(r, 1, 1);
166 return;
167 }
168 if (p == 1) {
169 return;
170 }
171
172 mpz_t num, den;
173 mpz_inits(num, den, nullptr);
174
175 // get numerator and denominator of 'res'
176 mpq_get_num(num, r);
177 mpq_get_den(den, r);
178
179 // operate power
180 mpz_pow_ui(num, num, p);
181 mpz_pow_ui(den, den, p);
182
183 // set value into 'res'
184 mpq_set_num(r, num);
185 mpq_set_den(r, den);
186
187 // canonicalise
188 mpq_canonicalize(r);
189
190 mpz_clears(num, den, nullptr);
191}
192
200inline
201void operate_power(mpq_t& r, const mpz_t& p) noexcept {
202 if (mpz_cmp_ui(p, 0) == 0) {
203 mpq_set_si(r, 1, 1);
204 return;
205 }
206 if (mpz_cmp_ui(p, 1) == 0) {
207 return;
208 }
209
210 mpz_t num, den;
211 mpz_inits(num, den, nullptr);
212
213 // get numerator and denominator of 'res'
214 mpq_get_num(num, r);
215 mpq_get_den(den, r);
216
217 // operate power
218 mpz_pow_mpz(num, num, p);
219 mpz_pow_mpz(den, den, p);
220
221 // set value into 'res'
222 mpq_set_num(r, num);
223 mpq_set_den(r, den);
224
225 // canonicalise
226 mpq_canonicalize(r);
227
228 mpz_clears(num, den, nullptr);
229}
230
231/* Getters of mpz_t objects */
232
234inline std::size_t mpz_bytes(const mpz_t& v) noexcept
235{
236 const std::size_t alloc = static_cast<std::size_t>(v[0]._mp_alloc);
237 return sizeof(mp_limb_t)*alloc;
238}
239
240} // -- namespace detail
241} // -- namespace lal
void mpz_divide_mpq(mpq_t &r, const mpz_t &k) noexcept
Rational-Integer division.
Definition: utils.hpp:114
std::size_t mpz_bytes(const mpz_t &v) noexcept
Returns the amount of bytes of a gmp's integer value.
Definition: utils.hpp:234
void mpq_divide_mpq(mpq_t &num, const mpq_t &den) noexcept
Rational-Rational division.
Definition: utils.hpp:136
void operate_power(mpq_t &r, uint64_t p) noexcept
Power operation.
Definition: utils.hpp:163
void mpz_pow_mpz(mpz_t &r, const mpz_t &b, const mpz_t &e) noexcept
Computes the exponentiation of a big integer to another big integer.
Definition: utils.hpp:67
Main namespace of the library.
Definition: basic_types.hpp:50