ChipFiring
Documentation for ChipFiring.
ChipFiring.ChipFiringGraph
ChipFiring.Divisor
ChipFiring.Workspace
Base.getindex
Base.setindex!
Base.show
Base.size
ChipFiring.borrow!
ChipFiring.borrow!
ChipFiring.clear!
ChipFiring.compute_genus
ChipFiring.compute_gonality
ChipFiring.dhar
ChipFiring.dhar!
ChipFiring.divisor_rank
ChipFiring.find_negative_vertices!
ChipFiring.get_num_edges
ChipFiring.has_rank_at_least_r
ChipFiring.has_rank_at_least_r
ChipFiring.is_equivalent
ChipFiring.is_winnable
ChipFiring.is_winnable!
ChipFiring.laplacian
ChipFiring.lend!
ChipFiring.lend!
ChipFiring.neighbors
ChipFiring.next_composition!
ChipFiring.parse_graph6
ChipFiring.q_reduced
ChipFiring.q_reduced!
ChipFiring.subdivide
ChipFiring.ChipFiringGraph
— TypeChipFiringGraph
A structure to represent the underlying graph of a chip-firing graph.
This struct provides multiple representations of the graph's structure to suit different computational needs. It is designed for undirected, connected graphs, and the input multiplicity matrix is expected to be symmetric.
Fields
adj_matrix::Matrix{Int}
: Then x n
multiplicity matrix, whereadj_matrix[i, j]
is the number of edges between vertexi
and vertexj
.num_vertices::Int
: The number of vertices in the graph,n
.num_edges::Int
: The total number of edges in the graph.adj_list::Vector{Vector{Int}}
: An adjacency list whereadj_list[i]
contains the neighbors of vertexi
. This represents the underlying simple graph, meaning each neighbor appears only once, regardless of edge multiplicity.edge_list::Vector{Tuple{Int, Int}}
: A vector of tuples, where each tuple(i, j)
represents an edge. Edges are included with their full multiplicity.degree_list::Vector{Int}
: A vector wheredegree_list[i]
stores the degree of vertexi
, accounting for edge multiplicity.
Constructors
ChipFiringGraph(multiplicity_matrix::Matrix{Int})
: Constructs aChipFiringGraph
from a square, symmetric multiplicity matrix. Throws an error if the matrix is not square, not symmetric, or if the graph is not connected.ChipFiringGraph(num_vertices::Int, edge_list::Vector{Tuple{Int, Int}})
: Constructs aChipFiringGraph
from a list of edges and the total number of vertices.
ChipFiring.Divisor
— TypeDivisor <: AbstractVector{Int}
A struct representing a chip configuration (or "divisor") on a graph.
Fields
chips::Vector{Int}
: Ann
-element vector wherechips[i]
is the number of chips on vertexi
.
ChipFiring.Workspace
— TypeWorkspace
A mutable container for pre-allocated arrays and temporary data structures used in performance-critical algorithms.
This struct is exposed for users who need to run many computations in a tight loop and want to avoid repeated memory allocations. For one-off calculations, it is often more convenient to use the wrapper functions (e.g., q_reduced(g, d, q)
) which handle workspace creation automatically.
Base.getindex
— Methodgetindex(d::Divisor, i::Int)
Returns the number of chips on vertex i
. Allows d[i]
syntax.
Base.setindex!
— Methodsetindex!(d::Divisor, val, i::Int)
Sets the number of chips on vertex i
. Allows d[i] = val
syntax.
Base.show
— Methodshow(io::IO, g::ChipFiringGraph)
Provides a concise, single-line string representation of a ChipFiringGraph. To obtain a string output, the string()
function can do so.
Base.size
— Methodsize(d::Divisor)
Returns the size of the divisor (the number of vertices).
ChipFiring.borrow!
— Methodborrow!(g::ChipFiringGraph, d::Divisor, v::Int)
Borrows from a single vertex v
.
ChipFiring.borrow!
— Methodborrow!(g::ChipFiringGraph, d::Divisor, vertices::Vector{Int})
Borrows from each vertex in the provided vector.
ChipFiring.clear!
— Methodclear!(ws::Workspace)
Resets all fields in the Workspace
to their default initial states.
ChipFiring.compute_genus
— Methodcompute_genus(g::ChipFiringGraph) -> Int
Returns the genus (in the topological sense) of the graph represented by g
. Note that this is not the typical definition of graph genus.
ChipFiring.compute_gonality
— Methodcompute_gonality(g::ChipFiringGraph; min_d=1, max_d=nothing, verbose=false, r=1) -> Int
Computes the r
-th (default: 1) gonality of a graph g
.
Arguments
g::ChipFiringGraph
: The graph to analyze.
Optional Arguments
min_d=1
: The minimum degreed
to check.max_d=nothing
: The maximum degreed
to check. Defaults tonothing
.verbose=false
: Iftrue
, prints progress updates.r=1
: Calculatesr
-th gonality. Defaults to1
.
Returns
Int
: The computed gonality of the graph. Returns -1 if not found withinmax_d
.
The result of computegonality may return r * n in the case when maxd is set to r * n - 1.
ChipFiring.dhar!
— Methoddhar!(g::ChipFiringGraph, divisor::Divisor, source::Int, ws::Workspace) -> Bool
Performs a recursive burn starting from a source
vertex to determine if a divisor
is super-stable with respect to that source.
Following the user's definition, a divisor is super-stable if the entire graph burns. A vertex v
"burns" if its number of chips is less than the number of edges connecting it to already-burnt vertices.
Arguments
g::ChipFiringGraph
: The graph structure.divisor::Divisor
: Input divisor.source::Int
: The vertex (1-indexed) from which to start the burn.ws::Workspace
: The following fields are read fromws
: ws.burned, ws.legals, ws.threats
Returns
is_superstable::Bool
:true
if the entire graph was burned.
Modifies
ws.burned::Vector{Bool}
: Tracks burned vertices.ws.legals::Vector{Int}
: The indices of unburned vertices that form a legal firing.
ChipFiring.dhar
— Methoddhar(g::ChipFiringGraph, divisor::Divisor, source::Int) -> Tuple{Bool, Vector{Int}}
Performs a burn starting from a source
vertex to determine if a divisor
is super-stable.
This is a convenience wrapper that allocates a temporary workspace. For performance-critical code where this function is called repeatedly, use the version that accepts a Workspace
argument.
Arguments
g::ChipFiringGraph
: The graph structure.divisor::Divisor
: The chip configuration to test.source::Int
: The vertex (1-indexed) from which to start the burn.
Returns
- The first element is
true
if the divisor is super-stable,false
otherwise. - The second element is a vector of unburned vertices. This vector is empty if the divisor is super-stable.
ChipFiring.divisor_rank
— Methoddivisor_rank(g::ChipFiringGraph, d::Divisor) -> Int
Given a ChipFiringGraph g
and Divisor d
, returns the rank (in the sense of Baker and Norine) of d
on g
. See Divisors and Sandpiles by Corry and Perkinson.
ChipFiring.find_negative_vertices!
— Methodfind_negative_vertices!(out_vec::Vector{Int}, g::ChipFiringGraph, d::Divisor, q::Int)
Finds all vertices with negative chips (excluding the sink q
) and pushes them into the pre-allocated out_vec
. This is a non-allocating operation.
ChipFiring.get_num_edges
— Methodget_num_edges(g::ChipFiringGraph, u::Int, v::Int) -> Int
Returns the number of edges (multiplicity) between two vertices u
and v
.
ChipFiring.has_rank_at_least_r
— Methodhas_rank_at_least_r(g::ChipFiringGraph, d::Divisor, r::Int) -> Bool
Given a ChipFiringGraph g
and Divisor d
, returns a boolean determining whether or not d
has rank at least r
.
ChipFiring.has_rank_at_least_r
— Methodhas_rank_at_least_r(g::ChipFiringGraph, r::Int, ws::Workspace) -> Bool
Checks if a divisor ws.d1
has rank at least r
.
ChipFiring.is_equivalent
— Methodis_equivalent(g::ChipFiringGraph, d1::Divisor, d2::Divisor) -> Bool
Tests if two divisors are equivalent under chip-firing.
ChipFiring.is_winnable!
— Methodis_winnable(g::ChipFiringGraph, divisor::Divisor, ws::Workspace) -> Bool
Checks if a chip configuration is linearly equivalent to an effective divisor using a version of Dhar's burning algorithm.
ChipFiring.is_winnable
— Methodis_winnable(g::ChipFiringGraph, divisor::Divisor) -> Bool
Checks if a chip configuration is linearly equivalent to an effective divisor using a version of Dhar's burning algorithm.
This is a convenience wrapper that allocates a temporary workspace. For performance-critical code where this function is called repeatedly, use the version that accepts a Workspace
argument.
ChipFiring.laplacian
— Methodlaplacian(g::ChipFiringGraph) -> Matrix{Int}
Returns the discrete Laplacian matrix of g
.
ChipFiring.lend!
— Methodlend!(g::ChipFiringGraph, d::Divisor, v::Int)
Lends (fires) a single vertex v
.
ChipFiring.lend!
— Methodlend!(g::ChipFiringGraph, d::Divisor, vertices::Vector{Int})
Lends (fires) from each vertex in the provided vector.
ChipFiring.neighbors
— Methodneighbors(g::ChipFiringGraph, v::Int) -> Vector{Int}
Returns a vector containing the indices of the neighbors of vertex v
.
ChipFiring.next_composition!
— Methodnext_composition!(v::Vector{Int}) -> Bool
Mutates a vector v
into the next composition of the integer sum(v)
, generating them in colexicographical order.
Algorithm
- Find the first non-zero element from the left,
v[t]
. This is the "pivot". - If no such element exists (or it's the last one), we are at the end of the sequence.
- Move one unit from the pivot to its right neighbor:
v[t+1] += 1
. - Move the remaining value of the pivot (
v[t] - 1
) to the very first positionv[1]
. - Set the pivot's original position
v[t]
to zero.
Example: [3, 0, 0]
-> [2, 1, 0]
-> [1, 2, 0]
-> [0, 3, 0]
-> [2, 0, 1]
...
Returns
true
if a next configuration was generated.false
ifv
was already the last configuration (e.g., [0, 0, ..., d]).
ChipFiring.parse_graph6
— Methodparse_graph6(g6_string::String) -> ChipFiringGraph
Parses a graph from a string in the graph6
format and returns a ChipFiringGraph
.
This function fully implements the graph6
specification for simple, undirected graphs, including the 1, 4, and 8-byte encodings for the number of vertices.
Arguments
g6_string::String
: The string representing the graph. An optional header>>graph6<<
is ignored if present.
Returns
- A
ChipFiringGraph
object.
Throws
ArgumentError
: If the string is malformed, contains invalid characters, or ends unexpectedly.
ChipFiring.q_reduced!
— Methodq_reduced(g::ChipFiringGraph, divisor::Divisor; q::Int, ws::Workspace) -> Divisor
Finds the equivalent, q-reduced effective divisor to the one given.
Arguments
g
: The graph structure.divisor
: The initial chip configuration.q
: The sink vertex.ws
: The workspace containing pre-allocated arrays.
Returns
d::Divisor
: The resulting divisor
ChipFiring.q_reduced
— Methodq_reduced(g::ChipFiringGraph, divisor::Divisor; q::Int, ws::Workspace) -> Divisor
Finds the equivalent, q-reduced effective divisor to the one given, based on the algorithm from the user-provided Python code.
This is a convenience wrapper that allocates a temporary workspace. For performance-critical code where this function is called repeatedly, use the version that accepts a Workspace
argument.
Arguments
g
: The graph structure.divisor
: The initial chip configuration.q
: The sink vertex.ws
: The workspace containing pre-allocated arrays.
Returns
d::Divisor
: The resulting divisor
ChipFiring.subdivide
— Methodsubdivide(g::ChipFiringGraph, subdivisions::Int) -> ChipFiringGraph
Given a ChipFiringGraph g
, produces another ChipFiringGraph which is an k-uniform subdivision of g
.
Arguments
g::ChipFiringGraph
the original graphsubdivisions::Int
number of uniform subdivisions (1 returns original graph, 2 produces 2-uniform subdivision, etc.)
Returns
- A k-uniform subdivided ChipFiringGraph