1use super::*;
48
49#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
62pub struct FixedVector<const M: usize, F>(pub [F; M]);
63
64impl<const M: usize, F: Field + Copy> Default for FixedVector<M, F> {
65 fn default() -> Self { Self([F::zero(); M]) }
66}
67
68impl<const M: usize, F: Field + Copy> Add for FixedVector<M, F> {
69 type Output = Self;
70
71 fn add(self, other: Self) -> Self::Output {
72 let mut sum = Self::zero();
73 for i in 0..M {
74 sum.0[i] = self.0[i] + other.0[i];
75 }
76 sum
77 }
78}
79
80impl<const M: usize, F: Field + Copy> AddAssign for FixedVector<M, F> {
81 fn add_assign(&mut self, rhs: Self) { *self = *self + rhs }
82}
83
84impl<const M: usize, F: Field + Copy> Neg for FixedVector<M, F> {
85 type Output = Self;
86
87 fn neg(self) -> Self::Output {
88 let mut neg = Self::zero();
89 for i in 0..M {
90 neg.0[i] = -self.0[i];
91 }
92 neg
93 }
94}
95
96impl<const M: usize, F: Field + Copy> Mul<F> for FixedVector<M, F> {
97 type Output = Self;
98
99 fn mul(self, scalar: F) -> Self::Output {
100 let mut scalar_multiple = Self::zero();
101 for i in 0..M {
102 scalar_multiple.0[i] = scalar * self.0[i];
103 }
104 scalar_multiple
105 }
106}
107
108impl<const M: usize, F: Field + Copy> Sub for FixedVector<M, F> {
109 type Output = Self;
110
111 fn sub(self, other: Self) -> Self::Output { self + -other }
112}
113
114impl<const M: usize, F: Field + Copy> SubAssign for FixedVector<M, F> {
115 fn sub_assign(&mut self, rhs: Self) { *self = *self - rhs }
116}
117
118impl<const M: usize, F: Field + Copy> Additive for FixedVector<M, F> {}
119
120impl<const M: usize, F: Field + Copy> Group for FixedVector<M, F> {
121 fn identity() -> Self { Self::zero() }
122
123 fn inverse(&self) -> Self { -*self }
124}
125
126impl<const M: usize, F: Field + Copy> Zero for FixedVector<M, F> {
127 fn zero() -> Self { Self([F::zero(); M]) }
128
129 fn is_zero(&self) -> bool { self.0.iter().all(|x| *x == F::zero()) }
130}
131
132impl<const M: usize, F: Field + Copy> AbelianGroup for FixedVector<M, F> {}
133
134impl<const M: usize, F: Field + Copy + Mul<Self>> LeftModule for FixedVector<M, F> {
135 type Ring = F;
136}
137
138impl<const M: usize, F: Field + Copy + Mul<Self>> RightModule for FixedVector<M, F> {
139 type Ring = F;
140}
141
142impl<const M: usize, F: Field + Copy + Mul<Self>> TwoSidedModule for FixedVector<M, F> {
143 type Ring = F;
144}
145
146impl<const M: usize, F: Field + Copy + Mul<Self>> VectorSpace for FixedVector<M, F> {}
147
148impl<const M: usize, F: Field> From<[F; M]> for FixedVector<M, F> {
149 fn from(components: [F; M]) -> Self { Self(components) }
150}
151
152impl<const M: usize, F: Field + Copy> From<&[F; M]> for FixedVector<M, F> {
153 fn from(components: &[F; M]) -> Self { Self(*components) }
154}
155
156#[cfg(test)]
157mod tests {
158 use super::*;
159 use crate::fixtures::Mod7;
160
161 #[test]
162 fn test_zero_vector() {
163 let zero_vec: FixedVector<3, Mod7> = FixedVector::zero();
164 assert!(zero_vec.is_zero());
165 assert_eq!(zero_vec.0, [Mod7::zero(), Mod7::zero(), Mod7::zero()]);
166
167 let zero_vec_default: FixedVector<3, Mod7> = FixedVector::default();
168 assert!(zero_vec_default.is_zero());
169 assert_eq!(zero_vec_default.0, [Mod7::zero(), Mod7::zero(), Mod7::zero()]);
170
171 let non_zero_vec = FixedVector::from([Mod7::from(1), Mod7::zero(), Mod7::from(2)]);
172 assert!(!non_zero_vec.is_zero());
173 }
174
175 #[test]
176 fn test_is_zero_all_components_zero() {
177 let vec: FixedVector<2, Mod7> = FixedVector::from([Mod7::zero(), Mod7::zero()]);
178 assert!(vec.is_zero());
179 }
180
181 #[test]
182 fn test_from_array() {
183 let arr = [Mod7::from(1), Mod7::from(2), Mod7::from(3)];
184 let vec: FixedVector<3, Mod7> = FixedVector::from(arr);
185 assert_eq!(vec.0, arr);
186 }
187
188 #[test]
189 fn test_addition() {
190 let vec1 = FixedVector::from([Mod7::from(1), Mod7::from(2)]);
191 let vec2 = FixedVector::from([Mod7::from(3), Mod7::from(4)]);
192 let sum = vec1 + vec2;
193 assert_eq!(sum.0, [Mod7::from(4), Mod7::from(6)]);
194 }
195
196 #[test]
197 fn test_add_assign() {
198 let mut vec1 = FixedVector::from([Mod7::from(1), Mod7::from(2)]);
199 let vec2 = FixedVector::from([Mod7::from(3), Mod7::from(4)]);
200 vec1 += vec2;
201 assert_eq!(vec1.0, [Mod7::from(4), Mod7::from(6)]);
202 }
203
204 #[test]
205 fn test_negation() {
206 let vec = FixedVector::from([Mod7::from(1), Mod7::from(0), Mod7::from(6)]);
207 let neg_vec = -vec;
208 assert_eq!(neg_vec.0, [Mod7::from(6), Mod7::from(0), Mod7::from(1)]);
209 }
210
211 #[test]
212 fn test_scalar_multiplication() {
213 let vec = FixedVector::from([Mod7::from(1), Mod7::from(2), Mod7::from(3)]);
214 let scalar = Mod7::from(2);
215 let product = vec * scalar;
216 assert_eq!(product.0, [Mod7::from(2), Mod7::from(4), Mod7::from(6)]);
217
218 let scalar_zero = Mod7::zero();
219 let product_zero = vec * scalar_zero;
220 assert_eq!(product_zero.0, [Mod7::zero(), Mod7::zero(), Mod7::zero()]);
221 }
222
223 #[test]
224 fn test_subtraction() {
225 let vec1 = FixedVector::from([Mod7::from(5), Mod7::from(3)]);
226 let vec2 = FixedVector::from([Mod7::from(1), Mod7::from(4)]);
227 let diff = vec1 - vec2;
228 assert_eq!(diff.0, [Mod7::from(4), Mod7::from(6)]);
230 }
231
232 #[test]
233 fn test_sub_assign() {
234 let mut vec1 = FixedVector::from([Mod7::from(5), Mod7::from(3)]);
235 let vec2 = FixedVector::from([Mod7::from(1), Mod7::from(4)]);
236 vec1 -= vec2;
237 assert_eq!(vec1.0, [Mod7::from(4), Mod7::from(6)]);
238 }
239}