use super::connected_components::connected_components;
use crate::array::*;
use core::ops::{Add, Deref, DerefMut, Index, RangeBounds, Sub};
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct VecKind {}
impl ArrayKind for VecKind {
type Type<T> = VecArray<T>;
type I = usize;
type Index = VecArray<usize>;
type Slice<'a, T: 'a> = &'a [T];
}
impl<T: PartialEq> PartialEq for VecArray<T> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
#[derive(Clone, Debug)]
pub struct VecArray<T>(pub Vec<T>);
impl AsRef<<VecKind as ArrayKind>::Index> for VecArray<usize> {
fn as_ref(&self) -> &<VecKind as ArrayKind>::Index {
self
}
}
impl AsMut<<VecKind as ArrayKind>::Index> for VecArray<usize> {
fn as_mut(&mut self) -> &mut <VecKind as ArrayKind>::Index {
self
}
}
impl<T> Deref for VecArray<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for VecArray<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T: Clone> Array<VecKind, T> for VecArray<T> {
fn empty() -> Self {
VecArray(Vec::default())
}
fn len(&self) -> usize {
self.0.len()
}
fn concatenate(&self, other: &Self) -> Self {
let mut result: Vec<T> = Vec::with_capacity(self.len() + other.len());
result.extend_from_slice(self);
result.extend_from_slice(other);
VecArray(result)
}
fn concatenate_many(arrays: &[&Self]) -> Self {
if arrays.is_empty() {
return Self::empty();
}
let mut n = 0;
for arr in arrays {
n += arr.len();
}
let mut out = Vec::with_capacity(n);
for arr in arrays {
out.extend_from_slice(arr);
}
Self(out)
}
fn fill(x: T, n: usize) -> Self {
VecArray(vec![x; n])
}
fn get(&self, i: usize) -> T {
self[i].clone()
}
fn get_range<R: RangeBounds<usize>>(&self, rb: R) -> &[T] {
self.index(self.to_range(rb))
}
fn set_range<R: RangeBounds<usize>>(&mut self, rb: R, v: &<VecKind as ArrayKind>::Type<T>) {
let r = self.to_range(rb);
self[r].clone_from_slice(v)
}
fn gather(&self, idx: &[usize]) -> Self {
VecArray(idx.iter().map(|i| self.0[*i].clone()).collect())
}
fn scatter(&self, idx: &[usize], n: usize) -> VecArray<T> {
if self.is_empty() {
assert!(idx.is_empty());
return VecArray(vec![]);
}
let mut y = vec![self[0].clone(); n];
for (i, x) in self.iter().enumerate() {
y[idx[i]] = x.clone();
}
VecArray(y)
}
fn from_slice(slice: &[T]) -> Self {
VecArray(slice.into())
}
fn scatter_assign_constant(&mut self, ixs: &VecArray<usize>, arg: T) {
for &idx in ixs.iter() {
self[idx] = arg.clone();
}
}
fn scatter_assign(&mut self, ixs: &<VecKind as ArrayKind>::Index, values: Self) {
for (i, x) in ixs.iter().zip(values.iter()) {
self[*i] = x.clone();
}
}
}
impl Add<&VecArray<usize>> for usize {
type Output = VecArray<usize>;
fn add(self, rhs: &VecArray<usize>) -> Self::Output {
VecArray(rhs.iter().map(|x| x + self).collect())
}
}
impl<T: Clone + Add<Output = T>> Add<VecArray<T>> for VecArray<T> {
type Output = VecArray<T>;
fn add(self, rhs: VecArray<T>) -> VecArray<T> {
assert_eq!(self.len(), rhs.len());
VecArray(
self.iter()
.zip(rhs.iter())
.map(|(x, y)| x.clone() + y.clone())
.collect(),
)
}
}
impl<T: Clone + Sub<Output = T>> Sub<VecArray<T>> for VecArray<T> {
type Output = VecArray<T>;
fn sub(self, rhs: VecArray<T>) -> VecArray<T> {
assert_eq!(self.len(), rhs.len());
VecArray(
self.iter()
.zip(rhs.iter())
.map(|(x, y)| x.clone() - y.clone())
.collect(),
)
}
}
impl<T: Ord + Clone> OrdArray<VecKind, T> for VecArray<T> {
fn argsort(&self) -> VecArray<usize> {
let mut indices = (0..self.len()).collect::<Vec<_>>();
indices.sort_by_key(|&i| &self[i]);
VecArray(indices)
}
}
impl NaturalArray<VecKind> for VecArray<usize> {
fn max(&self) -> Option<usize> {
self.iter().max().copied()
}
fn quot_rem(&self, d: usize) -> (Self, Self) {
assert!(d != 0);
let mut q = Vec::with_capacity(self.len());
let mut r = Vec::with_capacity(self.len());
for x in self.iter() {
q.push(x / d);
r.push(x % d);
}
(VecArray(q), VecArray(r))
}
fn mul_constant_add(&self, c: usize, x: &Self) -> Self {
assert_eq!(self.len(), x.len());
let mut r = Vec::with_capacity(self.len());
for (s, x) in self.iter().zip(x.iter()) {
r.push(s * c + x)
}
VecArray(r)
}
fn cumulative_sum(&self) -> Self {
let mut v = Vec::with_capacity(self.len() + 1);
let mut a = 0;
for x in self.iter() {
v.push(a);
a += x;
}
v.push(a); VecArray(v)
}
fn arange(start: &usize, stop: &usize) -> Self {
assert!(stop >= start, "invalid range [{:?}, {:?})", start, stop);
let n = stop - start;
let mut v = Vec::with_capacity(n);
for i in 0..n {
v.push(start + i);
}
VecArray(v)
}
fn repeat(&self, x: &[usize]) -> VecArray<usize> {
assert_eq!(self.len(), x.len());
let mut v: Vec<usize> = Vec::new();
for (k, xi) in self.iter().zip(x) {
v.extend(std::iter::repeat_n(xi, *k))
}
VecArray(v)
}
fn connected_components(
sources: &Self,
targets: &Self,
n: usize,
) -> (Self, <VecKind as ArrayKind>::I) {
let (cc_ix, c) = connected_components(sources, targets, n);
(VecArray(cc_ix), c)
}
fn bincount(&self, size: usize) -> VecArray<usize> {
let mut counts = vec![0; size];
for &idx in self.iter() {
counts[idx] += 1;
}
VecArray(counts)
}
fn zero(&self) -> VecArray<usize> {
let mut zero_indices = Vec::with_capacity(self.len());
for (i, &val) in self.iter().enumerate() {
if val == 0 {
zero_indices.push(i);
}
}
VecArray(zero_indices)
}
fn sparse_bincount(&self) -> (VecArray<usize>, VecArray<usize>) {
use std::collections::HashMap;
let mut counts_map = HashMap::new();
for &idx in self.iter() {
*counts_map.entry(idx).or_insert(0) += 1;
}
let mut unique_indices: Vec<_> = counts_map.keys().cloned().collect();
unique_indices.sort_unstable();
let counts: Vec<_> = unique_indices.iter().map(|&idx| counts_map[&idx]).collect();
(VecArray(unique_indices), VecArray(counts))
}
fn scatter_sub_assign(&mut self, ixs: &VecArray<usize>, rhs: &VecArray<usize>) {
for i in 0..ixs.len() {
self[ixs[i]] -= rhs[i];
}
}
}