Polydisc

NonArchimedeanMachineLearning.AbsPolydiscType
AbsPolydisc{S,T}

A polydisc over a p-adic field, where the radius is measured with respect to the norm.

Represents the product of p-adic discs where each disc is defined using the p-adic absolute value rather than valuation.

Note: we generally prefer the valuation format.

Fields

  • center::Vector{S}: The center point of the polydisc in p-adic space
  • radius::Vector{T}: The radius vector measured in norm coordinates

Type Parameters

  • S: The type of the center coordinates (typically p-adic numbers)
  • T: The type of the radius values (typically real numbers)
source
NonArchimedeanMachineLearning.HashedPolydiscType
HashedPolydisc{S,T,N}

A wrapper around ValuationPolydisc that caches the hash value for efficient use as a dictionary key. The hash is computed once at construction time and reused for all subsequent hash() calls.

This is used by DAG-MCTS for its transposition table, where the same polydisc may be hashed many times during Dict lookups. Other optimizers (MCTS, UCT, HOO, etc.) that never use polydiscs as Dict keys should use ValuationPolydisc directly to avoid the hashing overhead.

Fields

  • polydisc::ValuationPolydisc{S,T,N}: The underlying polydisc
  • _hash::UInt: The cached hash value
source
NonArchimedeanMachineLearning.ValuationPolydiscType
ValuationPolydisc{S,T,N}

A polydisc over a p-adic field, where the radius is measured with respect to valuation.

Represents the product of p-adic discs $B(c_1, r_1) \times \cdots \times B(c_n, r_n)$ where each disc $B(c_i, r_i) = \{x : v(x - c_i) \geq r_i\}$ with $v$ the p-adic valuation.

Fields

  • center::NTuple{N,S}: The center point of the polydisc in p-adic space
  • radius::NTuple{N,T}: The radius vector measured in valuation coordinates

Type Parameters

  • S: The type of the center coordinates (typically p-adic numbers)
  • T: The type of the radius values (typically integers or rationals)
  • N: The dimension of the polydisc
source
NonArchimedeanMachineLearning.ValuationPolydiscMethod
ValuationPolydisc(K::PadicField, center::Vector{PadicFieldElem}, radius::Vector{T}) where T

Constructor for ValuationPolydisc that accepts an explicit field parameter. This is useful for creating 0-dimensional polydiscs with ValuedFieldPoint wrapping.

Example

K = PadicField(2, 20)
p = ValuationPolydisc(K, Vector{PadicFieldElem}(), Vector{Int}())
# Creates ValuationPolydisc{ValuedFieldPoint{2,20,PadicFieldElem}, Int, 0}
source
NonArchimedeanMachineLearning.ValuationPolydiscMethod
ValuationPolydisc(center::Vector{PadicFieldElem}, radius::Vector{T}) where T

Convenience constructor that automatically wraps PadicFieldElem into ValuedFieldPoint for compile-time optimization.

This constructor extracts the prime and precision from the field and creates a ValuationPolydisc{ValuedFieldPoint{P,Prec,PadicFieldElem},T,N} where P and Prec are type parameters available at compile time.

Example

K = PadicField(2, 20)
p = ValuationPolydisc([K(1), K(2)], [0, 0])
# Creates ValuationPolydisc{ValuedFieldPoint{2,20,PadicFieldElem}, Int, 2}
source
Base.:(==)Method
Base.:(==)(p::ValuationPolydisc, q::ValuationPolydisc)

Check equality of two polydiscs in Berkovich space.

Two polydiscs D(a, r) and D(b, s) represent the same Berkovich point if and only if:

  1. They have the same radius: r = s
  2. Their centers are "close enough": v(a - b) >= r

This is the correct condition for Berkovich equality in non-Archimedean geometry.

Arguments

  • p::ValuationPolydisc: First polydisc
  • q::ValuationPolydisc: Second polydisc

Returns

Bool: true if the polydiscs represent the same Berkovich point, false otherwise

Mathematical Note

The condition v(a-b) >= r (not > r) is crucial: if v(a-b) = r exactly, then D(a, r) and D(b, r) are the same disc by the ultrametric property.

source
Base.eachindexMethod
Base.eachindex(p::ValuationPolydisc)

Return an iterator over the valid indices of the polydisc coordinates.

Arguments

  • p::ValuationPolydisc: The polydisc

Returns

Iterator over indices 1:dim(p)

source
Base.hashMethod
Base.hash(m::ValuationPolydisc, h::UInt)

Compute a hash value for a polydisc for use in hash-based collections.

Uses a canonical representation based on radius and center mod p^radius to ensure that equivalent polydiscs (same radius, centers differing by high-valuation elements) hash to the same value. This is essential for transposition table lookups in DAG-MCTS.

Arguments

  • m::ValuationPolydisc: The polydisc to hash
  • h::UInt: The initial hash value

Returns

UInt: The hash value

source
Base.isequalMethod
Base.isequal(p::ValuationPolydisc, q::ValuationPolydisc)

Check equality of two polydiscs for use in hash-based collections (Dict, Set).

This must be consistent with hash: if isequal(p, q) then hash(p) == hash(q). We use the same definition as == to ensure Dict lookups work correctly.

Note

Julia's Dict uses isequal (not ==) for key comparison. Without this definition, Dict would use === (identity), which is too strict for our purposes.

source
Base.showMethod
Base.show(io::IO, p::ValuationPolydisc)

Display a polydisc in human-readable format.

Arguments

  • io::IO: The output stream
  • p::ValuationPolydisc: The polydisc to display

Prints the base ring, center, and radius information.

source
NonArchimedeanMachineLearning.base_ringMethod
base_ring(p::ValuationPolydisc)

Get the underlying p-adic field of the polydisc.

Arguments

  • p::ValuationPolydisc: The polydisc

Returns

The parent ring (p-adic field) of the center coordinates

source
NonArchimedeanMachineLearning.canonical_centerMethod
canonical_center(p::ValuationPolydisc)

Compute a canonical representation of the polydisc center for hashing purposes.

For each coordinate i, computes center[i] mod p^radius[i] as an integer tuple. This ensures that polydiscs representing the same region (same radius and centers differing by elements with valuation > radius) have the same canonical form.

Uses Int64 arithmetic when prime^radius fits in Int64 (true for all typical parameters: prime ≤ 7, radius ≤ 20), falling back to BigInt for extreme cases.

Arguments

  • p::ValuationPolydisc: The polydisc

Returns

NTuple{N, Int64} (fast path) or NTuple{N, BigInt} (fallback): Canonical integer representation of the center

source
NonArchimedeanMachineLearning.centerMethod
center(p::ValuationPolydisc)

Extract the center point of a polydisc.

Arguments

  • p::ValuationPolydisc: The polydisc

Returns

NTuple{N,S}: The center coordinates of the polydisc

source
NonArchimedeanMachineLearning.childrenMethod
children(p::ValuationPolydisc{S,T,N}, degree=1) where {S,T,N}

Generate all child polydiscs obtained by refining the polydisc in a specified number of coordinates.

Computes all polydiscs obtained by increasing the valuation radius by 1 in exactly degree coordinates and adjusting centers according to residue classes. For degree=1, produces $p \cdot n$ children where $n = \dim(p)$ is the dimension and $p$ is the prime.

Arguments

  • p::ValuationPolydisc{S,T,N}: The parent polydisc
  • degree::Int=1: Number of coordinates to refine simultaneously (must satisfy degree ≤ dim(p))

Returns

Vector{ValuationPolydisc{S,T,N}}: All child polydiscs (of length $\binom{n}{degree} \cdot p^{degree}$)

Notes

  • Currently only works for $\mathbb{Q}_p$ (not general extensions)
  • Enumerates residue classes as 0:prime(p)-1
source
NonArchimedeanMachineLearning.childrenMethod
children(p::ValuationPolydisc{ValuedFieldPoint{P,Prec,PFE},T,N}, degree=1) where {P,Prec,PFE,T,N}

Specialized version of children() for ValuedFieldPoint that leverages compile-time prime.

This version benefits from having P available at compile time, allowing the compiler to optimize loops and potentially unroll iterations for small primes.

source
NonArchimedeanMachineLearning.children_along_branchMethod
children_along_branch(p::ValuationPolydisc{ValuedFieldPoint{P,Prec,PFE},T,N}, branch_index::Int) where {P,Prec,PFE,T,N}

Specialized version of children_along_branch() for ValuedFieldPoint that leverages compile-time prime.

This version benefits from having P available at compile time, allowing the compiler to optimize loops and potentially unroll iterations for small primes.

source
NonArchimedeanMachineLearning.children_along_branchMethod
children_along_branch(p::ValuationPolydisc{S,T,N}, branch_index::Int) where {S,T,N}

Generate all child polydiscs obtained by refining along a single coordinate branch.

Produces $p$ children (where $p$ is the prime) by increasing the radius in coordinate branch_index by 1 and varying the center over all residue classes in that coordinate.

Arguments

  • p::ValuationPolydisc{S,T,N}: The parent polydisc
  • branch_index::Int: The coordinate index to refine (must satisfy 1 ≤ branch_index ≤ dim(p))

Returns

Vector{ValuationPolydisc{S,T,N}}: All child polydiscs along this branch (of length prime(p))

source
NonArchimedeanMachineLearning.concatenateMethod
concatenate(p::ValuationPolydisc{S,T,N1}, q::ValuationPolydisc{S,T,N2}) where {S,T,N1,N2}

Concatenate two polydiscs to form a higher-dimensional polydisc.

If $p = B(a, r)$ is an $n$-dimensional polydisc and $q = B(a', r')$ is an $m$-dimensional polydisc, returns the $(n+m)$-dimensional polydisc $B((a, a'), (r, r'))$.

Arguments

  • p::ValuationPolydisc{S,T,N1}: First polydisc
  • q::ValuationPolydisc{S,T,N2}: Second polydisc

Returns

ValuationPolydisc{S,T,N1+N2}: The concatenated polydisc with dim(p) + dim(q) dimensions

source
NonArchimedeanMachineLearning.dimMethod
dim(p::ValuationPolydisc)

Return the dimension of the polydisc space.

The dimension is the number of coordinate discs in the product, i.e., the length of the center vector.

Arguments

  • p::ValuationPolydisc: The polydisc

Returns

Int: The dimension of the polydisc space

source
NonArchimedeanMachineLearning.distMethod
dist(b1::ValuationPolydisc{S,T,N}, b2::ValuationPolydisc{S,T,N}) where {S,T,N}

Compute the distance between two polydiscs in the polydisc space.

The distance is computed as the sum over all coordinates of the symmetric difference between the discs, measured using the formula: $d = \sum_i (p^{-r_j^i} - p^{-r_1^i} + p^{-r_j^i} - p^{-r_2^i})$ where $r_j^i$ is the radius of the join in coordinate $i$.

Arguments

  • b1::ValuationPolydisc{S,T,N}: First polydisc
  • b2::ValuationPolydisc{S,T,N}: Second polydisc

Returns

Float64: The distance between the two polydiscs

source
NonArchimedeanMachineLearning.joinMethod
join(b1::ValuationPolydisc{S,T,N}, b2::ValuationPolydisc{S,T,N}) where {S,T,N}

Compute the join (smallest common ancestor) of two polydiscs in the Bruhat-Tits tree.

The join is the largest polydisc containing both input polydiscs. For each coordinate $i$, the radius is $\min(r_1^i, v(c_1^i - c_2^i), r_2^i)$ where $r_j^i$ is the $i$-th radius of polydisc $j$ and $c_j^i$ is the $i$-th center coordinate.

Arguments

  • b1::ValuationPolydisc{S,T,N}: First polydisc
  • b2::ValuationPolydisc{S,T,N}: Second polydisc

Returns

ValuationPolydisc{S,T,N}: The join polydisc with center from b1 and computed radii

source
NonArchimedeanMachineLearning.primeMethod
prime(p::ValuationPolydisc)

Return the prime number of the p-adic field underlying the polydisc.

Arguments

  • p::ValuationPolydisc: The polydisc

Returns

Integer prime $p$ such that the base ring is $\mathbb{Q}_p$ or an extension thereof

source
NonArchimedeanMachineLearning.primeMethod
prime(p::ValuationPolydisc{ValuedFieldPoint{P,Prec,S},T,N}) where {P,Prec,S,T,N}

Return the prime of a polydisc with ValuedFieldPoint elements.

This is a compile-time constant when using ValuedFieldPoint, enabling optimizations in hot-path functions like children().

Returns

Int: The prime P (compile-time constant)

source
NonArchimedeanMachineLearning.radiusMethod
radius(p::ValuationPolydisc)

Extract the radius vector of a polydisc.

Arguments

  • p::ValuationPolydisc: The polydisc

Returns

NTuple{N,T}: The radius values (in valuation coordinates) for each dimension

source