numeris/dynmatrix/
vector.rs1use alloc::vec::Vec;
2use core::ops::{Index, IndexMut};
3
4use crate::matrix::vector::Vector;
5use crate::traits::{MatrixMut, MatrixRef, Scalar};
6
7use super::DynMatrix;
8
9#[derive(Debug, Clone, PartialEq)]
27pub struct DynVector<T> {
28 pub(crate) inner: DynMatrix<T>,
29}
30
31impl<T: Scalar> DynVector<T> {
32 pub fn from_slice(data: &[T]) -> Self {
41 Self {
42 inner: DynMatrix::from_slice(data.len(), 1, data),
43 }
44 }
45
46 pub fn from_vec(data: Vec<T>) -> Self {
54 let n = data.len();
55 Self {
56 inner: DynMatrix::from_vec(n, 1, data),
57 }
58 }
59
60 pub fn zeros(n: usize) -> Self {
69 Self {
70 inner: DynMatrix::zeros(n, 1),
71 }
72 }
73
74 pub fn fill(n: usize, value: T) -> Self {
76 Self {
77 inner: DynMatrix::fill(n, 1, value),
78 }
79 }
80
81 #[inline]
83 pub fn len(&self) -> usize {
84 self.inner.nrows()
85 }
86
87 #[inline]
89 pub fn is_empty(&self) -> bool {
90 self.len() == 0
91 }
92
93 pub fn dot(&self, rhs: &Self) -> T {
102 assert_eq!(self.len(), rhs.len(), "vector length mismatch");
103 crate::simd::dot_dispatch(self.as_slice(), rhs.as_slice())
104 }
105
106 pub fn cast<U: Scalar + num_traits::NumCast>(&self) -> DynVector<U>
115 where
116 T: num_traits::ToPrimitive,
117 {
118 DynVector {
119 inner: self.inner.cast(),
120 }
121 }
122
123 #[inline]
125 pub fn as_slice(&self) -> &[T] {
126 self.inner.as_slice()
127 }
128
129 #[inline]
131 pub fn as_mut_slice(&mut self) -> &mut [T] {
132 self.inner.as_mut_slice()
133 }
134}
135
136impl<T> Index<usize> for DynVector<T> {
139 type Output = T;
140
141 #[inline]
142 fn index(&self, i: usize) -> &T {
143 &self.inner[(i, 0)]
144 }
145}
146
147impl<T> IndexMut<usize> for DynVector<T> {
148 #[inline]
149 fn index_mut(&mut self, i: usize) -> &mut T {
150 &mut self.inner[(i, 0)]
151 }
152}
153
154impl<T> MatrixRef<T> for DynVector<T> {
157 #[inline]
158 fn nrows(&self) -> usize {
159 self.inner.nrows()
160 }
161
162 #[inline]
163 fn ncols(&self) -> usize {
164 1
165 }
166
167 #[inline]
168 fn get(&self, row: usize, col: usize) -> &T {
169 self.inner.get(row, col)
170 }
171
172 #[inline]
173 fn col_as_slice(&self, col: usize, row_start: usize) -> &[T] {
174 self.inner.col_as_slice(col, row_start)
175 }
176}
177
178impl<T> MatrixMut<T> for DynVector<T> {
179 #[inline]
180 fn get_mut(&mut self, row: usize, col: usize) -> &mut T {
181 self.inner.get_mut(row, col)
182 }
183
184 #[inline]
185 fn col_as_mut_slice(&mut self, col: usize, row_start: usize) -> &mut [T] {
186 self.inner.col_as_mut_slice(col, row_start)
187 }
188}
189
190impl<T: Scalar, const N: usize> From<Vector<T, N>> for DynVector<T> {
193 fn from(v: Vector<T, N>) -> Self {
203 Self::from_slice(v.as_slice())
204 }
205}
206
207impl<T: Scalar, const N: usize> From<&Vector<T, N>> for DynVector<T> {
208 fn from(v: &Vector<T, N>) -> Self {
209 Self::from_slice(v.as_slice())
210 }
211}
212
213impl<T: Scalar> From<DynVector<T>> for DynMatrix<T> {
214 fn from(v: DynVector<T>) -> Self {
215 v.inner
216 }
217}
218
219impl<T: Scalar> From<&DynVector<T>> for DynMatrix<T> {
220 fn from(v: &DynVector<T>) -> Self {
221 v.inner.clone()
222 }
223}
224
225#[cfg(test)]
226mod tests {
227 use super::*;
228 use crate::Vector;
229
230 #[test]
231 fn from_slice() {
232 let v = DynVector::from_slice(&[1.0, 2.0, 3.0]);
233 assert_eq!(v.len(), 3);
234 assert_eq!(v[0], 1.0);
235 assert_eq!(v[2], 3.0);
236 }
237
238 #[test]
239 fn from_vec() {
240 let v = DynVector::from_vec(vec![10.0, 20.0]);
241 assert_eq!(v.len(), 2);
242 assert_eq!(v[1], 20.0);
243 }
244
245 #[test]
246 fn zeros() {
247 let v = DynVector::<f64>::zeros(4);
248 assert_eq!(v.len(), 4);
249 for i in 0..4 {
250 assert_eq!(v[i], 0.0);
251 }
252 }
253
254 #[test]
255 fn index_mut() {
256 let mut v = DynVector::<f64>::zeros(3);
257 v[1] = 42.0;
258 assert_eq!(v[1], 42.0);
259 }
260
261 #[test]
262 fn dot_product() {
263 let a = DynVector::from_slice(&[1.0, 2.0, 3.0]);
264 let b = DynVector::from_slice(&[4.0, 5.0, 6.0]);
265 assert_eq!(a.dot(&b), 32.0);
266 }
267
268 #[test]
269 fn from_fixed_vector() {
270 let v = Vector::from_array([1.0, 2.0, 3.0]);
271 let dv: DynVector<f64> = v.into();
272 assert_eq!(dv.len(), 3);
273 assert_eq!(dv[0], 1.0);
274 assert_eq!(dv[2], 3.0);
275 }
276
277 #[test]
278 fn dimensions_match_vector() {
279 let v = DynVector::from_slice(&[1.0, 2.0, 3.0]);
281 assert_eq!(v.nrows(), 3);
282 assert_eq!(v.ncols(), 1);
283 }
284
285 #[test]
286 fn as_slice() {
287 let v = DynVector::from_slice(&[1.0, 2.0, 3.0]);
288 assert_eq!(v.as_slice(), &[1.0, 2.0, 3.0]);
289 }
290
291 #[test]
292 fn into_dynmatrix() {
293 let v = DynVector::from_slice(&[1.0, 2.0, 3.0]);
294 let m: DynMatrix<f64> = v.into();
295 assert_eq!(m.nrows(), 3);
296 assert_eq!(m.ncols(), 1);
297 assert_eq!(m[(1, 0)], 2.0);
298 }
299}