vigilant_lamp/math/
array_ext.rs

1use crate::extra::array_builder::ArrayBuilder;
2use std::{fmt::{Debug, Display}, ops::{Add, Deref, DerefMut, Div, Mul, Sub}};
3use num::{Num, Float};
4
5// NUMERIC ARRAY EXTENSION
6pub trait NumericArrayTraits<T: Copy + Num, const N: usize> {
7    fn sum (&self) -> T;
8    fn norm2 (&self) -> T;
9    fn norm (&self) -> T where T: Float;
10}
11
12impl<T: Copy + Num, const N: usize> NumericArrayTraits<T,N> for [T;N] {
13    fn sum (&self) -> T {
14        let mut sum = T::zero();
15        for x in self {
16            sum = sum + *x;
17        }
18
19        return sum;
20    }
21
22    fn norm2 (&self) -> T {
23        self.map(|f| f * f).sum()
24    }
25
26    fn norm (&self) -> T where T: Float {
27        if N == 2 {
28            return self[0].hypot(self[1]);
29        }
30
31        self.norm2().sqrt()
32    }
33}
34
35// NUMERIC ARRAY ARITHMETIC EXTENSION
36#[derive(Clone)]
37pub struct NumArray<T: Num, const N: usize> (pub [T;N]);
38
39impl<T: Num + Copy, const N: usize> NumArray<T,N>  {
40    pub fn zero () -> NumArray<T,N> {
41        NumArray([T::zero(); N])
42    }
43
44    pub fn one () -> NumArray<T,N> {
45        NumArray([T::one(); N])
46    }
47
48    pub fn x (&self) -> T {
49        self[0]
50    }
51
52    pub fn y (&self) -> T {
53        self[1]
54    }
55
56    pub fn z (&self) -> T {
57        self[2]
58    }
59
60    pub fn w (&self) -> T {
61        self[3]
62    }
63}
64
65impl<T: Copy + Float, const N: usize> NumArray<T,N> {
66    pub fn unit (self) -> NumArray<T,N> {
67        let norm = &self.norm();
68        return self / *norm;
69    }
70}
71
72impl<T: Num, const N: usize> Deref for NumArray<T,N> {
73    type Target = [T;N];
74
75    fn deref(&self) -> &[T;N] {
76        &self.0
77    }
78}
79
80impl<T: Num, const N: usize> DerefMut for NumArray<T,N> {
81    fn deref_mut(&mut self) -> &mut Self::Target {
82        &mut self.0
83    }
84}
85
86impl<T: Num + Debug, const N: usize> Display for NumArray<T,N>  {
87    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88        write!(f, "{:?}", self)
89    }
90}
91
92impl<T: Num + Debug, const N: usize> Debug for NumArray<T,N> {
93    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94        f.debug_tuple("NumArray").field(&self.0).finish()
95    }
96}
97
98// ADDITION
99impl<T: Copy + Num, const N: usize> Add<NumArray<T,N>> for NumArray<T,N> {
100    type Output = NumArray<T,N>;
101
102    fn add (self, rhs: NumArray<T,N>) -> NumArray<T,N> {
103        let array = <[T;N]>::build(|i| self[i] + rhs[i]);
104        return NumArray(array);
105    }
106}
107
108impl<T: Copy + Num, const N: usize> Add<[T;N]> for NumArray<T,N> {
109    type Output = NumArray<T,N>;
110
111    fn add (self, rhs: [T;N]) -> NumArray<T,N> {
112        let array = <[T;N]>::build(|i| self[i] + rhs[i]);
113        return NumArray(array);
114    }
115}
116
117impl<T: Copy + Num, const N: usize> Add<T> for NumArray<T,N> {
118    type Output = NumArray<T,N>;
119
120    fn add (self, rhs: T) -> NumArray<T,N> {
121        let array = <[T;N]>::build(|i| self[i] + rhs);
122        return NumArray(array);
123    }
124}
125
126// SUBTRACTION
127impl<T: Copy + Num, const N: usize> Sub<NumArray<T,N>> for NumArray<T,N> {
128    type Output = NumArray<T,N>;
129
130    fn sub (self, rhs: NumArray<T,N>) -> NumArray<T,N> {
131        let array = <[T;N]>::build(|i| self[i] - rhs[i]);
132        return NumArray(array);
133    }
134}
135
136impl<T: Copy + Num, const N: usize> Sub<[T;N]> for NumArray<T,N> {
137    type Output = NumArray<T,N>;
138
139    fn sub (self, rhs: [T;N]) -> NumArray<T,N> {
140        let array = <[T;N]>::build(|i| self[i] - rhs[i]);
141        return NumArray(array);
142    }
143}
144
145impl<T: Copy + Num, const N: usize> Sub<T> for NumArray<T,N> {
146    type Output = NumArray<T,N>;
147
148    fn sub (self, rhs: T) -> NumArray<T,N> {
149        let array = <[T;N]>::build(|i| self[i] - rhs);
150        return NumArray(array);
151    }
152}
153
154// MULTIPLICATION
155impl<T: Copy + Num, const N: usize> Mul<NumArray<T,N>> for NumArray<T,N> {
156    type Output = NumArray<T,N>;
157
158    fn mul (self, rhs: NumArray<T,N>) -> NumArray<T,N> {
159        let array = <[T;N]>::build(|i| self[i] * rhs[i]);
160        return NumArray(array);
161    }
162}
163
164impl<T: Copy + Num, const N: usize> Mul<[T;N]> for NumArray<T,N> {
165    type Output = NumArray<T,N>;
166
167    fn mul (self, rhs: [T;N]) -> NumArray<T,N> {
168        let array = <[T;N]>::build(|i| self[i] * rhs[i]);
169        return NumArray(array);
170    }
171}
172
173impl<T: Copy + Num, const N: usize> Mul<T> for NumArray<T,N> {
174    type Output = NumArray<T,N>;
175
176    fn mul (self, rhs: T) -> NumArray<T,N> {
177        let array = <[T;N]>::build(|i| self[i] * rhs);
178        return NumArray(array);
179    }
180}
181
182// DIVISION
183impl<T: Copy + Num, const N: usize> Div<NumArray<T,N>> for NumArray<T,N> {
184    type Output = NumArray<T,N>;
185
186    fn div (self, rhs: NumArray<T,N>) -> NumArray<T,N> {
187        let array = <[T;N]>::build(|i| self[i] / rhs[i]);
188        return NumArray(array);
189    }
190}
191
192impl<T: Copy + Num, const N: usize> Div<[T;N]> for NumArray<T,N> {
193    type Output = NumArray<T,N>;
194
195    fn div (self, rhs: [T;N]) -> NumArray<T,N> {
196        let array = <[T;N]>::build(|i| self[i] / rhs[i]);
197        return NumArray(array);
198    }
199}
200
201impl<T: Copy + Num, const N: usize> Div<T> for NumArray<T,N> {
202    type Output = NumArray<T,N>;
203
204    fn div (self, rhs: T) -> NumArray<T,N> {
205        let array = <[T;N]>::build(|i| self[i] / rhs);
206        return NumArray(array);
207    }
208}
209
210impl<T: Copy + Num, const N: usize> Copy for NumArray<T,N> {}