use super::Scalar;
pub trait VectorView<F: Scalar> {
fn len(&self) -> usize;
fn get(&self, index: usize) -> F;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn sum(&self) -> F {
(0..self.len()).map(|i| self.get(i)).sum()
}
}
pub trait VectorViewMut<F: Scalar>: VectorView<F> {
fn set(&mut self, index: usize, value: F);
}
pub trait VectorOwned<F: Scalar>: VectorView<F> {
type Owned: VectorOwned<F, Owned = Self::Owned> + VectorViewMut<F>;
fn owned_from_fn(len: usize, value: impl FnMut(usize) -> F) -> Self::Owned;
}
impl<F: Scalar> VectorOwned<F> for Vec<F> {
type Owned = Self;
fn owned_from_fn(len: usize, value: impl FnMut(usize) -> F) -> Self {
(0..len).map(value).collect()
}
}
impl<F: Scalar> VectorOwned<F> for [F] {
type Owned = Vec<F>;
fn owned_from_fn(len: usize, value: impl FnMut(usize) -> F) -> Vec<F> {
Vec::owned_from_fn(len, value)
}
}
impl<F: Scalar, const N: usize> VectorOwned<F> for [F; N] {
type Owned = Vec<F>;
fn owned_from_fn(len: usize, value: impl FnMut(usize) -> F) -> Vec<F> {
Vec::owned_from_fn(len, value)
}
}
impl<F: Scalar> VectorView<F> for [F] {
fn len(&self) -> usize {
<[F]>::len(self)
}
fn get(&self, index: usize) -> F {
self[index]
}
}
impl<F: Scalar> VectorViewMut<F> for [F] {
fn set(&mut self, index: usize, value: F) {
self[index] = value;
}
}
impl<F: Scalar> VectorView<F> for Vec<F> {
fn len(&self) -> usize {
Vec::len(self)
}
fn get(&self, index: usize) -> F {
self[index]
}
}
impl<F: Scalar> VectorViewMut<F> for Vec<F> {
fn set(&mut self, index: usize, value: F) {
self[index] = value;
}
}
impl<F: Scalar, const N: usize> VectorView<F> for [F; N] {
fn len(&self) -> usize {
N
}
fn get(&self, index: usize) -> F {
self[index]
}
}
impl<F: Scalar, const N: usize> VectorViewMut<F> for [F; N] {
fn set(&mut self, index: usize, value: F) {
self[index] = value;
}
}
pub trait DotProduct<F: Scalar> {
fn dot(&self, other: &Self) -> F;
}
pub trait L2Norm<F: Scalar> {
fn norm_l2(&self) -> F;
}
pub trait ScaledAddAssign<F: Scalar> {
fn scaled_add_assign(&mut self, alpha: F, other: &Self);
}
pub trait ScaleAssign<F: Scalar> {
fn scale_assign(&mut self, alpha: F);
}
pub trait ElemDivAssign<F: Scalar> {
fn elem_div_assign(&mut self, coeffs: &[F]);
}
pub trait DotSlice<F: Scalar> {
fn dot_slice(&self, coeffs: &[F]) -> F;
}
pub trait SubScalarAssign<F: Scalar> {
fn sub_scalar_assign(&mut self, k: F);
}
pub trait SumEntries<F: Scalar> {
fn sum_entries(&self) -> F;
}
pub trait ScaledSubSlice<F: Scalar> {
fn scaled_sub_slice(&mut self, k: F, coeffs: &[F]);
}
impl<F: Scalar> DotProduct<F> for Vec<F> {
fn dot(&self, other: &Self) -> F {
self.dot_slice(other)
}
}
impl<F: Scalar> L2Norm<F> for Vec<F> {
fn norm_l2(&self) -> F {
self.iter().map(|&value| value * value).sum::<F>().sqrt()
}
}
impl<F: Scalar> ScaledAddAssign<F> for Vec<F> {
fn scaled_add_assign(&mut self, alpha: F, other: &Self) {
assert_eq!(
self.len(),
other.len(),
"scaled_add_assign: length mismatch"
);
for (value, &other) in self.iter_mut().zip(other) {
*value = *value + alpha * other;
}
}
}
impl<F: Scalar> ScaleAssign<F> for Vec<F> {
fn scale_assign(&mut self, alpha: F) {
for value in self.iter_mut() {
*value = *value * alpha;
}
}
}
impl<F: Scalar> ElemDivAssign<F> for Vec<F> {
fn elem_div_assign(&mut self, coeffs: &[F]) {
assert_eq!(self.len(), coeffs.len(), "elem_div_assign: length mismatch");
for (value, &coefficient) in self.iter_mut().zip(coeffs) {
*value = *value / coefficient;
}
}
}
impl<F: Scalar> DotSlice<F> for Vec<F> {
fn dot_slice(&self, coeffs: &[F]) -> F {
assert_eq!(self.len(), coeffs.len(), "dot_slice: length mismatch");
self.iter().zip(coeffs).map(|(&a, &b)| a * b).sum()
}
}
impl<F: Scalar> SubScalarAssign<F> for Vec<F> {
fn sub_scalar_assign(&mut self, k: F) {
for value in self.iter_mut() {
*value = *value - k;
}
}
}
impl<F: Scalar> SumEntries<F> for Vec<F> {
fn sum_entries(&self) -> F {
self.iter().copied().sum()
}
}
impl<F: Scalar> ScaledSubSlice<F> for Vec<F> {
fn scaled_sub_slice(&mut self, k: F, coeffs: &[F]) {
assert_eq!(
self.len(),
coeffs.len(),
"scaled_sub_slice: length mismatch"
);
for (value, &coefficient) in self.iter_mut().zip(coeffs) {
*value = *value - k * coefficient;
}
}
}