lemonmath/
vectors.rs

1/*!
2# Vectors
3Math Vectors;
4
5# Examples
6```rust
7use lemonmath::vectors::Vector;
8
9// Create Vector from a list of numbers
10let x = Vector::new(vec![1, 2, 3], true);
11
12assert_eq!(x.content, vec![1.0, 2.0, 3.0, 4.0, 5.0]);
13
14// Push a new element to the vector
15let mut vector = Vector::new(vec![1.0, 2.0, 3.0, 4.0, 5.0], true);
16
17vector.push(6.0);
18
19assert_eq!(vector.content, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
20
21// Transpose example
22let mut vector1 = Vector::new(vec![1.0, 2.0, 3.0, 4.0, 5.0], true);
23let vector2 = Vector::new(vec![1.0, 2.0, 3.0, 4.0, 5.0], false);
24
25vector1.transpose();
26
27assert_eq!(format!("{}", vector1), format!("{}", vector2));
28
29// Display Trait
30let x = Vector::new(vec![1.0, 2.0, 3.0, 4.0, 5.0], true);
31
32assert_eq!(format!("{}", x), "[ 1.0 2.0 3.0 4.0 5.0 ]");
33
34// Dot Product
35let vector1 = Vector::new(vec![1.0, 2.0, 3.0, 4.0, 5.0], true);
36let vector2 = Vector::new(vec![1.0, 2.0, 3.0, 4.0, 5.0], false);
37
38assert_eq!(vector1 * vector2, 55.0);
39```
40*/
41
42use std::{fmt::Display, ops::{Mul, AddAssign}};
43
44#[allow(unused_imports)]
45use crate::helper::VecToFraction;
46
47#[test]
48pub fn vector_test() {
49    let vector1 = Vector::new(vec![1.32, 2.0, 3.432, 4.0, 5.0].to_fraction(), true);
50    let mut vector2 = Vector::new(vec![1.0, 2.0, 3.0, 4.53, 5.0].to_fraction(), true);
51    vector2.transpose();
52    println!("{}\n{}", vector1, vector2);
53    println!("{}", vector2 * vector1);
54}
55
56/// Math Vector
57#[derive(Clone, PartialEq, PartialOrd, Debug)]
58pub struct Vector<T> {
59    pub content: Vec<T>,
60    column_or_row: bool
61}
62
63impl<T> Vector<T> {
64    /// Create the Vector  
65    /// 
66    /// # Examples
67    /// ```
68    /// use lemonmath::vectors::Vector;
69    /// 
70    /// let x = Vector::new(vec![1.0, 2.0, 3.0, 4.0, 5.0], true);
71    /// 
72    /// assert_eq!(x.content, vec![1.0, 2.0, 3.0, 4.0, 5.0]);
73    /// ```
74    pub fn new(content: Vec<T>, column_or_row: bool) -> Self {
75        return Vector { 
76            content: content, 
77            column_or_row 
78        };
79        
80    }
81    /// Push new values into the vector
82    /// 
83    /// # Examples
84    /// ```
85    /// use lemonmath::vectors::Vector;
86    /// 
87    /// let mut vector = Vector::new(vec![1.0, 2.0, 3.0, 4.0, 5.0], true);
88    /// 
89    /// vector.push(6.0);
90    /// 
91    /// assert_eq!(vector.content, vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
92    /// ```
93    pub fn push(&mut self, value: T) {
94        self.content.push(value);
95    }
96    /// Switch between column and row vector
97    /// 
98    /// # Examples
99    /// ```
100    /// use lemonmath::vectors::Vector;
101    /// 
102    /// let mut vector1 = Vector::new(vec![1.0, 2.0, 3.0, 4.0, 5.0], true);
103    /// let vector2 = Vector::new(vec![1.0, 2.0, 3.0, 4.0, 5.0], false);
104    /// 
105    /// vector1.transpose();
106    /// 
107    /// assert_eq!(format!("{}", vector1), format!("{}", vector2));
108    /// ```
109    pub fn transpose(&mut self) {
110        self.column_or_row = !self.column_or_row;
111    }
112}
113
114impl<T: Display> Display for Vector<T> {
115    /// Display the vector
116    /// 
117    /// # Examples
118    /// ```
119    /// use lemonmath::vectors::Vector;
120    /// 
121    /// let x = Vector::new(vec![1.0, 2.0, 3.0, 4.0, 5.0], true);
122    /// 
123    /// assert_eq!(format!("{}", x), "[ 1.0 2.0 3.0 4.0 5.0 ]");
124    /// ```
125    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
126        let mut final_str = String::new();
127        if self.column_or_row == true {
128            let mut max_length = 1;
129            for x in &self.content {
130                if format!("{}", x).len() > max_length {
131                    max_length = format!("{}", x).len();
132                }
133            }
134            for x in (&self.content).into_iter().enumerate() {
135                let mut padding = String::new();
136                for _ in 0..(max_length - format!("{}", x.1).len()) {
137                    padding.push(' ');
138                }
139                if x.0 == 0 {
140                    final_str.push_str(&format!("⎡ {}{} ⎤\n", x.1, padding));
141                } else if x.0 + 1 == self.content.len() {
142                    final_str.push_str(&format!("⎣ {}{} ⎦", x.1, padding));
143                } else {
144                    final_str.push_str(&format!("⎢ {}{} ⎥\n", x.1, padding));
145                }
146            }
147        } else {
148            final_str.push('[');
149            final_str.push(' ');
150            for x in &self.content {
151                final_str.push_str(format!("{} ", x).as_str());
152            }
153            final_str.push(']');
154        }
155        return f.write_str(final_str.as_str());
156    }
157}
158
159impl<T: AddAssign + Default + Mul + Mul<Output = T> + Copy + Display> Mul for Vector<T>{
160    type Output = T;
161
162    /// Dot Product
163    /// 
164    /// # Examples
165    /// ```
166    /// use lemonmath::vectors::Vector;
167    /// 
168    /// let vector1 = Vector::new(vec![1.0, 2.0, 3.0, 4.0, 5.0], true);
169    /// let vector2 = Vector::new(vec![1.0, 2.0, 3.0, 4.0, 5.0], false);
170    /// 
171    /// assert_eq!(vector1 * vector2, 55.0);
172    /// ```
173    fn mul(self, other: Self) -> Self::Output {
174        let mut result = T::default();
175        if self.content.len() != other.content.len() {
176            panic!("Vectors must have the same length");
177        }
178        if self.column_or_row != other.column_or_row {
179            for x in 0..self.content.len() {
180                result += self.content[x] * other.content[x];
181            }
182        } else {
183            panic!("Can't multiply two vectors with the same orientation");
184        }
185        return result;
186    }
187}