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