Fraction fields

Nemo allows the creation of fraction fields over any ring RR. We don't require RR to be an integral domain, however no attempt is made to deal with the general case. Two fractions a/ba/b and c/dc/d are equal in Nemo iff ad=bcad = bc. Thus, in practice, a greatest common divisor function is currently required for the ring RR.

In order to make the representation a/ba/b unique for printing, we have a notion of canonical unit for elements of a ring RR. When canonicalising a/ba/b, each of the elements aa and bb is first divided by the canonical unit of bb.

The canonical_unit function is defined for elements of every Nemo ring. It must have the properties

canonical_unit(u) == u
canonical_unit(a*b) == canonical_unit(a)*canonical_unit(b)

for any unit uu of the ring in question, and aa and bb arbitrary elements of the ring.

For example, the canonical unit of an integer is its sign. Thus a fraction of integers always has positive denominator after canonicalisation.

The canonical unit of a polynomial is the canonical unit of its leading coefficient, etc.

There are two different kinds of implementation of fraction fields in Nemo: a generic one for the case where no specific implementation exists (provided by AbstractAlgebra.jl), and efficient implementations of fractions over specific rings, usually provided by C/C++ libraries.

The following table shows each of the fraction types available in Nemo, the base ring RR, and the Julia/Nemo types for that kind of fraction (the type information is mainly of concern to developers).

Base ringLibraryElement typeParent type
Generic ring RRAbstractAlgebra.jlGeneric.FracFieldElem{T}Generic.FracField{T}
Z\mathbb{Z}FLINTQQFieldElemQQField

All fraction element types belong to the abstract type FracElem and all of the fraction field types belong to the abstract type FracField. This enables one to write generic functions that can accept any Nemo fraction type.

Fraction functionality

All fraction types in Nemo provide functionality for fields described in AbstractAlgebra.jl:

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

In addition all the fraction field functionality of AbstractAlgebra.jl is provided, along with generic fractions fields as described here:

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

Basic manipulation

signMethod
sign(a::QQFieldElem)

Return the sign of aa (1-1, 00 or 11) as a fraction.

source
heightMethod
height(a::QQFieldElem)

Return the height of the fraction aa, namely the largest of the absolute values of the numerator and denominator.

source
height_bitsMethod
height_bits(a::QQFieldElem)

Return the number of bits of the height of the fraction aa.

source
<<Method
<<(a::QQFieldElem, b::Int)

Return a×2ba \times 2^b.

source
>>Method
>>(a::QQFieldElem, b::Int)

Return a/2ba/2^b.

source
floorMethod
floor(a::QQFieldElem)

Return the greatest integer that is less than or equal to aa. The result is returned as a rational with denominator 11.

source
ceilMethod
ceil(a::QQFieldElem)

Return the least integer that is greater than or equal to aa. The result is returned as a rational with denominator 11.

source

Examples

julia> d = abs(ZZ(11)//3)
11//3

julia> 4 <= ZZ(7)//ZZ(3)
false

Modular arithmetic

The following functions are available for rationals.

modMethod
mod(a::QQFieldElem, b::ZZRingElem)
mod(a::QQFieldElem, b::Integer)

Return a(modb)a \pmod{b} where bb is an integer coprime to the denominator of aa.

Examples

julia> mod(-ZZ(2)//3, 7)
4

julia> mod(ZZ(1)//2, ZZ(5))
3
source

Rational Reconstruction

Rational reconstruction is available for rational numbers.

reconstructMethod
reconstruct(a::ZZRingElem, m::ZZRingElem)
reconstruct(a::ZZRingElem, m::Integer)
reconstruct(a::Integer, m::ZZRingElem)
reconstruct(a::Integer, m::Integer)

Attempt to return a rational number n/dn/d such that 0nm/20 \leq |n| \leq \lfloor\sqrt{m/2}\rfloor and 0<dm/20 < d \leq \lfloor\sqrt{m/2}\rfloor such that gcd(n,d)=1(n, d) = 1 and and1(modm)a \equiv nd^{-1} \pmod{m}. If no solution exists, an exception is thrown.

Examples

julia> a = reconstruct(7, 13)
1//2

julia> b = reconstruct(ZZ(15), 31)
-1//2

julia> c = reconstruct(ZZ(123), ZZ(237))
9//2
source
reconstructMethod
reconstruct(a::ZZRingElem, m::ZZRingElem, N::ZZRingElem, D::ZZRingElem)

Attempt to return a rational number n/dn/d such that 0nN0 \leq |n| \leq N and 0<dD0 < d \leq D such that 2ND<m2 N D < m, gcd(n,d)=1(n, d) = 1, and and1(modm)a \equiv nd^{-1} \pmod{m}.

Returns a tuple (success, n/d), where success signals the success of reconstruction.

The behaviour is undefined if aa is negative or larger than mm.

source

Rational enumeration

Various methods exist to enumerate rationals.

next_minimalMethod
next_minimal(a::QQFieldElem)

Given aa, return the next rational number in the sequence obtained by enumerating all positive denominators qq, and for each qq enumerating the numerators 1p<q1 \le p < q in order and generating both p/qp/q and q/pq/p, but skipping all gcd(p,q)1(p,q) \neq 1. Starting with zero, this generates every non-negative rational number once and only once, with the first few entries being 0,1,1/2,2,1/3,3,2/3,3/2,1/4,4,3/4,4/3,0, 1, 1/2, 2, 1/3, 3, 2/3, 3/2, 1/4, 4, 3/4, 4/3, \ldots. This enumeration produces the rational numbers in order of minimal height. It has the disadvantage of being somewhat slower to compute than the Calkin-Wilf enumeration. If a<0a < 0 we throw a DomainError().

Examples

julia> next_minimal(ZZ(2)//3)
3//2
source
next_signed_minimalMethod
next_signed_minimal(a::QQFieldElem)

Given a signed rational number aa assumed to be in canonical form, return the next element in the minimal-height sequence generated by next_minimal but with negative numbers interleaved. The sequence begins 0,1,1,1/2,1/2,2,2,1/3,1/3,0, 1, -1, 1/2, -1/2, 2, -2, 1/3, -1/3, \ldots. Starting with zero, this generates every rational number once and only once, in order of minimal height.

Examples

julia> next_signed_minimal(-ZZ(21)//31)
31//21
source
next_calkin_wilfMethod
next_calkin_wilf(a::QQFieldElem)

Return the next number after aa in the breadth-first traversal of the Calkin-Wilf tree. Starting with zero, this generates every non-negative rational number once and only once, with the first few entries being 0,1,1/2,2,1/3,3/2,2/3,3,1/4,4/3,3/5,5/2,2/5,0, 1, 1/2, 2, 1/3, 3/2, 2/3, 3, 1/4, 4/3, 3/5, 5/2, 2/5, \ldots. Despite the appearance of the initial entries, the Calkin-Wilf enumeration does not produce the rational numbers in order of height: some small fractions will appear late in the sequence. This order has the advantage of being faster to produce than the minimal-height order.

Examples

julia> next_calkin_wilf(ZZ(321)//113)
113//244
source
next_signed_calkin_wilfMethod
next_signed_calkin_wilf(a::QQFieldElem)

Given a signed rational number aa returns the next element in the Calkin-Wilf sequence with negative numbers interleaved. The sequence begins 0,1,1,1/2,1/2,2,2,1/3,1/3,0, 1, -1, 1/2, -1/2, 2, -2, 1/3, -1/3, \ldots. Starting with zero, this generates every rational number once and only once, but not in order of minimal height.

Examples

julia> next_signed_calkin_wilf(-ZZ(51)//(17))
1//4
source

Random generation

rand_bitsMethod
rand_bits(::QQField, b::Int)

Return a random signed rational whose numerator and denominator both have bb bits before canonicalisation. Note that the resulting numerator and denominator can be smaller than bb bits.

source

Special functions

The following special functions are available for specific rings in Nemo.

harmonicMethod
harmonic(n::Int)

Return the harmonic number Hn=1+1/2+1/3++1/nH_n = 1 + 1/2 + 1/3 + \cdots + 1/n. Table lookup is used for HnH_n whose numerator and denominator fit in a single limb. For larger nn, a divide and conquer strategy is used.

Examples

julia> a = harmonic(12)
86021//27720
source
bernoulliMethod
bernoulli(n::Int)

Return the Bernoulli number BnB_n for non-negative nn.

See also bernoulli_cache.

Examples

julia> d = bernoulli(12)
-691//2730
source
bernoulli_cacheMethod
bernoulli_cache(n::Int)

Precomputes and caches all the Bernoulli numbers up to BnB_n. This is much faster than repeatedly calling bernoulli(k). Once cached, subsequent calls to bernoulli(k) for any knk \le n will read from the cache, making them virtually free.

See also bernoulli.

Examples

julia> bernoulli_cache(100)

julia> e = bernoulli(100)
-94598037819122125295227433069493721872702841533066936133385696204311395415197247711//33330
source
dedekind_sumMethod
dedekind_sum(h::ZZRingElem, k::ZZRingElem)

Return the Dedekind sum s(h,k)s(h,k) for arbitrary hh and kk.

Examples

julia> b = dedekind_sum(12, 13)
-11//13

julia> c = dedekind_sum(-120, ZZ(1305))
-575//522
source
simplest_betweenMethod
  simplest_between(l::QQFieldElem, r::QQFieldElem)

Return the simplest fraction in the closed interval [l,r][l, r]. A canonical fraction a1/b1a_1 / b_1 is defined to be simpler than a2/b2a_2 / b_2 if and only if b1<b2b_1 < b_2 or b1=b2b_1 = b_2 and a1<a2a_1 < a_2.

Examples

julia> simplest_between(QQ(1//10), QQ(3//10))
1//4
source