elfes.modules
Torch operations for geometry, physical data, model outputs, and learning.
BlockSparseAffineTransform
BlockSparseAffineTransform(
basis_set: BasisSet,
onsite_shifts: Tensor,
onsite_scales: Tensor,
offsite_shifts: Tensor,
offsite_scales: Tensor,
)
Bases: Module
Apply a fixed invertible affine transform in coupled coordinates.
For each canonical onsite or offsite path \(a=(s_1,s_2,n_1\ell_1, n_2\ell_2,L)\), all \(2L+1\) components share one nonzero scale \(A_a\). Only \(L=0\) paths may have a shift \(B_a\). For coupled input \(x\) and output \(y\), the forward transform is
and its inverse is
Onsite and offsite parameters are distinct, while Hermitian reverse species and shell pairs use the same path parameters.
Both directions accept and return coupled-coordinate
BlockSparseOrbData. This module does not couple or decouple
block-sparse values and does not assign normalization semantics to either direction;
a model or experiment composes it with BlockSparseCGTransform according
to its own data flow.
Parameters:
-
(basis_setBasisSet) –Basis set defining species, shells, and orbital order.
-
(onsite_shiftsTensor) –Scalar-path shifts with shape
[n_onsite_paths, *extra_shape]; higher-\(L\) entries must be zero. -
(onsite_scalesTensor) –Nonzero onsite scales with the same shape.
-
(offsite_shiftsTensor) –Offsite shifts with shape
[n_offsite_paths, *extra_shape]; higher-\(L\) entries must be zero. -
(offsite_scalesTensor) –Nonzero offsite scales with the same shape.
from_stats
classmethod
from_stats(basis_set: BasisSet, stats: BlockSparseStats) -> Self
Construct the transform represented by dataset statistics.
identity
classmethod
identity(basis_set: BasisSet, *, extra_shape: tuple[int, ...] = ()) -> Self
Construct an identity transform with the requested value shape.
forward
forward(
coupled_matrix: BlockSparseOrbData, species_indices: Tensor
) -> BlockSparseOrbData
Return values * scale + shift in coupled coordinates.
inverse
inverse(
coupled_matrix: BlockSparseOrbData, species_indices: Tensor
) -> BlockSparseOrbData
Return (values - shift) / scale in coupled coordinates.
OrbVectorAffineTransform
OrbVectorAffineTransform(
basis_set: BasisSet, shell_shifts: Sequence[Tensor], shell_scales: Sequence[Tensor]
)
Bases: Module
Apply a fixed invertible affine transform to real orbital vectors.
Parameters are specified once per atomic basis and shell in the canonical
species order of one BasisSet, and every scale is nonzero. Let atomic
site \(i\) belong to species \(s\).
A shell is labeled by \((n,\ell)\), where \(n\) enumerates radial shells with
the same \(\ell\) in their AtomicBasis order; \(c\) is any trailing channel
multi-index that is not transformed by spatial rotations.
For \(\ell=0\), \(x^i_{n0c}\) and \(y^i_{n0c}\) are scalars. For \(\ell>0\), \(\mathbf{x}^i_{n\ell c}\) and \(\mathbf{y}^i_{n\ell c}\) are complete real spherical vectors in the \((2\ell+1)\)-dimensional orbital representation \(V_{\ell,(-1)^\ell}\). The scale \(A^s_{n\ell c}\) and scalar-shell shift \(B^s_{n0c}\) are scalars. The forward transform is
and
Its inverse is
and
For \(g\in\mathrm{O}(3)\) and \(\ell>0\), the spherical vector transforms by the real orbital irrep matrix \(D^{(\ell,(-1)^\ell)}(g)\). Because \(A^s_{n\ell c}\) is a scalar,
For \(\ell=0\), \(D^{(0,+)}(g)=1\), so
Thus the shift is allowed only for scalar shells. The inverse replaces \(A\) by \(A^{-1}\) and \(B\) by \(-A^{-1}B\), so it obeys the same argument and is O(3)-equivariant as well.
Parameters:
-
(basis_setBasisSet) –Basis set defining the canonical model species order and orbital layouts.
-
(shell_shiftsSequence[Tensor]) –One tensor per entry of
basis_set.atomic_bases, with shape[n_shells, *extra_shape]. -
(shell_scalesSequence[Tensor]) –Nonzero scales with the same shapes as
shell_shifts.
Attributes:
-
orb_shifts(Tensor) –Shifts expanded from shells to orbital components, with shape
[sum_s n_orb(s), *extra_shape]. The first axis concatenates species inbasis_set.atomic_basesorder, then each species in shell order and the2 * ell + 1spherical components within each shell. -
orb_scales(Tensor) –Scales expanded in the same layout and with the same shape as
orb_shifts. -
orb_counts(Tensor) –Number of orbital components per atom for each model species, with shape
[num_species]and dtypetorch.long. -
species_offsets(Tensor) –Leading-zero prefix sum of
orb_counts, with shape[num_species + 1]and dtypetorch.long. Speciessoccupiesorb_shifts[species_offsets[s]:species_offsets[s + 1]], and likewise fororb_scales.
from_stats
classmethod
from_stats(basis_set: BasisSet, stats: OrbVectorStats) -> Self
Construct the transform represented by dataset statistics.
identity
classmethod
identity(basis_set: BasisSet, *, extra_shape: tuple[int, ...] = ()) -> Self
Construct an identity transform with the requested value shape.
forward
forward(vector: OrbData, species_indices: Tensor) -> OrbData
Return values * scale + shift in the model's packed order.
Parameters:
-
(vectorOrbData) –Real orbital vectors in packed atom order.
-
(species_indicesTensor) –Model species index of every atom, with shape
[n_atoms]and dtypetorch.long.
inverse
inverse(vector: OrbData, species_indices: Tensor) -> OrbData
Return (values - shift) / scale in the model's packed order.
Parameters:
-
(vectorOrbData) –Real orbital vectors in packed atom order.
-
(species_indicesTensor) –Model species index of every atom, with shape
[n_atoms]and dtypetorch.long.
BlockSparseCGTransform
Bases: Module
Change packed block-sparse values to and from coupled coordinates.
The transform is defined by one BasisSet. For every ordered pair of
shells with angular momenta \((\ell_1, \ell_2)\), it replaces the flattened
product basis \(m_1 \otimes m_2\) by the canonical sequence
Both orbital axes and the coupled M components use ELFES's Wikipedia real spherical-harmonic basis, ordered from -l to +l (l=1: y, z, x). No Cartesian permutation or conversion to another component basis is required. Coefficients come from the vendored NumPy Wigner-3j generator also used by S2NN tensor products, with its real coupling-path phases. Multiplying each unit-Frobenius-norm block by \(\sqrt{2L+1}\) makes the complete matrix orthogonal, so the inverse is its transpose.
Input and output use the same BlockSparseOrbData mapping. Block order,
block lengths, and all metadata are preserved; only values_real and an
optional values_imag are replaced. The output of decompose is therefore
a transient coupled-coordinate view of the same ragged storage, not another
physical-data type. Any trailing value axes are carried independently
through the spatial transform.
Parameters:
-
(basis_setBasisSet) –Basis set defining species, shell, and orbital order.
decompose
decompose(matrix: BlockSparseOrbData, species_indices: Tensor) -> BlockSparseOrbData
Decompose physical matrix blocks into coupled coordinates.
compose
compose(
coupled_matrix: BlockSparseOrbData, species_indices: Tensor
) -> BlockSparseOrbData
Compose coupled coordinates into physical matrix blocks.
AtomCartesianVectorDecoder
AtomCartesianVectorDecoder(node_channels: int)
Bases: Module
Decode l=1 node features into atom-level Cartesian vectors.
The same channel-mixing weights act on all three l=1 components, which
makes the readout SO(3)-equivariant. ELFES spherical tensors use (y, z,
x) order at l=1; returned Cartesian vectors use ordinary (x, y, z)
order.
Parameters:
-
(node_channelsint) –Channel multiplicity of the spherical node features.
forward
forward(node_features: Tensor) -> Tensor
Parameters:
-
(node_featuresTensor) –[N_atom, (l_max+1)**2, C_node].
Returns:
-
vectors(Tensor) –[N_atom, 3].
BlockSparseOrbMatrixDecoder
BlockSparseOrbMatrixDecoder(
node_channels: int,
edge_channels: int,
basis_set: BasisSet,
l_max: int,
m_max: int | None = None,
*,
hermitian: bool = False,
output_transform: BlockSparseAffineTransform | None = None,
)
Bases: Module
Decode real spinless atom-pair blocks, optionally enforcing Hermiticity.
Nodes use global l-major features; edges use local m-major features and
global-to-local Wigner matrices. The basis set determines ordered species,
shell pairs, coupled irreps and packed output sizes. Outputs contain only
requested atom pairs, in request order, independent of connectivity order.
With hermitian=True, both directed edges must exist even when only one
member of a Hermitian pair is requested. Zero-shift onsite blocks read nodes.
Nonzero-shift pairs with equal atom indices read edges.
l_max must cover all output coupled degrees. Truncated local modes are
zero-filled before rotation; this restricts the offsite readout function.
U(1) real/imaginary components are converted to real spherical components,
not physical values_imag. No spin or SOC coupling is performed.
output_transform optionally restores physical scales in global coupled
coordinates before CG composition and Hermitian averaging. It must use
the same basis set and scalar values (extra_shape=()). Its canonical
path policy applies to Hermitian targets only.
forward
forward(
node_features: Tensor,
edge_features: Tensor,
species_indices: Tensor,
edge_index: Tensor,
edge_shifts: Tensor,
wigner_matrices: Tensor,
atom_pair_index: Tensor,
pair_shifts: Tensor,
batch: Tensor,
ptr: Tensor,
) -> BlockSparseOrbData
Parameters:
-
(node_featuresTensor) –[N, (l_max+1)**2, C_node]. -
(edge_featuresTensor) –[E, K, C_edge]in m-major layout. -
(species_indicesTensor) –[N], in basis-set species order. -
(edge_indexTensor) –[2, E]. -
(edge_shiftsTensor) –[E, 3], integer cell shifts. -
(wigner_matricesTensor) –[E, sum_l (2*l+1)**2]. -
(atom_pair_indexTensor) –[2, P], batch-global atom indices. -
(pair_shiftsTensor) –[P, 3], integer cell shifts. -
(batchTensor) –[N]. -
(ptrTensor) –[B+1].
Returns:
-
matrix(BlockSparseOrbData) –Requested packed blocks,
values_real: [V]. Requests are grouped by sample, with arbitrary order within it.
OrbVectorDecoder
OrbVectorDecoder(node_channels: int, basis_set: BasisSet)
Bases: Module
Decode dense spherical node features into packed orbital vectors.
Each output shell uses a species- and shell-specific linear combination of
the input channels. The same weights act on every component within the
shell's l block, so the readout is SO(3)-equivariant. Output components
follow the atomic-basis shell order and the ELFES real spherical-harmonic
convention within each shell.
Attributes:
-
weight–Channel-mixing weights for every species shell, with shape
[sum_s n_shells(s), node_channels]. -
orb_counts(Tensor) –Number of orbital components per atom for each model species, with shape
[num_species]. -
species_offsets(Tensor) –Leading-zero prefix sum of
orb_counts, with shape[num_species + 1]. -
value_component_indices(Tensor) –Spherical component for every species orbital component, with shape
[sum_s n_orb(s)]. -
value_weight_indices(Tensor) –Shell-weight row for every species orbital component, with shape
[sum_s n_orb(s)].
forward
forward(
node_features: Tensor, species_indices: Tensor, batch: Tensor, ptr: Tensor
) -> OrbData
Parameters:
-
(node_featuresTensor) –[N_atom, (l_max+1)**2, C_node]. -
(species_indicesTensor) –[N_atom]. -
(batchTensor) –[N_atom]. -
(ptrTensor) –[B+1].
Returns:
-
orb_data(OrbData) –values_real:
[N_orb]. num_values:[B].
ScalarDecoder
ScalarDecoder(node_channels: int, hidden_channels: int)
Bases: Module
Decode spherical node features into one additive scalar per sample.
The decoder maps each node's l=0 features to a scalar contribution and
sums the contributions over the nodes belonging to each sample.
Parameters:
-
(node_channelsint) –Channel multiplicity of the spherical node features.
-
(hidden_channelsint) –Width of the scalar readout MLP.
forward
forward(node_features: Tensor, batch: Tensor, ptr: Tensor) -> Tensor
Parameters:
-
(node_featuresTensor) –[N_atom, (l_max+1)**2, C_node]. -
(batchTensor) –[N_atom]. -
(ptrTensor) –[B+1].
Returns:
-
scalars(Tensor) –[B].
SymmetricTensorDecoder
SymmetricTensorDecoder(node_channels: int, hidden_channels: int)
Bases: Module
Decode intensive symmetric Cartesian tensors [B,3,3] by atom mean.
A scalar MLP predicts the isotropic coefficient; a shared channel linear
maps l=2 to the five traceless coefficients in ELFES real harmonics.
The six Cartesian basis tensors are orthonormal under the Frobenius product.
neighbor_list
neighbor_list(
quantities: str,
positions: Tensor,
cell: Tensor,
pbc: Tensor,
cutoff: float,
batch_ptr: Tensor | None = None,
*,
algorithm: Literal["auto", "brute_force", "cell_list"] = "auto",
cpu_threads: int | None = None,
sorted: bool = False,
half_list: bool = False,
include_self: bool = False,
) -> tuple[Tensor, ...]
Build a Torch neighbor list within a strict distance cutoff.
Parameters:
-
(quantitiesstr) –Returned quantities in order:
"i"and"j"select source and target indices,"P"paired indices,"S"integer cell shifts,"d"distances, and"D"displacement vectors. -
(positionsTensor) –Cartesian positions with shape
(n_atoms, 3)for one structure or(n_total_atoms, 3)for a batch. Tensors may reside on CPU or CUDA and must have dtypefloat32orfloat64. -
(cellTensor) –Cell vectors stored as rows, with shape
(3, 3)for one structure or(n_structures, 3, 3)for a batch. Its dtype and device must matchpositions. -
(pbcTensor) –Periodic-axis flags with shape
(3,)for one structure or(n_structures, 3)for a batch, dtypebool, and the same device aspositions. -
(cutofffloat) –Strict, finite, positive distance cutoff in the same length unit as
positionsandcell. -
(batch_ptrTensor | None, default:None) –Optional
int64structure boundaries with shape(n_structures + 1,).Nonedenotes one structure. -
(algorithmLiteral['auto', 'brute_force', 'cell_list'], default:'auto') –Native search algorithm.
-
(cpu_threadsint | None, default:None) –CPU thread count.
Noneuses one CPU thread and leaves the CUDA option unspecified. -
(sortedbool, default:False) –Whether to sort pairs by source index.
-
(half_listbool, default:False) –Whether to retain one member of each reverse-pair class.
-
(include_selfbool, default:False) –Whether to include zero-shift self pairs.
Returns:
-
Tensor–One tensor per character in
quantities. Forn_edgespairs,iand -
...–jhave shape(n_edges,),Phas shape(n_edges, 2),Shas -
tuple[Tensor, ...]–shape
(n_edges, 3),dhas shape(n_edges,), andDhas shape -
tuple[Tensor, ...]–(n_edges, 3). Results remain on the input device. Distances and -
tuple[Tensor, ...]–displacements preserve the floating dtype and remain differentiable
-
tuple[Tensor, ...]–with respect to
positionsandcellwhile the discrete neighbor -
tuple[Tensor, ...]–identity is fixed.
bloch_transform
bloch_transform(
matrix_r: BlockSparseOrbData,
orb_counts: Tensor,
batch_ptr: Tensor,
kpoints: Tensor,
*,
hermitian: bool,
) -> OrbData
Transform cell-shift blocks into compact dense Bloch matrices.
The transform uses fractional reciprocal coordinates and the ELFES forward phase
matrix_r follows the batched BlockSparseOrbData layout, with
batch-global atom indices. When hermitian=True, its stored blocks are the
independent rows of a Hermitian matrix and the omitted conjugate-transpose
partners are included in the result.
Each sample's full dense matrix is flattened in C order along the leading
values axis. The sample matrices remain consecutive but are not padded to a
common orbital dimension. The operation is expressed entirely in ordinary
PyTorch and is differentiable with respect to values_real and optional
values_imag.
Parameters:
-
(matrix_rBlockSparseOrbData) –Real or complex block values.
values_realand optionalvalues_imaghave shape[n_values, *extra_shape]. -
(orb_countsTensor) –Number of orbitals on every atom in the batch, with shape
[n_atoms]. -
(batch_ptrTensor) –Sample boundaries on the atom axis, with shape
[n_samples + 1]. -
(kpointsTensor) –One fractional k-point with shape
[3]or multiple k-points with shape[n_kpoints, 3]. -
(hermitianbool) –Whether
matrix_rstores only independent Hermitian blocks.
Returns:
spherical_harmonics
spherical_harmonics(l_max: int, directions: Tensor) -> Tensor
Evaluate normalized real spherical harmonics through l_max.
The harmonics follow the Wikipedia real spherical harmonic convention and
are ordered in consecutive \(l\) blocks, with m = -l, ..., l within each
block.
Parameters:
-
(l_maxint) –Highest \(l\) to calculate. Results include every \(l\) from zero through
l_max. -
(directionsTensor) –Nonzero Cartesian directions with shape
(..., 3)on CPU or CUDA and dtypefloat32orfloat64.
Returns:
-
Tensor–Harmonic values with shape
(..., (l_max + 1) ** 2), preserving the -
Tensor–dtype and device of
directionsand supporting reverse-mode -
Tensor–differentiation through second derivatives.
wigner_D
Return flattened real Wigner \(D\) matrices through l_max.
The matrices use the Wikipedia real spherical-harmonic basis, with each
block ordered by m = -l, ..., l and the l = 1 block ordered as
\((y,z,x)\). The input acts actively on Cartesian column vectors and the
result satisfies \(Y_l(R^\mathsf{T}x)=Y_l(x)D^{(l)}(R)\) for row harmonic
values.
Parameters:
-
(l_maxint) –Highest non-negative
l. This is a static model configuration undertorch.compile. -
(rotationTensor) –Proper rotation matrices in SO(3), with shape
(..., 3, 3), dtypefloat32orfloat64, and device CPU or CUDA. Matrix entries are treated as independent variables when differentiating.
Returns:
-
Tensor–Consecutive row-major flattened blocks
-
Tensor–\(D^{(0)},\ldots,D^{(l_{\max})}\),
-
Tensor–with shape
-
Tensor–(..., sum((2 * l + 1) ** 2 for l in range(l_max + 1))). Values -
Tensor–preserve the input dtype and device and support reverse-mode
-
Tensor–differentiation through second derivatives.