Fixed precision real balls

Fixed precision real ball arithmetic is supplied by Arb which provides a ball representation which tracks error bounds rigorously. Real numbers are represented in mid-rad interval form $[m \pm r] = [m-r, m+r]$.

The Arb real field is constructed using the ArbField constructor. This constructs the parent object for the Arb real field.

The types of real balls in Nemo are given in the following table, along with the libraries that provide them and the associated types of the parent objects.

LibraryFieldElement typeParent type
Arb$\mathbb{R}$ (balls)ArbFieldElemArbField

All the real field types belong to the Field abstract type and the types of elements in this field, i.e. balls in this case, belong to the FieldElem abstract type.

Real ball functionality

Real balls in Nemo provide all the field functionality described in AbstractAlgebra:

https://nemocas.github.io/AbstractAlgebra.jl/stable/field

Below, we document the additional functionality provided for real balls.

Constructors

In order to construct real balls in Nemo, one must first construct the Arb real field itself. This is accomplished with the following constructor.

ArbField(prec::Int)

Return the Arb field with precision in bits prec used for operations on interval midpoints. The precision used for interval radii is a fixed implementation-defined constant (30 bits).

Here is an example of creating an Arb real field and using the resulting parent object to coerce values into the resulting field.

Examples

RR = ArbField(64)

a = RR("0.25")
b = RR("0.1 +/- 0.001")
c = RR(0.5)
d = RR(12)

Note that whilst one can coerce double precision floating point values into an Arb real field, unless those values can be represented exactly in double precision the resulting ball can't be any more precise than the double precision supplied.

If instead, values can be represented precisely using decimal arithmetic then one can supply them to Arb using a string. In this case, Arb will store them to the precision specified when creating the Arb field.

If the values can be stored precisely as a binary floating point number, Arb will store the values exactly. See the function is_exact below for more information.

Real ball constructors

Nemo.ballMethod
ball(x::ArbFieldElem, y::ArbFieldElem)

Constructs an Arb ball enclosing $x_m \pm (|x_r| + |y_m| + |y_r|)$, given the pair $(x, y) = (x_m \pm x_r, y_m \pm y_r)$.

source

Examples

RR = ArbField(64)

c = ball(RR(3), RR("0.0001"))

Conversions

RR = ArbField(64)

convert(Float64, RR(1//3))

Basic manipulation

Nemo.is_nonzeroMethod
is_nonzero(x::ArbFieldElem)

Return true if $x$ is certainly not equal to zero, otherwise return false.

source
Base.isfiniteMethod
isfinite(x::ArbFieldElem)

Return true if $x$ is finite, i.e. having finite midpoint and radius, otherwise return false.

source
Nemo.is_exactMethod
is_exact(x::ArbFieldElem)

Return true if $x$ is exact, i.e. has zero radius, otherwise return false.

source
Base.isintegerMethod
isinteger(x::ArbFieldElem)

Return true if $x$ is an exact integer, otherwise return false.

source
Nemo.is_nonnegativeMethod
is_nonnegative(x::ArbFieldElem)

Return true if $x$ is certainly non-negative, otherwise return false.

source
Nemo.is_nonpositiveMethod
is_nonpositive(x::ArbFieldElem)

Return true if $x$ is certainly nonpositive, otherwise return false.

source
Nemo.midpointMethod
midpoint(x::ArbFieldElem)

Return the midpoint of the ball $x$ as an Arb ball.

source
Nemo.radiusMethod
radius(x::ArbFieldElem)

Return the radius of the ball $x$ as an Arb ball.

source
Nemo.accuracy_bitsMethod
accuracy_bits(x::ArbFieldElem)

Return the relative accuracy of $x$ measured in bits, capped between typemax(Int) and -typemax(Int).

source

Examples

RR = ArbField(64)

a = RR("1.2 +/- 0.001")
b = RR(3)

is_positive(a)
isfinite(b)
isinteger(b)
is_negative(a)
c = radius(a)
d = midpoint(b)
f = accuracy_bits(a)

Printing

Printing real balls can at first sight be confusing. Lets look at the following example:

RR = ArbField(64)

a = RR(1)
b = RR(2)
c = RR(12)

x = ball(a, b)
y = ball(c, b)

mid = midpoint(x)
rad = radius(x)

print(x, "\n", y, "\n", mid, "\n", rad)

which generates

[+/- 3.01]
[1e+1 +/- 4.01]
1.0000000000000000000
[2.0000000037252902985 +/- 3.81e-20]

The first reason that c is not printed as [1 +/- 2] is that the midpoint does not have a greater exponent than the radius in its scientific notation. For similar reasons y is not printed as [12 +/- 2].

The second reason is that we get an additional error term after our addition. As we see, radius(c) is not equal to $2$, which when printed rounds it up to a reasonable decimal place. This is because real balls keep track of rounding errors of basic arithmetic.

Containment

It is often necessary to determine whether a given exact value or ball is contained in a given real ball or whether two balls overlap. The following functions are provided for this purpose.

Nemo.overlapsMethod
overlaps(x::ArbFieldElem, y::ArbFieldElem)

Returns true if any part of the ball $x$ overlaps any part of the ball $y$, otherwise return false.

source
Base.containsMethod
contains(x::ArbFieldElem, y::ArbFieldElem)

Returns true if the ball $x$ contains the ball $y$, otherwise return false.

source
Base.containsMethod
contains(x::ArbFieldElem, y::Integer)

Returns true if the ball $x$ contains the given integer value, otherwise return false.

source
Base.containsMethod
contains(x::ArbFieldElem, y::ZZRingElem)

Returns true if the ball $x$ contains the given integer value, otherwise return false.

source
Base.containsMethod
contains(x::ArbFieldElem, y::QQFieldElem)

Returns true if the ball $x$ contains the given rational value, otherwise return false.

source
Base.containsMethod
contains(x::ArbFieldElem, y::Rational{T}) where {T <: Integer}

Returns true if the ball $x$ contains the given rational value, otherwise return false.

source
Base.containsMethod
contains(x::ArbFieldElem, y::BigFloat)

Returns true if the ball $x$ contains the given floating point value, otherwise return false.

source

The following functions are also provided for determining if a ball intersects a certain part of the real number line.

Nemo.contains_zeroMethod
contains_zero(x::ArbFieldElem)

Returns true if the ball $x$ contains zero, otherwise return false.

source
Nemo.contains_negativeMethod
contains_negative(x::ArbFieldElem)

Returns true if the ball $x$ contains any negative value, otherwise return false.

source
Nemo.contains_positiveMethod
contains_positive(x::ArbFieldElem)

Returns true if the ball $x$ contains any positive value, otherwise return false.

source
Nemo.contains_nonnegativeMethod
contains_nonnegative(x::ArbFieldElem)

Returns true if the ball $x$ contains any non-negative value, otherwise return false.

source
Nemo.contains_nonpositiveMethod
contains_nonpositive(x::ArbFieldElem)

Returns true if the ball $x$ contains any nonpositive value, otherwise return false.

source

Examples

RR = ArbField(64)
x = RR("1 +/- 0.001")
y = RR("3")

overlaps(x, y)
contains(x, y)
contains(y, 3)
contains(x, ZZ(1)//2)
contains_zero(x)
contains_positive(y)

Comparison

Nemo provides a full range of comparison operations for Arb balls. Note that a ball is considered less than another ball if every value in the first ball is less than every value in the second ball, etc.

In addition to the standard comparison operators, we introduce an exact equality. This is distinct from arithmetic equality implemented by ==, which merely compares up to the minimum of the precisions of its operands.

Base.isequalMethod
isequal(x::ArbFieldElem, y::ArbFieldElem)

Return true if the balls $x$ and $y$ are precisely equal, i.e. have the same midpoints and radii.

source

We also provide a full range of ad hoc comparison operators. These are implemented directly in Julia, but we document them as though isless and == were provided.

Function
==(x::ArbFieldElem, y::Integer)
==(x::Integer, y::ArbFieldElem)
==(x::ArbFieldElem, y::ZZRingElem)
==(x::ZZRingElem, y::ArbFieldElem)
==(x::ArbFieldElem, y::Float64)
==(x::Float64, y::ArbFieldElem)
isless(x::ArbFieldElem, y::Integer)
isless(x::Integer, y::ArbFieldElem)
isless(x::ArbFieldElem, y::ZZRingElem)
isless(x::ZZRingElem, y::ArbFieldElem)
isless(x::ArbFieldElem, y::Float64)
isless(x::Float64, y::ArbFieldElem)
isless(x::ArbFieldElem, y::BigFloat)
isless(x::BigFloat, y::ArbFieldElem)
isless(x::ArbFieldElem, y::QQFieldElem)
isless(x::QQFieldElem, y::ArbFieldElem)

Examples

RR = ArbField(64)
x = RR("1 +/- 0.001")
y = RR("3")
z = RR("4")

isequal(x, deepcopy(x))
x == 3
ZZ(3) < z
x != 1.23

Absolute value

Examples

RR = ArbField(64)
x = RR("-1 +/- 0.001")

a = abs(x)

Shifting

Examples

RR = ArbField(64)
x = RR("-3 +/- 0.001")

a = ldexp(x, 23)
b = ldexp(x, -ZZ(15))

Miscellaneous operations

Nemo.add_error!Method
add_error!(x::ArbFieldElem, y::ArbFieldElem)

Adds the absolute values of the midpoint and radius of $y$ to the radius of $x$.

source
Nemo.trimMethod
trim(x::ArbFieldElem)

Return an ArbFieldElem interval containing $x$ but which may be more economical, by rounding off insignificant bits from the midpoint.

source
Nemo.unique_integerMethod
unique_integer(x::ArbFieldElem)

Return a pair where the first value is a boolean and the second is an ZZRingElem integer. The boolean indicates whether the interval $x$ contains a unique integer. If this is the case, the second return value is set to this unique integer.

source
Nemo.setunionMethod
setunion(x::ArbFieldElem, y::ArbFieldElem)

Return an ArbFieldElem containing the union of the intervals represented by $x$ and $y$.

source

Examples

RR = ArbField(64)
x = RR("-3 +/- 0.001")
y = RR("2 +/- 0.5")

a = trim(x)
b, c = unique_integer(x)
d = setunion(x, y)

Constants

Nemo.const_piMethod
const_pi(r::ArbField)

Return $\pi = 3.14159\ldots$ as an element of $r$.

source
Nemo.const_eMethod
const_e(r::ArbField)

Return $e = 2.71828\ldots$ as an element of $r$.

source
Nemo.const_log2Method
const_log2(r::ArbField)

Return $\log(2) = 0.69314\ldots$ as an element of $r$.

source
Nemo.const_log10Method
const_log10(r::ArbField)

Return $\log(10) = 2.302585\ldots$ as an element of $r$.

source
Nemo.const_eulerMethod
const_euler(r::ArbField)

Return Euler's constant $\gamma = 0.577215\ldots$ as an element of $r$.

source
Nemo.const_catalanMethod
const_catalan(r::ArbField)

Return Catalan's constant $C = 0.915965\ldots$ as an element of $r$.

source
Nemo.const_khinchinMethod
const_khinchin(r::ArbField)

Return Khinchin's constant $K = 2.685452\ldots$ as an element of $r$.

source
Nemo.const_glaisherMethod
const_glaisher(r::ArbField)

Return Glaisher's constant $A = 1.282427\ldots$ as an element of $r$.

source

Examples

RR = ArbField(200)

a = const_pi(RR)
b = const_e(RR)
c = const_euler(RR)
d = const_glaisher(RR)

Mathematical and special functions

Nemo.rsqrtMethod
rsqrt(x::ArbFieldElem)

Return the reciprocal of the square root of $x$, i.e. $1/\sqrt{x}$.

source
Nemo.sqrt1pm1Method
sqrt1pm1(x::ArbFieldElem)

Return $\sqrt{1+x}-1$, evaluated accurately for small $x$.

source
Nemo.sqrtposMethod
sqrtpos(x::ArbFieldElem)

Return the sqrt root of $x$, assuming that $x$ represents a non-negative number. Thus any negative number in the input interval is discarded.

source
Nemo.gammaMethod
gamma(x::ArbFieldElem)

Return the Gamma function evaluated at $x$.

source
Nemo.lgammaMethod
lgamma(x::ArbFieldElem)

Return the logarithm of the Gamma function evaluated at $x$.

source
Nemo.rgammaMethod
rgamma(x::ArbFieldElem)

Return the reciprocal of the Gamma function evaluated at $x$.

source
Nemo.digammaMethod
digamma(x::ArbFieldElem)

Return the logarithmic derivative of the gamma function evaluated at $x$, i.e. $\psi(x)$.

source
Nemo.gammaMethod
gamma(s::ArbFieldElem, x::ArbFieldElem)

Return the upper incomplete gamma function $\Gamma(s,x)$.

source
Nemo.gamma_regularizedMethod
gamma_regularized(s::ArbFieldElem, x::ArbFieldElem)

Return the regularized upper incomplete gamma function $\Gamma(s,x) / \Gamma(s)$.

source
Nemo.gamma_lowerMethod
gamma_lower(s::ArbFieldElem, x::ArbFieldElem)

Return the lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

source
Nemo.gamma_lower_regularizedMethod
gamma_lower_regularized(s::ArbFieldElem, x::ArbFieldElem)

Return the regularized lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.

source
Nemo.zetaMethod
zeta(x::ArbFieldElem)

Return the Riemann zeta function evaluated at $x$.

source
Nemo.atan2Method
atan2(y::ArbFieldElem, x::ArbFieldElem)

Return $\operatorname{atan2}(y,x) = \arg(x+yi)$. Same as atan(y, x).

source
Nemo.agmMethod
agm(x::ArbFieldElem, y::ArbFieldElem)

Return the arithmetic-geometric mean of $x$ and $y$

source
Nemo.zetaMethod
zeta(s::ArbFieldElem, a::ArbFieldElem)

Return the Hurwitz zeta function $\zeta(s,a)$.

source
Base.factorialMethod
factorial(n::Int, r::ArbField)

Return the factorial of $n$ in the given Arb field.

source
Base.binomialMethod
binomial(x::ArbFieldElem, n::UInt)

Return the binomial coefficient ${x \choose n}$.

source
Base.binomialMethod
binomial(n::UInt, k::UInt, r::ArbField)

Return the binomial coefficient ${n \choose k}$ in the given Arb field.

source
Nemo.fibonacciMethod
fibonacci(n::ZZRingElem, r::ArbField)

Return the $n$-th Fibonacci number in the given Arb field.

source
Nemo.fibonacciMethod
fibonacci(n::Int, r::ArbField)

Return the $n$-th Fibonacci number in the given Arb field.

source
Nemo.gammaMethod
gamma(x::ZZRingElem, r::ArbField)

Return the Gamma function evaluated at $x$ in the given Arb field.

source
Nemo.gammaMethod
gamma(x::QQFieldElem, r::ArbField)

Return the Gamma function evaluated at $x$ in the given Arb field.

source
Nemo.zetaMethod
zeta(n::Int, r::ArbField)

Return the Riemann zeta function $\zeta(n)$ as an element of the given Arb field.

source
Nemo.bernoulliMethod
bernoulli(n::Int, r::ArbField)

Return the $n$-th Bernoulli number as an element of the given Arb field.

source
Nemo.polylogMethod
polylog(s::Union{ArbFieldElem,Int}, a::ArbFieldElem)

Return the polylogarithm Li$_s(a)$.

source
Nemo.bellMethod
bell(n::ZZRingElem, r::ArbField)

Return the Bell number $B_n$ as an element of $r$.

source
Nemo.bellMethod
bell(n::Int, r::ArbField)

Return the Bell number $B_n$ as an element of $r$.

source
Nemo.numpartMethod
numpart(n::ZZRingElem, r::ArbField)

Return the number of partitions $p(n)$ as an element of $r$.

source
Nemo.numpartMethod
numpart(n::Int, r::ArbField)

Return the number of partitions $p(n)$ as an element of $r$.

source
Nemo.airy_aiMethod
airy_ai(x::ArbFieldElem)

Return the Airy function $\operatorname{Ai}(x)$.

source
Nemo.airy_ai_primeMethod
airy_ai_prime(x::ArbFieldElem)

Return the derivative of the Airy function $\operatorname{Ai}^\prime(x)$.

source
Nemo.airy_biMethod
airy_bi(x::ArbFieldElem)

Return the Airy function $\operatorname{Bi}(x)$.

source
Nemo.airy_bi_primeMethod
airy_bi_prime(x::ArbFieldElem)

Return the derivative of the Airy function $\operatorname{Bi}^\prime(x)$.

source

Examples

RR = ArbField(64)

a = floor(exp(RR(1)))
b = sinpi(QQ(5,6), RR)
c = gamma(QQ(1,3), ArbField(256))
d = bernoulli(1000, ArbField(53))
f = polylog(3, RR(-10))

Linear dependence

Nemo.lindepMethod
lindep(A::Vector{ArbFieldElem}, bits::Int)

Find a small linear combination of the entries of the array $A$ that is small (using LLL). The entries are first scaled by the given number of bits before truncating to integers for use in LLL. This function can be used to find linear dependence between a list of real numbers. The algorithm is heuristic only and returns an array of Nemo integers representing the linear combination.

Examples

julia> RR = ArbField(64)
Real Field with 64 bits of precision and error bounds

julia> a = RR(-0.33198902958450931620250069492231652319)
[-0.33198902958450932088 +/- 4.15e-22]

julia> V = [RR(1), a, a^2, a^3, a^4, a^5]
6-element Vector{ArbFieldElem}:
 1.0000000000000000000
 [-0.33198902958450932088 +/- 4.15e-22]
 [0.11021671576446420510 +/- 7.87e-21]
 [-0.03659074051063616184 +/- 4.17e-21]
 [0.012147724433904692427 +/- 4.99e-22]
 [-0.004032911246472051677 +/- 6.25e-22]

julia> W = lindep(V, 20)
6-element Vector{ZZRingElem}:
 1
 3
 0
 0
 0
 1
source

Examples

RR = ArbField(128)

a = RR(-0.33198902958450931620250069492231652319)

V = [RR(1), a, a^2, a^3, a^4, a^5]
W = lindep(V, 20)
Nemo.simplest_rational_insideMethod
  simplest_rational_inside(x::ArbFieldElem)

Return the simplest fraction inside the ball $x$. A canonical fraction $a_1/b_1$ is defined to be simpler than $a_2/b_2$ iff $b_1 < b_2$ or $b_1 = b_2$ and $a_1 < a_2$.

Examples

julia> RR = ArbField(64)
Real Field with 64 bits of precision and error bounds

julia> simplest_rational_inside(const_pi(RR))
8717442233//2774848045
source

Examples

RR = ArbField(64)
simplest_rational_inside(const_pi(RR))

Random generation

Base.randMethod
rand(r::ArbField; randtype::Symbol=:urandom)

Return a random element in given Arb field.

The randtype default is :urandom which return an ArbFieldElem contained in $[0,1]$.

The rest of the methods return non-uniformly distributed values in order to exercise corner cases. The option :randtest will return a finite number, and :randtest_exact the same but with a zero radius. The option :randtest_precise return an ArbFieldElem with a radius around $2^{-\mathrm{prec}}$ the magnitude of the midpoint, while :randtest_wide return a radius that might be big relative to its midpoint. The :randtest_special-option might return a midpoint and radius whose values are NaN or inf.

source

Examples

RR = ArbField(100)

a = rand(RR)
b = rand(RR; randtype = :null_exact)
c = rand(RR; randtype = :exact)
d = rand(RR; randtype = :special)