Qadics

Q-adic fields, that is, unramified extensions of p-adic fields, are provided in Nemo by Flint. This allows construction of $q$-adic fields for any prime power $q$.

Q-adic fields are constructed using the FlintQadicField function. However, for convenience we define

QadicField = FlintQadicField

so that $q$-adic fields can be constructed using QadicField rather than FlintQadicField. Note that this is the name of the constructor, but not of qadic field type.

The types of $q$-adic fields 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
Flint$\mathbb{Q}_q$qadicQadicField

All the $q$-adic field types belong to the Field abstract type and the $q$-adic field element types belong to the FieldElem abstract type.

P-adic functionality

Q-adic fields in Nemo provide all the functionality described in AbstractAlgebra for fields:.

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

Below, we document all the additional function that is provide by Nemo for q-adic fields.

Constructors

In order to construct $q$-adic field elements in Nemo, one must first construct the $q$-adic field itself. This is accomplished with one of the following constructors.

FlintQadicFieldMethod
FlintQadicField(p::Integer, d::Int, prec::Int, var::String = "a")

Returns the parent object for the $q$-adic field for given prime $p$ and degree $d$, where the default absolute precision of elements of the field is given by prec and the generator is printed as var.

It is also possible to call the inner constructor directly. It has the following form.

FlintQadicField(p::ZZRingElem, d::Int, prec::Int)

Returns the parent object for the $q$-adic field for given prime $p$ and degree $d$, where the default absolute precision of elements of the field is given by prec. It also return the uniformizer p with the default precision.

Here are some examples of creating $q$-adic fields and making use of the resulting parent objects to coerce various elements into those fields.

Examples

julia> R, p = QadicField(7, 1, 30);

julia> S, _ = QadicField(ZZ(65537), 1, 30);

julia> a = R()
0

julia> b = S(1)
65537^0 + O(65537^30)

julia> c = S(ZZ(123))
123*65537^0 + O(65537^30)

julia> d = R(ZZ(1)//7^2)
7^-2 + O(7^28)

Big-oh notation

Elements of p-adic fields can be constructed using the big-oh notation. For this purpose we define the following functions.

OMethod
O(R::FlintQadicField, m::Integer)

Construct the value $0 + O(p^n)$ given $m = p^n$. An exception results if $m$ is not found to be a power of p = prime(R).

OMethod
O(R::FlintQadicField, m::ZZRingElem)

Construct the value $0 + O(p^n)$ given $m = p^n$. An exception results if $m$ is not found to be a power of p = prime(R).

OMethod
O(R::FlintQadicField, m::QQFieldElem)

Construct the value $0 + O(p^n)$ given $m = p^n$. An exception results if $m$ is not found to be a power of p = prime(R).

The $O(p^n)$ construction can be used to construct $q$-adic values of precision $n$ by adding it to integer values representing the $q$-adic value modulo $p^n$ as in the examples.

Examples

julia> R, _ = QadicField(7, 1, 30);

julia> S, _ = QadicField(ZZ(65537), 1, 30);

julia> c = 1 + 2*7 + 4*7^2 + O(R, 7^3)
7^0 + 2*7^1 + 4*7^2 + O(7^3)

julia> d = 13 + 357*ZZ(65537) + O(S, ZZ(65537)^12)
13*65537^0 + 357*65537^1 + O(65537^12)

julia> f = ZZ(1)//7^2 + ZZ(2)//7 + 3 + 4*7 + O(R, 7^2)
7^-2 + 2*7^-1 + 3*7^0 + 4*7^1 + O(7^2)

Beware that the expression 1 + 2*p + 3*p^2 + O(R, p^n) is actually computed as a normal Julia expression. Therefore if {Int} values are used instead of Flint integers or Julia bignums, overflow may result in evaluating the value.

Basic manipulation

primeMethod
prime(R::FlintQadicField)

Return the prime $p$ for the given $q$-adic field.

precisionMethod
precision(a::qadic)

Return the precision of the given $q$-adic field element, i.e. if the element is known to $O(p^n)$ this function will return $n$.

valuationMethod
valuation(a::qadic)

Return the valuation of the given $q$-adic field element, i.e. if the given element is divisible by $p^n$ but not a higher power of $q$ then the function will return $n$.

liftMethod
lift(R::QQPolyRing, a::qadic)

Return a lift of the given $q$-adic field element to $\mathbb{Q}[x]$.

liftMethod
lift(R::ZZPolyRing, a::qadic)

Return a lift of the given $q$-adic field element to $\mathbb{Z}[x]$ if possible.

Examples

R, _ = QadicField(7, 1, 30);

a = 1 + 2*7 + 4*7^2 + O(R, 7^3)
b = 7^2 + 3*7^3 + O(R, 7^5)
c = R(2)

k = precision(a)
m = prime(R)
n = valuation(b)
Qx, x = FlintQQ["x"]
p = lift(Qx, a)
Zy, y = FlintZZ["y"]
q = lift(Zy, divexact(a, b))

Square root

sqrtMethod
sqrt(a::Generic.PuiseuxSeriesElem{T}; check::Bool=true) where T <: RingElement

Return the square root of the given Puiseux series $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

Base.sqrt(f::PolyRingElem{T}; check::Bool=true) where T <: RingElement

Return the square root of $f$. By default the function checks the input is square and raises an exception if not. If check=false this check is omitted.

Base.sqrt(a::FracElem{T}; check::Bool=true) where T <: RingElem

Return the square root of $a$. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

sqrt(a::FieldElem)

Return the square root of the element a. By default the function will throw an exception if the input is not square. If check=false this test is omitted.

Examples

julia> R, _ = QadicField(7, 1, 30);

julia> a = 1 + 7 + 2*7^2 + O(R, 7^3)
7^0 + 7^1 + 2*7^2 + O(7^3)

julia> b = 2 + 3*7 + O(R, 7^5)
2*7^0 + 3*7^1 + O(7^5)

julia> c = 7^2 + 2*7^3 + O(R, 7^4)
7^2 + 2*7^3 + O(7^4)

julia> d = sqrt(a)
7^0 + 4*7^1 + 3*7^2 + O(7^3)

julia> f = sqrt(b)
4*7^0 + 7^1 + 5*7^2 + 5*7^3 + 6*7^4 + O(7^5)

julia> f = sqrt(c)
7^1 + 7^2 + O(7^3)

julia> g = sqrt(R(121))
4*7^0 + 7^1 + O(7^30)

Special functions

expMethod
exp(a::Generic.LaurentSeriesElem)

Return the exponential of the power series $a$.

exp(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the exponential of the given Puiseux series $a$.

exp(a::AbsPowerSeriesRingElem)

Return the exponential of the power series $a$.

exp(a::RelPowerSeriesRingElem)

Return the exponential of the power series $a$.

logMethod
log(a::Generic.PuiseuxSeriesElem{T}) where T <: RingElement

Return the logarithm of the given Puiseux series $a$.

log(a::SeriesElem{T}) where T <: FieldElement

Return the logarithm of the power series $a$.

teichmullerMethod
teichmuller(a::qadic)

Return the Teichmuller lift of the $q$-adic value $a$. We require the valuation of $a$ to be nonnegative. The precision of the output will be the same as the precision of the input. For convenience, if $a$ is congruent to zero modulo $q$ we return zero. If the input is not valid an exception is thrown.

frobeniusMethod
frobenius(a::qadic, e::Int = 1)

Return the image of the $e$-th power of Frobenius on the $q$-adic value $a$. The precision of the output will be the same as the precision of the input.

Examples

julia> R, _ = QadicField(7, 1, 30);

julia> a = 1 + 7 + 2*7^2 + O(R, 7^3)
7^0 + 7^1 + 2*7^2 + O(7^3)

julia> b = 2 + 5*7 + 3*7^2 + O(R, 7^3)
2*7^0 + 5*7^1 + 3*7^2 + O(7^3)

julia> c = 3*7 + 2*7^2 + O(R, 7^5)
3*7^1 + 2*7^2 + O(7^5)

julia> c = exp(c)
7^0 + 3*7^1 + 3*7^2 + 4*7^3 + 4*7^4 + O(7^5)

julia> d = log(a)
7^1 + 5*7^2 + O(7^3)

julia> c = exp(R(0))
7^0 + O(7^30)

julia> d = log(R(1))
0

julia> f = teichmuller(b)
2*7^0 + 4*7^1 + 6*7^2 + O(7^3)

julia> g = frobenius(a, 2)
7^0 + 7^1 + 2*7^2 + O(7^3)