use crate::{
Array, MutableArrayImpl, RawAccessMut, base_types::MemoryLayout, dense::array::StaticArray,
};
use super::UnsafeRandom1DAccessByValue;
pub trait BaseItem {
type Item: Copy + Default;
}
pub trait BorrowAtRuntime {
type Target<'a>
where
Self: 'a;
fn borrow(&self) -> Self::Target<'_>;
}
pub trait BorrowAtRuntimeMut {
type Target<'a>
where
Self: 'a;
fn borrow_mut(&self) -> Self::Target<'_>;
}
pub trait Shape<const NDIM: usize> {
fn shape(&self) -> [usize; NDIM];
#[inline(always)]
fn len(&self) -> usize {
self.shape().iter().product()
}
#[inline(always)]
fn is_empty(&self) -> bool {
self.len() == 0
}
}
pub trait Stride<const NDIM: usize> {
fn stride(&self) -> [usize; NDIM];
fn memory_layout(&self) -> MemoryLayout
where
Self: Shape<NDIM>,
{
let stride = self.stride();
let shape = self.shape();
let mut factor = 1;
if stride[0] == 1 {
if NDIM == 1 {
return MemoryLayout::ColumnMajor;
}
for i in 1..NDIM {
factor *= shape[i - 1];
if stride[i] != factor {
return MemoryLayout::Unknown;
}
}
MemoryLayout::ColumnMajor
} else if stride[NDIM - 1] == 1 {
for i in 2..NDIM + 1 {
factor *= shape[NDIM - i + 1];
if stride[NDIM - i] != factor {
return MemoryLayout::Unknown;
}
}
MemoryLayout::RowMajor
} else {
MemoryLayout::Unknown
}
}
fn is_contiguous(&self) -> bool
where
Self: Shape<NDIM>,
{
self.memory_layout() != MemoryLayout::Unknown
}
}
pub trait NumberOfElements {
fn number_of_elements(&self) -> usize;
}
pub trait ResizeInPlace<const NDIM: usize> {
fn resize_in_place(&mut self, shape: [usize; NDIM]);
}
pub trait FillFrom<Other> {
fn fill_from(&mut self, other: &Other);
}
pub trait FillFromIter<Iter: Iterator> {
fn fill_from_iter(&mut self, iter: Iter);
}
pub trait ScalarAsArray: Sized + Copy + Default {
fn as_array<const NDIM: usize>(&self) -> StaticArray<Self, NDIM, 1>;
}
pub trait FillFromResize<Other> {
fn fill_from_resize(&mut self, other: &Other);
}
pub trait SumFrom<Other> {
fn sum_from(&mut self, other: &Other);
}
pub trait CmpMulFrom<Other> {
fn cmp_mul_from(&mut self, other: &Other);
}
pub trait ScalarMul<Scalar> {
type Output;
fn scalar_mul(self, scalar: Scalar) -> Self::Output;
}
pub trait CmpMulAddFrom<Other1, Other2> {
fn cmp_mul_add_from(&mut self, other1: &Other1, other2: &Other2);
}
pub trait FillWithValue: BaseItem {
fn fill_with_value(&mut self, value: Self::Item);
}
pub trait SetZero {
fn set_zero(&mut self);
}
pub trait SetOne {
fn set_one(&mut self);
}
pub trait SetIdentity {
fn set_identity(&mut self);
}
pub trait ScaleInPlace: BaseItem {
fn scale_inplace(&mut self, alpha: Self::Item);
}
pub trait Trace: BaseItem {
fn trace(&self) -> Self::Item;
}
pub trait Sum: BaseItem {
fn sum(&self) -> Self::Item;
}
pub trait Len {
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
}
pub trait ConjObject {
type Output;
fn conj(self) -> Self::Output;
}
pub trait EvaluateArray<Item, const NDIM: usize>
where
Item: Copy + Default,
{
type OutputImpl: MutableArrayImpl<Item, NDIM> + RawAccessMut<Item = Item> + Stride<NDIM>;
fn eval(&self) -> Array<Self::OutputImpl, NDIM>;
}
pub trait EvaluateRowMajorArray<Item, const NDIM: usize>
where
Item: Copy + Default,
{
type OutputImpl: MutableArrayImpl<Item, NDIM> + RawAccessMut<Item = Item> + Stride<NDIM>;
fn eval_row_major(&self) -> Array<Self::OutputImpl, NDIM>;
}
pub trait DispatchEval<const NDIM: usize> {
type Output;
type ArrayImpl: Shape<NDIM> + UnsafeRandom1DAccessByValue;
fn dispatch(&self, arr: &Array<Self::ArrayImpl, NDIM>) -> Self::Output;
}
pub trait DispatchEvalRowMajor<const NDIM: usize> {
type Output;
type ArrayImpl: Shape<NDIM> + UnsafeRandom1DAccessByValue;
fn dispatch(&self, arr: &Array<Self::ArrayImpl, NDIM>) -> Self::Output;
}
pub trait ToType<T> {
type Item;
type Output;
fn into_type(self) -> Self::Output
where
Self::Item: Into<T>;
}
pub trait Linspace<Item> {
fn linspace(&mut self, a: Item, b: Item);
}