A Julia package for computing the equilibrium, or barycentric, placement of vertices
of a periodic graph, as defined by Olaf Delgado-Friedrichs and Michael O'Keeffe.
It is accessible through the equilibrium
exported function, which returns a matrix of
rational coordinates that can be fed to the PeriodicGraphEmbedding
or
SortedPeriodicGraphEmbedding
methods from PeriodicGraphEmbeddings.jl:
julia> tbo = PeriodicGraph3D("3 1 2 0 0 0 1 3 0 0 0 1 4 0 0 0 2 5 0 0 0 2 6 0 0 0 2 7 0 0 0 3 6 0 0 1 3 8 0 0 0 3 9 0 0 0 4 6 1 0 0 4 10 0 0 0 4 11 0 0 0 5 12 0 0 0 5 13 0 0 0 7 12 1 1 -1 7 13 0 1 0 8 12 0 0 0 8 14 0 0 0 9 12 1 1 0 9 14 0 1 0 10 13 0 0 0 10 14 0 0 0 11 13 1 1 0 11 14 1 1 -1");
julia> equilibrium(tbo)
3×14 Matrix{Rational{Int64}}:
0//1 -1//6 -1//6 1//3 -1//3 -1//3 0//1 -1//3 0//1 0//1 2//3 -2//3 -1//6 -1//6
0//1 0//1 0//1 0//1 -1//3 0//1 1//3 -1//3 1//3 -1//3 1//3 -1//2 -1//2 -1//2
0//1 -1//6 1//3 -1//6 0//1 -1//3 -1//3 1//3 1//3 0//1 -1//3 1//3 -1//6 1//3
The implementation is optimized through a custom solver specialized for the exact
resolution of sparse integer linear system through Dixon's algorithm.
The solver is directly accessible through the dixon_solve
function:
julia> A = sparse([-3 0 2 0; 0 -5 2 3; 2 2 -2 0; 0 3 0 -3]);
julia> Y = [1 1; 0 2; 1 -1; 0 0];
julia> A * dixon_solve(Val(2), A, Y) == Y
true
The first argument of dixon_solve
must be Val(size(Y)[2])
and the second must be square.
The package also exposes a rational_solve
function which solves the same systems through
a simpler LU decomposition approach. It serves as fallback to dixon_solve
when Dixon's
algorithm fails, but can also be used as-is with the same API. Its performance is in
general lower than dixon_solve
, often significantly so.
See also:
- PeriodicGraphs.jl for the
underlying library and the API of the
PeriodicGraph
type. - CrystalNets.jl for a dependent package specialized on crystal nets.