use super::fiber::{Fiber, FiberClass, FiberClassMut, FiberMut};
use super::indices::{AbstractFiberIndex, FiberData};
use crate::structure::{
concrete_index::{ExpandedIndex, FlatIndex},
dimension::Dimension,
representation::{RepName, Representation},
HasStructure, TensorStructure,
};
use bitvec::vec::BitVec;
use linnet::permutation::Permutation;
pub trait FiberIteratorItem {
type OtherData;
fn flat_idx(&self) -> FlatIndex;
fn other_data(self) -> Self::OtherData;
}
impl FiberIteratorItem for FlatIndex {
type OtherData = ();
fn flat_idx(&self) -> FlatIndex {
*self
}
fn other_data(self) -> Self::OtherData {}
}
pub trait ResetableIterator {
fn reset(&mut self);
}
pub trait ShiftableIterator {
fn shift(&mut self, shift: usize);
}
pub trait IteratesAlongFibers<R: RepName>:
Iterator + ShiftableIterator + ResetableIterator
{
fn new<I, J>(fiber: &I, conj: bool) -> Self
where
I: AbstractFiber<J, Repr = R>,
J: AbstractFiberIndex,
Self: Sized;
fn new_paired_conjugates<I, J>(fiber: &I) -> (Self, Self)
where
I: AbstractFiber<J, Repr = R>,
J: AbstractFiberIndex,
Self: Sized;
}
pub trait IteratesAlongPermutedFibers<R: RepName>: IteratesAlongFibers<R> {
fn new_permuted<I, J>(fiber: &I, conj: bool, permutation: Permutation) -> Self
where
I: AbstractFiber<J, Repr = R>,
J: AbstractFiberIndex;
}
pub trait AbstractFiber<Out: AbstractFiberIndex>: std::ops::Index<usize, Output = Out> {
type Repr: RepName;
fn strides(&self) -> Vec<usize>;
fn shape(&self) -> Vec<Dimension>;
fn reps(&self) -> Vec<Representation<Self::Repr>>;
fn order(&self) -> usize;
fn single(&self) -> Option<usize>;
fn bitvec(&self) -> BitVec;
}
pub trait IteratableTensor: HasStructure + Sized + TensorStructure {
type Data<'a>
where
Self: 'a;
fn iter_expanded(&self) -> impl Iterator<Item = (ExpandedIndex, Self::Data<'_>)>;
fn iter_flat(&self) -> impl Iterator<Item = (FlatIndex, Self::Data<'_>)>;
fn fiber<'a>(&'a self, fiber_data: FiberData<'_>) -> Fiber<'a, Self> {
Fiber::from(fiber_data, self)
}
fn fiber_mut<'a>(&'a mut self, fiber_data: FiberData<'_>) -> FiberMut<'a, Self> {
FiberMut::from(fiber_data, self)
}
fn fiber_class<'a>(&'a self, fiber_data: FiberData<'_>) -> FiberClass<'a, Self> {
Fiber::from(fiber_data, self).into()
}
fn fiber_class_mut<'a>(&'a mut self, fiber_data: FiberData<'_>) -> FiberClassMut<'a, Self> {
FiberMut::from(fiber_data, self).into()
}
}