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