1use rug::{Float, Integer};
2
3#[derive(Debug, Clone)]
62pub struct Vector<T> {
63 pub vec: Vec<T>, pub norm: Option<T>, }
66
67pub trait GaussReduce<T> {
69 fn reduce(&mut self, v: &Vector<T>) -> bool;
70}
71
72impl std::ops::Mul for &Vector<i64> {
73 type Output = i64;
75 #[inline]
77 fn mul(self, _rhs: &Vector<i64>) -> i64 {
78 assert!(!self.vec.is_empty() && self.vec.len() == _rhs.vec.len());
79 let mut res = self.vec[0] * _rhs.vec[0];
80 for i in 1..self.vec.len() {
81 res += self.vec[i] * _rhs.vec[i];
82 }
83 res
84 }
85}
86
87impl std::ops::Mul for &Vector<f64> {
88 type Output = f64;
90 #[inline]
92 fn mul(self, _rhs: &Vector<f64>) -> f64 {
93 assert!(!self.vec.is_empty() && self.vec.len() == _rhs.vec.len());
94 let mut res: f64 = self.vec[0] * _rhs.vec[0];
95 for i in 1..self.vec.len() {
96 res += self.vec[i] * _rhs.vec[i];
97 }
98 res
99 }
100}
101
102impl std::ops::Mul<&Vector<f64>> for &Vector<i64> {
103 type Output = f64;
105 #[inline]
107 fn mul(self, _rhs: &Vector<f64>) -> f64 {
108 assert!(!self.vec.is_empty() && self.vec.len() == _rhs.vec.len());
109 let mut res: f64 = self.vec[0] as f64 * _rhs.vec[0];
110 for i in 1..self.vec.len() {
111 res += self.vec[i] as f64 * _rhs.vec[i];
112 }
113 res
114 }
115}
116
117impl std::ops::Mul for &Vector<Integer> {
118 type Output = Integer;
120 #[inline]
122 fn mul(self, _rhs: &Vector<Integer>) -> Integer {
123 assert!(!self.vec.is_empty() && self.vec.len() == _rhs.vec.len());
124 let mut res: Integer = Integer::from(&self.vec[0] * &_rhs.vec[0]);
125 for i in 1..self.vec.len() {
126 res += &self.vec[i] * &_rhs.vec[i];
127 }
128 res
129 }
130}
131
132impl std::ops::Mul for &Vector<Float> {
133 type Output = Float;
135 #[inline]
137 fn mul(self, _rhs: &Vector<Float>) -> Float {
138 assert!(!self.vec.is_empty() && self.vec.len() == _rhs.vec.len());
139 let mut res: Float = Float::with_val(self.vec[0].prec(), &self.vec[0] * &_rhs.vec[0]);
140 for i in 1..self.vec.len() {
141 res += &self.vec[i] * &_rhs.vec[i];
142 }
143 res
144 }
145}
146
147impl std::ops::Mul<&Vector<Float>> for &Vector<Integer> {
148 type Output = Float;
150 #[inline]
152 fn mul(self, _rhs: &Vector<Float>) -> Float {
153 assert!(!self.vec.is_empty() && self.vec.len() == _rhs.vec.len());
154 let prec = _rhs.vec[0].prec();
155 let mut res: Float = Float::with_val(prec, &_rhs.vec[0] * &self.vec[0]);
156 for i in 1..self.vec.len() {
157 res += Float::with_val(prec, &self.vec[i] * &_rhs.vec[i]);
158 }
159 res
160 }
161}
162
163impl GaussReduce<i64> for Vector<i64> {
164 fn reduce(&mut self, v: &Vector<i64>) -> bool {
166 let ip = &*self * v;
167 if v.norm.unwrap() < (ip << 1).abs() {
168 let q = (ip as f64 / v.norm.unwrap() as f64).round() as i64;
169 for i in 0..self.vec.len() {
170 self.vec[i] -= q * v.vec[i];
171 }
172 self.norm = Some(&*self * &*self);
173 return true;
174 }
175 false
176 }
177}
178
179impl GaussReduce<Integer> for Vector<Integer> {
180 fn reduce(&mut self, v: &Vector<Integer>) -> bool {
182 let ip = &*self * v;
183 let ip2: Integer = ip.clone() * 2;
184 if v.norm.as_ref().unwrap() < &ip2.abs() {
185 let (q, _) = ip.div_rem_round(v.norm.clone().unwrap());
186 for i in 0..self.vec.len() {
187 self.vec[i] -= &q * &v.vec[i];
188 }
189 self.norm = Some(&*self * &*self);
190 return true;
191 }
192 false
193 }
194}
195
196#[macro_export]
214macro_rules! nvec {
215 ($elem:expr; $n:expr) => (
216 Vector {
217 vec: vec![$elem; $n],
218 norm: None,
219 }
220 );
221 ($($x:expr),*) => (
222 Vector {
223 vec: <[_]>::into_vec(Box::new([$($x),*])),
224 norm: None,
225 }
226 );
227 ($($x:expr,)*) => (nvec![$($x),*])
228}
229
230#[cfg(test)]
231mod tests {
232 use super::*;
233
234 #[test]
235 fn test_prim() {
236 let mut v1 = nvec![1; 5];
237 v1.norm = Some(&v1 * &v1);
238 assert_eq!(v1.norm.unwrap(), 5);
239
240 let mut e0 = nvec![1, 0, 0];
241 let mut e1 = nvec![0, 1, 0];
242 let mut e2 = nvec![0, 0, 1];
243
244 e0.norm = Some(&e0 * &e0);
245 e1.norm = Some(&e0 * &e0);
246 e2.norm = Some(&e0 * &e0);
247 assert!(e0.norm == e1.norm && e1.norm == e2.norm);
248 }
249
250 #[test]
251 fn test_mp() {
252 let mut v1 = nvec![Integer::from(1); 5];
253 v1.norm = Some(&v1 * &v1);
254 assert_eq!(v1.norm.unwrap(), 5);
255
256 let mut e0 = nvec![Integer::from(1), Integer::new(), Integer::new()];
257 let mut e1 = nvec![Integer::new(), Integer::from(1), Integer::new()];
258 let mut e2 = nvec![Integer::new(), Integer::new(), Integer::from(1)];
259
260 e0.norm = Some(&e0 * &e0);
261 e1.norm = Some(&e1 * &e1);
262 e2.norm = Some(&e2 * &e2);
263 assert!(e0.norm == e1.norm && e1.norm == e2.norm);
264 }
265}