| Crates.io | butler-portugal |
| lib.rs | butler-portugal |
| version | 0.1.3 |
| created_at | 2025-06-16 16:34:42.585506+00 |
| updated_at | 2025-06-28 09:01:04.549257+00 |
| description | A Rust library implementing the Butler-Portugal algorithm for tensor canonicalization |
| homepage | https://github.com/sdiehl/butler-portugal |
| repository | https://github.com/sdiehl/butler-portugal |
| max_upload_size | |
| id | 1714475 |
| size | 175,545 |
A Rust implementation of the Butler-Portugal algorithm for tensor canonicalization.
The Butler–Portugal algorithm is for bringing tensors with arbitrary symmetries into canonical form. It systematically applies all slot and dummy symmetries by finding a canonical representative in the double coset $D g S$ (where $S$ is the slot symmetry group and $D$ is the dummy index symmetry group), using the Schreier–Sims algorithm to handle large permutation groups and ensure the minimal (canonical) index arrangement is found under all allowed symmetries.
We provide two canonicalization methods:
Schreier–Sims (Group-theoretic): Uses the Schreier–Sims algorithm to efficiently enumerate all index permutations allowed by the tensor's symmetries, finding the lexicographically minimal representative. This is the default and most general method.
Young Symmetrizer (Tableau-based): Projects the tensor onto an irreducible symmetry type using a Young tableau, symmetrizing and antisymmetrizing indices according to the tableau's rows and columns. This is useful for explicit irreducible decomposition.
To add the crate to your project, run:
cargo add butler-portugal
For example usage, see the basic.rs example.
The Riemann curvature tensor $R_{\mu\nu\rho\sigma}$ satisfies the following symmetries:
Antisymmetry in the first two indices:
$$R_{\mu\nu\rho\sigma} = -R_{\nu\mu\rho\sigma}$$
Antisymmetry in the last two indices:
$$R_{\mu\nu\rho\sigma} = -R_{\mu\nu\sigma\rho}$$
Pairwise interchange symmetry:
$$R_{\mu\nu\rho\sigma} = R_{\rho\sigma\mu\nu}$$
First Bianchi Identity (cyclic symmetry on the first three indices):
$$R_{\mu\nu\rho\sigma} + R_{\mu\rho\sigma\nu} + R_{\mu\sigma\nu\rho} = 0$$
We can use the crate to canonicalize the Riemann tensor:
use butler_portugal::*;
let mut riemann = Tensor::new(
"R",
vec![
TensorIndex::new("mu", 0),
TensorIndex::new("nu", 1),
TensorIndex::new("rho", 2),
TensorIndex::new("sigma", 3),
],
);
// Antisymmetry in first pair
riemann.add_symmetry(Symmetry::antisymmetric(vec![0, 1]));
// Antisymmetry in second pair
riemann.add_symmetry(Symmetry::antisymmetric(vec![2, 3]));
// Symmetric exchange of pairs
riemann.add_symmetry(Symmetry::symmetric_pairs(vec![(0, 1), (2, 3)]));
let canonical = canonicalize(&riemann);
Released under the MIT License. See the LICENSE file for details.