use crate::num::arithmetic::traits::{EntrywiseMin, EntrywiseMinAssign};
use crate::num::basic::unsigneds::PrimitiveUnsigned;
use crate::unsigned_vector::UnsignedVector;
use core::cmp::min;
fn assert_same_dimension<T: PrimitiveUnsigned>(v: &UnsignedVector<T>, w: &UnsignedVector<T>) {
assert_eq!(
v.elements.len(),
w.elements.len(),
"cannot take the entrywise minimum of vectors of different dimensions"
);
}
impl<T: PrimitiveUnsigned> EntrywiseMin<Self> for UnsignedVector<T> {
type Output = Self;
#[inline]
fn entrywise_min(mut self, other: Self) -> Self {
self.entrywise_min_assign(other);
self
}
}
impl<T: PrimitiveUnsigned> EntrywiseMin<&Self> for UnsignedVector<T> {
type Output = Self;
#[inline]
fn entrywise_min(mut self, other: &Self) -> Self {
self.entrywise_min_assign(other);
self
}
}
impl<T: PrimitiveUnsigned> EntrywiseMin<UnsignedVector<T>> for &UnsignedVector<T> {
type Output = UnsignedVector<T>;
#[inline]
fn entrywise_min(self, mut other: UnsignedVector<T>) -> UnsignedVector<T> {
other.entrywise_min_assign(self);
other
}
}
impl<T: PrimitiveUnsigned> EntrywiseMin<&UnsignedVector<T>> for &UnsignedVector<T> {
type Output = UnsignedVector<T>;
fn entrywise_min(self, other: &UnsignedVector<T>) -> UnsignedVector<T> {
assert_same_dimension(self, other);
UnsignedVector {
elements: self
.elements
.iter()
.zip(&other.elements)
.map(|(&x, &y)| min(x, y))
.collect(),
}
}
}
impl<T: PrimitiveUnsigned> EntrywiseMinAssign<Self> for UnsignedVector<T> {
fn entrywise_min_assign(&mut self, other: Self) {
assert_same_dimension(self, &other);
for (x, y) in self.elements.iter_mut().zip(other.elements) {
if y < *x {
*x = y;
}
}
}
}
impl<T: PrimitiveUnsigned> EntrywiseMinAssign<&Self> for UnsignedVector<T> {
fn entrywise_min_assign(&mut self, other: &Self) {
assert_same_dimension(self, other);
for (x, &y) in self.elements.iter_mut().zip(&other.elements) {
if y < *x {
*x = y;
}
}
}
}