1use 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)]
24pub struct DynVector<T> {
25 pub(crate) inner: DynMatrix<T>,
26}
27
28impl<T: Scalar> DynVector<T> {
29 pub fn from_slice(data: &[T]) -> Self {
38 Self {
39 inner: DynMatrix::from_slice(1, data.len(), data),
40 }
41 }
42
43 pub fn from_vec(data: Vec<T>) -> Self {
51 let n = data.len();
52 Self {
53 inner: DynMatrix::from_vec(1, n, data),
54 }
55 }
56
57 pub fn zeros(n: usize, _zero: T) -> Self {
66 Self {
67 inner: DynMatrix::zeros(1, n, T::zero()),
68 }
69 }
70
71 pub fn fill(n: usize, value: T) -> Self {
73 Self {
74 inner: DynMatrix::fill(1, n, value),
75 }
76 }
77
78 #[inline]
80 pub fn len(&self) -> usize {
81 self.inner.ncols()
82 }
83
84 #[inline]
86 pub fn is_empty(&self) -> bool {
87 self.len() == 0
88 }
89
90 pub fn dot(&self, rhs: &Self) -> T {
99 assert_eq!(self.len(), rhs.len(), "vector length mismatch");
100 crate::simd::dot_dispatch(self.as_slice(), rhs.as_slice())
101 }
102
103 pub fn cast<U: Scalar + num_traits::NumCast>(&self) -> DynVector<U>
112 where
113 T: num_traits::ToPrimitive,
114 {
115 DynVector {
116 inner: self.inner.cast(),
117 }
118 }
119
120 #[inline]
122 pub fn as_slice(&self) -> &[T] {
123 self.inner.as_slice()
124 }
125
126 #[inline]
128 pub fn as_mut_slice(&mut self) -> &mut [T] {
129 self.inner.as_mut_slice()
130 }
131}
132
133impl<T> Index<usize> for DynVector<T> {
136 type Output = T;
137
138 #[inline]
139 fn index(&self, i: usize) -> &T {
140 &self.inner[(0, i)]
141 }
142}
143
144impl<T> IndexMut<usize> for DynVector<T> {
145 #[inline]
146 fn index_mut(&mut self, i: usize) -> &mut T {
147 &mut self.inner[(0, i)]
148 }
149}
150
151impl<T> MatrixRef<T> for DynVector<T> {
154 #[inline]
155 fn nrows(&self) -> usize {
156 1
157 }
158
159 #[inline]
160 fn ncols(&self) -> usize {
161 self.inner.ncols()
162 }
163
164 #[inline]
165 fn get(&self, row: usize, col: usize) -> &T {
166 self.inner.get(row, col)
167 }
168
169 #[inline]
170 fn col_as_slice(&self, col: usize, row_start: usize) -> &[T] {
171 self.inner.col_as_slice(col, row_start)
172 }
173}
174
175impl<T> MatrixMut<T> for DynVector<T> {
176 #[inline]
177 fn get_mut(&mut self, row: usize, col: usize) -> &mut T {
178 self.inner.get_mut(row, col)
179 }
180
181 #[inline]
182 fn col_as_mut_slice(&mut self, col: usize, row_start: usize) -> &mut [T] {
183 self.inner.col_as_mut_slice(col, row_start)
184 }
185}
186
187impl<T: Scalar, const N: usize> From<Vector<T, N>> for DynVector<T> {
190 fn from(v: Vector<T, N>) -> Self {
200 Self {
201 inner: DynMatrix::from(v),
202 }
203 }
204}
205
206impl<T: Scalar, const N: usize> From<&Vector<T, N>> for DynVector<T> {
207 fn from(v: &Vector<T, N>) -> Self {
208 Self {
209 inner: DynMatrix::from(v),
210 }
211 }
212}
213
214impl<T: Scalar> From<DynVector<T>> for DynMatrix<T> {
215 fn from(v: DynVector<T>) -> Self {
216 v.inner
217 }
218}
219
220impl<T: Scalar> From<&DynVector<T>> for DynMatrix<T> {
221 fn from(v: &DynVector<T>) -> Self {
222 v.inner.clone()
223 }
224}
225
226#[cfg(test)]
227mod tests {
228 use super::*;
229 use crate::Vector;
230
231 #[test]
232 fn from_slice() {
233 let v = DynVector::from_slice(&[1.0, 2.0, 3.0]);
234 assert_eq!(v.len(), 3);
235 assert_eq!(v[0], 1.0);
236 assert_eq!(v[2], 3.0);
237 }
238
239 #[test]
240 fn from_vec() {
241 let v = DynVector::from_vec(vec![10.0, 20.0]);
242 assert_eq!(v.len(), 2);
243 assert_eq!(v[1], 20.0);
244 }
245
246 #[test]
247 fn zeros() {
248 let v = DynVector::zeros(4, 0.0_f64);
249 assert_eq!(v.len(), 4);
250 for i in 0..4 {
251 assert_eq!(v[i], 0.0);
252 }
253 }
254
255 #[test]
256 fn index_mut() {
257 let mut v = DynVector::zeros(3, 0.0_f64);
258 v[1] = 42.0;
259 assert_eq!(v[1], 42.0);
260 }
261
262 #[test]
263 fn dot_product() {
264 let a = DynVector::from_slice(&[1.0, 2.0, 3.0]);
265 let b = DynVector::from_slice(&[4.0, 5.0, 6.0]);
266 assert_eq!(a.dot(&b), 32.0);
267 }
268
269 #[test]
270 fn from_fixed_vector() {
271 let v = Vector::from_array([1.0, 2.0, 3.0]);
272 let dv: DynVector<f64> = v.into();
273 assert_eq!(dv.len(), 3);
274 assert_eq!(dv[0], 1.0);
275 assert_eq!(dv[2], 3.0);
276 }
277
278 #[test]
279 fn matrix_ref_trait() {
280 let v = DynVector::from_slice(&[1.0, 2.0, 3.0]);
281 assert_eq!(v.nrows(), 1);
282 assert_eq!(v.ncols(), 3);
283 assert_eq!(*v.get(0, 1), 2.0);
284 }
285
286 #[test]
287 fn as_slice() {
288 let v = DynVector::from_slice(&[1.0, 2.0, 3.0]);
289 assert_eq!(v.as_slice(), &[1.0, 2.0, 3.0]);
290 }
291
292 #[test]
293 fn into_dynmatrix() {
294 let v = DynVector::from_slice(&[1.0, 2.0, 3.0]);
295 let m: DynMatrix<f64> = v.into();
296 assert_eq!(m.nrows(), 1);
297 assert_eq!(m.ncols(), 3);
298 assert_eq!(m[(0, 1)], 2.0);
299 }
300}