Arbitrary precision real balls
Arbitrary 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 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.
| Library | Field | Element type | Parent type |
|---|---|---|---|
| Arb | $\mathbb{R}$ (balls) | RealFieldElem | RealField |
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.
Precision management
Precision for ball arithmetic and creation of elements can be controlled using the functions:
set_precision! — Method
set_precision!(::Type{Balls}, n::Int)Set the precision for all ball arithmetic to be n.
Examples
julia> const_pi(real_field())
[3.141592653589793239 +/- 5.96e-19]
julia> set_precision!(Balls, 200); const_pi(real_field())
[3.14159265358979323846264338327950288419716939937510582097494 +/- 5.73e-60]sourceset_precision! — Method
set_precision!(f, ::Type{Balls}, n::Int)Change ball arithmetic precision to n for the duration of f..
Examples
julia> set_precision!(Balls, 4) do
const_pi(real_field())
end
[3e+0 +/- 0.376]
julia> set_precision!(Balls, 200) do
const_pi(real_field())
end
[3.1415926535897932385 +/- 3.74e-20]sourceConstructors
In order to construct real balls in Nemo, one must first construct the Arb real field itself. This is accomplished with the following constructor.
real_field — Method
real_field()Return the field of real numbers modelled via real balls.
See precision and set_precision! on how to control the precision.
Here is an example of creating the real field and using the resulting parent object to coerce values into the resulting field.
Examples
julia> RR = real_field()
Real field
julia> a = RR("0.25")
0.25000000000000000000
julia> b = RR("0.1 +/- 0.001")
[0.1 +/- 1.01e-3]
julia> c = RR(0.5)
0.50000000000000000000
julia> d = RR(12)
12.000000000000000000Note 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
Using coercion into the real field, new elements can be created.
Examples
julia> c = RR(1)
1.0000000000000000000
julia> d = RR(1//2)
0.50000000000000000000Note that for the construction, also the precision can be supplied:
julia> c = RR(1//3, precision=100)
[0.33333333333333333333 +/- 3.34e-21]
julia> d = RR(1//3, precision=4)
[0.3 +/- 0.0438]Conversions
julia> convert(Float64, RR(1//3))
0.3333333333333333Basic manipulation
is_nonzero — Method
is_nonzero(x::RealFieldElem)Return true if $x$ is certainly not equal to zero, otherwise return false.
is_positive — Method
is_positive(x::RealFieldElem)Return true if $x$ is certainly positive, otherwise return false.
is_nonnegative — Method
is_nonnegative(x::RealFieldElem)Return true if $x$ is certainly non-negative, otherwise return false.
is_negative — Method
is_negative(x::RealFieldElem)Return true if $x$ is certainly negative, otherwise return false.
is_nonpositive — Method
is_nonpositive(x::RealFieldElem)Return true if $x$ is certainly nonpositive, otherwise return false.
accuracy_bits — Method
accuracy_bits(x::RealFieldElem)Return the relative accuracy of $x$ measured in bits, capped between typemax(Int) and -typemax(Int).
Examples
julia> RR = real_field()
Real field
julia> a = RR("1.2 +/- 0.001")
[1.20 +/- 1.01e-3]
julia> b = RR(3)
3.0000000000000000000
julia> is_positive(a)
true
julia> isfinite(b)
true
julia> isinteger(b)
true
julia> is_negative(a)
false
julia> c = radius(a)
[0.0010000000038417056203 +/- 1.12e-23]
julia> d = midpoint(b)
3.0000000000000000000
julia> f = accuracy_bits(a)
9Printing
Printing real balls can at first sight be confusing. Lets look at the following example:
julia> a = RR(1)
1.0000000000000000000
julia> b = RR(2)
2.0000000000000000000
julia> c = RR(12)
12.000000000000000000
julia> x = ball(a, b)
[+/- 3.01]
julia> y = ball(c, b)
[1e+1 +/- 4.01]
julia> mid = midpoint(x)
1.0000000000000000000
julia> rad = radius(x)
[2.0000000037252902985 +/- 3.81e-20]
julia> print(x, "\n", y, "\n", mid, "\n", rad)
[+/- 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.
The following functions are also provided for determining if a ball intersects a certain part of the real number line.
contains_zero — Method
contains_zero(x::RealFieldElem)Returns true if the ball $x$ contains zero, otherwise return false.
contains_negative — Method
contains_negative(x::RealFieldElem)Returns true if the ball $x$ contains any negative value, otherwise return false.
contains_positive — Method
contains_positive(x::RealFieldElem)Returns true if the ball $x$ contains any positive value, otherwise return false.
contains_nonnegative — Method
contains_nonnegative(x::RealFieldElem)Returns true if the ball $x$ contains any non-negative value, otherwise return false.
contains_nonpositive — Method
contains_nonpositive(x::RealFieldElem)Returns true if the ball $x$ contains any nonpositive value, otherwise return false.
Examples
julia> x = RR("1 +/- 0.001")
[1.00 +/- 1.01e-3]
julia> y = RR("3")
3.0000000000000000000
julia> overlaps(x, y)
false
julia> contains(x, y)
false
julia> contains(y, 3)
true
julia> contains(x, ZZ(1)//2)
false
julia> contains_zero(x)
false
julia> contains_positive(y)
trueComparison
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.
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::RealFieldElem, y::Integer) |
==(x::Integer, y::RealFieldElem) |
==(x::RealFieldElem, y::ZZRingElem) |
==(x::ZZRingElem, y::RealFieldElem) |
==(x::RealFieldElem, y::Float64) |
==(x::Float64, y::RealFieldElem) |
isless(x::RealFieldElem, y::Integer) |
isless(x::Integer, y::RealFieldElem) |
isless(x::RealFieldElem, y::ZZRingElem) |
isless(x::ZZRingElem, y::RealFieldElem) |
isless(x::RealFieldElem, y::Float64) |
isless(x::Float64, y::RealFieldElem) |
isless(x::RealFieldElem, y::BigFloat) |
isless(x::BigFloat, y::RealFieldElem) |
isless(x::RealFieldElem, y::QQFieldElem) |
isless(x::QQFieldElem, y::RealFieldElem) |
Examples
julia> x = RR("1 +/- 0.001")
[1.00 +/- 1.01e-3]
julia> y = RR("3")
3.0000000000000000000
julia> z = RR("4")
4.0000000000000000000
julia> isequal(x, deepcopy(x))
true
julia> x == 3
false
julia> ZZ(3) < z
true
julia> x != 1.23
trueAbsolute value
Examples
julia> x = RR("-1 +/- 0.001")
[-1.00 +/- 1.01e-3]
julia> a = abs(x)
[1.00 +/- 1.01e-3]Shifting
Examples
julia> x = RR("-3 +/- 0.001")
[-3.00 +/- 1.01e-3]
julia> a = ldexp(x, 23)
[-2.52e+7 +/- 4.26e+4]
julia> b = ldexp(x, -ZZ(15))
[-9.16e-5 +/- 7.78e-8]Miscellaneous operations
add_error! — Method
add_error!(x::RealFieldElem, y::RealFieldElem)Adds the absolute values of the midpoint and radius of $y$ to the radius of $x$.
sourceunique_integer — Method
unique_integer(x::RealFieldElem)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.
Examples
julia> x = RR("-3 +/- 0.001")
[-3.00 +/- 1.01e-3]
julia> y = RR("2 +/- 0.5")
[2e+0 +/- 0.501]
julia> a = trim(x)
[-3.00 +/- 1.01e-3]
julia> b, c = unique_integer(x)
(true, -3)
julia> d = setunion(x, y)
[+/- 3.01]Constants
const_log2 — Method
const_log10 — Method
const_euler — Method
const_euler(r::RealField)Return Euler's constant $\gamma = 0.577215\ldots$ as an element of $r$.
sourceconst_catalan — Method
const_catalan(r::RealField)Return Catalan's constant $C = 0.915965\ldots$ as an element of $r$.
sourceconst_khinchin — Method
const_khinchin(r::RealField)Return Khinchin's constant $K = 2.685452\ldots$ as an element of $r$.
sourceconst_glaisher — Method
const_glaisher(r::RealField)Return Glaisher's constant $A = 1.282427\ldots$ as an element of $r$.
sourceExamples
julia> a = const_pi(RR)
[3.141592653589793239 +/- 5.96e-19]
julia> b = const_e(RR)
[2.718281828459045235 +/- 4.29e-19]
julia> c = const_euler(RR)
[0.5772156649015328606 +/- 4.35e-20]
julia> d = const_glaisher(RR)
[1.282427129100622637 +/- 3.01e-19]Mathematical and special functions
gamma_regularized — Method
gamma_regularized(s::RealFieldElem, x::RealFieldElem)Return the regularized upper incomplete gamma function $\Gamma(s,x) / \Gamma(s)$.
sourcegamma_lower — Method
gamma_lower(s::RealFieldElem, x::RealFieldElem)Return the lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.
sourcegamma_lower_regularized — Method
gamma_lower_regularized(s::RealFieldElem, x::RealFieldElem)Return the regularized lower incomplete gamma function $\gamma(s,x) / \Gamma(s)$.
sourcerising_factorial — Method
rising_factorial(x::RealFieldElem, n::Int)Return the rising factorial $x(x + 1)\ldots (x + n - 1)$.
sourcerising_factorial(x::RingElement, n::Integer)Return the rising factorial of $x$, i.e. $x(x + 1)(x + 2)\cdots (x + n - 1)$. If $n < 0$ we throw a DomainError().
Examples
julia> R, x = ZZ[:x];
julia> rising_factorial(x, 1)
x
julia> rising_factorial(x, 2)
x^2 + x
julia> rising_factorial(4, 2)
20sourcerising_factorial — Method
rising_factorial(x::QQFieldElem, n::Int, r::RealField)Return the rising factorial $x(x + 1)\ldots (x + n - 1)$ as an element of the given field.
sourcerising_factorial2 — Method
rising_factorial2(x::RealFieldElem, n::Int)Return a tuple containing the rising factorial $x(x + 1)\ldots (x + n - 1)$ and its derivative.
sourcerising_factorial2(x::RingElement, n::Integer)Return a tuple containing the rising factorial $x(x + 1)\cdots (x + n - 1)$ and its derivative. If $n < 0$ we throw a DomainError().
Examples
julia> R, x = ZZ[:x];
julia> rising_factorial2(x, 1)
(x, 1)
julia> rising_factorial2(x, 2)
(x^2 + x, 2*x + 1)
julia> rising_factorial2(4, 2)
(20, 9)sourcechebyshev_t — Method
chebyshev_u — Method
chebyshev_t2 — Method
chebyshev_u2 — Method
airy_ai_prime — Method
airy_ai_prime(x::RealFieldElem)Return the derivative of the Airy function $\operatorname{Ai}^\prime(x)$.
sourceairy_bi_prime — Method
airy_bi_prime(x::RealFieldElem)Return the derivative of the Airy function $\operatorname{Bi}^\prime(x)$.
sourceExamples
julia> a = floor(exp(RR(1)))
2.0000000000000000000
julia> b = sinpi(QQ(5,6), RR)
0.50000000000000000000
julia> c = gamma(QQ(1,3), RR)
[2.678938534707747634 +/- 7.13e-19]
julia> d = bernoulli(1000, RR)
[-5.318704469415522036e+1769 +/- 6.61e+1750]
julia> f = polylog(3, RR(-10))
[-5.92106480375697 +/- 6.68e-15]Linear dependence
lindep — Method
lindep(A::Vector{RealFieldElem}, 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 = real_field()
Real field
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{RealFieldElem}:
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
1sourcesimplest_rational_inside — Method
simplest_rational_inside(x::RealFieldElem)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 = real_field()
Real field
julia> simplest_rational_inside(const_pi(RR))
8717442233//2774848045sourceRandom generation
rand — Method
rand(r::RealField; randtype::Symbol=:urandom)Return a random element in given field.
The randtype default is :urandom which return an RealFieldElem 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 RealFieldElem 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.
Examples
a = rand(RR)
b = rand(RR; randtype = :null_exact)
c = rand(RR; randtype = :exact)
d = rand(RR; randtype = :special)