rust_numpy/
vector.rs

1use crate::{Dot};
2use crate::Init;
3use crate::matrix::Matrix;
4
5use impl_ops::*;
6use std::ops;
7
8
9pub struct Vector {
10    array : Vec<f64>,
11}
12
13
14impl Vector {
15
16    #[inline]
17    pub fn from(array: Vec<f64>) -> Vector {
18        Vector { array }
19    }
20
21    #[inline]
22    pub fn empty() -> Vector {
23        Vector { array : Vec::new() }
24    }
25
26    #[inline]
27    pub fn iter(&self) -> std::slice::Iter<'_, f64> {
28        self.array.iter()
29    }
30    
31    #[inline]
32    pub fn iter_mut(&mut self) -> std::slice::IterMut<'_,f64> {
33        self.array.iter_mut()
34    }
35
36    #[inline]
37    pub fn len(&self) -> usize {
38        self.array.len()
39    }
40
41    pub fn into_vec(&self) -> Vec<f64> {
42        self.array.clone()
43    }
44
45    pub fn to_vec(&self) -> &Vec<f64> {
46        &self.array
47    }
48}
49
50
51
52impl Init for Vector {
53    type Output = Vector;
54    type Size = usize;
55
56    fn init(value: f64, size: Self::Size) -> Self::Output {
57        Vector { array : vec![value; size] }
58    }
59
60    fn init_func<F>(func: F, size: Self::Size) -> Self::Output
61        where F: Fn(Self::Size) -> f64 {
62        Vector {
63            array : (0..size).map(func).collect(),
64        }
65    }
66}
67
68
69impl std::clone::Clone for Vector {
70
71    fn clone(&self) -> Self {
72        Vector { array : self.array.clone() }
73    }
74}
75
76
77impl Dot<Vector> for Vector {
78    type Output = f64;
79
80    fn dot(&self, rhs: &Vector) -> Self::Output {
81        assert_eq!(self.len(), rhs.len());
82
83        self.array.iter()
84            .zip(rhs.array.iter())
85            .map(|(x,y)| x*y)
86            .sum()
87    }
88}
89
90
91impl Dot<Matrix> for Vector {
92    type Output = Vector;
93
94    fn dot(&self, rhs: &Matrix) -> Self::Output {
95        // xA = (A^T x^T)^T && x^T = x
96        rhs.transpose().dot(self)
97    }
98}
99
100
101impl std::ops::Index<usize> for Vector {
102    type Output = f64;
103
104    #[inline]
105    fn index(&self, index: usize) -> &Self::Output {
106        &self.array[index]
107    }
108}
109
110
111impl std::ops::IndexMut<usize> for Vector {
112    #[inline]
113    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
114        &mut self.array[index]
115    }
116}
117
118
119impl std::ops::Neg for Vector {
120    type Output = Vector;
121
122    // moves self !!!
123    fn neg(self) -> Self::Output {
124        Vector::from(self.iter().map(|x| -x).collect())
125    }
126}
127
128impl std::ops::Neg for &Vector {
129    type Output = Vector;
130    fn neg(self) -> Self::Output {
131        Vector::from(self.iter().map(|x| -x).collect())
132    }
133}
134
135
136macro_rules! impl_operator {
137    ( $($op:tt),* ) => {
138        $(
139        impl_op_ex!($op |a: &Vector, b: &Vector| -> Vector {
140            Vector::from(a.iter()
141                .zip(b.iter())
142                .map(|(x,y)| x $op y)
143                .collect()
144            )
145        });
146
147        impl_op_ex!($op |a: &Vector, k: &f64| -> Vector {
148            Vector::from(a.iter()
149                .map(|x| x $op k)
150                .collect()
151            )
152        });
153        )*
154    }
155}
156
157
158macro_rules! impl_operator_assign {
159    ( $($op:tt),* ) => {
160        $(
161        impl_op_ex!($op |a: &mut Vector, b: &Vector| {
162            a.iter_mut().zip(b.iter())
163                .for_each(|(x,y)| *x $op y);
164        });
165
166        impl_op_ex!($op |a: &mut Vector, k: &f64| {
167            a.iter_mut().for_each(|x| *x $op k);
168        });
169        )*
170    }
171}
172
173impl_operator![+, -, *, /];
174impl_operator_assign![+=, -=, *=, /=];
175
176
177