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