1use core::fmt;
32use num::{Float, Zero, Num, Signed};
33use core::ops::{Deref, DerefMut};
34
35use core::ops::{Add, Sub, Div, Mul, SubAssign, AddAssign, Neg};
36
37use crate::slices_methods::{norm_inf, norm_l};
38use crate::errors::VectorErrors;
39use crate::matrix5x5::M55;
40#[derive(Copy, Clone, Debug, PartialEq)]
44pub struct V5<T>([T; 5]);
45
46impl<T> V5<T> {
47 pub const fn new(input: [T; 5]) -> Self {
49 Self(input)
50 }
51
52 pub const fn new_from(num1: T, num2: T, num3: T, num4: T, num5: T) -> Self {
54 Self::new([num1, num2, num3, num4, num5])
55 }
56}
57
58impl<T: Num + Copy> V5<T> {
59 pub fn zeros() -> Self {
61 <V5<T> as Zero>::zero()
62 }
63
64 pub fn ones() -> Self {
66 let one = T::one();
67 Self::new([one, one, one, one, one])
68 }
69}
70
71impl<T: Num + Copy + core::cmp::PartialOrd> V5<T> {
72 pub fn norm_inf(&self) -> T {
73 norm_inf(&**self)
74 }
75}
76
77impl<T: Num + Copy + Signed + core::iter::Sum> V5<T> {
78 pub fn norm_l(&self) -> T {
79 norm_l(&**self)
80 }
81}
82
83impl<T: Num + Copy + Signed> Neg for V5<T> {
84 type Output = Self;
85
86 #[inline]
87 fn neg(self) -> Self {
88 Self::new_from(-self[0], -self[1], -self[2], -self[3], -self[4])
89 }
90}
91
92impl<T: Float> V5<T> {
93 #[inline]
95 pub fn norm2(&self) -> T {
96 T::sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2] + self[3] * self[3] + self[4] * self[4])
97 }
98
99 pub fn normalize(&mut self) -> Result<Self, VectorErrors> {
101 let n = self.norm2();
102 if n != T::zero() {
103 let mut result = Self::zeros();
105 for i in 0..self.len() {
106 result[i] = self[i] / n;
107 }
108 Ok(result)
109 } else {
110 Err(VectorErrors::Norm2IsZero)
111 }
112 }
113}
114
115impl<T: Num + Copy> Mul for V5<T> {
117 type Output = T;
118
119 #[inline]
120 fn mul(self, rhs: Self) -> T {
121 self[0] * rhs[0] + self[1] * rhs[1] + self[2] * rhs[2] + self[3] * rhs[3] + self[4] * rhs[4]
122 }
123}
124
125impl<T: Num + Copy> Mul<T> for V5<T> {
127 type Output = V5<T>;
128
129 #[inline]
130 fn mul(self, rhs: T) -> V5<T> {
131 Self::new_from(self[0] * rhs, self[1] * rhs, self[2] * rhs, self[3] * rhs, self[4] * rhs)
132 }
133}
134
135impl<T: Num + Copy> Div<T> for V5<T> {
137 type Output = Self;
138
139 fn div(self, rhs: T) -> Self::Output {
140 Self::new_from(self[0] / rhs, self[1] / rhs, self[2] / rhs, self[3] / rhs, self[4] / rhs)
141 }
142}
143impl Mul<V5<f32>> for f32 {
145 type Output = V5<f32>;
146
147 #[inline]
148 fn mul(self, rhs: V5<f32>) -> V5<f32> {
149 V5::new_from(self * rhs[0], self * rhs[1], self * rhs[2], self * rhs[3], self * rhs[4])
150 }
151}
152
153impl<T: Num + Copy> Mul<M55<T>> for V5<T> {
155 type Output = V5<T>;
156
157 #[inline]
158 fn mul(self, rhs: M55<T>) -> V5<T> {
159 Self::new_from(
160 rhs[(0, 0)] * self[0] + rhs[(1, 0)] * self[1] + rhs[(2, 0)] * self[2] + rhs[(3, 0)] * self[3] + rhs[(4, 0)] * self[4],
161 rhs[(0, 1)] * self[0] + rhs[(1, 1)] * self[1] + rhs[(2, 1)] * self[2] + rhs[(3, 1)] * self[3] + rhs[(4, 1)] * self[4],
162 rhs[(0, 2)] * self[0] + rhs[(1, 2)] * self[1] + rhs[(2, 2)] * self[2] + rhs[(3, 2)] * self[3] + rhs[(4, 2)] * self[4],
163 rhs[(0, 3)] * self[0] + rhs[(1, 3)] * self[1] + rhs[(2, 3)] * self[2] + rhs[(3, 3)] * self[3] + rhs[(4, 3)] * self[4],
164 rhs[(0, 4)] * self[0] + rhs[(1, 4)] * self[1] + rhs[(2, 4)] * self[2] + rhs[(3, 4)] * self[3] + rhs[(4, 4)] * self[4],
165 )
166 }
167}
168
169impl<T: Num + Copy> Sub for V5<T> {
171 type Output = Self;
172
173 #[inline]
174 fn sub(self, rhs: Self) -> Self {
175 Self::new_from(self[0] - rhs[0], self[1] - rhs[1], self[2] - rhs[2], self[3] - rhs[3], self[4] - rhs[4])
176 }
177}
178
179impl<T: Num + Copy> SubAssign for V5<T> {
181 #[inline]
182 fn sub_assign(&mut self, other: Self) {
183 *self = *self - other
184 }
185}
186
187impl<T: Num + Copy> Add for V5<T> {
189 type Output = Self;
190 #[inline]
191 fn add(self, rhs: Self) -> Self {
192 Self::new_from(self[0] + rhs[0], self[1] + rhs[1], self[2] + rhs[2], self[3] + rhs[3], self[4] + rhs[4])
193 }
194}
195
196impl<T: Num + Copy> AddAssign for V5<T> {
198 #[inline]
199 fn add_assign(&mut self, other: Self) {
200 *self = *self + other
201 }
202}
203
204impl<T: Num + Copy> Zero for V5<T> {
205 fn zero() -> V5<T> {
206 Self::new([T::zero(); 5])
207 }
208
209 fn is_zero(&self) -> bool {
210 *self == V5::zero()
211 }
212}
213
214impl<T> Deref for V5<T> {
215 type Target = [T; 5];
216 #[inline]
217 fn deref(&self) -> &Self::Target {
218 &self.0
219 }
220}
221
222impl<T> DerefMut for V5<T> {
223 #[inline]
224 fn deref_mut(&mut self) -> &mut Self::Target {
225 &mut self.0
226 }
227}
228
229impl<T> From<[T; 5]> for V5<T> {
230 fn from(data: [T; 5]) -> V5<T> {
231 V5(data)
232 }
233}
234
235impl<T: Num + fmt::Display> fmt::Display for V5<T> {
239 fn fmt(&self, dest: &mut fmt::Formatter) -> fmt::Result {
240 writeln!(dest, "[{0:^3.2} {1:^3.2} {2:^3.2} {3:^3.2} {4:^3.2}]", self[0], self[1], self[2], self[3], self[4])
241 }
242}
243
244#[cfg(test)]
248mod vector5_test {
249
250 use crate::matrix5x5::M55;
251 use crate::vector5::V5;
252
253 #[test]
254 fn vector5_creation_test() {
255 let v = V5::new([1.0, 2.0, 3.0, 4.0, 5.0]);
256 assert_eq!(v[0], 1.0);
257 assert_eq!(v[1], 2.0);
258 assert_eq!(v[2], 3.0);
259 assert_eq!(v[3], 4.0);
260 assert_eq!(v[4], 5.0);
261 }
262
263 #[test]
264 fn vector5_zeros_test() {
265 let result: V5<f32> = V5::zeros();
266 let expected = V5::new([0.0, 0.0, 0.0, 0.0, 0.0]);
267 assert_eq!(
268 &result[..],
269 &expected[..],
270 "\nExpected\n{:?}\nfound\n{:?}",
271 &result[..],
272 &expected[..]
273 );
274 }
275
276 #[test]
277 fn vector5_add_test() {
278 let v1 = V5::new([1.0, 2.0, 3.0, 4.0, 5.0]);
279 let v2 = V5::new([6.0, 7.0, 8.0, 9.0, 10.0]);
280 let result = v1 + v2;
281 let expected = V5::new([7.0, 9.0, 11.0, 13.0, 15.0]);
282 assert_eq!(
283 &result[..],
284 &expected[..],
285 "\nExpected\n{:?}\nfound\n{:?}",
286 &result[..],
287 &expected[..]
288 );
289 }
290
291 #[test]
292 fn sub_test() {
293 let v1 = V5::new([1.0, 2.0, 3.0, 4.0, 5.0]);
294 let v2 = V5::new([6.0, 7.0, 8.0, 9.0, 10.0]);
295 let result = v1 - v2;
296 let expected = V5::new([-5.0, -5.0, -5.0, -5.0, -5.0]);
297 assert_eq!(
298 &result[..],
299 &expected[..],
300 "\nExpected\n{:?}\nfound\n{:?}",
301 &result[..],
302 &expected[..]
303 );
304 }
305
306 #[test]
307 fn vector5_mul_test() {
308 let v1 = V5::new([1.0, 2.0, 3.0, 4.0, 5.0]);
309 let v2 = V5::new([6.0, 7.0, 8.0, 9.0, 10.0]);
310 let result = v1 * v2;
311 let expected = 130.0;
312 assert_eq!(result, expected);
313 }
314
315 #[test]
316 fn vector5_norm_test() {
317 let v1 = V5::new([1.0, 2.0, 3.0, 4.0, 5.0]);
318 let result = v1.norm2();
319 let expected = 7.416198487095663;
320 assert_eq!(result, expected);
321 }
322
323 #[test]
324 fn mul_const_rhs() {
325 let v = V5::new([1.0, 2.0, 3.0, 4.0, 5.0]);
326 let result = 2.0 * v;
327 let expected = V5::new([2.0, 4.0, 6.0, 8.0, 10.0]);
328 assert_eq!(
329 &result[..],
330 &expected[..],
331 "\nExpected\n{:?}\nfound\n{:?}",
332 &result[..],
333 &expected[..]
334 );
335 }
336
337 #[test]
338 fn mul_const() {
339 let v = V5::new([1.0, 2.0, 3.0, 4.0, 5.0]);
340 let result = v * 2.0;
341 let expected = V5::new([2.0, 4.0, 6.0, 8.0, 10.0]);
342 assert_eq!(
343 &result[..],
344 &expected[..],
345 "\nExpected\n{:?}\nfound\n{:?}",
346 &result[..],
347 &expected[..]
348 );
349 }
350
351 #[test]
352 fn vector5_mul_matrix5x5_test() {
353 let v1 = V5::new([1.0, 2.0, 3.0, 4.0, 5.0]);
354 let m = M55::new([
355 [10.0, 1.0, 7.0, 1.0, 5.0],
356 [2.0, 4.0, 8.0, 3.0, 2.0],
357 [5.0, 1.0, 2.0, 9.0, 10.0],
358 [6.0, 9.0, 9.0, 7.0, 3.0],
359 [1.0, 8.0, 8.0, 10.0, 5.0],
360 ]);
361 let result = v1 * m;
362 let expected = V5::new([58.0, 88.0, 105.0, 112.0, 76.0]);
363 assert_eq!(
364 &result[..],
365 &expected[..],
366 "\nExpected\n{:?}\nfound\n{:?}",
367 &result[..],
368 &expected[..]
369 );
370 }
371
372 #[test]
373 fn normalize_test() {
374 let result = V5::new([1.0, 1.0, 1.0, 1.0, 1.0]).normalize().unwrap();
375 let expected = V5::new([0.4472135954999579, 0.4472135954999579, 0.4472135954999579, 0.4472135954999579, 0.4472135954999579]);
376 assert_eq!(
377 &result[..],
378 &expected[..],
379 "\nExpected\n{:?}\nfound\n{:?}",
380 &result[..],
381 &expected[..]
382 );
383 }
384
385 #[test]
386 fn sub_assigment_test() {
387 let mut result = V5::new([1.0, 2.0, 3.0, 4.0, 5.0]);
388 let v = V5::new([0.0, 1.0, 2.0, 3.0, 4.0]);
389 let expected = V5::new([1.0, 1.0, 1.0, 1.0, 1.0]);
390 result -= v;
391 assert_eq!(
392 &result[..],
393 &expected[..],
394 "\nExpected\n{:?}\nfound\n{:?}",
395 &result[..],
396 &expected[..]
397 );
398 }
399
400 #[test]
401 fn add_assigment_test() {
402 let mut result = V5::new_from(1.0, 2.0, 3.0, 4.0, 5.0);
403 let v = V5::new_from(0.0, 1.0, 2.0, 3.0, 4.0);
404 let expected = V5::new_from(1.0, 3.0, 5.0, 7.0, 9.0);
405 result += v;
406 assert_eq!(
407 &result[..],
408 &expected[..],
409 "\nExpected\n{:?}\nfound\n{:?}",
410 &result[..],
411 &expected[..]
412 );
413 }
414
415 #[test]
416 fn norm_inf_test() {
417 let v = V5::new_from(1, 2, 30, 91, 10);
418 let result = v.norm_inf();
419 let expected = 91;
420 assert_eq!(result, expected);
421 }
422
423 #[test]
424 fn norm_l_test() {
425 let v = V5::new_from(-1, 1, -1, 1, -1);
426 let result = v.norm_l();
427 let expected = 5;
428 assert_eq!(result, expected);
429 }
430}
431