use std::collections::HashMap;
use crate::Symbol;
#[derive(Debug, Clone, Default)]
pub struct SymmetrySpec {
pub symmetric_subsets: Vec<Vec<usize>>,
pub antisymmetric_subsets: Vec<Vec<usize>>,
pub cyclic: Option<Vec<usize>>,
}
impl SymmetrySpec {
pub fn none() -> Self {
Self {
symmetric_subsets: Vec::new(),
antisymmetric_subsets: Vec::new(),
cyclic: None,
}
}
pub fn fully_symmetric(rank: usize) -> Self {
Self {
symmetric_subsets: vec![(0..rank).collect()],
antisymmetric_subsets: Vec::new(),
cyclic: None,
}
}
pub fn fully_antisymmetric(rank: usize) -> Self {
Self {
symmetric_subsets: Vec::new(),
antisymmetric_subsets: vec![(0..rank).collect()],
cyclic: None,
}
}
pub fn is_slot_hidden(&self, pos: usize) -> bool {
for subset in &self.symmetric_subsets {
if subset.contains(&pos) {
return true;
}
}
self.cyclic.as_ref().is_some_and(|c| c.contains(&pos))
}
}
#[derive(Debug, Clone, Default)]
pub struct TensorRegistry {
specs: HashMap<Symbol, SymmetrySpec>,
index_groups: HashMap<Symbol, u64>,
}
impl TensorRegistry {
pub fn new() -> Self {
Self::default()
}
pub fn register(&mut self, name: Symbol, spec: SymmetrySpec) {
self.specs.insert(name, spec);
}
pub fn set_index_group(&mut self, label: Symbol, group: u64) {
self.index_groups.insert(label, group);
}
pub fn spec(&self, name: Symbol) -> Option<&SymmetrySpec> {
self.specs.get(&name)
}
pub fn index_group(&self, label: Symbol) -> u64 {
self.index_groups.get(&label).copied().unwrap_or(0)
}
}