1use super::MatZq;
12use crate::{
13 integer::{MatZ, Z},
14 integer_mod_q::{Modulus, Zq, fmpz_mod_helpers::length},
15 traits::{MatrixDimensions, MatrixGetEntry, MatrixGetSubmatrix, MatrixSetEntry},
16};
17use flint_sys::{
18 fmpz::{fmpz, fmpz_init_set},
19 fmpz_mat::fmpz_mat_set,
20 fmpz_mod_mat::{
21 fmpz_mod_mat_entry, fmpz_mod_mat_init_set, fmpz_mod_mat_window_clear,
22 fmpz_mod_mat_window_init,
23 },
24};
25use std::mem::MaybeUninit;
26
27impl MatZq {
28 pub fn get_representative_least_nonnegative_residue(&self) -> MatZ {
50 let mut out = MatZ::new(self.get_num_rows(), self.get_num_columns());
51 unsafe { fmpz_mat_set(&mut out.matrix, &self.matrix.mat[0]) };
52 out
53 }
54
55 pub fn get_representative_least_absolute_residue(&self) -> MatZ {
82 let modulus: Z = Z::from(&self.modulus);
83 let modulus_half = modulus.div_floor(2);
84
85 let mut out = MatZ::new(self.get_num_rows(), self.get_num_columns());
86
87 for row in 0..self.get_num_rows() {
88 for column in 0..self.get_num_columns() {
89 let entry: Z = unsafe { self.get_entry_unchecked(row, column) };
90
91 if entry > modulus_half {
93 unsafe { out.set_entry_unchecked(row, column, entry - &modulus) };
94 } else {
95 unsafe { out.set_entry_unchecked(row, column, entry) };
96 }
97 }
98 }
99
100 out
101 }
102
103 pub fn get_mod(&self) -> Modulus {
113 self.modulus.clone()
114 }
115}
116
117impl MatrixGetSubmatrix for MatZq {
118 unsafe fn get_submatrix_unchecked(
152 &self,
153 row_1: i64,
154 row_2: i64,
155 col_1: i64,
156 col_2: i64,
157 ) -> Self {
158 let mut window = MaybeUninit::uninit();
159 unsafe {
161 fmpz_mod_mat_window_init(
162 window.as_mut_ptr(),
163 &self.matrix,
164 row_1,
165 col_1,
166 row_2,
167 col_2,
168 )
169 };
170 let mut window_copy = MaybeUninit::uninit();
171 unsafe {
172 fmpz_mod_mat_init_set(window_copy.as_mut_ptr(), window.as_ptr());
174 fmpz_mod_mat_window_clear(window.as_mut_ptr());
177 }
178 MatZq {
179 matrix: unsafe { window_copy.assume_init() },
180 modulus: self.get_mod(),
181 }
182 }
183}
184
185impl MatZq {
186 pub(crate) fn collect_entries(&self) -> Vec<fmpz> {
202 let mut entries: Vec<fmpz> =
203 Vec::with_capacity((self.get_num_rows() * self.get_num_columns()) as usize);
204
205 for row in 0..self.get_num_rows() {
206 for col in 0..self.get_num_columns() {
207 let entry = unsafe { *fmpz_mod_mat_entry(&self.matrix, row, col) };
209 entries.push(entry);
210 }
211 }
212
213 entries
214 }
215
216 pub(crate) fn collect_lengths(&self) -> Vec<Z> {
229 let entries_fmpz = self.collect_entries();
230
231 let modulus_fmpz = self.matrix.mod_[0];
232 let mut entry_lengths = Vec::with_capacity(entries_fmpz.len());
233 for value in entries_fmpz {
234 entry_lengths.push(length(&value, &modulus_fmpz));
235 }
236
237 entry_lengths
238 }
239}
240
241impl MatrixDimensions for MatZq {
242 fn get_num_rows(&self) -> i64 {
253 self.matrix.mat[0].r
254 }
255
256 fn get_num_columns(&self) -> i64 {
267 self.matrix.mat[0].c
268 }
269}
270
271impl MatrixGetEntry<Z> for MatZq {
272 unsafe fn get_entry_unchecked(&self, row: i64, column: i64) -> Z {
305 let mut out = Z::default();
306 let entry = unsafe { fmpz_mod_mat_entry(&self.matrix, row, column) };
307 unsafe { fmpz_init_set(&mut out.value, entry) };
308
309 out
310 }
311}
312
313impl MatrixGetEntry<Zq> for MatZq {
314 unsafe fn get_entry_unchecked(&self, row: i64, column: i64) -> Zq {
342 let mut out = Zq::from((0, &self.modulus));
343 let entry = unsafe { fmpz_mod_mat_entry(&self.matrix, row, column) };
344 unsafe { fmpz_init_set(&mut out.value.value, entry) };
345
346 out
347 }
348}
349
350#[cfg(test)]
351mod test_get_entry {
352 use super::Zq;
353 use crate::{
354 integer::Z,
355 integer_mod_q::MatZq,
356 traits::{MatrixGetEntry, MatrixSetEntry},
357 };
358 use std::str::FromStr;
359
360 #[test]
362 fn get_edges() {
363 let matrix = MatZq::new(5, 10, u64::MAX);
364
365 let entry_1: Z = matrix.get_entry(0, 0).unwrap();
366 let entry_2: Z = matrix.get_entry(4, 9).unwrap();
367
368 assert_eq!(0, entry_1);
369 assert_eq!(0, entry_2);
370 }
371
372 #[test]
374 fn max_int_positive() {
375 let mut matrix = MatZq::new(5, 10, u64::MAX);
376 let value = Z::from(i64::MAX);
377 matrix.set_entry(0, 0, value).unwrap();
378
379 let entry: Z = matrix.get_entry(0, 0).unwrap();
380
381 assert_eq!(i64::MAX, entry);
382 }
383
384 #[test]
386 fn large_positive() {
387 let mut matrix = MatZq::new(5, 10, u64::MAX);
388 let value = Z::from(u64::MAX - 1);
389 matrix.set_entry(0, 0, value).unwrap();
390
391 let entry: Z = matrix.get_entry(0, 0).unwrap();
392
393 assert_eq!(u64::MAX - 1, entry);
394 }
395
396 #[test]
398 fn max_int_negative() {
399 let mut matrix = MatZq::new(5, 10, u64::MAX);
400 let value = Z::from(-i64::MAX);
401 matrix.set_entry(0, 0, value).unwrap();
402
403 let entry: Z = matrix.get_entry(0, 0).unwrap();
404
405 assert_eq!((u64::MAX as i128 - i64::MAX as i128) as u64, entry);
406 }
407
408 #[test]
410 fn large_negative() {
411 let mut matrix = MatZq::new(5, 10, u64::MAX);
412 let value = Z::from(-i64::MAX - 1);
413 matrix.set_entry(0, 0, value).unwrap();
414
415 let entry: Z = matrix.get_entry(0, 0).unwrap();
416
417 assert_eq!((u64::MAX as i128 - i64::MAX as i128) as u64 - 1, entry);
418 }
419
420 #[test]
422 fn error_wrong_row() {
423 let matrix: MatZq = MatZq::new(5, 10, 7);
424
425 assert!(MatrixGetEntry::<Z>::get_entry(&matrix, 5, 1).is_err());
426 assert!(MatrixGetEntry::<Z>::get_entry(&matrix, -6, 1).is_err());
427 assert!(MatrixGetEntry::<Zq>::get_entry(&matrix, 5, 1).is_err());
428 assert!(MatrixGetEntry::<Zq>::get_entry(&matrix, -6, 1).is_err());
429 }
430
431 #[test]
433 fn error_wrong_column() {
434 let matrix = MatZq::new(5, 10, 7);
435
436 assert!(MatrixGetEntry::<Z>::get_entry(&matrix, 1, 10).is_err());
437 assert!(MatrixGetEntry::<Z>::get_entry(&matrix, 1, -11).is_err());
438 assert!(MatrixGetEntry::<Zq>::get_entry(&matrix, 1, 10).is_err());
439 assert!(MatrixGetEntry::<Zq>::get_entry(&matrix, 1, -11).is_err());
440 }
441
442 #[test]
444 fn negative_indexing() {
445 let matrix = MatZq::from_str("[[1, 2, 3],[4, 5, 6],[7, 8, 9]] mod 10").unwrap();
446
447 let entry_1: Z = matrix.get_entry(-1, -1).unwrap();
448 let entry_2: Z = matrix.get_entry(-1, -2).unwrap();
449 let entry_3: Z = matrix.get_entry(-3, -3).unwrap();
450 let entry_4: Zq = matrix.get_entry(-1, -1).unwrap();
451 let entry_5: Zq = matrix.get_entry(-1, -2).unwrap();
452 let entry_6: Zq = matrix.get_entry(-3, -3).unwrap();
453
454 assert_eq!(9, entry_1);
455 assert_eq!(8, entry_2);
456 assert_eq!(1, entry_3);
457 assert_eq!(Zq::from((9, 10)), entry_4);
458 assert_eq!(Zq::from((8, 10)), entry_5);
459 assert_eq!(Zq::from((1, 10)), entry_6);
460 }
461
462 #[test]
464 fn memory_test() {
465 let mut matrix = MatZq::new(5, 10, u64::MAX);
466 let value = Zq::from((u64::MAX - 1, u64::MAX));
467 matrix.set_entry(1, 1, value).unwrap();
468 let entry: Z = matrix.get_entry(1, 1).unwrap();
469 matrix.set_entry(1, 1, Z::ONE).unwrap();
470
471 assert_eq!(u64::MAX - 1, entry);
472 }
473
474 #[test]
476 fn get_entry_z_memory() {
477 let mut matrix = MatZq::new(5, 10, u64::MAX);
478 matrix.set_entry(1, 1, Z::from(u64::MAX - 3)).unwrap();
479 let _: Z = matrix.get_entry(1, 1).unwrap();
480 matrix.set_entry(2, 2, Z::from(u64::MAX - 10)).unwrap();
481
482 let entry: Z = matrix.get_entry(1, 1).unwrap();
483 let _z = Z::from(u64::MAX);
484
485 assert_eq!(entry, Z::from(u64::MAX - 3));
486 }
487
488 #[test]
490 fn get_entry_zq_memory() {
491 let mut matrix = MatZq::new(5, 10, u64::MAX);
492 matrix.set_entry(1, 1, Z::from(u64::MAX - 3)).unwrap();
493 let _: Zq = matrix.get_entry(1, 1).unwrap();
494 matrix.set_entry(2, 2, Z::from(u64::MAX - 10)).unwrap();
495
496 let entry: Z = matrix.get_entry(1, 1).unwrap();
497 let _z = Z::from(u64::MAX);
498
499 assert_eq!(entry, Z::from(u64::MAX - 3));
500 }
501
502 #[test]
504 fn diff_types() {
505 let matrix = MatZq::new(5, 10, u64::MAX);
506
507 let _: Z = matrix.get_entry(0, 0).unwrap();
508 let _: Zq = matrix.get_entry(0, 0).unwrap();
509 }
510}
511
512#[cfg(test)]
513mod test_get_num {
514 use crate::{integer_mod_q::MatZq, traits::MatrixDimensions};
515
516 #[test]
518 fn num_rows() {
519 let matrix = MatZq::new(5, 10, 7);
520
521 assert_eq!(matrix.get_num_rows(), 5);
522 }
523
524 #[test]
526 fn num_columns() {
527 let matrix = MatZq::new(5, 10, 7);
528
529 assert_eq!(matrix.get_num_columns(), 10);
530 }
531}
532
533#[cfg(test)]
534mod test_get_representative_least_nonnegative_residue {
535 use crate::{
536 integer::Z,
537 integer_mod_q::MatZq,
538 traits::{MatrixDimensions, MatrixGetEntry, MatrixSetEntry},
539 };
540
541 #[test]
543 fn dimensions() {
544 let matzq = MatZq::new(15, 17, 13);
545
546 let matz_1 = matzq.get_representative_least_nonnegative_residue();
547
548 assert_eq!(15, matz_1.get_num_rows());
549 assert_eq!(17, matz_1.get_num_columns());
550 }
551
552 #[test]
554 fn entries_taken_over_correctly() {
555 let mut matzq = MatZq::new(2, 2, u64::MAX);
556 matzq.set_entry(0, 0, u64::MAX - 58).unwrap();
557 matzq.set_entry(0, 1, -1).unwrap();
558
559 let matz_1 = matzq.get_representative_least_nonnegative_residue();
560
561 assert_eq!(Z::from(u64::MAX - 1), matz_1.get_entry(0, 1).unwrap());
562 assert_eq!(Z::from(u64::MAX - 58), matz_1.get_entry(0, 0).unwrap());
563 }
564}
565
566#[cfg(test)]
567mod test_mod {
568 use crate::integer_mod_q::{MatZq, Modulus};
569
570 #[test]
572 fn get_mod() {
573 let matrix = MatZq::new(5, 10, 7);
574
575 assert_eq!(matrix.get_mod(), Modulus::from(7));
576 }
577
578 #[test]
580 fn get_mod_large() {
581 let matrix = MatZq::new(5, 10, u64::MAX);
582
583 assert_eq!(matrix.get_mod(), Modulus::from(u64::MAX));
584 }
585
586 #[test]
588 fn get_mod_memory() {
589 let matrix = MatZq::new(5, 10, u64::MAX);
590 let _ = matrix.get_mod();
591 let _ = Modulus::from(u64::MAX - 1);
592
593 let modulus = matrix.get_mod();
594
595 assert_eq!(modulus, Modulus::from(u64::MAX));
596 }
597}
598
599#[cfg(test)]
600mod test_get_vec {
601 use crate::{integer_mod_q::MatZq, traits::MatrixGetSubmatrix};
602 use std::str::FromStr;
603
604 #[test]
606 fn get_row_works() {
607 let matrix = MatZq::from_str(&format!(
608 "[[0, 0, 0],[4, {}, {}]] mod {}",
609 i64::MAX,
610 i64::MIN,
611 u64::MAX
612 ))
613 .unwrap();
614 let row_1 = matrix.get_row(0).unwrap();
615 let row_2 = matrix.get_row(1).unwrap();
616
617 let cmp_1 = MatZq::from_str(&format!("[[0, 0, 0]] mod {}", u64::MAX)).unwrap();
618 let cmp_2 = MatZq::from_str(&format!(
619 "[[4, {}, {}]] mod {}",
620 i64::MAX,
621 i64::MIN,
622 u64::MAX
623 ))
624 .unwrap();
625
626 assert_eq!(cmp_1, row_1);
627 assert_eq!(cmp_2, row_2);
628 }
629
630 #[test]
632 fn get_row_negative_indexing_works() {
633 let matrix = MatZq::from_str(&format!(
634 "[[0, 0, 0],[42, {}, {}]] mod {}",
635 i64::MAX,
636 u64::MAX - 1,
637 u64::MAX
638 ))
639 .unwrap();
640 let row_1 = matrix.get_row(-2).unwrap();
641 let row_2 = matrix.get_row(-1).unwrap();
642
643 let cmp_1 = MatZq::from_str(&format!("[[0, 0, 0]] mod {}", u64::MAX)).unwrap();
644 let cmp_2 = MatZq::from_str(&format!(
645 "[[42, {}, {}]] mod {}",
646 i64::MAX,
647 u64::MAX - 1,
648 u64::MAX
649 ))
650 .unwrap();
651
652 assert_eq!(cmp_1, row_1);
653 assert_eq!(cmp_2, row_2);
654 }
655
656 #[test]
658 fn get_column_works() {
659 let matrix = MatZq::from_str(&format!(
660 "[[1, 0, 3],[{}, 0, 5],[{}, 0, 7]] mod {}",
661 i64::MAX,
662 i64::MIN,
663 u64::MAX
664 ))
665 .unwrap();
666 let column_1 = matrix.get_column(0).unwrap();
667 let column_2 = matrix.get_column(1).unwrap();
668 let column_3 = matrix.get_column(2).unwrap();
669
670 let cmp_1 = MatZq::from_str(&format!(
671 "[[1],[{}],[{}]] mod {}",
672 i64::MAX,
673 i64::MIN,
674 u64::MAX
675 ))
676 .unwrap();
677 let cmp_2 = MatZq::from_str(&format!("[[0],[0],[0]] mod {}", u64::MAX)).unwrap();
678 let cmp_3 = MatZq::from_str(&format!("[[3],[5],[7]] mod {}", u64::MAX)).unwrap();
679
680 assert_eq!(cmp_1, column_1);
681 assert_eq!(cmp_2, column_2);
682 assert_eq!(cmp_3, column_3);
683 }
684
685 #[test]
687 fn get_column_negative_indexing_works() {
688 let matrix = MatZq::from_str(&format!(
689 "[[42, 0, 42],[{}, 0, 17],[{}, 0, 42]] mod {}",
690 i64::MAX,
691 u64::MAX - 1,
692 u64::MAX
693 ))
694 .unwrap();
695 let column_1 = matrix.get_column(-3).unwrap();
696 let column_2 = matrix.get_column(-2).unwrap();
697 let column_3 = matrix.get_column(-1).unwrap();
698
699 let cmp_1 = MatZq::from_str(&format!(
700 "[[42],[{}],[{}]] mod {}",
701 i64::MAX,
702 u64::MAX - 1,
703 u64::MAX
704 ))
705 .unwrap();
706 let cmp_2 = MatZq::from_str(&format!("[[0],[0],[0]] mod {}", u64::MAX)).unwrap();
707 let cmp_3 = MatZq::from_str(&format!("[[42],[17],[42]] mod {}", u64::MAX)).unwrap();
708
709 assert_eq!(cmp_1, column_1);
710 assert_eq!(cmp_2, column_2);
711 assert_eq!(cmp_3, column_3);
712 }
713
714 #[test]
716 fn wrong_dim_error() {
717 let matrix = MatZq::from_str(&format!(
718 "[[1, 2, 3],[{}, 4, 5],[{}, 6, 7]] mod {}",
719 i64::MAX,
720 i64::MIN,
721 u64::MAX
722 ))
723 .unwrap();
724 let row_1 = matrix.get_row(-4);
725 let row_2 = matrix.get_row(4);
726 let column_1 = matrix.get_column(-4);
727 let column_2 = matrix.get_column(4);
728
729 assert!(row_1.is_err());
730 assert!(row_2.is_err());
731 assert!(column_1.is_err());
732 assert!(column_2.is_err());
733 }
734}
735
736#[cfg(test)]
737mod test_get_submatrix {
738 use crate::{
739 integer::Z,
740 integer_mod_q::MatZq,
741 traits::{MatrixDimensions, MatrixGetSubmatrix},
742 };
743 use std::str::FromStr;
744
745 #[test]
747 fn entire_matrix() {
748 let mat = MatZq::identity(5, 5, i64::MAX);
749
750 let sub_mat = mat.get_submatrix(0, 4, 0, 4).unwrap();
751
752 assert_eq!(mat, sub_mat);
753 }
754
755 #[test]
757 fn matrix_single_entry() {
758 let mat = MatZq::identity(5, 5, i64::MAX);
759
760 let sub_mat = mat.get_submatrix(0, 0, 0, 0).unwrap();
761
762 let cmp_mat = MatZq::identity(1, 1, i64::MAX);
763 assert_eq!(cmp_mat, sub_mat);
764 }
765
766 #[test]
768 fn correct_dimensions() {
769 let mat = MatZq::identity(100, 100, i64::MAX);
770
771 let sub_mat = mat.get_submatrix(1, 37, 0, 29).unwrap();
772
773 assert_eq!(37, sub_mat.get_num_rows());
774 assert_eq!(30, sub_mat.get_num_columns());
775 }
776
777 #[test]
780 fn large_entries() {
781 let mat = MatZq::from_str(&format!(
782 "[[{}, 2, 3],[1, {}, 3]] mod {}",
783 u64::MAX,
784 i64::MIN,
785 u128::MAX
786 ))
787 .unwrap();
788
789 let sub_mat = mat.get_submatrix(0, 1, 0, 1).unwrap();
790
791 let cmp_mat = MatZq::from_str(&format!(
792 "[[{}, 2],[1, {}]] mod {}",
793 u64::MAX,
794 i64::MIN,
795 u128::MAX
796 ))
797 .unwrap();
798 assert_eq!(cmp_mat, sub_mat);
799 }
800
801 #[test]
804 fn invalid_coordinates() {
805 let mat = MatZq::identity(10, 10, u64::MAX);
806
807 assert!(mat.get_submatrix(0, 0, 0, 10).is_err());
808 assert!(mat.get_submatrix(0, 10, 0, 0).is_err());
809 assert!(mat.get_submatrix(0, 0, -11, 0).is_err());
810 assert!(mat.get_submatrix(-11, 0, 0, 0).is_err());
811 }
812
813 #[test]
815 fn negative_indexing() {
816 let matrix = MatZq::identity(3, 3, u64::MAX);
817
818 assert_eq!(matrix, matrix.get_submatrix(0, -1, 0, -1).unwrap());
819 assert_eq!(matrix, matrix.get_submatrix(-3, -1, -3, -1).unwrap());
820 assert_eq!(
821 matrix.get_row(0).unwrap(),
822 matrix.get_submatrix(0, -3, -3, -1).unwrap()
823 );
824 }
825
826 #[test]
828 #[should_panic]
829 fn no_columns() {
830 let mat = MatZq::identity(10, 10, u64::MAX);
831
832 let _ = mat.get_submatrix(0, 0, 6, 5);
833 }
834
835 #[test]
837 #[should_panic]
838 fn no_rows() {
839 let mat = MatZq::identity(10, 10, u64::MAX);
840
841 let _ = mat.get_submatrix(5, 4, 0, 0);
842 }
843
844 #[test]
846 fn availability() {
847 let mat = MatZq::identity(10, 10, u64::MAX);
848
849 let _ = mat.get_submatrix(0_i8, 0_i8, 0_i8, 0_i8);
850 let _ = mat.get_submatrix(0_i16, 0_i16, 0_i16, 0_i16);
851 let _ = mat.get_submatrix(0_i32, 0_i32, 0_i32, 0_i32);
852 let _ = mat.get_submatrix(0_i64, 0_i64, 0_i64, 0_i64);
853 let _ = mat.get_submatrix(0_u8, 0_u8, 0_u8, 0_u8);
854 let _ = mat.get_submatrix(0_u16, 0_i16, 0_u16, 0_u16);
855 let _ = mat.get_submatrix(0_u32, 0_i32, 0_u32, 0_u32);
856 let _ = mat.get_submatrix(0_u64, 0_i64, 0_u64, 0_u64);
857 let _ = mat.get_submatrix(&Z::ZERO, &Z::ZERO, &Z::ZERO, &Z::ZERO);
858 }
859}
860
861#[cfg(test)]
862mod test_collect_entries {
863 use super::MatZq;
864 use std::str::FromStr;
865
866 #[test]
868 fn all_entries_collected() {
869 let mat_1 = MatZq::from_str(&format!(
870 "[[1, 2],[{}, {}],[3, 4]] mod {}",
871 i64::MAX,
872 i64::MIN,
873 u64::MAX
874 ))
875 .unwrap();
876 let mat_2 = MatZq::from_str("[[-1, 2]] mod 2").unwrap();
877
878 let entries_1 = mat_1.collect_entries();
879 let entries_2 = mat_2.collect_entries();
880
881 assert_eq!(entries_1.len(), 6);
882 assert_eq!(entries_1[0].0, 1);
883 assert_eq!(entries_1[1].0, 2);
884 assert!(entries_1[2].0 >= 2_i64.pow(62));
885 assert!(entries_1[3].0 >= 2_i64.pow(62));
886 assert_eq!(entries_1[4].0, 3);
887 assert_eq!(entries_1[5].0, 4);
888
889 assert_eq!(entries_2.len(), 2);
890 assert_eq!(entries_2[0].0, 1);
891 assert_eq!(entries_2[1].0, 0);
892 }
893}
894
895#[cfg(test)]
896mod test_collect_lengths {
897 use super::{MatZq, Z};
898 use std::str::FromStr;
899
900 #[test]
902 fn lengths_correctly_computed() {
903 let mat_1 = MatZq::from_str(&format!(
904 "[[1, 2],[{}, {}],[3, 4]] mod {}",
905 i64::MAX - 2,
906 i64::MIN,
907 i64::MAX - 1
908 ))
909 .unwrap();
910 let mat_2 = MatZq::from_str("[[-1, 2]] mod 2").unwrap();
911
912 let lengths_1 = mat_1.collect_lengths();
913 let lengths_2 = mat_2.collect_lengths();
914
915 assert_eq!(lengths_1.len(), 6);
916 assert_eq!(lengths_1[0], Z::ONE);
917 assert_eq!(lengths_1[1], Z::from(2));
918 assert_eq!(lengths_1[2], Z::ONE);
919 assert_eq!(lengths_1[3], Z::from(2));
920 assert_eq!(lengths_1[4], Z::from(3));
921 assert_eq!(lengths_1[5], Z::from(4));
922
923 assert_eq!(lengths_2.len(), 2);
924 assert_eq!(lengths_2[0], Z::ONE);
925 assert_eq!(lengths_2[1], Z::ZERO);
926 }
927}
928
929#[cfg(test)]
930mod test_get_representative_least_absolute_residue {
931 use super::*;
932 use std::str::FromStr;
933
934 #[test]
936 fn large_modulus() {
937 let mat_zq = MatZq::from_str(&format!("[[1,2],[-1,-2]] mod {}", u64::MAX)).unwrap();
938
939 let mat_z = mat_zq.get_representative_least_absolute_residue();
940
941 let mat_cmp = MatZ::from_str("[[1,2],[-1,-2]]").unwrap();
942 assert_eq!(mat_z.to_string(), mat_cmp.to_string());
943 }
944
945 #[test]
947 fn even_modulus() {
948 let mat_zq = MatZq::from_str("[[0,1,2,3,4,5,6,7,8,9,10]] mod 10").unwrap();
949
950 let mat_z = mat_zq.get_representative_least_absolute_residue();
951
952 let mat_cmp = MatZ::from_str("[[0,1,2,3,4,5,-4,-3,-2,-1,0]]").unwrap();
953 assert_eq!(mat_z.to_string(), mat_cmp.to_string());
954 }
955
956 #[test]
958 fn uneven_modulus() {
959 let mat_zq = MatZq::from_str("[[0,1,2,3,4,5,6,7,8,9,10,11]] mod 11").unwrap();
960
961 let mat_z = mat_zq.get_representative_least_absolute_residue();
962
963 let mat_cmp = MatZ::from_str("[[0,1,2,3,4,5,-5,-4,-3,-2,-1,0]]").unwrap();
964 assert_eq!(mat_z.to_string(), mat_cmp.to_string());
965 }
966}