1use super::MatPolyOverZ;
12use crate::{
13 error::MathError,
14 integer::PolyOverZ,
15 macros::for_others::implement_for_owned,
16 traits::{MatrixDimensions, MatrixSetEntry, MatrixSetSubmatrix, MatrixSwaps},
17 utils::index::{evaluate_index_for_vector, evaluate_indices_for_matrix},
18};
19use flint_sys::{
20 fmpz_poly::{fmpz_poly_set, fmpz_poly_swap},
21 fmpz_poly_mat::{
22 fmpz_poly_mat_entry, fmpz_poly_mat_set, fmpz_poly_mat_window_clear,
23 fmpz_poly_mat_window_init,
24 },
25};
26use std::{fmt::Display, mem::MaybeUninit};
27
28impl MatrixSetEntry<&PolyOverZ> for MatPolyOverZ {
29 unsafe fn set_entry_unchecked(&mut self, row: i64, column: i64, value: &PolyOverZ) {
59 unsafe {
60 let entry = fmpz_poly_mat_entry(&self.matrix, row, column);
61 fmpz_poly_set(entry, &value.poly)
62 };
63 }
64}
65
66implement_for_owned!(PolyOverZ, MatPolyOverZ, MatrixSetEntry);
67
68impl MatrixSetSubmatrix for MatPolyOverZ {
69 unsafe fn set_submatrix_unchecked(
106 &mut self,
107 row_self_start: i64,
108 col_self_start: i64,
109 row_self_end: i64,
110 col_self_end: i64,
111 other: &Self,
112 row_other_start: i64,
113 col_other_start: i64,
114 row_other_end: i64,
115 col_other_end: i64,
116 ) {
117 {
118 let mut window_self = MaybeUninit::uninit();
119 unsafe {
121 fmpz_poly_mat_window_init(
122 window_self.as_mut_ptr(),
123 &self.matrix,
124 row_self_start,
125 col_self_start,
126 row_self_end,
127 col_self_end,
128 )
129 };
130 let mut window_other = MaybeUninit::uninit();
131 unsafe {
133 fmpz_poly_mat_window_init(
134 window_other.as_mut_ptr(),
135 &other.matrix,
136 row_other_start,
137 col_other_start,
138 row_other_end,
139 col_other_end,
140 )
141 };
142 unsafe {
143 fmpz_poly_mat_set(window_self.as_mut_ptr(), window_other.as_mut_ptr());
145
146 fmpz_poly_mat_window_clear(window_self.as_mut_ptr());
149 fmpz_poly_mat_window_clear(window_other.as_mut_ptr());
150 }
151 }
152 }
153}
154
155impl MatrixSwaps for MatPolyOverZ {
156 fn swap_entries(
182 &mut self,
183 row_0: impl TryInto<i64> + Display,
184 col_0: impl TryInto<i64> + Display,
185 row_1: impl TryInto<i64> + Display,
186 col_1: impl TryInto<i64> + Display,
187 ) -> Result<(), MathError> {
188 let (row_0, col_0) = evaluate_indices_for_matrix(self, row_0, col_0)?;
189 let (row_1, col_1) = evaluate_indices_for_matrix(self, row_1, col_1)?;
190
191 unsafe {
192 fmpz_poly_swap(
193 fmpz_poly_mat_entry(&self.matrix, row_0, col_0),
194 fmpz_poly_mat_entry(&self.matrix, row_1, col_1),
195 )
196 };
197 Ok(())
198 }
199
200 fn swap_columns(
224 &mut self,
225 col_0: impl TryInto<i64> + Display,
226 col_1: impl TryInto<i64> + Display,
227 ) -> Result<(), MathError> {
228 let num_cols = self.get_num_columns();
229 let col_0 = evaluate_index_for_vector(col_0, num_cols)?;
230 let col_1 = evaluate_index_for_vector(col_1, num_cols)?;
231
232 if col_0 >= num_cols || col_1 >= num_cols {
233 return Err(MathError::OutOfBounds(
234 format!("smaller than {num_cols}"),
235 if col_0 > col_1 {
236 col_0.to_string()
237 } else {
238 col_1.to_string()
239 },
240 ));
241 }
242 for row in 0..self.get_num_rows() {
243 unsafe {
244 let entry_0 = fmpz_poly_mat_entry(&self.matrix, row, col_0);
245 let entry_1 = fmpz_poly_mat_entry(&self.matrix, row, col_1);
246 fmpz_poly_swap(entry_0, entry_1);
247 }
248 }
249 Ok(())
250 }
251
252 fn swap_rows(
276 &mut self,
277 row_0: impl TryInto<i64> + Display,
278 row_1: impl TryInto<i64> + Display,
279 ) -> Result<(), MathError> {
280 let num_rows = self.get_num_rows();
281 let row_0 = evaluate_index_for_vector(row_0, num_rows)?;
282 let row_1 = evaluate_index_for_vector(row_1, num_rows)?;
283
284 if row_0 >= num_rows || row_1 >= num_rows {
285 return Err(MathError::OutOfBounds(
286 format!("smaller than {num_rows}"),
287 if row_0 > row_1 {
288 row_0.to_string()
289 } else {
290 row_1.to_string()
291 },
292 ));
293 }
294 for col in 0..self.get_num_columns() {
295 unsafe {
296 let entry_0 = fmpz_poly_mat_entry(&self.matrix, row_0, col);
297 let entry_1 = fmpz_poly_mat_entry(&self.matrix, row_1, col);
298 fmpz_poly_swap(entry_0, entry_1);
299 }
300 }
301 Ok(())
302 }
303}
304
305impl MatPolyOverZ {
306 pub fn reverse_columns(&mut self) {
317 let num_cols = self.get_num_columns();
318 for col in 0..(num_cols / 2) {
319 self.swap_columns(col, num_cols - col - 1).unwrap();
320 }
321 }
322
323 pub fn reverse_rows(&mut self) {
334 let num_rows = self.get_num_rows();
335 for row in 0..(num_rows / 2) {
336 self.swap_rows(row, num_rows - row - 1).unwrap();
337 }
338 }
339}
340
341#[cfg(test)]
342mod test_setter {
343 use crate::{
344 integer::{MatPolyOverZ, PolyOverZ},
345 traits::{MatrixGetEntry, MatrixSetEntry, MatrixSetSubmatrix},
346 };
347 use std::str::FromStr;
348
349 #[test]
351 fn standard_value() {
352 let mut matrix = MatPolyOverZ::new(5, 10);
353 let value = PolyOverZ::from_str("2 889 1").unwrap();
354 matrix.set_entry(4, 7, &value).unwrap();
355
356 let entry = matrix.get_entry(4, 7).unwrap();
357
358 assert_eq!("2 889 1", entry.to_string());
359 }
360
361 #[test]
363 fn max_int_positive() {
364 let mut matrix = MatPolyOverZ::new(5, 10);
365 let value = PolyOverZ::from_str(&format!("2 {} 1", i64::MAX)).unwrap();
366 matrix.set_entry(4, 7, &value).unwrap();
367
368 let entry = matrix.get_entry(4, 7).unwrap();
369
370 assert_eq!(format!("2 {} 1", i64::MAX), entry.to_string());
371 }
372
373 #[test]
375 fn large_positive() {
376 let mut matrix = MatPolyOverZ::new(5, 10);
377 let value = PolyOverZ::from_str(&format!("2 {} 1", u64::MAX)).unwrap();
378 matrix.set_entry(4, 7, &value).unwrap();
379
380 let entry = matrix.get_entry(4, 7).unwrap();
381
382 assert_eq!(format!("2 {} 1", u64::MAX), entry.to_string());
383 }
384
385 #[test]
387 fn large_positive_ref() {
388 let mut matrix = MatPolyOverZ::new(5, 10);
389 let value_1 = PolyOverZ::from_str(&format!("2 {} 1", u64::MAX)).unwrap();
390 let value_2 = PolyOverZ::from_str("2 8 1").unwrap();
391 matrix.set_entry(1, 1, &value_1).unwrap();
392 matrix.set_entry(0, 0, value_2).unwrap();
393
394 let entry_1 = matrix.get_entry(1, 1).unwrap();
395 let entry_2 = matrix.get_entry(0, 0).unwrap();
396
397 assert_eq!(format!("2 {} 1", u64::MAX), entry_1.to_string());
398 assert_eq!("2 8 1", entry_2.to_string());
399 }
400
401 #[test]
403 fn max_int_negative() {
404 let mut matrix = MatPolyOverZ::new(5, 10);
405 let value = PolyOverZ::from_str(&format!("2 {} 1", i64::MIN)).unwrap();
406 matrix.set_entry(4, 7, &value).unwrap();
407
408 let entry = matrix.get_entry(4, 7).unwrap();
409
410 assert_eq!(format!("2 {} 1", i64::MIN), entry.to_string());
411 }
412
413 #[test]
415 fn large_negative() {
416 let mut matrix = MatPolyOverZ::new(5, 10);
417 let value_str = &format!("2 -{} 1", u64::MAX);
418 let value = PolyOverZ::from_str(value_str).unwrap();
419 matrix.set_entry(4, 7, &value).unwrap();
420
421 let entry = matrix.get_entry(4, 7).unwrap();
422
423 assert_eq!(PolyOverZ::from_str(value_str).unwrap(), entry);
424 }
425
426 #[test]
428 fn setting_at_zero() {
429 let mut matrix = MatPolyOverZ::new(5, 10);
430 let value = PolyOverZ::from_str(&format!("2 {} 1", u64::MAX)).unwrap();
431 matrix.set_entry(0, 0, &value).unwrap();
432
433 let entry = matrix.get_entry(0, 0).unwrap();
434
435 assert_eq!(format!("2 {} 1", u64::MAX), entry.to_string());
436 }
437
438 #[test]
440 fn error_wrong_row() {
441 let mut matrix = MatPolyOverZ::new(5, 10);
442 let value = PolyOverZ::default();
443
444 assert!(matrix.set_entry(5, 1, &value).is_err());
445 assert!(matrix.set_entry(-6, 1, value).is_err());
446 }
447
448 #[test]
450 fn error_wrong_column() {
451 let mut matrix = MatPolyOverZ::new(5, 10);
452 let value = PolyOverZ::default();
453
454 assert!(matrix.set_entry(1, 100, &value).is_err());
455 assert!(matrix.set_entry(1, -11, value).is_err());
456 }
457
458 #[test]
460 fn negative_indexing() {
461 let mut matrix = MatPolyOverZ::new(3, 3);
462
463 matrix.set_entry(-1, -1, &PolyOverZ::from(9)).unwrap();
464 matrix.set_entry(-1, -2, &PolyOverZ::from(8)).unwrap();
465 matrix.set_entry(-3, -3, &PolyOverZ::from(1)).unwrap();
466
467 let matrix_cmp =
468 MatPolyOverZ::from_str("[[1 1, 0, 0],[0, 0, 0],[0, 1 8, 1 9]]").unwrap();
469 assert_eq!(matrix_cmp, matrix);
470 }
471
472 #[test]
474 fn column_small_entries() {
475 let mut mat_1 = MatPolyOverZ::from_str("[[0, 1 2, 0],[0, 1 5, 1 6]]").unwrap();
476 let mat_2 = MatPolyOverZ::from_str("[[0],[1 -1]]").unwrap();
477 let cmp = MatPolyOverZ::from_str("[[0, 0, 0],[0, 1 -1, 1 6]]").unwrap();
478
479 mat_1.set_column(1, &mat_2, 0).unwrap();
480
481 assert_eq!(cmp, mat_1);
482 }
483
484 #[test]
486 fn column_large_entries() {
487 let mut mat_1 = MatPolyOverZ::from_str(&format!(
488 "[[1 {}, 1 1, 1 3, 1 4],[1 {}, 1 4, 1 {}, 1 5],[1 7, 1 6, 2 8 9, 0]]",
489 i64::MIN,
490 i64::MAX,
491 u64::MAX
492 ))
493 .unwrap();
494 let mat_2 = MatPolyOverZ::from_str(&format!(
495 "[[1 1, 1 {}],[1 {}, 0],[1 7, 1 -1]]",
496 i64::MIN,
497 i64::MAX
498 ))
499 .unwrap();
500 let cmp = MatPolyOverZ::from_str(&format!(
501 "[[1 {}, 1 1, 1 3, 1 4],[0, 1 4, 1 {}, 1 5],[1 -1, 1 6, 2 8 9, 0]]",
502 i64::MIN,
503 u64::MAX
504 ))
505 .unwrap();
506
507 mat_1.set_column(0, &mat_2, 1).unwrap();
508
509 assert_eq!(cmp, mat_1);
510 }
511
512 #[test]
514 fn column_swap_same_entry() {
515 let mut mat_1 = MatPolyOverZ::from_str(&format!(
516 "[[1 {}, 1 1, 1 3, 1 4],[1 {}, 1 4, 1 {}, 1 5],[1 7, 1 6, 2 8 9, 0]]",
517 i64::MIN,
518 i64::MAX,
519 u64::MAX
520 ))
521 .unwrap();
522 let cmp = mat_1.clone();
523
524 mat_1.set_column(0, &cmp, 0).unwrap();
525 mat_1.set_column(1, &cmp, 1).unwrap();
526
527 assert_eq!(cmp, mat_1);
528 }
529
530 #[test]
532 fn column_out_of_bounds() {
533 let mut mat_1 = MatPolyOverZ::new(5, 2);
534 let mat_2 = mat_1.clone();
535
536 assert!(mat_1.set_column(-3, &mat_2, 0).is_err());
537 assert!(mat_1.set_column(2, &mat_2, 0).is_err());
538 assert!(mat_1.set_column(1, &mat_2, -3).is_err());
539 assert!(mat_1.set_column(1, &mat_2, 2).is_err());
540 }
541
542 #[test]
544 fn column_mismatching_columns() {
545 let mut mat_1 = MatPolyOverZ::new(5, 2);
546 let mat_2 = MatPolyOverZ::new(2, 2);
547
548 assert!(mat_1.set_column(0, &mat_2, 0).is_err());
549 assert!(mat_1.set_column(1, &mat_2, 1).is_err());
550 }
551
552 #[test]
554 fn row_small_entries() {
555 let mut mat_1 = MatPolyOverZ::from_str("[[0, 1 2, 0],[0, 2 5 6, 0]]").unwrap();
556 let mat_2 = MatPolyOverZ::from_str("[[0, 1 -1, 1 2]]").unwrap();
557 let cmp = MatPolyOverZ::from_str("[[0, 1 2, 0],[0, 1 -1, 1 2]]").unwrap();
558
559 let _ = mat_1.set_row(1, &mat_2, 0);
560
561 assert_eq!(cmp, mat_1);
562 }
563
564 #[test]
566 fn row_large_entries() {
567 let mut mat_1 = MatPolyOverZ::from_str(&format!(
568 "[[1 {}, 1 1, 1 3, 1 4],[1 {}, 1 4, 1 {}, 1 5],[1 7, 1 6, 2 8 9, 0]]",
569 i64::MIN,
570 i64::MAX,
571 u64::MAX
572 ))
573 .unwrap();
574 let mat_2 = MatPolyOverZ::from_str(&format!(
575 "[[0, 0, 0, 0],[1 {}, 0, 1 {}, 0]]",
576 i64::MIN,
577 i64::MAX
578 ))
579 .unwrap();
580 let cmp = MatPolyOverZ::from_str(&format!(
581 "[[1 {}, 0, 1 {}, 0],[1 {}, 1 4, 1 {}, 1 5],[1 7, 1 6, 2 8 9, 0]]",
582 i64::MIN,
583 i64::MAX,
584 i64::MAX,
585 u64::MAX
586 ))
587 .unwrap();
588
589 let _ = mat_1.set_row(0, &mat_2, 1);
590
591 assert_eq!(cmp, mat_1);
592 }
593
594 #[test]
596 fn row_swap_same_entry() {
597 let mut mat_1 = MatPolyOverZ::from_str(&format!(
598 "[[1 {}, 1 1, 1 3, 1 4],[1 {}, 1 4, 1 {}, 1 5],[1 7, 1 6, 2 8 9, 0]]",
599 i64::MIN,
600 i64::MAX,
601 u64::MAX
602 ))
603 .unwrap();
604 let cmp = mat_1.clone();
605
606 let _ = mat_1.set_row(0, &cmp, 0);
607 let _ = mat_1.set_row(1, &cmp, 1);
608
609 assert_eq!(cmp, mat_1);
610 }
611
612 #[test]
614 fn row_out_of_bounds() {
615 let mut mat_1 = MatPolyOverZ::new(5, 2);
616 let mat_2 = mat_1.clone();
617
618 assert!(mat_1.set_row(-6, &mat_2, 0).is_err());
619 assert!(mat_1.set_row(5, &mat_2, 0).is_err());
620 assert!(mat_1.set_row(2, &mat_2, -6).is_err());
621 assert!(mat_1.set_row(2, &mat_2, 5).is_err());
622 }
623
624 #[test]
626 fn row_mismatching_columns() {
627 let mut mat_1 = MatPolyOverZ::new(3, 2);
628 let mat_2 = MatPolyOverZ::new(3, 3);
629
630 assert!(mat_1.set_row(0, &mat_2, 0).is_err());
631 assert!(mat_1.set_row(1, &mat_2, 1).is_err());
632 }
633
634 #[test]
636 fn negative_indexing_row_column() {
637 let mut matrix = MatPolyOverZ::identity(3, 3);
638 let matrix2 = MatPolyOverZ::identity(3, 3);
639
640 matrix.set_column(-1, &matrix2, -2).unwrap();
641 matrix.set_row(-1, &matrix2, -2).unwrap();
642
643 let matrix_cmp =
644 MatPolyOverZ::from_str("[[1 1, 0, 0],[0, 1 1, 1 1],[0, 1 1, 0]]").unwrap();
645 assert_eq!(matrix_cmp, matrix);
646 }
647}
648
649#[cfg(test)]
650mod test_swaps {
651 use super::MatPolyOverZ;
652 use crate::traits::{MatrixGetSubmatrix, MatrixSwaps};
653 use std::str::FromStr;
654
655 #[test]
657 fn entries_small_entries() {
658 let mut matrix = MatPolyOverZ::from_str("[[1 1, 1 2, 1 3],[1 4, 2 5 6, 0]]").unwrap();
659 let cmp = MatPolyOverZ::from_str("[[1 1, 2 5 6, 1 3],[1 4, 1 2, 0]]").unwrap();
660
661 let _ = matrix.swap_entries(1, 1, 0, 1);
662
663 assert_eq!(cmp, matrix);
664 }
665
666 #[test]
668 fn entries_large_entries() {
669 let mut matrix = MatPolyOverZ::from_str(&format!(
670 "[[1 {}, 1 1, 1 3, 1 4],[1 {}, 1 4, 1 {}, 1 5],[1 7, 1 6, 2 8 9, 0]]",
671 i64::MIN,
672 i64::MAX,
673 u64::MAX
674 ))
675 .unwrap();
676 let cmp = MatPolyOverZ::from_str(&format!(
677 "[[1 {}, 1 1, 1 3, 1 4],[1 {}, 1 4, 1 {}, 1 5],[1 7, 1 6, 2 8 9, 0]]",
678 u64::MAX,
679 i64::MAX,
680 i64::MIN
681 ))
682 .unwrap();
683
684 let _ = matrix.swap_entries(0, 0, 1, 2);
685
686 assert_eq!(cmp, matrix);
687 }
688
689 #[test]
691 fn entries_swap_same_entry() {
692 let mut matrix = MatPolyOverZ::from_str(&format!(
693 "[[1 {}, 1 1, 1 3, 1 4],[1 {}, 1 4, 1 {}, 1 5],[1 7, 1 6, 2 8 9, 0]]",
694 i64::MIN,
695 i64::MAX,
696 u64::MAX
697 ))
698 .unwrap();
699 let cmp = matrix.clone();
700
701 let _ = matrix.swap_entries(0, 0, 0, 0);
702 let _ = matrix.swap_entries(1, 1, 1, 1);
703
704 assert_eq!(cmp, matrix);
705 }
706
707 #[test]
709 fn entries_out_of_bounds() {
710 let mut matrix = MatPolyOverZ::new(5, 2);
711
712 assert!(matrix.swap_entries(-6, 0, 0, 0).is_err());
713 assert!(matrix.swap_entries(0, -3, 0, 0).is_err());
714 assert!(matrix.swap_entries(0, 0, 5, 0).is_err());
715 assert!(matrix.swap_entries(0, 5, 0, 0).is_err());
716 }
717
718 #[test]
720 fn entries_negative_indexing() {
721 let mut matrix = MatPolyOverZ::identity(2, 2);
722
723 matrix.swap_entries(-2, -2, -2, -1).unwrap();
724 assert_eq!("[[0, 1 1],[0, 1 1]]", matrix.to_string());
725 }
726
727 #[test]
729 fn columns_small_entries() {
730 let mut matrix = MatPolyOverZ::from_str("[[1 1, 1 2, 1 3],[1 4, 1 5, 1 6]]").unwrap();
731 let cmp_vec_0 = MatPolyOverZ::from_str("[[1 1],[1 4]]").unwrap();
732 let cmp_vec_1 = MatPolyOverZ::from_str("[[1 3],[1 6]]").unwrap();
733 let cmp_vec_2 = MatPolyOverZ::from_str("[[1 2],[1 5]]").unwrap();
734
735 let _ = matrix.swap_columns(1, 2);
736
737 assert_eq!(cmp_vec_0, matrix.get_column(0).unwrap());
738 assert_eq!(cmp_vec_1, matrix.get_column(1).unwrap());
739 assert_eq!(cmp_vec_2, matrix.get_column(2).unwrap());
740 }
741
742 #[test]
744 fn columns_large_entries() {
745 let mut matrix = MatPolyOverZ::from_str(&format!(
746 "[[1 {}, 1 1, 1 3, 1 4],[1 {}, 1 4, 1 {}, 1 5],[1 7, 1 6, 2 8 7, 0]]",
747 i64::MIN,
748 i64::MAX,
749 u64::MAX
750 ))
751 .unwrap();
752 let cmp_vec_0 =
753 MatPolyOverZ::from_str(&format!("[[1 3],[1 {}],[2 8 7]]", u64::MAX)).unwrap();
754 let cmp_vec_1 = MatPolyOverZ::from_str("[[1 1],[1 4],[1 6]]").unwrap();
755 let cmp_vec_2 =
756 MatPolyOverZ::from_str(&format!("[[1 {}],[1 {}],[1 7]]", i64::MIN, i64::MAX))
757 .unwrap();
758 let cmp_vec_3 = MatPolyOverZ::from_str("[[1 4],[1 5],[0]]").unwrap();
759
760 let _ = matrix.swap_columns(0, 2);
761
762 assert_eq!(cmp_vec_0, matrix.get_column(0).unwrap());
763 assert_eq!(cmp_vec_1, matrix.get_column(1).unwrap());
764 assert_eq!(cmp_vec_2, matrix.get_column(2).unwrap());
765 assert_eq!(cmp_vec_3, matrix.get_column(3).unwrap());
766 }
767
768 #[test]
770 fn columns_swap_same_col() {
771 let mut matrix = MatPolyOverZ::from_str(&format!(
772 "[[1 {}, 1 1, 1 3, 1 4],[1 {}, 1 4, 1 {}, 1 5],[1 7, 1 6, 1 8, 1 9]]",
773 i64::MIN,
774 i64::MAX,
775 u64::MAX
776 ))
777 .unwrap();
778 let cmp = matrix.clone();
779
780 let _ = matrix.swap_columns(0, 0);
781
782 assert_eq!(cmp, matrix);
783 }
784
785 #[test]
787 fn column_out_of_bounds() {
788 let mut matrix = MatPolyOverZ::new(5, 2);
789
790 assert!(matrix.swap_columns(-6, 0).is_err());
791 assert!(matrix.swap_columns(0, -6).is_err());
792 assert!(matrix.swap_columns(5, 0).is_err());
793 assert!(matrix.swap_columns(0, 5).is_err());
794 }
795
796 #[test]
798 fn rows_small_entries() {
799 let mut matrix = MatPolyOverZ::from_str("[[1 1, 1 2],[1 3, 2 4 5]]").unwrap();
800 let cmp_vec_0 = MatPolyOverZ::from_str("[[1 3, 2 4 5]]").unwrap();
801 let cmp_vec_1 = MatPolyOverZ::from_str("[[1 1, 1 2]]").unwrap();
802
803 let _ = matrix.swap_rows(1, 0);
804
805 assert_eq!(cmp_vec_0, matrix.get_row(0).unwrap());
806 assert_eq!(cmp_vec_1, matrix.get_row(1).unwrap());
807 }
808
809 #[test]
811 fn rows_large_entries() {
812 let mut matrix = MatPolyOverZ::from_str(&format!(
813 "[[1 {}, 1 1, 1 3, 1 4],[1 7, 1 6, 1 8, 0],[1 {}, 1 4, 1 {}, 1 5]]",
814 i64::MIN,
815 i64::MAX,
816 u64::MAX
817 ))
818 .unwrap();
819 let cmp_vec_0 =
820 MatPolyOverZ::from_str(&format!("[[1 {}, 1 4, 1 {}, 1 5]]", i64::MAX, u64::MAX))
821 .unwrap();
822 let cmp_vec_1 = MatPolyOverZ::from_str("[[1 7, 1 6, 1 8, 0]]").unwrap();
823 let cmp_vec_2 =
824 MatPolyOverZ::from_str(&format!("[[1 {}, 1 1, 1 3, 1 4]]", i64::MIN)).unwrap();
825
826 let _ = matrix.swap_rows(0, 2);
827
828 assert_eq!(cmp_vec_0, matrix.get_row(0).unwrap());
829 assert_eq!(cmp_vec_1, matrix.get_row(1).unwrap());
830 assert_eq!(cmp_vec_2, matrix.get_row(2).unwrap());
831 }
832
833 #[test]
835 fn rows_swap_same_row() {
836 let mut matrix = MatPolyOverZ::from_str(&format!(
837 "[[1 {}, 1 1, 1 3, 1 4],[1 {}, 1 4, 1 {}, 1 5],[1 7, 1 6, 1 8, 1 9]]",
838 i64::MIN,
839 i64::MAX,
840 u64::MAX
841 ))
842 .unwrap();
843 let cmp = matrix.clone();
844
845 let _ = matrix.swap_rows(1, 1);
846
847 assert_eq!(cmp, matrix);
848 }
849
850 #[test]
852 fn row_out_of_bounds() {
853 let mut matrix = MatPolyOverZ::new(2, 4);
854
855 assert!(matrix.swap_rows(-3, 0).is_err());
856 assert!(matrix.swap_rows(0, -3).is_err());
857 assert!(matrix.swap_rows(4, 0).is_err());
858 assert!(matrix.swap_rows(0, 4).is_err());
859 }
860
861 #[test]
863 fn negative_indexing_row_column() {
864 let mut matrix = MatPolyOverZ::identity(3, 3);
865 let mut matrix2 = MatPolyOverZ::identity(3, 3);
866
867 matrix.swap_columns(-1, -2).unwrap();
868 matrix2.swap_rows(-1, -2).unwrap();
869
870 let matrix_cmp =
871 MatPolyOverZ::from_str("[[1 1, 0, 0],[0, 0, 1 1],[0, 1 1, 0]]").unwrap();
872 assert_eq!(matrix_cmp, matrix);
873 assert_eq!(matrix_cmp, matrix2);
874 }
875}
876
877#[cfg(test)]
878mod test_reverses {
879 use super::MatPolyOverZ;
880 use crate::traits::MatrixGetSubmatrix;
881 use std::str::FromStr;
882
883 #[test]
885 fn columns_small_entries() {
886 let mut matrix = MatPolyOverZ::from_str("[[1 1, 1 2, 2 3 4],[0, 1 5, 1 6]]").unwrap();
887 let cmp_vec_0 = MatPolyOverZ::from_str("[[1 1],[0]]").unwrap();
888 let cmp_vec_1 = MatPolyOverZ::from_str("[[1 2],[1 5]]").unwrap();
889 let cmp_vec_2 = MatPolyOverZ::from_str("[[2 3 4],[1 6]]").unwrap();
890
891 matrix.reverse_columns();
892
893 assert_eq!(cmp_vec_2, matrix.get_column(0).unwrap());
894 assert_eq!(cmp_vec_1, matrix.get_column(1).unwrap());
895 assert_eq!(cmp_vec_0, matrix.get_column(2).unwrap());
896 }
897
898 #[test]
900 fn columns_large_entries() {
901 let mut matrix = MatPolyOverZ::from_str(&format!(
902 "[[1 {}, 1 1, 1 3, 1 4],[1 {}, 1 4, 1 {}, 1 5],[1 7, 1 6, 2 8 9, 0]]",
903 i64::MIN,
904 i64::MAX,
905 u64::MAX
906 ))
907 .unwrap();
908 let cmp_vec_0 =
909 MatPolyOverZ::from_str(&format!("[[1 {}],[1 {}],[1 7]]", i64::MIN, i64::MAX))
910 .unwrap();
911 let cmp_vec_1 = MatPolyOverZ::from_str("[[1 1],[1 4],[1 6]]").unwrap();
912 let cmp_vec_2 =
913 MatPolyOverZ::from_str(&format!("[[1 3],[1 {}],[2 8 9]]", u64::MAX)).unwrap();
914 let cmp_vec_3 = MatPolyOverZ::from_str("[[1 4],[1 5],[0]]").unwrap();
915
916 matrix.reverse_columns();
917
918 assert_eq!(cmp_vec_3, matrix.get_column(0).unwrap());
919 assert_eq!(cmp_vec_2, matrix.get_column(1).unwrap());
920 assert_eq!(cmp_vec_1, matrix.get_column(2).unwrap());
921 assert_eq!(cmp_vec_0, matrix.get_column(3).unwrap());
922 }
923
924 #[test]
926 fn rows_small_entries() {
927 let mut matrix = MatPolyOverZ::from_str("[[1 1, 1 2],[2 3 4, 0]]").unwrap();
928 let cmp_vec_0 = MatPolyOverZ::from_str("[[1 1, 1 2]]").unwrap();
929 let cmp_vec_1 = MatPolyOverZ::from_str("[[2 3 4, 0]]").unwrap();
930
931 matrix.reverse_rows();
932
933 assert_eq!(cmp_vec_1, matrix.get_row(0).unwrap());
934 assert_eq!(cmp_vec_0, matrix.get_row(1).unwrap());
935 }
936
937 #[test]
939 fn rows_large_entries() {
940 let mut matrix = MatPolyOverZ::from_str(&format!(
941 "[[1 {}, 1 1, 1 3, 1 4],[1 7, 1 6, 2 8 9, 0],[1 {}, 1 4, 1 {}, 1 5]]",
942 i64::MIN,
943 i64::MAX,
944 u64::MAX
945 ))
946 .unwrap();
947 let cmp_vec_0 =
948 MatPolyOverZ::from_str(&format!("[[1 {}, 1 1, 1 3, 1 4]]", i64::MIN)).unwrap();
949 let cmp_vec_1 = MatPolyOverZ::from_str("[[1 7, 1 6, 2 8 9, 0]]").unwrap();
950 let cmp_vec_2 =
951 MatPolyOverZ::from_str(&format!("[[1 {}, 1 4, 1 {}, 1 5]]", i64::MAX, u64::MAX))
952 .unwrap();
953
954 matrix.reverse_rows();
955
956 assert_eq!(cmp_vec_2, matrix.get_row(0).unwrap());
957 assert_eq!(cmp_vec_1, matrix.get_row(1).unwrap());
958 assert_eq!(cmp_vec_0, matrix.get_row(2).unwrap());
959 }
960}
961
962#[cfg(test)]
963mod test_set_submatrix {
964 use crate::{integer::MatPolyOverZ, traits::MatrixSetSubmatrix};
965 use std::str::FromStr;
966
967 #[test]
969 fn entire_matrix() {
970 let mut mat = MatPolyOverZ::sample_uniform(10, 10, 5, -100, 100).unwrap();
971 let identity = MatPolyOverZ::identity(10, 10);
972
973 mat.set_submatrix(0, 0, &identity, 0, 0, 9, 9).unwrap();
974
975 assert_eq!(identity, mat);
976 }
977
978 #[test]
980 fn out_of_bounds() {
981 let mut mat = MatPolyOverZ::identity(10, 10);
982
983 assert!(mat.set_submatrix(10, 0, &mat.clone(), 0, 0, 9, 9).is_err());
984 assert!(mat.set_submatrix(0, 10, &mat.clone(), 0, 0, 9, 9).is_err());
985 assert!(mat.set_submatrix(0, 0, &mat.clone(), 10, 0, 9, 9).is_err());
986 assert!(mat.set_submatrix(0, 0, &mat.clone(), 0, 10, 9, 9).is_err());
987 assert!(mat.set_submatrix(0, 0, &mat.clone(), 0, 0, 10, 9).is_err());
988 assert!(mat.set_submatrix(0, 0, &mat.clone(), 0, 0, 9, 10).is_err());
989 assert!(mat.set_submatrix(-11, 0, &mat.clone(), 0, 0, 9, 9).is_err());
990 assert!(mat.set_submatrix(0, -11, &mat.clone(), 0, 0, 9, 9).is_err());
991 assert!(mat.set_submatrix(0, 0, &mat.clone(), -11, 0, 9, 9).is_err());
992 assert!(mat.set_submatrix(0, 0, &mat.clone(), 0, -11, 9, 9).is_err());
993 assert!(mat.set_submatrix(0, 0, &mat.clone(), 0, 0, -11, 9).is_err());
994 assert!(mat.set_submatrix(0, 0, &mat.clone(), 0, 0, 9, -11).is_err());
995 }
996
997 #[test]
1000 fn submatrix_too_large() {
1001 let mut mat = MatPolyOverZ::sample_uniform(10, 10, 5, -100, 100).unwrap();
1002
1003 assert!(
1004 mat.set_submatrix(0, 0, &MatPolyOverZ::identity(11, 11), 0, 0, 10, 10)
1005 .is_err()
1006 );
1007 assert!(mat.set_submatrix(1, 2, &mat.clone(), 0, 0, 9, 9).is_err());
1008 }
1009
1010 #[test]
1012 fn large_values() {
1013 let mut mat = MatPolyOverZ::from_str(&format!(
1014 "[[1 1, 2 1 {}],[1 -{}, 0]]",
1015 u64::MAX,
1016 u64::MAX
1017 ))
1018 .unwrap();
1019 let cmp_mat =
1020 MatPolyOverZ::from_str(&format!("[[1 -{}, 0],[1 -{}, 0]]", u64::MAX, u64::MAX))
1021 .unwrap();
1022
1023 mat.set_submatrix(0, 0, &mat.clone(), 1, 0, 1, 1).unwrap();
1024 assert_eq!(cmp_mat, mat);
1025 }
1026
1027 #[test]
1029 #[should_panic]
1030 fn submatrix_negative() {
1031 let mut mat = MatPolyOverZ::identity(10, 10);
1032
1033 let _ = mat.set_submatrix(0, 0, &mat.clone(), 0, 9, 9, 5);
1034 }
1035}