qfall_math/utils/factorization/
from.rs1use super::Factorization;
12use crate::integer::Z;
13use flint_sys::fmpz_factor::{_fmpz_factor_append, fmpz_factor_get_fmpz};
14
15impl<Integer: Into<Z>> From<Integer> for Factorization {
16 fn from(factor: Integer) -> Self {
30 let factor = factor.into();
31 let mut out = Self::default();
32 unsafe { _fmpz_factor_append(&mut out.factors, &factor.value, 1) };
33 out
34 }
35}
36
37impl<Integer: Into<Z>> From<(Integer, Integer)> for Factorization {
38 fn from(factors: (Integer, Integer)) -> Self {
54 let factor_1 = factors.0.into();
55 let factor_2 = factors.1.into();
56 let mut out = Self::default();
57 unsafe { _fmpz_factor_append(&mut out.factors, &factor_1.value, 1) };
58 unsafe { _fmpz_factor_append(&mut out.factors, &factor_2.value, 1) };
59 out
60 }
61}
62
63impl From<&Factorization> for Vec<(Z, u64)> {
64 fn from(factors: &Factorization) -> Self {
82 let mut out = Vec::with_capacity(factors.factors.num as usize + 1);
83
84 if factors.factors.sign == -1 {
85 out.push((Z::MINUS_ONE, 1));
86 }
87
88 for i in 0..factors.factors.num {
89 let mut factor = Z::default();
90 unsafe { fmpz_factor_get_fmpz(&mut factor.value, &factors.factors, i) };
91
92 let exp = unsafe { *factors.factors.exp.offset(i.try_into().unwrap()) };
93 out.push((factor, exp));
94 }
95
96 if out.is_empty() && factors.factors.sign == 1 {
97 out.push((Z::ONE, 1));
98 }
99 out
100 }
101}
102
103impl From<&Vec<(Z, u64)>> for Factorization {
104 fn from(factors: &Vec<(Z, u64)>) -> Self {
123 let mut out = Factorization::default();
124
125 for (factor, exponent) in factors {
126 unsafe { _fmpz_factor_append(&mut out.factors, &factor.value, *exponent) };
127 }
128 out
129 }
130}
131
132#[cfg(test)]
133mod tests_from_one {
134 use crate::utils::Factorization;
135
136 #[test]
138 fn from_one() {
139 let fac = Factorization::from(8);
140
141 assert_eq!("[(8, 1)]", fac.to_string());
142 }
143
144 #[test]
146 fn from_one_large() {
147 let fac = Factorization::from(i64::MAX);
148
149 assert_eq!(format!("[({}, 1)]", i64::MAX), fac.to_string());
150 }
151
152 #[test]
154 fn from_one_negative() {
155 let fac = Factorization::from(-8);
156
157 assert_eq!("[(-8, 1)]", fac.to_string());
158 }
159
160 #[test]
162 fn from_one_one() {
163 let fac = Factorization::from(1);
164
165 assert_eq!("[(1, 1)]", fac.to_string());
166 }
167
168 #[test]
170 fn from_one_zero() {
171 let fac = Factorization::from(0);
172
173 assert_eq!("[(0, 1)]", fac.to_string());
174 }
175}
176
177#[cfg(test)]
178mod tests_from_two {
179 use crate::utils::Factorization;
180
181 #[test]
184 fn from_two() {
185 let fac = Factorization::from((8, 3));
186
187 assert_eq!("[(8, 1), (3, 1)]", fac.to_string());
188 }
189
190 #[test]
192 fn from_two_large() {
193 let fac = Factorization::from((i64::MAX, 3));
194
195 assert_eq!(format!("[({}, 1), (3, 1)]", i64::MAX), fac.to_string());
196 }
197
198 #[test]
200 fn from_two_negative() {
201 let fac = Factorization::from((-8, -3));
202
203 assert_eq!("[(-8, 1), (-3, 1)]", fac.to_string());
204 }
205
206 #[test]
208 fn from_two_zero_one() {
209 let fac = Factorization::from((0, 1));
210
211 assert_eq!("[(0, 1), (1, 1)]", fac.to_string());
212 }
213
214 #[test]
216 fn from_two_unrefined() {
217 let fac = Factorization::from((8, 8));
218
219 assert_eq!("[(8, 1), (8, 1)]", fac.to_string());
220 }
221}
222
223#[cfg(test)]
224mod tests_from_factorization_for_vector {
225 use crate::{integer::Z, utils::Factorization};
226
227 #[test]
229 fn from_factorization() {
230 let fac = Factorization::from((4, 3));
231 let vec = Vec::<(Z, u64)>::from(&fac);
232
233 assert_eq!(Z::from(4), vec[0].0);
234 assert_eq!(Z::from(3), vec[1].0);
235
236 assert_eq!(1, vec[0].1);
237 assert_eq!(1, vec[1].1);
238 }
239
240 #[test]
243 fn from_factorization_large() {
244 let fac = Factorization::from((i64::MAX, 3));
245 let vec = Vec::<(Z, u64)>::from(&fac);
246
247 assert_eq!(Z::from(i64::MAX), vec[0].0);
248 assert_eq!(Z::from(3), vec[1].0);
249
250 assert_eq!(1, vec[0].1);
251 assert_eq!(1, vec[1].1);
252 }
253
254 #[test]
257 fn from_factorization_negative() {
258 let fac = Factorization::from((-i64::MAX, 3));
259 let vec = Vec::<(Z, u64)>::from(&fac);
260
261 assert_eq!(Z::from(-i64::MAX), vec[0].0);
262 assert_eq!(Z::from(3), vec[1].0);
263
264 assert_eq!(1, vec[0].1);
265 assert_eq!(1, vec[1].1);
266 }
267
268 #[test]
270 fn from_factorization_one_entry() {
271 let fac = Factorization::from(4);
272 let vec = Vec::<(Z, u64)>::from(&fac);
273
274 assert_eq!(Z::from(4), vec[0].0);
275
276 assert_eq!(1, vec[0].1);
277 }
278
279 #[test]
281 fn from_factorization_refined() {
282 let mut fac = Factorization::from((-1200, 20));
283 fac.refine();
284
285 let vec = Vec::<(Z, u64)>::from(&fac);
286
287 assert_eq!(Z::MINUS_ONE, vec[0].0);
288 assert_eq!(Z::from(3), vec[1].0);
289 assert_eq!(Z::from(20), vec[2].0);
290
291 assert_eq!(1, vec[0].1);
292 assert_eq!(1, vec[1].1);
293 assert_eq!(3, vec[2].1);
294 }
295
296 #[test]
298 fn from_factorization_one() {
299 let mut fac = Factorization::default();
300 fac.refine();
301
302 let vec = Vec::<(Z, u64)>::from(&fac);
303
304 assert_eq!(Z::ONE, vec[0].0);
305 assert_eq!(1, vec[0].1);
306 }
307
308 #[test]
310 fn from_factorization_minus_one() {
311 let mut fac = Factorization::from(-1);
312 fac.refine();
313
314 let vec = Vec::<(Z, u64)>::from(&fac);
315
316 assert_eq!(Z::MINUS_ONE, vec[0].0);
317 assert_eq!(1, vec[0].1);
318 }
319
320 #[test]
322 fn from_factorization_zero() {
323 let mut fac_1 = Factorization::from(0);
324 let mut fac_2 = Factorization::from((0, 1));
325 fac_1.refine();
326 fac_2.refine();
327
328 let vec_1 = Vec::<(Z, u64)>::from(&fac_1);
329 let vec_2 = Vec::<(Z, u64)>::from(&fac_2);
330
331 assert!(vec_1.is_empty());
332 assert!(vec_2.is_empty());
333 }
334
335 #[test]
337 fn doc_test() {
338 let fac = Factorization::from(10);
339 let _vec = Vec::<(Z, u64)>::from(&fac);
340 }
341}
342
343#[cfg(test)]
344mod tests_from_vector_for_factorization {
345 use crate::{integer::Z, utils::Factorization};
346
347 #[test]
349 fn from_vector() {
350 let vec: Vec<(Z, u64)> = vec![(Z::from(3), 2), (Z::from(8), 2)];
351 let fac = Factorization::from(&vec);
352
353 assert_eq!("[(3, 2), (8, 2)]", fac.to_string());
354 }
355
356 #[test]
359 fn from_vector_large() {
360 let vec: Vec<(Z, u64)> = vec![(Z::from(i64::MAX), 2), (Z::from(8), 2)];
361 let fac = Factorization::from(&vec);
362
363 assert_eq!(format!("[({}, 2), (8, 2)]", i64::MAX), fac.to_string());
364 }
365
366 #[test]
369 fn from_vector_negative() {
370 let vec: Vec<(Z, u64)> = vec![(Z::from(-i64::MAX), 2), (Z::from(-8), 2)];
371 let fac = Factorization::from(&vec);
372
373 assert_eq!(format!("[(-{}, 2), (-8, 2)]", i64::MAX), fac.to_string());
374 }
375
376 #[test]
378 fn from_vector_one_entry() {
379 let vec: Vec<(Z, u64)> = vec![(Z::from(3), 2)];
380 let fac = Factorization::from(&vec);
381
382 assert_eq!("[(3, 2)]", fac.to_string());
383 }
384
385 #[test]
387 fn from_vector_no_entry() {
388 let vec: Vec<(Z, u64)> = vec![];
389 let fac = Factorization::from(&vec);
390
391 assert_eq!("[(1, 1)]", fac.to_string());
392 }
393
394 #[test]
396 fn from_vector_zero() {
397 let vec: Vec<(Z, u64)> = vec![(Z::ZERO, 1)];
398 let fac = Factorization::from(&vec);
399
400 assert_eq!("[(0, 1)]", fac.to_string());
401 }
402}