arb.hpp - C++ Wrapper for FLINT Ball Arithmetic#
-
class Arb#
A wrapper for
arb_t
elements so we get C++ style memory management.We use some Yap magic to get nice operators (which is tricky otherwise because we cannot pass the additional prec and rnd parameters to operators in C++.)
If you don’t like that magic and only want memory management, just create elements
1+1 // -> 2
#include <exact-real/arb.hpp> exactreal::Arb x, y;
and then use the Arb functions directly:
arb_add(x.arb_t(), x.arb_t(), y.arb_t(), 64);
Using yap this can be rewritten as any of the following:
#include <exact-real/yap/arb.hpp> x += y(64); x = (x + y)(64);
Note that the latter might use an additional temporary Arb. See the yap/arb.hpp header for more details.
Note that methods here are usually named as their counterparts in arb.h with the leading arb_ removed.
Note
We do not really recommend that you use the yap interface. We are considering to remove it because it is not terribly useful in practice and annoying to maintain.
Note
This class has nothing to do with exact-real but should be implemented by FLINT itself. Eventually we would like to migrate these classes into a proper C++ wrapper that provides C++ memory management for FLINT.
Arb(…)
-
Arb() noexcept#
Create an exact zero element.
exactreal::Arb x; x // -> 0
-
Arb(const Arb&) noexcept#
Create a copy of
x
.exactreal::Arb x{1337}; exactreal::Arb y{x}; (x == y) == true // -> true
-
Arb(Arb&&) noexcept#
Create a new element from
x
.exactreal::Arb x{1337}; exactreal::Arb y{std::move(x)}; y // -> 1337.00
-
explicit Arb(const mpz_class&) noexcept#
Create an exact element equal to this integer.
#include <gmpxx.h> exactreal::Arb x{mpz_class{1337}}; x // -> 1337.00
-
explicit Arb(const mpq_class&) noexcept#
Create an element containing this rational. Typically, the result won’t be exact, in particular not if the rational cannot be represented exactly in base 2.
exactreal::Arb x{mpq_class{1, 2}}; x // -> 0.500000 exactreal::Arb y{mpq_class{1, 3}}; std::cout << std::setprecision(32) << y; // -> [0.33333333333333333331526329712524 +/- 2.72e-20]
-
explicit Arb(const mpq_class&, const prec) noexcept#
Create an element containing this rational using
arb_set_fmpq()
, i.e., by performing the division of numerator and denominator with precisionprec
.exactreal::Arb x{mpq_class{1, 2}, 256}; x // -> 0.500000 exactreal::Arb y{mpq_class{1, 3}, 256}; std::cout << std::setprecision(32) << y; // -> [0.33333333333333333333333333333333 +/- 3.34e-33]
-
explicit Arb(const eantic::renf_elem_class&) noexcept#
Create an element containing this number field element. The precision of the Arb ball, depends on the internal representation of the number field element.
#include <e-antic/renf_class.hpp> #include <e-antic/renf_elem_class.hpp> auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1"); auto a = eantic::renf_elem_class(*K, std::vector{-1, 1}); exactreal::Arb x{a}; x // -> [0.414214 +/- 4.38e-7]
-
explicit Arb(const eantic::renf_elem_class&, const prec) noexcept#
Create an element containing this number field element in a ball of precision at least
prec
.#include <e-antic/renf_class.hpp> #include <e-antic/renf_elem_class.hpp> auto K = eantic::renf_class::make("x^2 - 2", "x", "1.4 +/- 1"); auto a = eantic::renf_elem_class(*K, std::vector{-1, 1}); exactreal::Arb x{a, 8}; std::cout << std::setprecision(32) << x; // -> [0.41406250000000000000000000000000 +/- 7.82e-3] exactreal::Arb y{a, 256}; std::cout << std::setprecision(32) << y; // -> [0.41421356237309504880168872420970 +/- 1.93e-33] exactreal::Arb z{a, 8}; std::cout << std::setprecision(32) << z; // -> [0.41406250000000000000000000000000 +/- 7.82e-3]
-
explicit Arb(const std::pair<Arf, Arf>&, const prec = ARF_PREC_EXACT)#
Create an Arb ball with lower and upper bound as given by the pair, see
arb_set_interval_arf()
.#include <exact-real/arf.hpp> exactreal::Arf lower{0}, upper{1}; exactreal::Arb x{std::pair{lower, upper}}; x // -> [0.500000 +/- 0.501] exactreal::Arb y{std::pair{lower, upper}, 64}; y // -> [0.500000 +/- 0.501]
-
explicit Arb(const Arf &midpoint)#
Create an exact element equal to the given floating point element, see
arb_set_arf()
.#include <exact-real/arf.hpp> exactreal::Arf x{1}; exactreal::Arb y{x}; y // -> 1.00000
-
template<typename Integer, typename std::enable_if_t<std::is_integral_v<Integer>, int> = 0>
explicit Arb(Integer) noexcept# Create an exact element, equal to this integer.
exactreal::Arb x{1}; x // -> 1.00000
-
explicit Arb(const std::string&, const prec)#
Create an element from this string, see
arb_set_str()
.exactreal::Arb x{"[3.25 +/- 0.0001]", 64}; x // -> [3.25000 +/- 1.01e-4]
-
~Arb() noexcept#
operator=
Reset this element to the one given.
exactreal::Arb x{1}, y; y = std::move(x); y // -> 1.00000 x = y; y // -> 1.00000 x = 1; x // -> 1.00000
Comparison Operators
The comparison operators return a value if the relation is true for all elements in the ball described by the element, e.g., x < y, returns true if the relation is true for every element in x and y, they return false if the relation is false for every element in x and y, and nothing otherwise. Note that this is different from the semantic in Arb where false is returned in both of the latter cases.
exactreal::Arb x{mpq_class{1, 3}}; (x < 1).has_value() // -> true (x < 1).value() // -> true (x < x).has_value() // -> false
-
template<typename Integer, typename std::enable_if_t<std::is_integral_v<Integer>, int> = 0>
std::optional<bool> operator<(Integer) const noexcept#
-
template<typename Integer, typename std::enable_if_t<std::is_integral_v<Integer>, int> = 0>
std::optional<bool> operator>(Integer) const noexcept#
-
template<typename Integer, typename std::enable_if_t<std::is_integral_v<Integer>, int> = 0>
std::optional<bool> operator<=(Integer) const noexcept#
-
template<typename Integer, typename std::enable_if_t<std::is_integral_v<Integer>, int> = 0>
std::optional<bool> operator>=(Integer) const noexcept#
-
template<typename Integer, typename std::enable_if_t<std::is_integral_v<Integer>, int> = 0>
std::optional<bool> operator==(Integer) const noexcept#
-
template<typename Integer, typename std::enable_if_t<std::is_integral_v<Integer>, int> = 0>
std::optional<bool> operator!=(Integer) const noexcept#
-
std::optional<bool> operator<(const mpq_class&) const noexcept#
-
std::optional<bool> operator>(const mpq_class&) const noexcept#
-
std::optional<bool> operator<=(const mpq_class&) const noexcept#
-
std::optional<bool> operator>=(const mpq_class&) const noexcept#
-
std::optional<bool> operator==(const mpq_class&) const noexcept#
-
std::optional<bool> operator!=(const mpq_class&) const noexcept#
Public Functions
-
Arb operator-() const noexcept#
Return the negative of this element. This method returns a ball whose lower and upper bound is the negative of the upper and lower bound, respectively.
exactreal::Arb x{1}; -x // -> -1.00000
-
bool is_exact() const noexcept#
Return whether this Arb element exactly represents a floating point number, i.e., whether its radius is zero, see
arb_is_exact()
.exactreal::Arb x{1}; x.is_exact() // -> true exactreal::Arb y{mpq_class{1, 3}}; y.is_exact() // -> false
-
bool is_finite() const noexcept#
Return whether this Arb element does contain neither plus nor minus infinity, see
arb_is_finite()
.exactreal::Arb x{1}; x.is_finite() // -> true exactreal::Arb y{1}; arb_div_si(y.arb_t(), y.arb_t(), 0, 64); y.is_finite() // -> false
-
explicit operator std::pair<Arf, Arf>() const noexcept#
Return the lower and the upper bound of this ball. See
arb_get_interval_arf()
.exactreal::Arb x{mpq_class{1, 3}}; auto bounds = static_cast<std::pair<exactreal::Arf, exactreal::Arf>>(x); std::cout << bounds.first << ", " << bounds.second; // -> 0.333333=1537228672809129301p-62, 0.333333=3074457345618258603p-63
-
explicit operator double() const noexcept#
Return the midpoint of this ball rounded to the closest double. Note that ties are rounded to even.
exactreal::Arb x{mpq_class{1, 3}}; static_cast<double>(x) // -> 0.333333
-
explicit operator Arf() const noexcept#
Return the exact midpoint of this ball.
#include <exact-real/arf.hpp> exactreal::Arb x{mpq_class{1, 3}}; static_cast<exactreal::Arf>(x) // -> 0.333333=6148914691236517205p-64
-
::arb_t &arb_t() noexcept#
Return a reference to the underlying
arb_t
element for direct manipulation with the C API of Arb.
Public Static Functions
-
static Arb zero() noexcept#
Return an exact zero element, i.e., the ball of radius zero centered at zero.
exactreal::Arb::zero() // -> 0
-
static Arb one() noexcept#
Return an exact one element, i.e., the ball of radius zero centered at one.
exactreal::Arb::one() // -> 1.00000
-
static Arb pos_inf() noexcept#
Return plus infinity, i.e., the ball of radius zero centered at plus infinity, see
arb_pos_inf()
. Note that the result is printed as[+/- inf]
unfortunately, see fredrik-johansson/arb#332.exactreal::Arb::pos_inf() // -> [+/- inf]
-
static Arb neg_inf() noexcept#
Return minus infinity, i.e., the ball of radius zero centered at minus infinity, see [arb_neg_inf](). Note that the result is printed as
[+/- inf]
unfortunately, see fredrik-johansson/arb#332.exactreal::Arb::neg_inf() // -> [+/- inf]
-
static Arb zero_pm_inf() noexcept#
Return the extended real line, i.e., the interval [-∞,∞], see
arb_zero_pm_inf()
.exactreal::Arb::zero_pm_inf() // -> [+/- inf]
-
static Arb indeterminate() noexcept#
Return an indeterminate, i.e., [NaN±∞] see
arb_indeterminate()
.exactreal::Arb::indeterminate() // -> nan
-
static Arb zero_pm_one() noexcept#
Return the interval [-1, 1], i.e., the ball of radius one centered at zero, see
arb_zero_pm_one()
. Note that this prints as[+/- 1.01]
instead of[+/- 1.00]
, see fredrik-johansson/arb#391exactreal::Arb::zero_pm_one() // -> [+/- 1.01]
-
static Arb unit_interval() noexcept#
Return the unit interval [0, 1], i.e., the ball of radius 1/2 centered at 1/2, see
arb_unit_interval()
. Note that that this does not print as[0.5 +/- 0.5]
, see fredrik-johansson/arb#391exactreal::Arb::unit_interval() // -> [0.500000 +/- 0.501]
-
static Arb randtest(flint_rand_t, prec precision, prec magbits) noexcept#
Return a random element, see
arb_randtest()
.#include <flint/flint.h> flint_rand_t rnd; flint_randinit(rnd); auto a = exactreal::Arb::randtest(rnd, 64, 16); auto b = exactreal::Arb::randtest(rnd, 64, 16); a.equal(b) // -> false
-
static Arb randtest_exact(flint_rand_t, prec precision, prec magbits) noexcept#
Return a random element, see
arb_randtest_exact()
.auto a = exactreal::Arb::randtest_exact(rnd, 64, 16); auto b = exactreal::Arb::randtest_exact(rnd, 64, 16); a.equal(b) // -> false
-
Arb() noexcept#