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::matrix6x6::M66;
40
41#[derive(Copy, Clone, Debug, PartialEq)]
45pub struct V6<T>([T; 6]);
46
47impl<T> V6<T> {
48 pub const fn new(input: [T; 6]) -> Self {
50 V6(input)
51 }
52
53 pub const fn new_from(num1: T, num2: T, num3: T, num4: T, num5: T, num6: T) -> Self {
55 Self::new([num1, num2, num3, num4, num5, num6])
56 }
57}
58
59impl<T: Num + Copy> V6<T> {
60 pub fn zeros() -> Self {
62 <V6<T> as Zero>::zero()
63 }
64
65 pub fn ones() -> Self {
67 let one = T::one();
68 Self::new([one, one, one, one, one, one])
69 }
70}
71
72impl<T: Num + Copy + core::cmp::PartialOrd> V6<T> {
73 pub fn norm_inf(&self) -> T {
74 norm_inf(&**self)
75 }
76}
77
78impl<T: Num + Copy + Signed + core::iter::Sum> V6<T> {
79 pub fn norm_l(&self) -> T {
80 norm_l(&**self)
81 }
82}
83
84impl<T: Num + Copy + Signed> Neg for V6<T> {
85 type Output = Self;
86
87 #[inline]
88 fn neg(self) -> Self {
89 Self::new_from(-self[0], -self[1], -self[2], -self[3], -self[4], -self[5])
90 }
91}
92
93impl<T: Float> V6<T> {
94 #[inline]
96 pub fn norm2(&self) -> T {
97 T::sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]
98 + self[3] * self[3] + self[4] * self[4] + self[5] * self[5])
99 }
100
101 pub fn normalize(&mut self) -> Result<Self, VectorErrors> {
103 let n = self.norm2();
104 if n != T::zero() {
105 let mut result = Self::zeros();
107 for i in 0..self.len() {
108 result[i] = self[i] / n;
109 }
110 Ok(result)
111 } else {
112 Err(VectorErrors::Norm2IsZero)
113 }
114 }
115}
116
117impl<T: Num + Copy> Mul<T> for V6<T> {
119 type Output = V6<T>;
120
121 #[inline]
122 fn mul(self, rhs: T) -> V6<T> {
123 Self::new_from(self[0] * rhs, self[1] * rhs, self[2] * rhs,
124 self[3] * rhs, self[4] * rhs, self[5] * rhs)
125 }
126}
127
128impl<T: Num + Copy> Div<T> for V6<T> {
130 type Output = Self;
131
132 #[inline]
133 fn div(self, rhs: T) -> Self::Output {
134 Self::new_from(self[0] / rhs, self[1] / rhs, self[2] / rhs,
135 self[3] / rhs, self[4] / rhs, self[5] / rhs)
136 }
137}
138
139impl Mul<V6<f32>> for f32 {
141 type Output = V6<f32>;
142
143 #[inline]
144 fn mul(self, rhs: V6<f32>) -> V6<f32> {
145 V6::new_from(self * rhs[0], self * rhs[1], self * rhs[2],
146 self * rhs[3], self * rhs[4], self * rhs[5])
147 }
148}
149
150impl<T: Num + Copy> Mul for V6<T> {
152 type Output = T;
153
154 #[inline]
155 fn mul(self, rhs: Self) -> T {
156 self[0] * rhs[0] + self[1] * rhs[1] + self[2] * rhs[2] + self[3] * rhs[3]
157 + self[4] * rhs[4] + self[5] * rhs[5]
158 }
159}
160
161impl<T: Num + Copy> Mul<M66<T>> for V6<T> {
163 type Output = V6<T>;
164
165 fn mul(self, rhs: M66<T>) -> V6<T> {
166 let a_00 = rhs[(0, 0)];
167 let a_01 = rhs[(0, 1)];
168 let a_02 = rhs[(0, 2)];
169 let a_03 = rhs[(0, 3)];
170 let a_04 = rhs[(0, 4)];
171 let a_05 = rhs[(0, 5)];
172 let a_10 = rhs[(1, 0)];
173 let a_11 = rhs[(1, 1)];
174 let a_12 = rhs[(1, 2)];
175 let a_13 = rhs[(1, 3)];
176 let a_14 = rhs[(1, 4)];
177 let a_15 = rhs[(1, 5)];
178 let a_20 = rhs[(2, 0)];
179 let a_21 = rhs[(2, 1)];
180 let a_22 = rhs[(2, 2)];
181 let a_23 = rhs[(2, 3)];
182 let a_24 = rhs[(2, 4)];
183 let a_25 = rhs[(2, 5)];
184 let a_30 = rhs[(3, 0)];
185 let a_31 = rhs[(3, 1)];
186 let a_32 = rhs[(3, 2)];
187 let a_33 = rhs[(3, 3)];
188 let a_34 = rhs[(3, 4)];
189 let a_35 = rhs[(3, 5)];
190 let a_40 = rhs[(4, 0)];
191 let a_41 = rhs[(4, 1)];
192 let a_42 = rhs[(4, 2)];
193 let a_43 = rhs[(4, 3)];
194 let a_44 = rhs[(4, 4)];
195 let a_45 = rhs[(4, 5)];
196 let a_50 = rhs[(5, 0)];
197 let a_51 = rhs[(5, 1)];
198 let a_52 = rhs[(5, 2)];
199 let a_53 = rhs[(5, 3)];
200 let a_54 = rhs[(5, 4)];
201 let a_55 = rhs[(5, 5)];
202
203 let v0 = self[0];
204 let v1 = self[1];
205 let v2 = self[2];
206 let v3 = self[3];
207 let v4 = self[4];
208 let v5 = self[5];
209
210 V6::new([
211 a_00 * v0 + a_10 * v1 + a_20 * v2 + a_30 * v3 + a_40 * v4 + a_50 * v5,
212 a_01 * v0 + a_11 * v1 + a_21 * v2 + a_31 * v3 + a_41 * v4 + a_51 * v5,
213 a_02 * v0 + a_12 * v1 + a_22 * v2 + a_32 * v3 + a_42 * v4 + a_52 * v5,
214 a_03 * v0 + a_13 * v1 + a_23 * v2 + a_33 * v3 + a_43 * v4 + a_53 * v5,
215 a_04 * v0 + a_14 * v1 + a_24 * v2 + a_34 * v3 + a_44 * v4 + a_54 * v5,
216 a_05 * v0 + a_15 * v1 + a_25 * v2 + a_35 * v3 + a_45 * v4 + a_55 * v5,
217 ])
218 }
219}
220
221impl<T: Num + Copy> Sub for V6<T> {
223 type Output = Self;
224
225 #[inline]
226 fn sub(self, rhs: Self) -> Self {
227 Self::new_from(self[0] - rhs[0], self[1] - rhs[1], self[2] - rhs[2],
228 self[3] - rhs[3], self[4] - rhs[4], self[5] - rhs[5])
229 }
230}
231
232impl<T: Num + Copy> SubAssign for V6<T> {
234 #[inline]
235 fn sub_assign(&mut self, other: Self) {
236 *self = *self - other
237 }
238}
239
240impl<T: Num + Copy> Add for V6<T> {
242 type Output = Self;
243
244 #[inline]
245 fn add(self, rhs: Self) -> Self {
246 Self::new_from(self[0] + rhs[0], self[1] + rhs[1], self[2] + rhs[2],
247 self[3] + rhs[3], self[4] + rhs[4], self[5] + rhs[5])
248 }
249}
250
251impl<T: Num + Copy> AddAssign for V6<T> {
253 #[inline]
254 fn add_assign(&mut self, other: Self) {
255 *self = *self + other
256 }
257}
258
259impl<T: Num + Copy> Zero for V6<T> {
261 fn zero() -> V6<T> {
262 V6::new([T::zero(); 6])
263 }
264
265 fn is_zero(&self) -> bool {
266 *self == V6::zero()
267 }
268}
269
270impl<T> Deref for V6<T> {
271 type Target = [T; 6];
272 #[inline]
273 fn deref(&self) -> &Self::Target {
274 &self.0
275 }
276}
277
278impl<T> DerefMut for V6<T> {
279 #[inline]
280 fn deref_mut(&mut self) -> &mut Self::Target {
281 &mut self.0
282 }
283}
284
285impl<T> From<[T; 6]> for V6<T> {
286 fn from(data: [T; 6]) -> V6<T> {
287 V6(data)
288 }
289}
290
291impl<T: Num + fmt::Display> fmt::Display for V6<T> {
295 fn fmt(&self, dest: &mut fmt::Formatter) -> fmt::Result {
296 writeln!(dest, "[{0:^3.2} {1:^3.2} {2:^3.2} {3:^3.2} {4:^3.2} {5:^3.2}]",
297 self[0], self[1], self[2], self[3], self[4], self[5])
298 }
299}
300
301#[cfg(test)]
305mod vector6_tests {
306
307 use crate::matrix6x6::M66;
308 use crate::vector6::V6;
309
310 #[test]
311 fn vector6_creation_test() {
312 let v = V6::new([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
313 assert_eq!(v[0], 1.0);
314 assert_eq!(v[1], 2.0);
315 assert_eq!(v[2], 3.0);
316 assert_eq!(v[3], 4.0);
317 assert_eq!(v[4], 5.0);
318 assert_eq!(v[5], 6.0);
319 }
320
321 #[test]
322 fn vector6_add_test() {
323 let v = V6::new([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
324 let result = v + v;
325 let expected = V6::new([2.0, 4.0, 6.0, 8.0, 10.0, 12.0]);
326 assert_eq!(
327 &result[..],
328 &expected[..],
329 "\nExpected\n{:?}\nfound\n{:?}",
330 &result[..],
331 &expected[..]
332 );
333 }
334
335 #[test]
336 fn sub_test() {
337 let v = V6::new([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
338 let result = v - v;
339 let expected = V6::new([0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
340 assert_eq!(
341 &result[..],
342 &expected[..],
343 "\nExpected\n{:?}\nfound\n{:?}",
344 &result[..],
345 &expected[..]
346 );
347 }
348
349 #[test]
350 fn mul_const_rhs() {
351 let v = V6::new([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
352 let result = 2.0 * v;
353 let expected = V6::new([2.0, 4.0, 6.0, 8.0, 10.0, 12.0]);
354 assert_eq!(
355 &result[..],
356 &expected[..],
357 "\nExpected\n{:?}\nfound\n{:?}",
358 &result[..],
359 &expected[..]
360 );
361 }
362
363 #[test]
364 fn mul_const() {
365 let v = V6::new([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
366 let result = v * 2.0;
367 let expected = V6::new([2.0, 4.0, 6.0, 8.0, 10.0, 12.0]);
368 assert_eq!(
369 &result[..],
370 &expected[..],
371 "\nExpected\n{:?}\nfound\n{:?}",
372 &result[..],
373 &expected[..]
374 );
375 }
376
377 #[test]
378 fn product_test() {
379 let v = V6::new([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
380 let result = v * v;
381 let expected = 91.0;
382 assert_eq!(result, expected);
383 }
384 #[test]
385 fn product_matrix6x6_test() {
386 let v = V6::new([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
387
388 let m = M66::new([
389 [0.0, 1.0, 2.0, 3.0, 4.0, 5.0],
390 [6.0, 7.0, 8.0, 9.0, 10.0, 11.0],
391 [12.0, 13.0, 14.0, 15.0, 16.0, 17.0],
392 [18.0, 19.0, 20.0, 21.0, 22.0, 23.0],
393 [24.0, 25.0, 26.0, 27.0, 28.0, 29.0],
394 [30.0, 31.0, 32.0, 33.0, 34.0, 35.0],
395 ]);
396 let result = v * m;
397 let expected = V6::new([420.0, 441.0, 462.0, 483.0, 504.0, 525.0]);
398 assert_eq!(
399 &result[..],
400 &expected[..],
401 "\nExpected\n{:?}\nfound\n{:?}",
402 &result[..],
403 &expected[..]
404 );
405 }
406
407 #[test]
408 fn normalize_test() {
409 let result = V6::new([1.0, 1.0, 1.0, 1.0, 1.0, 1.0]).normalize().unwrap();
410 let expected = V6::new([0.4082482904638631, 0.4082482904638631, 0.4082482904638631, 0.4082482904638631, 0.4082482904638631, 0.4082482904638631]);
411 assert_eq!(
412 &result[..],
413 &expected[..],
414 "\nExpected\n{:?}\nfound\n{:?}",
415 &result[..],
416 &expected[..]
417 );
418 }
419
420 #[test]
421 fn sub_assigment_test() {
422 let mut result = V6::new([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
423 let v = V6::new([0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
424 let expected = V6::new([1.0, 1.0, 1.0, 1.0, 1.0, 1.0]);
425 result -= v;
426 assert_eq!(
427 &result[..],
428 &expected[..],
429 "\nExpected\n{:?}\nfound\n{:?}",
430 &result[..],
431 &expected[..]
432 );
433 }
434
435 #[test]
436 fn add_assigment_test() {
437 let mut result = V6::new_from(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
438 let v = V6::new_from(0.0, 1.0, 2.0, 3.0, 4.0, 5.0);
439 let expected = V6::new_from(1.0, 3.0, 5.0, 7.0, 9.0, 11.0);
440 result += v;
441 assert_eq!(
442 &result[..],
443 &expected[..],
444 "\nExpected\n{:?}\nfound\n{:?}",
445 &result[..],
446 &expected[..]
447 );
448 }
449
450 #[test]
451 fn norm_inf_test() {
452 let v = V6::new_from(1, 10, -10, 10, 100, 3);
453 let result = v.norm_inf();
454 let expected = 100;
455 assert_eq!(result, expected);
456 }
457
458 #[test]
459 fn norm_l_test() {
460 let v = V6::new_from(1, -1, 1, -1, 1, -1);
461 let result = v.norm_l();
462 let expected = 6;
463 assert_eq!(result, expected);
464 }
465}