Polydisc
NonArchimedeanMachineLearning.AbsPolydisc — Type
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 spaceradius::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)
NonArchimedeanMachineLearning.HashedPolydisc — Type
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
NonArchimedeanMachineLearning.HashedPolydisc — Method
HashedPolydisc(p::ValuationPolydisc{S,T,N}) where {S,T,N}Create a HashedPolydisc by computing and caching the hash of p.
NonArchimedeanMachineLearning.ValuationPolydisc — Type
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 spaceradius::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
NonArchimedeanMachineLearning.ValuationPolydisc — Method
ValuationPolydisc(K::PadicField, center::Vector{PadicFieldElem}, radius::Vector{T}) where TConstructor 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}NonArchimedeanMachineLearning.ValuationPolydisc — Method
ValuationPolydisc(center::Vector{PadicFieldElem}, radius::Vector{T}) where TConvenience 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}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:
- They have the same radius: r = s
- 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 polydiscq::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.
Base.eachindex — Method
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)
Base.hash — Method
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 hashh::UInt: The initial hash value
Returns
UInt: The hash value
Base.isequal — Method
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.
NonArchimedeanMachineLearning.base_ring — Method
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
NonArchimedeanMachineLearning.canonical_center — Method
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
NonArchimedeanMachineLearning.center — Method
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
NonArchimedeanMachineLearning.children — Method
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 polydiscdegree::Int=1: Number of coordinates to refine simultaneously (must satisfydegree ≤ 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
NonArchimedeanMachineLearning.children — Method
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.
NonArchimedeanMachineLearning.children_along_branch — Method
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.
NonArchimedeanMachineLearning.children_along_branch — Method
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 polydiscbranch_index::Int: The coordinate index to refine (must satisfy1 ≤ branch_index ≤ dim(p))
Returns
Vector{ValuationPolydisc{S,T,N}}: All child polydiscs along this branch (of length prime(p))
NonArchimedeanMachineLearning.concatenate — Method
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 polydiscq::ValuationPolydisc{S,T,N2}: Second polydisc
Returns
ValuationPolydisc{S,T,N1+N2}: The concatenated polydisc with dim(p) + dim(q) dimensions
NonArchimedeanMachineLearning.dim — Method
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
NonArchimedeanMachineLearning.dist — Method
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 polydiscb2::ValuationPolydisc{S,T,N}: Second polydisc
Returns
Float64: The distance between the two polydiscs
NonArchimedeanMachineLearning.join — Method
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 polydiscb2::ValuationPolydisc{S,T,N}: Second polydisc
Returns
ValuationPolydisc{S,T,N}: The join polydisc with center from b1 and computed radii
NonArchimedeanMachineLearning.prime — Method
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
NonArchimedeanMachineLearning.prime — Method
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)
NonArchimedeanMachineLearning.radius — Method
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