use num::{Float, FromPrimitive, Num};
use rand::distributions::uniform::SampleUniform;
use rand::distributions::{Distribution, Normal, Uniform};
use std::fmt;
use std::iter;
use std::ops;
#[macro_export]
macro_rules! vector {
($elem:expr; $len:expr) => ($crate::Vector::full($len, $elem));
($($x:expr),*) => {{
let elements = vec![$($x),*];
$crate::Vector::from(elements)
}};
}
pub struct Vector<T> {
pub(crate) elements: Vec<T>,
}
impl<T> Vector<T> {
pub fn len(&self) -> usize {
self.elements.len()
}
pub fn full(len: usize, value: T) -> Vector<T>
where
T: FromPrimitive + Num + Copy,
{
let elements = vec![value; len];
Vector { elements }
}
pub fn full_like(v: &Vector<T>, value: T) -> Vector<T>
where
T: FromPrimitive + Num + Copy,
{
let elements = vec![value; v.len()];
Vector { elements }
}
pub fn zeros(len: usize) -> Vector<T>
where
T: FromPrimitive + Num + Copy,
{
Self::full(len, T::from_i32(0).unwrap())
}
pub fn zeros_like(v: &Vector<T>) -> Vector<T>
where
T: FromPrimitive + Num + Copy,
{
Self::full(v.elements.len(), T::from_i32(0).unwrap())
}
pub fn ones(len: usize) -> Vector<T>
where
T: FromPrimitive + Num + Copy,
{
Self::full(len, T::from_i32(1).unwrap())
}
pub fn ones_like(v: &Vector<T>) -> Vector<T>
where
T: FromPrimitive + Num + Copy,
{
Self::full(v.elements.len(), T::from_i32(1).unwrap())
}
pub fn power(&self, exp: usize) -> Vector<T>
where
T: FromPrimitive + Num + Copy,
{
let elements =
self.elements.iter().map(|x| num::pow(*x, exp)).collect();
Vector { elements }
}
pub fn filter(&self, criteria: impl Fn(T) -> bool) -> Vector<T>
where
T: Copy,
{
let elements = self
.elements
.iter()
.filter(|&&x| criteria(x))
.map(|x| *x)
.collect();
Vector { elements }
}
pub fn sum(&self) -> T
where
T: FromPrimitive + Num + Copy,
{
self.elements
.iter()
.fold(T::from_f32(0.0).unwrap(), |acc, x| acc + *x)
}
pub fn max(&self) -> T
where
T: num::Integer + Copy,
{
let max = self.elements.iter().max().unwrap();
*max
}
pub fn min(&self) -> T
where
T: num::Integer + Copy,
{
let min = self.elements.iter().min().unwrap();
*min
}
pub fn uniform(len: usize, low: T, high: T) -> Vector<T>
where
T: SampleUniform,
{
let mut elements = Vec::with_capacity(len);
let uniform_distribution = Uniform::new(low, high);
let mut rng = rand::thread_rng();
for _ in 0..len {
elements.push(uniform_distribution.sample(&mut rng));
}
Vector { elements }
}
pub fn range(start: T, stop: T, step: T) -> Vector<T>
where
T: Num
+ FromPrimitive
+ Copy
+ PartialOrd
+ ops::AddAssign
+ fmt::Display,
{
if start >= stop {
panic!("Invalid range interval start={} stop={}", start, stop)
}
let mut elements = Vec::new();
let mut current_step = start;
while current_step < stop {
elements.push(current_step);
current_step += step;
}
Vector { elements }
}
pub fn linspace(len: usize, start: T, stop: T) -> Vector<T>
where
T: Float
+ FromPrimitive
+ Copy
+ PartialOrd
+ ops::AddAssign
+ fmt::Display,
{
if start >= stop {
panic!("Invalid linspace interval start={} stop={}", start, stop)
}
let divisor = T::from_usize(len).unwrap();
let mut elements = Vec::with_capacity(len);
let mut current_step = start;
let step = (stop - start) / (divisor - T::from_f32(1.0).unwrap());
while current_step < stop {
elements.push(current_step);
current_step += step;
}
if elements.len() == len {
elements[len - 1] = stop;
} else {
elements.push(stop);
}
Vector { elements }
}
}
impl Vector<f64> {
pub fn normal(len: usize, mean: f64, std_dev: f64) -> Vector<f64> {
let mut elements = Vec::with_capacity(len);
let normal_distribution = Normal::new(mean, std_dev);
let mut rng = rand::thread_rng();
for _ in 0..len {
elements.push(normal_distribution.sample(&mut rng));
}
Vector { elements }
}
}
impl<T> From<Vec<T>> for Vector<T>
where
T: Num + Copy,
{
fn from(elements: Vec<T>) -> Self {
Vector { elements }
}
}
impl<T> PartialEq for Vector<T>
where
T: Num + Copy,
{
fn eq(&self, other: &Vector<T>) -> bool {
if self.elements != other.elements {
return false;
}
true
}
fn ne(&self, other: &Vector<T>) -> bool {
if self.elements == other.elements {
return false;
}
true
}
}
macro_rules! impl_partial_eq_slice_for_type {
($t: ty) => {
impl PartialEq<Vector<$t>> for [$t] {
fn eq(&self, other: &Vector<$t>) -> bool {
if other.elements != self {
return false;
}
true
}
fn ne(&self, other: &Vector<$t>) -> bool {
if other.elements == self {
return false;
}
true
}
}
};
}
impl_partial_eq_slice_for_type!(usize);
impl_partial_eq_slice_for_type!(i8);
impl_partial_eq_slice_for_type!(i16);
impl_partial_eq_slice_for_type!(i32);
impl_partial_eq_slice_for_type!(i64);
impl_partial_eq_slice_for_type!(i128);
impl_partial_eq_slice_for_type!(u8);
impl_partial_eq_slice_for_type!(u16);
impl_partial_eq_slice_for_type!(u32);
impl_partial_eq_slice_for_type!(u64);
impl_partial_eq_slice_for_type!(u128);
impl_partial_eq_slice_for_type!(f32);
impl_partial_eq_slice_for_type!(f64);
impl<T> fmt::Debug for Vector<T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
return write!(f, "Vector({:?})", self.elements);
}
}
impl<T> ops::Index<usize> for Vector<T> {
type Output = T;
fn index(&self, i: usize) -> &T {
&self.elements[i]
}
}
impl<T> ops::Add<Vector<T>> for Vector<T>
where
T: Num + Copy,
{
type Output = Vector<T>;
fn add(self, other: Vector<T>) -> Vector<T> {
if self.len() != other.len() {
panic!(
"Vector addition with invalid length: {} != {}",
self.len(),
other.len()
);
}
let elements = self
.elements
.iter()
.enumerate()
.map(|(i, x)| *x + other[i])
.collect();
Vector { elements }
}
}
impl<T> ops::Add<T> for Vector<T>
where
T: Num + Copy,
{
type Output = Vector<T>;
fn add(self, value: T) -> Vector<T> {
let elements = self.elements.iter().map(|x| *x + value).collect();
Vector { elements }
}
}
macro_rules! impl_add_vector_for_type {
($t: ty) => {
impl ops::Add<Vector<$t>> for $t {
type Output = Vector<$t>;
fn add(self, v: Vector<$t>) -> Vector<$t> {
let elements = v.elements.iter().map(|x| *x + self).collect();
Vector { elements }
}
}
};
}
impl_add_vector_for_type!(usize);
impl_add_vector_for_type!(i8);
impl_add_vector_for_type!(i16);
impl_add_vector_for_type!(i32);
impl_add_vector_for_type!(i64);
impl_add_vector_for_type!(i128);
impl_add_vector_for_type!(u8);
impl_add_vector_for_type!(u16);
impl_add_vector_for_type!(u32);
impl_add_vector_for_type!(u64);
impl_add_vector_for_type!(u128);
impl_add_vector_for_type!(f32);
impl_add_vector_for_type!(f64);
impl<T> ops::AddAssign<Vector<T>> for Vector<T>
where
T: Num + Copy + ops::AddAssign,
{
fn add_assign(&mut self, other: Vector<T>) {
if self.len() != other.len() {
panic!(
"Vector addition with invalid length: {} != {}",
self.len(),
other.len()
);
}
for (i, x) in self.elements.iter_mut().enumerate() {
*x += other[i];
}
}
}
impl<T> ops::AddAssign<T> for Vector<T>
where
T: Num + Copy + ops::AddAssign,
{
fn add_assign(&mut self, value: T) {
for x in self.elements.iter_mut() {
*x += value
}
}
}
impl<T> ops::Sub<Vector<T>> for Vector<T>
where
T: Num + Copy,
{
type Output = Vector<T>;
fn sub(self, other: Vector<T>) -> Vector<T> {
if self.len() != other.len() {
panic!(
"Vector substraction with invalid length: {} != {}",
self.len(),
other.len()
);
}
let elements = self
.elements
.iter()
.enumerate()
.map(|(i, x)| *x - other[i])
.collect();
Vector { elements }
}
}
impl<T> ops::Sub<T> for Vector<T>
where
T: Num + Copy,
{
type Output = Vector<T>;
fn sub(self, value: T) -> Vector<T> {
let elements = self.elements.iter().map(|x| *x - value).collect();
Vector { elements }
}
}
macro_rules! impl_sub_vector_for_type {
($t: ty) => {
impl ops::Sub<Vector<$t>> for $t {
type Output = Vector<$t>;
fn sub(self, v: Vector<$t>) -> Vector<$t> {
let elements = v.elements.iter().map(|x| self - *x).collect();
Vector { elements }
}
}
};
}
impl_sub_vector_for_type!(usize);
impl_sub_vector_for_type!(i8);
impl_sub_vector_for_type!(i16);
impl_sub_vector_for_type!(i32);
impl_sub_vector_for_type!(i64);
impl_sub_vector_for_type!(i128);
impl_sub_vector_for_type!(u8);
impl_sub_vector_for_type!(u16);
impl_sub_vector_for_type!(u32);
impl_sub_vector_for_type!(u64);
impl_sub_vector_for_type!(u128);
impl_sub_vector_for_type!(f32);
impl_sub_vector_for_type!(f64);
impl<T> ops::SubAssign<Vector<T>> for Vector<T>
where
T: Num + Copy + ops::SubAssign,
{
fn sub_assign(&mut self, other: Vector<T>) {
if self.len() != other.len() {
panic!(
"Vector addition with invalid length: {} != {}",
self.len(),
other.len()
);
}
for (i, x) in self.elements.iter_mut().enumerate() {
*x -= other[i];
}
}
}
impl<T> ops::SubAssign<T> for Vector<T>
where
T: Num + Copy + ops::SubAssign,
{
fn sub_assign(&mut self, value: T) {
for x in self.elements.iter_mut() {
*x -= value
}
}
}
impl<T> Clone for Vector<T>
where
T: Copy,
{
fn clone(&self) -> Vector<T> {
Vector {
elements: self.elements.clone(),
}
}
}
impl<T> ops::Mul<Vector<T>> for Vector<T>
where
T: Num + Copy,
{
type Output = Vector<T>;
fn mul(self, other: Vector<T>) -> Vector<T> {
if self.len() != other.len() {
panic!(
"Vector multiplication with invalid length: {} != {}",
self.len(),
other.len()
);
}
Vector {
elements: self
.elements
.iter()
.enumerate()
.map(|(i, v)| *v * other[i])
.collect(),
}
}
}
impl<T> ops::Mul<T> for Vector<T>
where
T: Num + Copy,
{
type Output = Vector<T>;
fn mul(self, value: T) -> Vector<T> {
Vector {
elements: self.elements.iter().map(|x| *x * value).collect(),
}
}
}
macro_rules! impl_mul_vector_for_type {
($t: ty) => {
impl ops::Mul<Vector<$t>> for $t {
type Output = Vector<$t>;
fn mul(self, v: Vector<$t>) -> Vector<$t> {
let elements = v.elements.iter().map(|x| *x * self).collect();
Vector { elements }
}
}
};
}
impl_mul_vector_for_type!(usize);
impl_mul_vector_for_type!(i8);
impl_mul_vector_for_type!(i16);
impl_mul_vector_for_type!(i32);
impl_mul_vector_for_type!(i64);
impl_mul_vector_for_type!(i128);
impl_mul_vector_for_type!(u8);
impl_mul_vector_for_type!(u16);
impl_mul_vector_for_type!(u32);
impl_mul_vector_for_type!(u64);
impl_mul_vector_for_type!(u128);
impl_mul_vector_for_type!(f32);
impl_mul_vector_for_type!(f64);
impl<T> ops::MulAssign<Vector<T>> for Vector<T>
where
T: Num + Copy + ops::MulAssign,
{
fn mul_assign(&mut self, other: Vector<T>) {
if self.len() != other.len() {
panic!(
"Vector addition with invalid length: {} != {}",
self.len(),
other.len()
);
}
for (i, x) in self.elements.iter_mut().enumerate() {
*x *= other[i];
}
}
}
impl<T> ops::MulAssign<T> for Vector<T>
where
T: Num + Copy + ops::MulAssign,
{
fn mul_assign(&mut self, value: T) {
for x in self.elements.iter_mut() {
*x *= value
}
}
}
pub trait Slice<Idx: ?Sized> {
type Output: ?Sized;
fn slice(&self, index: Idx) -> Self::Output;
}
impl<T> Slice<ops::Range<usize>> for Vector<T>
where
T: Num + Copy,
{
type Output = Vector<T>;
fn slice(&self, index: ops::Range<usize>) -> Vector<T> {
Vector::from(self.elements[index].to_vec())
}
}
impl<T> Slice<ops::RangeFrom<usize>> for Vector<T>
where
T: Num + Copy,
{
type Output = Vector<T>;
fn slice(&self, index: ops::RangeFrom<usize>) -> Vector<T> {
Vector::from(self.elements[index].to_vec())
}
}
impl<T> Slice<ops::RangeTo<usize>> for Vector<T>
where
T: Num + Copy,
{
type Output = Vector<T>;
fn slice(&self, index: ops::RangeTo<usize>) -> Vector<T> {
Vector::from(self.elements[index].to_vec())
}
}
impl<T> Slice<ops::RangeFull> for Vector<T>
where
T: Num + Copy,
{
type Output = Vector<T>;
fn slice(&self, index: ops::RangeFull) -> Vector<T> {
Vector::from(self.elements[index].to_vec())
}
}
impl<T> Slice<ops::RangeInclusive<usize>> for Vector<T>
where
T: Num + Copy,
{
type Output = Vector<T>;
fn slice(&self, index: ops::RangeInclusive<usize>) -> Vector<T> {
Vector::from(self.elements[index].to_vec())
}
}
impl<T> Slice<ops::RangeToInclusive<usize>> for Vector<T>
where
T: Num + Copy,
{
type Output = Vector<T>;
fn slice(&self, index: ops::RangeToInclusive<usize>) -> Vector<T> {
Vector::from(self.elements[index].to_vec())
}
}
impl<T> IntoIterator for Vector<T> {
type Item = T;
type IntoIter = ::std::vec::IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.elements.into_iter()
}
}
impl<T> iter::FromIterator<T> for Vector<T>
where
T: Num + Copy,
{
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut v = Vec::new();
for i in iter {
v.push(i);
}
Vector::from(v)
}
}