harness_algebra/tensors/dynamic/
vector.rs1use std::fmt;
56
57use super::*;
58use crate::category::Category;
59
60#[derive(Default, Clone, Debug, PartialEq, Eq, Hash)]
100pub struct DynamicVector<F> {
101 pub components: Vec<F>,
103}
104
105impl<F> DynamicVector<F> {
106 pub const fn new(components: Vec<F>) -> Self { Self { components } }
116
117 pub const fn dimension(&self) -> usize { self.components.len() }
121
122 pub fn components(&self) -> &[F] { &self.components }
126
127 pub const fn components_mut(&mut self) -> &mut Vec<F> { &mut self.components }
131
132 pub fn get_component(&self, index: usize) -> &F { &self.components[index] }
146
147 pub fn set_component(&mut self, index: usize, value: F) { self.components[index] = value }
158
159 pub fn append(&mut self, value: F) { self.components.push(value) }
165
166 pub fn pop(&mut self) -> Option<F> { self.components.pop() }
172
173 pub fn zeros(dimension: usize) -> Self
175 where F: Zero + Copy {
176 Self { components: vec![F::zero(); dimension] }
177 }
178}
179
180impl<F: Field> From<Vec<F>> for DynamicVector<F> {
181 fn from(components: Vec<F>) -> Self { Self { components } }
187}
188
189impl<const M: usize, F: Field + Copy> From<[F; M]> for DynamicVector<F> {
190 fn from(components: [F; M]) -> Self { Self { components: components.to_vec() } }
196}
197
198impl<F: Field + Clone> From<&[F]> for DynamicVector<F> {
199 fn from(components: &[F]) -> Self { Self { components: components.to_vec() } }
205}
206
207impl<F: Field + Copy> Category for DynamicVector<F> {
208 type Morphism = DynamicDenseMatrix<F, RowMajor>;
209
210 fn compose(f: Self::Morphism, g: Self::Morphism) -> Self::Morphism { f * g }
211
212 fn identity(a: Self) -> Self::Morphism {
213 let mut mat = DynamicDenseMatrix::<F, RowMajor>::new();
214 for i in 0..a.dimension() {
215 let mut col = Self::from(vec![F::zero(); a.dimension()]);
216 col.components[i] = F::one();
217 mat.append_column(&col);
218 }
219 mat
220 }
221
222 fn apply(f: Self::Morphism, x: Self) -> Self { f * x }
223}
224
225impl<F: Field + Copy> Add for DynamicVector<F> {
227 type Output = Self;
228
229 fn add(self, other: Self) -> Self::Output {
243 assert_eq!(self.components.len(), other.components.len());
244 let mut sum = Self { components: vec![F::zero(); self.components.len()] };
245 for i in 0..self.components.len() {
246 sum.components[i] = self.components[i] + other.components[i];
247 }
248 sum
249 }
250}
251
252impl<F: Field + Copy> AddAssign for DynamicVector<F> {
253 fn add_assign(&mut self, rhs: Self) { *self = self.clone() + rhs }
263}
264
265impl<F: Field + Copy> Neg for DynamicVector<F> {
266 type Output = Self;
267
268 fn neg(self) -> Self::Output {
274 let mut neg = Self { components: vec![F::zero(); self.components.len()] };
275 for i in 0..self.components.len() {
276 neg.components[i] = -self.components[i];
277 }
278 neg
279 }
280}
281
282impl<F: Field + Copy> Mul<F> for DynamicVector<F> {
283 type Output = Self;
284
285 fn mul(self, scalar: F) -> Self::Output {
295 let mut scalar_multiple = Self { components: vec![F::zero(); self.components.len()] };
296 for i in 0..self.components.len() {
297 scalar_multiple.components[i] = scalar * self.components[i];
298 }
299 scalar_multiple
300 }
301}
302
303impl<F: Field + Copy> Sub for DynamicVector<F> {
304 type Output = Self;
305
306 fn sub(self, other: Self) -> Self::Output { self + -other }
320}
321
322impl<F: Field + Copy> SubAssign for DynamicVector<F> {
323 fn sub_assign(&mut self, rhs: Self) { *self = self.clone() - rhs }
333}
334
335impl<F: Field + Copy> Additive for DynamicVector<F> {}
336
337impl<F: Field + Copy> Group for DynamicVector<F> {
338 fn identity() -> Self { Self::zero() }
340
341 fn inverse(&self) -> Self { -self.clone() }
343}
344
345impl<F: Field + Copy> Zero for DynamicVector<F> {
346 fn zero() -> Self { Self { components: vec![] } }
348
349 fn is_zero(&self) -> bool {
355 self.components.iter().all(|x| *x == F::zero()) || self.components.is_empty()
356 }
357}
358
359impl<F: Field + Copy> AbelianGroup for DynamicVector<F> {}
360
361impl<F: Field + Copy + Mul<Self>> LeftModule for DynamicVector<F> {
362 type Ring = F;
363}
364
365impl<F: Field + Copy + Mul<Self>> RightModule for DynamicVector<F> {
366 type Ring = F;
367}
368
369impl<F: Field + Copy + Mul<Self>> TwoSidedModule for DynamicVector<F> {
370 type Ring = F;
371}
372
373impl<F: Field + Copy + Mul<Self>> VectorSpace for DynamicVector<F> {}
374
375impl<F> Iterator for DynamicVector<F> {
376 type Item = F;
377
378 fn next(&mut self) -> Option<Self::Item> { self.components.pop() }
379}
380
381impl<F: Field + Copy + fmt::Display> fmt::Display for DynamicVector<F> {
382 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
383 if self.components.is_empty() {
384 return write!(f, "( )");
385 }
386
387 if self.components.len() == 1 {
388 return write!(f, "( {} )", self.components[0]);
390 }
391
392 let mut max_width = 0;
394 for component in &self.components {
395 let component_str = format!("{component}");
396 max_width = max_width.max(component_str.len());
397 }
398
399 for (i, component) in self.components.iter().enumerate() {
401 if i == 0 {
402 writeln!(f, "⎛ {component:>max_width$} ⎞")?;
403 } else if i == self.components.len() - 1 {
404 write!(f, "⎝ {component:>max_width$} ⎠")?;
405 } else {
406 writeln!(f, "⎜ {component:>max_width$} ⎟")?;
407 }
408 }
409
410 Ok(())
411 }
412}
413
414#[cfg(test)]
415mod tests {
416 use fixtures::Mod7;
417
418 use super::*;
419
420 #[test]
421 fn test_zero_vector() {
422 let zero_vec: DynamicVector<Mod7> = DynamicVector::zero();
423 assert!(zero_vec.is_zero());
424 assert_eq!(zero_vec.components.len(), 0, "Default zero vector should have 0 components");
425
426 let non_zero_vec = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(0)]);
427 assert!(!non_zero_vec.is_zero());
428
429 let zero_vec_explicit_empty: DynamicVector<Mod7> = DynamicVector::from([]);
430 assert!(zero_vec_explicit_empty.is_zero());
431 assert_eq!(
432 zero_vec_explicit_empty.components.len(),
433 0,
434 "Explicit empty vector should have 0 components"
435 );
436 }
437
438 #[test]
439 fn test_is_zero_for_non_empty_vector_with_all_zeros() {
440 let vec_all_zeros: DynamicVector<Mod7> =
441 DynamicVector::from([Mod7::from(0), Mod7::from(0), Mod7::from(0)]);
442 assert!(vec_all_zeros.is_zero());
443 }
444
445 #[test]
446 fn test_addition_zero_vectors() {
447 let vec1: DynamicVector<Mod7> = DynamicVector::zero();
448 let vec2: DynamicVector<Mod7> = DynamicVector::zero();
449 let sum = vec1 + vec2;
450 assert!(sum.is_zero());
451 assert_eq!(
452 sum.components.len(),
453 0,
454 "Sum of two default zero vectors should be a zero vector with 0 components"
455 );
456 }
457
458 #[test]
459 fn test_addition_same_dimension() {
460 let vec1 = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(0)]);
461 let vec2 = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(1)]);
462 let sum = vec1 + vec2;
463 assert_eq!(sum.components, vec![Mod7::from(2), Mod7::from(1)]);
464 }
465
466 #[test]
467 #[should_panic(expected = "assertion `left == right` failed\n left: 2\n right: 0")]
468 fn test_addition_with_zero_vector_implicit_panics() {
469 let vec1 = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(0)]);
470 let zero_vec: DynamicVector<Mod7> = DynamicVector::zero();
471 let _ = vec1 + zero_vec; }
473
474 #[test]
475 #[should_panic(expected = "assertion `left == right` failed\n left: 2\n right: 3")]
476 fn test_addition_different_dimensions_panic() {
477 let vec1 = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(0)]);
478 let vec2 = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(1), Mod7::from(1)]);
479 let _ = vec1 + vec2; }
481
482 #[test]
483 fn test_negation() {
484 let vec = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(0)]);
485 let neg_vec = -vec;
486 assert_eq!(neg_vec.components, vec![Mod7::from(6), Mod7::from(0)]);
487 }
488
489 #[test]
490 fn test_scalar_multiplication() {
491 let vec = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(0), Mod7::from(1)]);
492 let scalar_one = Mod7::from(1);
493 let scalar_zero = Mod7::from(0);
494
495 let mul_one = vec.clone() * scalar_one;
496 assert_eq!(mul_one.components, vec![
497 Mod7::from(1) * scalar_one,
498 Mod7::from(0) * scalar_one,
499 Mod7::from(1) * scalar_one
500 ]);
501
502 let mul_zero = vec * scalar_zero;
503 assert_eq!(mul_zero.components, vec![Mod7::from(0), Mod7::from(0), Mod7::from(0)]);
504 }
505
506 #[test]
507 fn test_subtraction_same_dimension() {
508 let vec1 = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(1)]);
509 let vec2 = DynamicVector::<Mod7>::from([Mod7::from(0), Mod7::from(1)]);
510 let diff = vec1 + (-vec2);
511 assert_eq!(diff.components, vec![Mod7::from(1), Mod7::from(0)]);
512 }
513
514 #[test]
515 #[should_panic(expected = "assertion `left == right` failed\n left: 2\n right: 1")]
516 fn test_subtraction_different_dimensions_panic() {
517 let vec1 = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(0)]);
518 let vec2 = DynamicVector::<Mod7>::from([Mod7::from(1)]);
519 let _ = vec1 - vec2;
520 }
521
522 #[test]
523 fn test_add_assign_same_dimension() {
524 let mut vec1 = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(0)]);
525 let vec2 = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(1)]);
526 vec1 += vec2;
527 assert_eq!(vec1.components, vec![Mod7::from(2), Mod7::from(1)]);
528 }
529
530 #[test]
531 #[should_panic(expected = "assertion `left == right` failed\n left: 2\n right: 1")]
532 fn test_add_assign_different_dimensions_panic() {
533 let mut vec1 = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(0)]);
534 let vec2 = DynamicVector::<Mod7>::from([Mod7::from(1)]);
535 vec1 += vec2; }
537
538 #[test]
539 fn test_sub_assign_same_dimension() {
540 let mut vec1 = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(1)]);
541 let vec2 = DynamicVector::<Mod7>::from([Mod7::from(0), Mod7::from(1)]);
542 vec1 -= vec2;
543 assert_eq!(vec1.components, vec![Mod7::from(1), Mod7::from(0)]);
544 }
545
546 #[test]
547 #[should_panic(expected = "assertion `left == right` failed\n left: 2\n right: 1")]
548 fn test_sub_assign_different_dimensions_panic() {
549 let mut vec1 = DynamicVector::<Mod7>::from([Mod7::from(1), Mod7::from(0)]);
550 let vec2 = DynamicVector::<Mod7>::from([Mod7::from(1)]);
551 vec1 -= vec2; }
553
554 #[test]
555 fn test_zeros() {
556 let zero_vec = DynamicVector::<Mod7>::zeros(3);
557 assert_eq!(zero_vec.components, vec![Mod7::from(0), Mod7::from(0), Mod7::from(0)]);
558 }
559
560 #[test]
561 fn test_display_formatting() {
562 let empty: DynamicVector<f64> = DynamicVector::new(vec![]);
564 println!("Empty vector: \n{empty}");
565
566 let single = DynamicVector::from([42.0]);
568 println!("Single element: \n{single}");
569
570 let multi = DynamicVector::from([1.0, 2.5, -3.7, 0.0]);
572 println!("Multiple elements: \n{multi}");
573 }
574}