use core::fmt::Debug;
use core::ops::{Add, Sub};
use core::ops::{Bound, Range, RangeBounds};
use num_traits::{One, Zero};
pub trait ArrayKind: Sized {
type Type<T>;
type I: Clone
+ PartialEq
+ Ord
+ Debug
+ One
+ Zero
+ Add<Output = Self::I>
+ Sub<Output = Self::I>
+ for<'a> Add<&'a Self::Index, Output = Self::Index>;
type Index: NaturalArray<Self>
+ Into<Self::Type<Self::I>>
+ From<Self::Type<Self::I>>
+ AsRef<Self::Type<Self::I>>
+ AsMut<Self::Type<Self::I>>
+ PartialEq;
type Slice<'a, T: 'a>; }
pub trait Array<K: ArrayKind, T>: Clone {
fn empty() -> Self;
fn len(&self) -> K::I;
fn is_empty(&self) -> bool {
self.len() == K::I::zero()
}
fn from_slice(slice: K::Slice<'_, T>) -> Self;
fn to_range<R: RangeBounds<K::I>>(&self, r: R) -> Range<K::I> {
let n = self.len();
let start = match r.start_bound().cloned() {
Bound::Included(i) => i,
Bound::Excluded(i) => i + K::I::one(),
Bound::Unbounded => K::I::zero(),
};
let end = match r.end_bound().cloned() {
Bound::Included(i) => i + K::I::one(),
Bound::Excluded(i) => i,
Bound::Unbounded => n,
};
Range { start, end }
}
fn concatenate(&self, other: &Self) -> Self;
fn concatenate_many(arrays: &[&Self]) -> Self;
fn fill(x: T, n: K::I) -> Self;
fn get(&self, i: K::I) -> T;
fn get_range<R: RangeBounds<K::I>>(&self, rb: R) -> K::Slice<'_, T>;
fn set_range<R: RangeBounds<K::I>>(&mut self, rb: R, v: &K::Type<T>);
fn gather(&self, idx: K::Slice<'_, K::I>) -> Self;
fn scatter(&self, idx: K::Slice<'_, K::I>, n: K::I) -> Self;
fn scatter_assign(&mut self, ixs: &K::Index, values: Self);
fn scatter_assign_constant(&mut self, ixs: &K::Index, arg: T);
}
pub trait OrdArray<K: ArrayKind, T>: Clone + Array<K, T> {
fn argsort(&self) -> K::Index;
fn sort_by(&self, key: &Self) -> Self {
self.gather(key.argsort().get_range(..))
}
}
pub trait NaturalArray<K: ArrayKind>:
OrdArray<K, K::I> + Sized + Sub<Self, Output = Self> + Add<Self, Output = Self> + AsRef<K::Index>
{
fn max(&self) -> Option<K::I>;
fn cumulative_sum(&self) -> Self;
#[must_use]
fn sum(&self) -> K::I {
if self.len() == K::I::zero() {
K::I::zero()
} else {
self.cumulative_sum().get(self.len())
}
}
fn arange(start: &K::I, stop: &K::I) -> Self;
fn repeat(&self, x: K::Slice<'_, K::I>) -> Self;
fn quot_rem(&self, d: K::I) -> (Self, Self);
fn mul_constant_add(&self, c: K::I, x: &Self) -> Self;
fn connected_components(sources: &Self, targets: &Self, n: K::I) -> (Self, K::I);
fn segmented_sum(&self, x: &Self) -> Self {
let segment_sizes = self;
let ptr = segment_sizes.cumulative_sum();
let sum = x.cumulative_sum();
let n = ptr.len();
sum.gather(ptr.get_range(K::I::one()..)) - sum.gather(ptr.get_range(..n - K::I::one()))
}
fn segmented_arange(&self) -> Self {
let p = self.cumulative_sum();
let last_idx = p.len() - K::I::one();
let sum = p.get(last_idx.clone());
let r = self.repeat(p.get_range(..last_idx));
let i = Self::arange(&K::I::zero(), &sum);
i - r
}
fn bincount(&self, size: K::I) -> K::Index;
fn sparse_bincount(&self) -> (K::Index, K::Index);
fn zero(&self) -> K::Index;
fn scatter_sub_assign(&mut self, ixs: &K::Index, rhs: &K::Index);
}