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 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 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