1use super::MatPolynomialRingZq;
12use crate::{
13 integer::{MatPolyOverZ, PolyOverZ},
14 integer_mod_q::{ModulusPolynomialRingZq, PolynomialRingZq},
15 traits::{MatrixDimensions, MatrixGetEntry, MatrixGetSubmatrix, MatrixSetEntry},
16};
17use flint3_sys::{fmpz_poly_mat_entry, fmpz_poly_struct};
18
19impl MatPolynomialRingZq {
20 pub fn get_mod(&self) -> ModulusPolynomialRingZq {
35 self.modulus.clone()
36 }
37}
38
39impl MatPolynomialRingZq {
40 pub fn get_representative_least_absolute_residue(&self) -> MatPolyOverZ {
64 let mut out = MatPolyOverZ::new(self.get_num_rows(), self.get_num_columns());
65 for row in 0..self.get_num_rows() {
66 for col in 0..self.get_num_columns() {
67 let poly: PolynomialRingZq = unsafe { self.get_entry_unchecked(row, col) };
68 let lar_poly = poly.get_representative_least_absolute_residue();
69 unsafe { out.set_entry_unchecked(row, col, lar_poly) };
70 }
71 }
72 out
73 }
74
75 pub fn get_representative_least_nonnegative_residue(&self) -> MatPolyOverZ {
99 self.matrix.clone()
100 }
101}
102
103impl MatrixDimensions for MatPolynomialRingZq {
104 fn get_num_rows(&self) -> i64 {
120 self.matrix.get_num_rows()
121 }
122
123 fn get_num_columns(&self) -> i64 {
139 self.matrix.get_num_columns()
140 }
141}
142
143impl MatrixGetEntry<PolyOverZ> for MatPolynomialRingZq {
144 unsafe fn get_entry_unchecked(&self, row: i64, column: i64) -> PolyOverZ {
178 unsafe { self.matrix.get_entry_unchecked(row, column) }
179 }
180}
181
182impl MatrixGetEntry<PolynomialRingZq> for MatPolynomialRingZq {
183 unsafe fn get_entry_unchecked(&self, row: i64, column: i64) -> PolynomialRingZq {
217 PolynomialRingZq {
218 poly: unsafe { self.matrix.get_entry_unchecked(row, column) },
219 modulus: self.get_mod(),
220 }
221 }
222}
223
224impl MatrixGetSubmatrix for MatPolynomialRingZq {
225 unsafe fn get_submatrix_unchecked(
263 &self,
264 row_1: i64,
265 row_2: i64,
266 col_1: i64,
267 col_2: i64,
268 ) -> Self {
269 MatPolynomialRingZq {
270 matrix: unsafe {
271 self.matrix
272 .get_submatrix_unchecked(row_1, row_2, col_1, col_2)
273 },
274 modulus: self.get_mod(),
275 }
276 }
277}
278
279impl MatPolynomialRingZq {
280 #[allow(dead_code)]
299 pub(crate) fn collect_entries<'a>(&self) -> Vec<&'a fmpz_poly_struct> {
300 let mut entries: Vec<&'a fmpz_poly_struct> =
301 Vec::with_capacity((self.get_num_rows() * self.get_num_columns()) as usize);
302
303 for row in 0..self.get_num_rows() {
304 for col in 0..self.get_num_columns() {
305 unsafe {
307 let entry_ptr = fmpz_poly_mat_entry(&self.matrix.matrix, row, col);
308 let entry_ref: &'a fmpz_poly_struct = &*entry_ptr;
309 entries.push(entry_ref);
310 }
311 }
313 }
314
315 entries
316 }
317}
318
319#[cfg(test)]
320mod test_get_entry {
321 use crate::integer::{MatPolyOverZ, PolyOverZ};
322 use crate::integer_mod_q::{MatPolynomialRingZq, ModulusPolynomialRingZq, PolynomialRingZq};
323 use crate::traits::MatrixGetEntry;
324 use std::str::FromStr;
325
326 const LARGE_PRIME: u64 = u64::MAX - 58;
327
328 #[test]
330 fn get_edges() {
331 let modulus = ModulusPolynomialRingZq::from_str("2 42 1 mod 89").unwrap();
332 let matrix = MatPolynomialRingZq::new(5, 10, &modulus);
333
334 let entry_1: PolyOverZ = matrix.get_entry(0, 0).unwrap();
335 let entry_2: PolyOverZ = matrix.get_entry(4, 9).unwrap();
336
337 assert_eq!(PolyOverZ::default(), entry_1);
338 assert_eq!(PolyOverZ::default(), entry_2);
339 }
340
341 #[test]
343 fn large_positive() {
344 let modulus =
345 ModulusPolynomialRingZq::from_str(&format!("5 42 17 1 2 1 mod {LARGE_PRIME}"))
346 .unwrap();
347 let poly_mat =
348 MatPolyOverZ::from_str(&format!("[[4 1 0 {} 1, 1 42],[0, 2 1 2]]", i64::MAX))
349 .unwrap();
350 let matrix = MatPolynomialRingZq::from((&poly_mat, &modulus));
351
352 let entry: PolyOverZ = matrix.get_entry(0, 0).unwrap();
353
354 assert_eq!(
355 PolyOverZ::from_str(&format!("4 1 0 {} 1", i64::MAX)).unwrap(),
356 entry
357 );
358 }
359
360 #[test]
362 fn error_wrong_row() {
363 let modulus =
364 ModulusPolynomialRingZq::from_str(&format!("5 42 17 1 2 1 mod {LARGE_PRIME}"))
365 .unwrap();
366 let matrix = MatPolynomialRingZq::new(5, 10, &modulus);
367
368 assert!(MatrixGetEntry::<PolynomialRingZq>::get_entry(&matrix, 5, 1).is_err());
369 assert!(MatrixGetEntry::<PolynomialRingZq>::get_entry(&matrix, -6, 1).is_err());
370 assert!(MatrixGetEntry::<PolyOverZ>::get_entry(&matrix, 5, 1).is_err());
371 assert!(MatrixGetEntry::<PolyOverZ>::get_entry(&matrix, -6, 1).is_err());
372 }
373
374 #[test]
376 fn error_wrong_column() {
377 let modulus =
378 ModulusPolynomialRingZq::from_str(&format!("5 42 17 1 2 1 mod {LARGE_PRIME}"))
379 .unwrap();
380 let matrix = MatPolynomialRingZq::new(5, 10, &modulus);
381
382 assert!(MatrixGetEntry::<PolynomialRingZq>::get_entry(&matrix, 1, 10).is_err());
383 assert!(MatrixGetEntry::<PolynomialRingZq>::get_entry(&matrix, 1, -11).is_err());
384 assert!(MatrixGetEntry::<PolyOverZ>::get_entry(&matrix, 1, 10).is_err());
385 assert!(MatrixGetEntry::<PolyOverZ>::get_entry(&matrix, 1, -11).is_err());
386 }
387
388 #[test]
390 fn diff_types() {
391 let modulus =
392 ModulusPolynomialRingZq::from_str(&format!("5 42 17 1 2 1 mod {LARGE_PRIME}"))
393 .unwrap();
394 let matrix = MatPolynomialRingZq::new(5, 10, &modulus);
395
396 let _: PolyOverZ = matrix.get_entry(0, 0).unwrap();
397 let _: PolynomialRingZq = matrix.get_entry(0, 0).unwrap();
398 }
399}
400
401#[cfg(test)]
402mod test_get_num {
403 use crate::{
404 integer_mod_q::{MatPolynomialRingZq, ModulusPolynomialRingZq},
405 traits::MatrixDimensions,
406 };
407 use std::str::FromStr;
408
409 #[test]
411 fn num_rows() {
412 let modulus = ModulusPolynomialRingZq::from_str("2 42 1 mod 89").unwrap();
413 let matrix = MatPolynomialRingZq::new(5, 10, &modulus);
414
415 assert_eq!(matrix.get_num_rows(), 5);
416 }
417
418 #[test]
420 fn num_columns() {
421 let modulus = ModulusPolynomialRingZq::from_str("2 42 1 mod 89").unwrap();
422 let matrix = MatPolynomialRingZq::new(5, 10, &modulus);
423
424 assert_eq!(matrix.get_num_columns(), 10);
425 }
426}
427
428#[cfg(test)]
429mod test_mod {
430 use crate::{
431 integer::MatPolyOverZ,
432 integer_mod_q::{MatPolynomialRingZq, ModulusPolynomialRingZq},
433 };
434 use std::str::FromStr;
435
436 const LARGE_PRIME: u64 = u64::MAX - 58;
437
438 #[test]
440 fn get_mod() {
441 let modulus = ModulusPolynomialRingZq::from_str("2 42 1 mod 89").unwrap();
442 let poly_mat = MatPolyOverZ::from_str("[[4 -1 0 1 1, 1 42],[0, 2 1 2]]").unwrap();
443 let matrix = MatPolynomialRingZq::from((&poly_mat, &modulus));
444
445 assert_eq!(
446 matrix.get_mod(),
447 ModulusPolynomialRingZq::from_str("2 42 1 mod 89").unwrap()
448 );
449 }
450
451 #[test]
453 fn get_mod_large() {
454 let modulus =
455 ModulusPolynomialRingZq::from_str(&format!("2 42 1 mod {LARGE_PRIME}")).unwrap();
456 let poly_mat = MatPolyOverZ::from_str("[[4 -1 0 1 1, 1 42],[0, 2 1 2]]").unwrap();
457 let matrix = MatPolynomialRingZq::from((&poly_mat, &modulus));
458
459 assert_eq!(
460 matrix.get_mod(),
461 ModulusPolynomialRingZq::from_str(&format!("2 42 1 mod {LARGE_PRIME}")).unwrap()
462 );
463 }
464
465 #[test]
467 fn get_mod_memory() {
468 let modulus =
469 ModulusPolynomialRingZq::from_str(&format!("2 42 1 mod {LARGE_PRIME}")).unwrap();
470 let poly_mat = MatPolyOverZ::from_str("[[4 -1 0 1 1, 1 42],[0, 2 1 2]]").unwrap();
471 let matrix = MatPolynomialRingZq::from((&poly_mat, &modulus));
472 let _ = matrix.get_mod();
473 let _ = ModulusPolynomialRingZq::from_str(&format!("2 42 1 mod {LARGE_PRIME}")).unwrap();
474
475 let modulus = matrix.get_mod();
476
477 assert_eq!(
478 modulus,
479 ModulusPolynomialRingZq::from_str(&format!("2 42 1 mod {LARGE_PRIME}")).unwrap()
480 );
481 }
482}
483
484#[cfg(test)]
485mod test_get_representative_least_absolute_residue {
486 use crate::{integer::MatPolyOverZ, integer_mod_q::MatPolynomialRingZq};
487 use std::str::FromStr;
488
489 #[test]
491 fn large_numbers() {
492 let poly_ring = MatPolynomialRingZq::from_str(&format!(
493 "[[2 {} {}]] / 4 1 0 0 1 mod {}",
494 i64::MAX,
495 u64::MAX - 1,
496 u64::MAX
497 ))
498 .unwrap();
499
500 let lar_mat = poly_ring.get_representative_least_absolute_residue();
501
502 let cmp_mat = MatPolyOverZ::from_str(&format!("[[2 {} -1]]", i64::MAX)).unwrap();
503 assert_eq!(cmp_mat, lar_mat);
504 }
505
506 #[test]
508 fn special_numbers() {
509 let mat = MatPolynomialRingZq::from_str("[[3 10 0 11]] / 4 1 0 0 1 mod 21").unwrap();
510
511 let lar_mat = mat.get_representative_least_absolute_residue();
512
513 let cmp_mat = MatPolyOverZ::from_str("[[3 10 0 -10]]").unwrap();
514 assert_eq!(cmp_mat, lar_mat);
515 }
516
517 fn coefficients_and_representatives(modulus: i64) -> (String, String) {
520 let coefficients: Vec<String> = (0..modulus).map(|value| value.to_string()).collect();
521 let representatives: Vec<String> = (0..modulus)
522 .map(|value| {
523 if value > modulus / 2 {
524 value - modulus
525 } else {
526 value
527 }
528 .to_string()
529 })
530 .collect();
531 (coefficients.join(" "), representatives.join(" "))
532 }
533
534 #[test]
537 fn full_range() {
538 for modulus in [10, 11] {
539 let (coefficients, representatives) = coefficients_and_representatives(modulus);
540 let mat = MatPolynomialRingZq::from_str(&format!(
542 "[[{modulus} {coefficients}]] / {} 1 {}1 mod {modulus}",
543 modulus + 1,
544 "0 ".repeat(modulus as usize - 1)
545 ))
546 .unwrap();
547
548 let lar_mat = mat.get_representative_least_absolute_residue();
549
550 let cmp_mat =
551 MatPolyOverZ::from_str(&format!("[[{modulus} {representatives}]]")).unwrap();
552 assert_eq!(cmp_mat, lar_mat);
553 }
554 }
555}
556
557#[cfg(test)]
558mod test_get_representative_least_nonnegative_residue {
559 use crate::{
560 integer::MatPolyOverZ,
561 integer_mod_q::{MatPolynomialRingZq, ModulusPolynomialRingZq},
562 };
563 use std::str::FromStr;
564
565 const LARGE_PRIME: u64 = u64::MAX - 58;
566
567 #[test]
569 fn get_representative_least_nonnegative_residue_large_entry_and_modulus() {
570 let modulus =
571 ModulusPolynomialRingZq::from_str(&format!("5 42 0 0 0 1 mod {LARGE_PRIME}")).unwrap();
572 let poly_mat = MatPolyOverZ::from_str("[[4 1 0 0 1, 1 42],[0, 1 -1]]").unwrap();
573 let matrix = MatPolynomialRingZq::from((&poly_mat, &modulus));
574
575 assert_eq!(
576 MatPolyOverZ::from_str(&format!(
577 "[[4 1 0 0 1, 1 42],[0, 1 {}]]",
578 LARGE_PRIME - 1
579 ))
580 .unwrap(),
581 matrix.get_representative_least_nonnegative_residue()
582 )
583 }
584}
585
586#[cfg(test)]
587mod test_get_vec {
588 use crate::{
589 integer::MatPolyOverZ,
590 integer_mod_q::{MatPolynomialRingZq, ModulusPolynomialRingZq},
591 traits::MatrixGetSubmatrix,
592 };
593 use std::str::FromStr;
594
595 #[test]
597 fn get_row_works() {
598 let matrix = MatPolyOverZ::from_str(&format!(
599 "[[0, 0, 0],[1 42, 1 {}, 1 {}]]",
600 i64::MAX,
601 i64::MIN
602 ))
603 .unwrap();
604 let modulus =
605 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
606 let matrix = MatPolynomialRingZq::from((&matrix, &modulus));
607
608 let row_1 = matrix.get_row(0).unwrap();
609 let row_2 = matrix.get_row(1).unwrap();
610
611 let cmp_1 = MatPolyOverZ::from_str("[[0, 0, 0]]").unwrap();
612 let cmp_2 = MatPolyOverZ::from_str(&format!("[[1 42, 1 {}, 1 {}]]", i64::MAX, i64::MIN))
613 .unwrap();
614 let cmp_1 = MatPolynomialRingZq::from((&cmp_1, &modulus));
615 let cmp_2 = MatPolynomialRingZq::from((&cmp_2, &modulus));
616 assert_eq!(cmp_1, row_1);
617 assert_eq!(cmp_2, row_2);
618 }
619
620 #[test]
622 fn get_row_negative_indexing_works() {
623 let matrix = MatPolyOverZ::from_str(&format!(
624 "[[0, 0, 0],[1 42, 1 {}, 1 {}]]",
625 i64::MAX,
626 u64::MAX - 1
627 ))
628 .unwrap();
629 let modulus =
630 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
631 let matrix = MatPolynomialRingZq::from((&matrix, &modulus));
632 let row_1 = matrix.get_row(-2).unwrap();
633 let row_2 = matrix.get_row(-1).unwrap();
634
635 let cmp_1 = MatPolyOverZ::from_str("[[0, 0, 0]]").unwrap();
636 let cmp_2 =
637 MatPolyOverZ::from_str(&format!("[[1 42, 1 {}, 1 {}]]", i64::MAX, u64::MAX - 1))
638 .unwrap();
639
640 assert_eq!(cmp_1, row_1.matrix);
641 assert_eq!(cmp_2, row_2.matrix);
642 }
643
644 #[test]
646 fn get_column_works() {
647 let matrix = MatPolyOverZ::from_str(&format!(
648 "[[1 42, 0, 2 17 42],[1 {}, 0, 2 17 42],[1 {}, 0, 2 17 42]]",
649 i64::MAX,
650 i64::MIN
651 ))
652 .unwrap();
653 let modulus =
654 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
655 let matrix = MatPolynomialRingZq::from((&matrix, &modulus));
656
657 let column_1 = matrix.get_column(0).unwrap();
658 let column_2 = matrix.get_column(1).unwrap();
659 let column_3 = matrix.get_column(2).unwrap();
660
661 let cmp_1 =
662 MatPolyOverZ::from_str(&format!("[[1 42],[1 {}],[1 {}]]", i64::MAX, i64::MIN))
663 .unwrap();
664 let cmp_2 = MatPolyOverZ::from_str("[[0],[0],[0]]").unwrap();
665 let cmp_3 = MatPolyOverZ::from_str("[[2 17 42],[2 17 42],[2 17 42]]").unwrap();
666 let cmp_1 = MatPolynomialRingZq::from((&cmp_1, &modulus));
667 let cmp_2 = MatPolynomialRingZq::from((&cmp_2, &modulus));
668 let cmp_3 = MatPolynomialRingZq::from((&cmp_3, &modulus));
669 assert_eq!(cmp_1, column_1);
670 assert_eq!(cmp_2, column_2);
671 assert_eq!(cmp_3, column_3);
672 }
673
674 #[test]
676 fn get_column_negative_indexing_works() {
677 let matrix = MatPolyOverZ::from_str(&format!(
678 "[[1 42, 0, 2 17 42],[1 {}, 0, 2 17 42],[1 {}, 0, 2 17 42]]",
679 i64::MAX,
680 u64::MAX - 1
681 ))
682 .unwrap();
683 let modulus =
684 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
685 let matrix = MatPolynomialRingZq::from((&matrix, &modulus));
686 let column_1 = matrix.get_column(-3).unwrap();
687 let column_2 = matrix.get_column(-2).unwrap();
688 let column_3 = matrix.get_column(-1).unwrap();
689
690 let cmp_1 = MatPolyOverZ::from_str(&format!(
691 "[[1 42],[1 {}],[1 {}]]",
692 i64::MAX,
693 u64::MAX - 1
694 ))
695 .unwrap();
696 let cmp_2 = MatPolyOverZ::from_str("[[0],[0],[0]]").unwrap();
697 let cmp_3 = MatPolyOverZ::from_str("[[2 17 42],[2 17 42],[2 17 42]]").unwrap();
698
699 assert_eq!(cmp_1, column_1.matrix);
700 assert_eq!(cmp_2, column_2.matrix);
701 assert_eq!(cmp_3, column_3.matrix);
702 }
703
704 #[test]
706 fn wrong_dim_error() {
707 let modulus =
708 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
709 let matrix = MatPolyOverZ::from_str(&format!(
710 "[[1 17, 2 17 42, 3 1 1 1],[1 {}, 1 1, 2 2 3],[1 {}, 1 142, 1 1]]",
711 i64::MAX,
712 i64::MIN
713 ))
714 .unwrap();
715 let matrix = MatPolynomialRingZq::from((&matrix, &modulus));
716
717 let row_1 = matrix.get_row(-4);
718 let row_2 = matrix.get_row(4);
719 let column_1 = matrix.get_column(-4);
720 let column_2 = matrix.get_column(4);
721
722 assert!(row_1.is_err());
723 assert!(row_2.is_err());
724 assert!(column_1.is_err());
725 assert!(column_2.is_err());
726 }
727}
728
729#[cfg(test)]
730mod test_get_submatrix {
731 use crate::{
732 integer::{MatPolyOverZ, Z},
733 integer_mod_q::{MatPolynomialRingZq, ModulusPolynomialRingZq},
734 traits::{MatrixDimensions, MatrixGetSubmatrix},
735 };
736 use std::str::FromStr;
737
738 #[test]
740 fn entire_matrix() {
741 let modulus =
742 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
743 let mat = MatPolyOverZ::identity(5, 5);
744 let mat = MatPolynomialRingZq::from((&mat, &modulus));
745
746 let sub_mat = mat.get_submatrix(0, 4, 0, 4).unwrap();
747
748 assert_eq!(mat, sub_mat);
749 }
750
751 #[test]
753 fn matrix_single_entry() {
754 let modulus =
755 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
756 let mat = MatPolyOverZ::identity(5, 5);
757 let mat = MatPolynomialRingZq::from((&mat, &modulus));
758
759 let sub_mat = mat.get_submatrix(0, 0, 0, 0).unwrap();
760
761 let cmp_mat = MatPolyOverZ::identity(1, 1);
762 let cmp_mat = MatPolynomialRingZq::from((&cmp_mat, &modulus));
763 assert_eq!(cmp_mat, sub_mat);
764 }
765
766 #[test]
768 fn correct_dimensions() {
769 let modulus =
770 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
771 let mat = MatPolyOverZ::identity(100, 100);
772 let mat = MatPolynomialRingZq::from((&mat, &modulus));
773
774 let sub_mat = mat.get_submatrix(1, 37, 0, 29).unwrap();
775
776 assert_eq!(37, sub_mat.get_num_rows());
777 assert_eq!(30, sub_mat.get_num_columns());
778 }
779
780 #[test]
783 fn large_entries() {
784 let modulus =
785 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
786 let mat = MatPolyOverZ::from_str(&format!(
787 "[[2 -1 {}, 1 2, 1 3],[1 1, 1 {}, 1 3]]",
788 i64::MAX,
789 i64::MIN
790 ))
791 .unwrap();
792 let mat = MatPolynomialRingZq::from((&mat, &modulus));
793
794 let sub_mat = mat.get_submatrix(0, 1, 0, 1).unwrap();
795
796 let cmp_mat = MatPolyOverZ::from_str(&format!(
797 "[[2 -1 {}, 1 2],[1 1, 1 {}]]",
798 i64::MAX,
799 i64::MIN
800 ))
801 .unwrap();
802 let cmp_mat = MatPolynomialRingZq::from((&cmp_mat, &modulus));
803 assert_eq!(cmp_mat, sub_mat);
804 }
805
806 #[test]
809 fn invalid_coordinates() {
810 let modulus =
811 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
812 let mat = MatPolyOverZ::identity(10, 10);
813 let mat = MatPolynomialRingZq::from((&mat, &modulus));
814
815 assert!(mat.get_submatrix(0, 0, 0, 10).is_err());
816 assert!(mat.get_submatrix(0, 10, 0, 0).is_err());
817 assert!(mat.get_submatrix(0, 0, -11, 0).is_err());
818 assert!(mat.get_submatrix(-11, 0, 0, 0).is_err());
819 }
820
821 #[test]
823 fn negative_indexing() {
824 let modulus =
825 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
826 let mat = MatPolyOverZ::identity(3, 3);
827 let matrix = MatPolynomialRingZq::from((&mat, &modulus));
828
829 assert_eq!(matrix, matrix.get_submatrix(0, -1, 0, -1).unwrap());
830 assert_eq!(matrix, matrix.get_submatrix(-3, -1, -3, -1).unwrap());
831 }
832
833 #[test]
835 #[should_panic]
836 fn no_columns() {
837 let modulus =
838 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
839 let mat = MatPolyOverZ::identity(10, 10);
840 let mat = MatPolynomialRingZq::from((&mat, &modulus));
841
842 let _ = mat.get_submatrix(0, 0, 6, 5);
843 }
844
845 #[test]
847 #[should_panic]
848 fn no_rows() {
849 let modulus =
850 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
851 let mat = MatPolyOverZ::identity(10, 10);
852 let mat = MatPolynomialRingZq::from((&mat, &modulus));
853
854 let _ = mat.get_submatrix(5, 4, 0, 0);
855 }
856
857 #[test]
859 fn availability() {
860 let modulus =
861 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
862 let mat = MatPolyOverZ::identity(10, 10);
863 let mat = MatPolynomialRingZq::from((&mat, &modulus));
864
865 let _ = mat.get_submatrix(0_i8, 0_i8, 0_i8, 0_i8);
866 let _ = mat.get_submatrix(0_i16, 0_i16, 0_i16, 0_i16);
867 let _ = mat.get_submatrix(0_i32, 0_i32, 0_i32, 0_i32);
868 let _ = mat.get_submatrix(0_i64, 0_i64, 0_i64, 0_i64);
869 let _ = mat.get_submatrix(0_u8, 0_u8, 0_u8, 0_u8);
870 let _ = mat.get_submatrix(0_u16, 0_i16, 0_u16, 0_u16);
871 let _ = mat.get_submatrix(0_u32, 0_i32, 0_u32, 0_u32);
872 let _ = mat.get_submatrix(0_u64, 0_i64, 0_u64, 0_u64);
873 let _ = mat.get_submatrix(&Z::ZERO, &Z::ZERO, &Z::ZERO, &Z::ZERO);
874 }
875}
876
877#[cfg(test)]
878mod test_collect_entries {
879 use crate::integer::{MatPolyOverZ, PolyOverZ};
880 use crate::integer_mod_q::{MatPolynomialRingZq, ModulusPolynomialRingZq};
881 use flint3_sys::fmpz_poly_set;
882 use std::str::FromStr;
883
884 const LARGE_PRIME: u64 = u64::MAX - 58;
885
886 #[test]
888 fn all_entries_collected() {
889 let modulus =
890 ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {LARGE_PRIME}")).unwrap();
891 let poly_mat_1 = MatPolyOverZ::from_str(&format!(
892 "[[4 -1 0 3 1, 1 {}],[2 1 2, 3 {} 1 1]]",
893 i64::MAX,
894 i64::MIN + 58,
895 ))
896 .unwrap();
897 let poly_ring_mat_1 = MatPolynomialRingZq::from((&poly_mat_1, &modulus));
898 let poly_mat_2 = MatPolyOverZ::from_str("[[1 42, 2 1 17]]").unwrap();
899 let poly_ring_mat_2 = MatPolynomialRingZq::from((&poly_mat_2, &modulus));
900
901 let entries_1 = poly_ring_mat_1.collect_entries();
902 let entries_2 = poly_ring_mat_2.collect_entries();
903
904 let mut entry_1 = PolyOverZ::default();
905 let mut entry_2 = entry_1.clone();
906 let mut entry_3 = entry_1.clone();
907
908 unsafe { fmpz_poly_set(&mut entry_1.poly, entries_1[1]) }
909 unsafe { fmpz_poly_set(&mut entry_2.poly, entries_1[3]) }
910 unsafe { fmpz_poly_set(&mut entry_3.poly, entries_2[0]) }
911
912 assert_eq!(entries_1.len(), 4);
913 assert_eq!(
914 PolyOverZ::from_str(&format!("1 {}", i64::MAX)).unwrap(),
915 entry_1
916 );
917 assert_eq!(
918 PolyOverZ::from_str(&format!("3 {} 1 1", i64::MAX)).unwrap(),
919 entry_2
920 );
921
922 assert_eq!(entries_2.len(), 2);
923 assert_eq!(PolyOverZ::from(42), entry_3);
924 }
925
926 #[test]
928 fn doc_test() {
929 let modulus = ModulusPolynomialRingZq::from_str("4 1 0 0 1 mod 17").unwrap();
930 let poly_mat = MatPolyOverZ::from_str("[[4 -1 0 1 1, 1 42],[2 1 2, 3 1 1 1]]").unwrap();
931 let poly_ring_mat = MatPolynomialRingZq::from((&poly_mat, &modulus));
932
933 let _ = poly_ring_mat.collect_entries();
934 }
935}