From 98378115ca92ec44fba8f7c5e63a2c3823e0d780 Mon Sep 17 00:00:00 2001 From: Sam Hadow Date: Fri, 23 May 2025 22:09:10 +0200 Subject: [PATCH] vector structure --- src/main.rs | 1 + src/vector.rs | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 src/vector.rs diff --git a/src/main.rs b/src/main.rs index a5ce515..cdc084f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ mod file; mod lll; mod matrix; mod utils; +mod vector; use crate::agcd::agcd; use crate::file::parse_file; diff --git a/src/vector.rs b/src/vector.rs new file mode 100644 index 0000000..aed0625 --- /dev/null +++ b/src/vector.rs @@ -0,0 +1,155 @@ +use rug::Integer; +use std::{ + fmt, + ops::{Add, Index, IndexMut, Mul, Sub}, +}; + +macro_rules! int { + ($x:expr) => { + rug::Integer::from($x) + }; +} + +#[derive(Clone)] +pub struct IntVector { + elements: Vec, +} + +impl IntVector { + pub fn init(size: usize) -> Self { + Self { + elements: vec![Default::default(); size], + } + } + + pub fn from_vec(elements: Vec) -> Self { + Self { elements } + } + + pub fn size(&self) -> usize { + self.elements.len() + } + + pub fn mul_scalar(&self, other: &Integer) -> Self { + let n = self.size(); + Self::from_vec((0..n).map(|i| int!(&self.elements[i] * other)).collect()) + } +} + +impl Add for IntVector { + type Output = Self; + fn add(self, other: Self) -> Self::Output { + assert_eq!(self.size(), other.size()); + let elements = self + .elements + .into_iter() + .zip(other.elements) + .map(|(a, b)| a + b) + .collect(); + IntVector::from_vec(elements) + } +} + +impl Sub for IntVector { + type Output = Self; + fn sub(self, other: Self) -> Self::Output { + assert_eq!(self.size(), other.size()); + let elements = self + .elements + .into_iter() + .zip(other.elements) + .map(|(a, b)| a - b) + .collect(); + IntVector::from_vec(elements) + } +} + +impl Mul for IntVector { + type Output = Integer; + fn mul(self, other: Self) -> Self::Output { + let n = self.size(); + assert_eq!(n, other.size()); + (0..n) + .map(|i| Integer::from(&self.elements[i] * &other.elements[i])) + .sum() + } +} + +impl Index for IntVector { + type Output = Integer; + + fn index(&self, index: usize) -> &Integer { + &self.elements[index] + } +} + +impl IndexMut for IntVector { + fn index_mut(&mut self, index: usize) -> &mut Integer { + &mut self.elements[index] + } +} + +impl fmt::Debug for IntVector { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.elements) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_from_vec() { + let v = IntVector::from_vec(vec![int!(1), int!(2), int!(3)]); + assert_eq!(v.size(), 3); + assert_eq!(v[0], int!(1)); + assert_eq!(v[1], int!(2)); + assert_eq!(v[2], int!(3)); + } + + #[test] + fn test_add_vectors() { + let v1 = IntVector::from_vec(vec![int!(1), int!(2), int!(3)]); + let v2 = IntVector::from_vec(vec![int!(4), int!(5), int!(6)]); + let result = v1 + v2; + assert_eq!(result[0], int!(5)); + assert_eq!(result[1], int!(7)); + assert_eq!(result[2], int!(9)); + } + + #[test] + fn test_sub_vectors() { + let v1 = IntVector::from_vec(vec![int!(5), int!(7), int!(9)]); + let v2 = IntVector::from_vec(vec![int!(4), int!(5), int!(6)]); + let result = v1 - v2; + assert_eq!(result[0], int!(1)); + assert_eq!(result[1], int!(2)); + assert_eq!(result[2], int!(3)); + } + + #[test] + fn test_scalar_multiplication() { + let v = IntVector::from_vec(vec![int!(2), int!(3), int!(4)]); + let scalar = int!(5); + let result = v.mul_scalar(&scalar); + assert_eq!(result[0], int!(10)); + assert_eq!(result[1], int!(15)); + assert_eq!(result[2], int!(20)); + } + + #[test] + fn test_dot_product() { + let v1 = IntVector::from_vec(vec![int!(1), int!(2), int!(3)]); + let v2 = IntVector::from_vec(vec![int!(4), int!(5), int!(6)]); + let dot = v1 * v2; + assert_eq!(dot, int!(32)); // 1*4 + 2*5 + 3*6 = 32 + } + + #[test] + fn test_indexing_mut() { + let mut v = IntVector::from_vec(vec![int!(1), int!(2), int!(3)]); + v[1] += int!(10); + assert_eq!(v[1], int!(12)); + } +}