1use crate::extra::array_builder::ArrayBuilder;
2use std::{fmt::{Debug, Display}, ops::{Add, Deref, DerefMut, Div, Mul, Sub}};
3use num::{Num, Float};
4
5pub 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#[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
98impl<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
126impl<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
154impl<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
182impl<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> {}