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}