1use super::MatZ;
12use crate::{
13 error::MathError,
14 integer::Z,
15 traits::{MatrixDimensions, MatrixSetEntry, MatrixSetSubmatrix, MatrixSwaps},
16 utils::index::{evaluate_index_for_vector, evaluate_indices_for_matrix},
17};
18use flint_sys::{
19 fmpz::{fmpz_set, fmpz_swap},
20 fmpz_mat::{
21 fmpz_mat_entry, fmpz_mat_invert_cols, fmpz_mat_invert_rows, fmpz_mat_set,
22 fmpz_mat_swap_cols, fmpz_mat_swap_rows, fmpz_mat_window_clear, fmpz_mat_window_init,
23 },
24};
25use std::{
26 fmt::Display,
27 mem::MaybeUninit,
28 ptr::{null, null_mut},
29};
30
31impl<Integer: Into<Z>> MatrixSetEntry<Integer> for MatZ {
32 unsafe fn set_entry_unchecked(&mut self, row: i64, column: i64, value: Integer) {
60 let value: Z = value.into();
61
62 unsafe {
63 let entry = fmpz_mat_entry(&self.matrix, row, column);
64 fmpz_set(entry, &value.value)
65 };
66 }
67}
68
69impl MatrixSetSubmatrix for MatZ {
70 unsafe fn set_submatrix_unchecked(
107 &mut self,
108 row_self_start: i64,
109 col_self_start: i64,
110 row_self_end: i64,
111 col_self_end: i64,
112 other: &Self,
113 row_other_start: i64,
114 col_other_start: i64,
115 row_other_end: i64,
116 col_other_end: i64,
117 ) {
118 let mut window_self = MaybeUninit::uninit();
119 unsafe {
121 fmpz_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_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_mat_set(window_self.as_mut_ptr(), window_other.as_ptr());
144
145 fmpz_mat_window_clear(window_self.as_mut_ptr());
148 fmpz_mat_window_clear(window_other.as_mut_ptr());
149 }
150 }
151}
152
153impl MatrixSwaps for MatZ {
154 fn swap_entries(
180 &mut self,
181 row_0: impl TryInto<i64> + Display,
182 col_0: impl TryInto<i64> + Display,
183 row_1: impl TryInto<i64> + Display,
184 col_1: impl TryInto<i64> + Display,
185 ) -> Result<(), MathError> {
186 let (row_0, col_0) = evaluate_indices_for_matrix(self, row_0, col_0)?;
187 let (row_1, col_1) = evaluate_indices_for_matrix(self, row_1, col_1)?;
188
189 unsafe {
190 fmpz_swap(
191 fmpz_mat_entry(&self.matrix, row_0, col_0),
192 fmpz_mat_entry(&self.matrix, row_1, col_1),
193 )
194 };
195 Ok(())
196 }
197
198 fn swap_columns(
222 &mut self,
223 col_0: impl TryInto<i64> + Display,
224 col_1: impl TryInto<i64> + Display,
225 ) -> Result<(), MathError> {
226 let num_cols = self.get_num_columns();
227 let col_0 = evaluate_index_for_vector(col_0, num_cols)?;
228 let col_1 = evaluate_index_for_vector(col_1, num_cols)?;
229
230 if col_0 >= num_cols || col_1 >= num_cols {
231 return Err(MathError::OutOfBounds(
232 format!("smaller than {num_cols}"),
233 if col_0 > col_1 {
234 col_0.to_string()
235 } else {
236 col_1.to_string()
237 },
238 ));
239 }
240 unsafe { fmpz_mat_swap_cols(&mut self.matrix, null(), col_0, col_1) }
241 Ok(())
242 }
243
244 fn swap_rows(
268 &mut self,
269 row_0: impl TryInto<i64> + Display,
270 row_1: impl TryInto<i64> + Display,
271 ) -> Result<(), MathError> {
272 let num_rows = self.get_num_rows();
273 let row_0 = evaluate_index_for_vector(row_0, num_rows)?;
274 let row_1 = evaluate_index_for_vector(row_1, num_rows)?;
275
276 if row_0 >= num_rows || row_1 >= num_rows {
277 return Err(MathError::OutOfBounds(
278 format!("smaller than {num_rows}"),
279 if row_0 > row_1 {
280 row_0.to_string()
281 } else {
282 row_1.to_string()
283 },
284 ));
285 }
286 unsafe { fmpz_mat_swap_rows(&mut self.matrix, null(), row_0, row_1) }
287 Ok(())
288 }
289}
290
291impl MatZ {
292 pub fn reverse_columns(&mut self) {
303 unsafe { fmpz_mat_invert_cols(&mut self.matrix, null_mut()) }
307 }
308
309 pub fn reverse_rows(&mut self) {
320 unsafe { fmpz_mat_invert_rows(&mut self.matrix, null_mut()) }
324 }
325}
326
327#[cfg(test)]
328mod test_setter {
329 use super::Z;
330 use crate::integer::MatZ;
331 use crate::traits::{MatrixGetEntry, MatrixSetEntry, MatrixSetSubmatrix};
332 use std::str::FromStr;
333
334 #[test]
336 fn standard_value() {
337 let mut matrix = MatZ::new(5, 10);
338 let value = Z::from(869);
339 matrix.set_entry(4, 7, &value).unwrap();
340
341 let entry = matrix.get_entry(4, 7).unwrap();
342
343 assert_eq!(entry, Z::from(869));
344 }
345
346 #[test]
348 fn max_int_positive() {
349 let mut matrix = MatZ::new(5, 10);
350 let value = Z::from(i64::MAX);
351 matrix.set_entry(1, 1, value).unwrap();
352
353 let entry = matrix.get_entry(1, 1).unwrap();
354
355 assert_eq!(entry, Z::from(i64::MAX));
356 }
357
358 #[test]
360 fn large_positive() {
361 let mut matrix = MatZ::new(5, 10);
362 let value = Z::from(u64::MAX);
363 matrix.set_entry(1, 1, value).unwrap();
364
365 let entry = matrix.get_entry(1, 1).unwrap();
366
367 assert_eq!(entry, Z::from(u64::MAX));
368 }
369
370 #[test]
372 fn large_positive_ref() {
373 let mut matrix = MatZ::new(5, 10);
374 let value_1 = Z::from(u64::MAX);
375 let value_2 = Z::from(8);
376 matrix.set_entry(1, 1, &value_1).unwrap();
377 matrix.set_entry(0, 0, value_2).unwrap();
378
379 let entry_1 = matrix.get_entry(1, 1).unwrap();
380 let entry_2 = matrix.get_entry(0, 0).unwrap();
381
382 assert_eq!(entry_1, Z::from(u64::MAX));
383 assert_eq!(entry_2, Z::from(8));
384 }
385
386 #[test]
388 fn max_int_negative() {
389 let mut matrix = MatZ::new(5, 10);
390 let value = Z::from(i64::MIN);
391 matrix.set_entry(1, 1, value).unwrap();
392
393 let entry = matrix.get_entry(1, 1).unwrap();
394
395 assert_eq!(entry, Z::from(i64::MIN));
396 }
397
398 #[test]
400 fn large_negative() {
401 let mut matrix = MatZ::new(5, 10);
402 let value_str = &format!("-{}", u64::MAX);
403 matrix
404 .set_entry(1, 1, Z::from_str(value_str).unwrap())
405 .unwrap();
406
407 let entry = matrix.get_entry(1, 1).unwrap();
408
409 assert_eq!(entry, Z::from_str(value_str).unwrap());
410 }
411
412 #[test]
414 fn setting_at_zero() {
415 let mut matrix = MatZ::new(5, 10);
416 let value = Z::from(i64::MIN);
417 matrix.set_entry(0, 0, value).unwrap();
418
419 let entry = matrix.get_entry(0, 0).unwrap();
420
421 assert_eq!(entry, Z::from(i64::MIN));
422 }
423
424 #[test]
426 fn error_wrong_row() {
427 let mut matrix = MatZ::new(5, 10);
428
429 assert!(matrix.set_entry(5, 1, 1).is_err());
430 assert!(matrix.set_entry(-6, 1, 1).is_err());
431 }
432
433 #[test]
435 fn error_wrong_column() {
436 let mut matrix = MatZ::new(5, 10);
437
438 assert!(matrix.set_entry(1, 100, 1).is_err());
439 assert!(matrix.set_entry(1, -11, 1).is_err());
440 }
441
442 #[test]
444 fn negative_indexing() {
445 let mut matrix = MatZ::new(3, 3);
446
447 matrix.set_entry(-1, -1, 9).unwrap();
448 matrix.set_entry(-1, -2, 8).unwrap();
449 matrix.set_entry(-3, -3, 1).unwrap();
450
451 let matrix_cmp = MatZ::from_str("[[1, 0, 0],[0, 0, 0],[0, 8, 9]]").unwrap();
452 assert_eq!(matrix_cmp, matrix);
453 }
454
455 #[test]
457 fn column_small_entries() {
458 let mut mat_1 = MatZ::from_str("[[1, 2, 3],[4, 5, 6]]").unwrap();
459 let mat_2 = MatZ::from_str("[[0],[-1]]").unwrap();
460 let cmp = MatZ::from_str("[[1, 0, 3],[4, -1, 6]]").unwrap();
461
462 mat_1.set_column(1, &mat_2, 0).unwrap();
463
464 assert_eq!(cmp, mat_1);
465 }
466
467 #[test]
469 fn column_large_entries() {
470 let mut mat_1 = MatZ::from_str(&format!(
471 "[[{}, 1, 3, 4],[{}, 4, {}, 5],[7, 6, 8, 9]]",
472 i64::MIN,
473 i64::MAX,
474 u64::MAX
475 ))
476 .unwrap();
477 let mat_2 =
478 MatZ::from_str(&format!("[[1, {}],[{}, 0],[7, -1]]", i64::MIN, i64::MAX)).unwrap();
479 let cmp = MatZ::from_str(&format!(
480 "[[{}, 1, 3, 4],[0, 4, {}, 5],[-1, 6, 8, 9]]",
481 i64::MIN,
482 u64::MAX
483 ))
484 .unwrap();
485
486 mat_1.set_column(0, &mat_2, 1).unwrap();
487
488 assert_eq!(cmp, mat_1);
489 }
490
491 #[test]
493 fn column_swap_same_entry() {
494 let mut mat_1 = MatZ::from_str(&format!(
495 "[[{}, 1, 3, 4],[{}, 4, {}, 5],[7, 6, 8, 9]]",
496 i64::MIN,
497 i64::MAX,
498 u64::MAX
499 ))
500 .unwrap();
501 let cmp = mat_1.clone();
502
503 mat_1.set_column(0, &cmp, 0).unwrap();
504 mat_1.set_column(1, &cmp, 1).unwrap();
505
506 assert_eq!(cmp, mat_1);
507 }
508
509 #[test]
511 fn column_out_of_bounds() {
512 let mut mat_1 = MatZ::new(5, 2);
513 let mat_2 = mat_1.clone();
514
515 assert!(mat_1.set_column(-3, &mat_2, 0).is_err());
516 assert!(mat_1.set_column(2, &mat_2, 0).is_err());
517 assert!(mat_1.set_column(1, &mat_2, -3).is_err());
518 assert!(mat_1.set_column(1, &mat_2, 2).is_err());
519 }
520
521 #[test]
523 fn column_mismatching_columns() {
524 let mut mat_1 = MatZ::new(5, 2);
525 let mat_2 = MatZ::new(2, 2);
526
527 assert!(mat_1.set_column(0, &mat_2, 0).is_err());
528 assert!(mat_1.set_column(1, &mat_2, 1).is_err());
529 }
530
531 #[test]
533 fn row_small_entries() {
534 let mut mat_1 = MatZ::from_str("[[1, 2, 3],[4, 5, 6]]").unwrap();
535 let mat_2 = MatZ::from_str("[[0, -1, 2]]").unwrap();
536 let cmp = MatZ::from_str("[[1, 2, 3],[0, -1, 2]]").unwrap();
537
538 let _ = mat_1.set_row(1, &mat_2, 0);
539
540 assert_eq!(cmp, mat_1);
541 }
542
543 #[test]
545 fn row_large_entries() {
546 let mut mat_1 = MatZ::from_str(&format!(
547 "[[{}, 1, 3, 4],[{}, 4, {}, 5],[7, 6, 8, 9]]",
548 i64::MIN,
549 i64::MAX,
550 u64::MAX
551 ))
552 .unwrap();
553 let mat_2 = MatZ::from_str(&format!(
554 "[[0, 0, 0, 0],[{}, 0, {}, 0]]",
555 i64::MIN,
556 i64::MAX
557 ))
558 .unwrap();
559 let cmp = MatZ::from_str(&format!(
560 "[[{}, 0, {}, 0],[{}, 4, {}, 5],[7, 6, 8, 9]]",
561 i64::MIN,
562 i64::MAX,
563 i64::MAX,
564 u64::MAX
565 ))
566 .unwrap();
567
568 let _ = mat_1.set_row(0, &mat_2, 1);
569
570 assert_eq!(cmp, mat_1);
571 }
572
573 #[test]
575 fn row_swap_same_entry() {
576 let mut mat_1 = MatZ::from_str(&format!(
577 "[[{}, 1, 3, 4],[{}, 4, {}, 5],[7, 6, 8, 9]]",
578 i64::MIN,
579 i64::MAX,
580 u64::MAX
581 ))
582 .unwrap();
583 let cmp = mat_1.clone();
584
585 let _ = mat_1.set_row(0, &cmp, 0);
586 let _ = mat_1.set_row(1, &cmp, 1);
587
588 assert_eq!(cmp, mat_1);
589 }
590
591 #[test]
593 fn row_out_of_bounds() {
594 let mut mat_1 = MatZ::new(5, 2);
595 let mat_2 = mat_1.clone();
596
597 assert!(mat_1.set_row(-6, &mat_2, 0).is_err());
598 assert!(mat_1.set_row(5, &mat_2, 0).is_err());
599 assert!(mat_1.set_row(2, &mat_2, -6).is_err());
600 assert!(mat_1.set_row(2, &mat_2, 5).is_err());
601 }
602
603 #[test]
605 fn row_mismatching_columns() {
606 let mut mat_1 = MatZ::new(3, 2);
607 let mat_2 = MatZ::new(3, 3);
608
609 assert!(mat_1.set_row(0, &mat_2, 0).is_err());
610 assert!(mat_1.set_row(1, &mat_2, 1).is_err());
611 }
612
613 #[test]
615 fn negative_indexing_row_column() {
616 let mut matrix = MatZ::identity(3, 3);
617 let matrix2 = MatZ::identity(3, 3);
618
619 matrix.set_column(-1, &matrix2, -2).unwrap();
620 matrix.set_row(-1, &matrix2, -2).unwrap();
621
622 let matrix_cmp = MatZ::from_str("[[1, 0, 0],[0, 1, 1],[0, 1, 0]]").unwrap();
623 assert_eq!(matrix_cmp, matrix);
624 }
625}
626
627#[cfg(test)]
628mod test_swaps {
629 use super::MatZ;
630 use crate::traits::{MatrixGetSubmatrix, MatrixSwaps};
631 use std::str::FromStr;
632
633 #[test]
635 fn entries_small_entries() {
636 let mut matrix = MatZ::from_str("[[1, 2, 3],[4, 5, 6]]").unwrap();
637 let cmp = MatZ::from_str("[[1, 5, 3],[4, 2, 6]]").unwrap();
638
639 let _ = matrix.swap_entries(1, 1, 0, 1);
640
641 assert_eq!(cmp, matrix);
642 }
643
644 #[test]
646 fn entries_large_entries() {
647 let mut matrix = MatZ::from_str(&format!(
648 "[[{}, 1, 3, 4],[{}, 4, {}, 5],[7, 6, 8, 9]]",
649 i64::MIN,
650 i64::MAX,
651 u64::MAX
652 ))
653 .unwrap();
654 let cmp = MatZ::from_str(&format!(
655 "[[{}, 1, 3, 4],[{}, 4, {}, 5],[7, 6, 8, 9]]",
656 u64::MAX,
657 i64::MAX,
658 i64::MIN
659 ))
660 .unwrap();
661
662 let _ = matrix.swap_entries(0, 0, 1, 2);
663
664 assert_eq!(cmp, matrix);
665 }
666
667 #[test]
669 fn entries_swap_same_entry() {
670 let mut matrix = MatZ::from_str(&format!(
671 "[[{}, 1, 3, 4],[{}, 4, {}, 5],[7, 6, 8, 9]]",
672 i64::MIN,
673 i64::MAX,
674 u64::MAX
675 ))
676 .unwrap();
677 let cmp = matrix.clone();
678
679 let _ = matrix.swap_entries(0, 0, 0, 0);
680 let _ = matrix.swap_entries(1, 1, 1, 1);
681
682 assert_eq!(cmp, matrix);
683 }
684
685 #[test]
687 fn entries_out_of_bounds() {
688 let mut matrix = MatZ::new(5, 2);
689
690 assert!(matrix.swap_entries(-6, 0, 0, 0).is_err());
691 assert!(matrix.swap_entries(0, -3, 0, 0).is_err());
692 assert!(matrix.swap_entries(0, 0, 5, 0).is_err());
693 assert!(matrix.swap_entries(0, 5, 0, 0).is_err());
694 }
695
696 #[test]
698 fn entries_negative_indexing() {
699 let mut matrix = MatZ::identity(2, 2);
700
701 matrix.swap_entries(-2, -2, -2, -1).unwrap();
702 assert_eq!("[[0, 1],[0, 1]]", matrix.to_string());
703 }
704
705 #[test]
707 fn columns_small_entries() {
708 let mut matrix = MatZ::from_str("[[1, 2, 3],[4, 5, 6]]").unwrap();
709 let cmp_vec_0 = MatZ::from_str("[[1],[4]]").unwrap();
710 let cmp_vec_1 = MatZ::from_str("[[3],[6]]").unwrap();
711 let cmp_vec_2 = MatZ::from_str("[[2],[5]]").unwrap();
712
713 let _ = matrix.swap_columns(1, 2);
714
715 assert_eq!(cmp_vec_0, matrix.get_column(0).unwrap());
716 assert_eq!(cmp_vec_1, matrix.get_column(1).unwrap());
717 assert_eq!(cmp_vec_2, matrix.get_column(2).unwrap());
718 }
719
720 #[test]
722 fn columns_large_entries() {
723 let mut matrix = MatZ::from_str(&format!(
724 "[[{}, 1, 3, 4],[{}, 4, {}, 5],[7, 6, 8, 9]]",
725 i64::MIN,
726 i64::MAX,
727 u64::MAX
728 ))
729 .unwrap();
730 let cmp_vec_0 = MatZ::from_str(&format!("[[3],[{}],[8]]", u64::MAX)).unwrap();
731 let cmp_vec_1 = MatZ::from_str("[[1],[4],[6]]").unwrap();
732 let cmp_vec_2 = MatZ::from_str(&format!("[[{}],[{}],[7]]", i64::MIN, i64::MAX)).unwrap();
733 let cmp_vec_3 = MatZ::from_str("[[4],[5],[9]]").unwrap();
734
735 let _ = matrix.swap_columns(0, 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 assert_eq!(cmp_vec_3, matrix.get_column(3).unwrap());
741 }
742
743 #[test]
745 fn columns_swap_same_col() {
746 let mut matrix = MatZ::from_str(&format!(
747 "[[{}, 1, 3, 4],[{}, 4, {}, 5],[7, 6, 8, 9]]",
748 i64::MIN,
749 i64::MAX,
750 u64::MAX
751 ))
752 .unwrap();
753 let cmp = matrix.clone();
754
755 let _ = matrix.swap_columns(0, 0);
756
757 assert_eq!(cmp, matrix);
758 }
759
760 #[test]
762 fn column_out_of_bounds() {
763 let mut matrix = MatZ::new(5, 2);
764
765 assert!(matrix.swap_columns(-6, 0).is_err());
766 assert!(matrix.swap_columns(0, -6).is_err());
767 assert!(matrix.swap_columns(5, 0).is_err());
768 assert!(matrix.swap_columns(0, 5).is_err());
769 }
770
771 #[test]
773 fn rows_small_entries() {
774 let mut matrix = MatZ::from_str("[[1, 2],[3, 4]]").unwrap();
775 let cmp_vec_0 = MatZ::from_str("[[3, 4]]").unwrap();
776 let cmp_vec_1 = MatZ::from_str("[[1, 2]]").unwrap();
777
778 let _ = matrix.swap_rows(1, 0);
779
780 assert_eq!(cmp_vec_0, matrix.get_row(0).unwrap());
781 assert_eq!(cmp_vec_1, matrix.get_row(1).unwrap());
782 }
783
784 #[test]
786 fn rows_large_entries() {
787 let mut matrix = MatZ::from_str(&format!(
788 "[[{}, 1, 3, 4],[7, 6, 8, 9],[{}, 4, {}, 5]]",
789 i64::MIN,
790 i64::MAX,
791 u64::MAX
792 ))
793 .unwrap();
794 let cmp_vec_0 = MatZ::from_str(&format!("[[{}, 4, {}, 5]]", i64::MAX, u64::MAX)).unwrap();
795 let cmp_vec_1 = MatZ::from_str("[[7, 6, 8, 9]]").unwrap();
796 let cmp_vec_2 = MatZ::from_str(&format!("[[{}, 1, 3, 4]]", i64::MIN)).unwrap();
797
798 let _ = matrix.swap_rows(0, 2);
799
800 assert_eq!(cmp_vec_0, matrix.get_row(0).unwrap());
801 assert_eq!(cmp_vec_1, matrix.get_row(1).unwrap());
802 assert_eq!(cmp_vec_2, matrix.get_row(2).unwrap());
803 }
804
805 #[test]
807 fn rows_swap_same_row() {
808 let mut matrix = MatZ::from_str(&format!(
809 "[[{}, 1, 3, 4],[{}, 4, {}, 5],[7, 6, 8, 9]]",
810 i64::MIN,
811 i64::MAX,
812 u64::MAX
813 ))
814 .unwrap();
815 let cmp = matrix.clone();
816
817 let _ = matrix.swap_rows(1, 1);
818
819 assert_eq!(cmp, matrix);
820 }
821
822 #[test]
824 fn row_out_of_bounds() {
825 let mut matrix = MatZ::new(2, 4);
826
827 assert!(matrix.swap_rows(-3, 0).is_err());
828 assert!(matrix.swap_rows(0, -3).is_err());
829 assert!(matrix.swap_rows(4, 0).is_err());
830 assert!(matrix.swap_rows(0, 4).is_err());
831 }
832
833 #[test]
835 fn negative_indexing_row_column() {
836 let mut matrix = MatZ::identity(3, 3);
837 let mut matrix2 = MatZ::identity(3, 3);
838
839 matrix.swap_columns(-1, -2).unwrap();
840 matrix2.swap_rows(-1, -2).unwrap();
841
842 let matrix_cmp = MatZ::from_str("[[1, 0, 0],[0, 0, 1],[0, 1, 0]]").unwrap();
843 assert_eq!(matrix_cmp, matrix);
844 assert_eq!(matrix_cmp, matrix2);
845 }
846}
847
848#[cfg(test)]
849mod test_reverses {
850 use super::MatZ;
851 use crate::traits::MatrixGetSubmatrix;
852 use std::str::FromStr;
853
854 #[test]
856 fn columns_small_entries() {
857 let mut matrix = MatZ::from_str("[[1, 2, 3],[4, 5, 6]]").unwrap();
858 let cmp_vec_0 = MatZ::from_str("[[1],[4]]").unwrap();
859 let cmp_vec_1 = MatZ::from_str("[[2],[5]]").unwrap();
860 let cmp_vec_2 = MatZ::from_str("[[3],[6]]").unwrap();
861
862 matrix.reverse_columns();
863
864 assert_eq!(cmp_vec_2, matrix.get_column(0).unwrap());
865 assert_eq!(cmp_vec_1, matrix.get_column(1).unwrap());
866 assert_eq!(cmp_vec_0, matrix.get_column(2).unwrap());
867 }
868
869 #[test]
871 fn columns_large_entries() {
872 let mut matrix = MatZ::from_str(&format!(
873 "[[{}, 1, 3, 4],[{}, 4, {}, 5],[7, 6, 8, 9]]",
874 i64::MIN,
875 i64::MAX,
876 u64::MAX
877 ))
878 .unwrap();
879 let cmp_vec_0 = MatZ::from_str(&format!("[[{}],[{}],[7]]", i64::MIN, i64::MAX)).unwrap();
880 let cmp_vec_1 = MatZ::from_str("[[1],[4],[6]]").unwrap();
881 let cmp_vec_2 = MatZ::from_str(&format!("[[3],[{}],[8]]", u64::MAX)).unwrap();
882 let cmp_vec_3 = MatZ::from_str("[[4],[5],[9]]").unwrap();
883
884 matrix.reverse_columns();
885
886 assert_eq!(cmp_vec_3, matrix.get_column(0).unwrap());
887 assert_eq!(cmp_vec_2, matrix.get_column(1).unwrap());
888 assert_eq!(cmp_vec_1, matrix.get_column(2).unwrap());
889 assert_eq!(cmp_vec_0, matrix.get_column(3).unwrap());
890 }
891
892 #[test]
894 fn rows_small_entries() {
895 let mut matrix = MatZ::from_str("[[1, 2],[3, 4]]").unwrap();
896 let cmp_vec_0 = MatZ::from_str("[[1, 2]]").unwrap();
897 let cmp_vec_1 = MatZ::from_str("[[3, 4]]").unwrap();
898
899 matrix.reverse_rows();
900
901 assert_eq!(cmp_vec_1, matrix.get_row(0).unwrap());
902 assert_eq!(cmp_vec_0, matrix.get_row(1).unwrap());
903 }
904
905 #[test]
907 fn rows_large_entries() {
908 let mut matrix = MatZ::from_str(&format!(
909 "[[{}, 1, 3, 4],[7, 6, 8, 9],[{}, 4, {}, 5]]",
910 i64::MIN,
911 i64::MAX,
912 u64::MAX
913 ))
914 .unwrap();
915 let cmp_vec_0 = MatZ::from_str(&format!("[[{}, 1, 3, 4]]", i64::MIN)).unwrap();
916 let cmp_vec_1 = MatZ::from_str("[[7, 6, 8, 9]]").unwrap();
917 let cmp_vec_2 = MatZ::from_str(&format!("[[{}, 4, {}, 5]]", i64::MAX, u64::MAX)).unwrap();
918
919 matrix.reverse_rows();
920
921 assert_eq!(cmp_vec_2, matrix.get_row(0).unwrap());
922 assert_eq!(cmp_vec_1, matrix.get_row(1).unwrap());
923 assert_eq!(cmp_vec_0, matrix.get_row(2).unwrap());
924 }
925}
926
927#[cfg(test)]
928mod test_set_submatrix {
929 use crate::{integer::MatZ, traits::MatrixSetSubmatrix};
930 use std::str::FromStr;
931
932 #[test]
934 fn entire_matrix() {
935 let mut mat = MatZ::sample_uniform(10, 10, -100, 100).unwrap();
936 let identity = MatZ::identity(10, 10);
937
938 mat.set_submatrix(0, 0, &identity, 0, 0, 9, 9).unwrap();
939
940 assert_eq!(identity, mat);
941 }
942
943 #[test]
945 fn out_of_bounds() {
946 let mut mat = MatZ::identity(10, 10);
947
948 assert!(mat.set_submatrix(10, 0, &mat.clone(), 0, 0, 9, 9).is_err());
949 assert!(mat.set_submatrix(0, 10, &mat.clone(), 0, 0, 9, 9).is_err());
950 assert!(mat.set_submatrix(0, 0, &mat.clone(), 10, 0, 9, 9).is_err());
951 assert!(mat.set_submatrix(0, 0, &mat.clone(), 0, 10, 9, 9).is_err());
952 assert!(mat.set_submatrix(0, 0, &mat.clone(), 0, 0, 10, 9).is_err());
953 assert!(mat.set_submatrix(0, 0, &mat.clone(), 0, 0, 9, 10).is_err());
954 assert!(mat.set_submatrix(-11, 0, &mat.clone(), 0, 0, 9, 9).is_err());
955 assert!(mat.set_submatrix(0, -11, &mat.clone(), 0, 0, 9, 9).is_err());
956 assert!(mat.set_submatrix(0, 0, &mat.clone(), -11, 0, 9, 9).is_err());
957 assert!(mat.set_submatrix(0, 0, &mat.clone(), 0, -11, 9, 9).is_err());
958 assert!(mat.set_submatrix(0, 0, &mat.clone(), 0, 0, -11, 9).is_err());
959 assert!(mat.set_submatrix(0, 0, &mat.clone(), 0, 0, 9, -11).is_err());
960 }
961
962 #[test]
965 fn submatrix_too_large() {
966 let mut mat = MatZ::sample_uniform(10, 10, -100, 100).unwrap();
967
968 assert!(
969 mat.set_submatrix(0, 0, &MatZ::identity(11, 11), 0, 0, 10, 10)
970 .is_err()
971 );
972 assert!(mat.set_submatrix(1, 2, &mat.clone(), 0, 0, 9, 9).is_err());
973 }
974
975 #[test]
977 fn large_values() {
978 let mut mat = MatZ::from_str(&format!("[[1, {}],[-{}, 0]]", u64::MAX, u64::MAX)).unwrap();
979 let cmp_mat = MatZ::from_str(&format!("[[-{}, 0],[-{}, 0]]", u64::MAX, u64::MAX)).unwrap();
980
981 mat.set_submatrix(0, 0, &mat.clone(), 1, 0, 1, 1).unwrap();
982 assert_eq!(cmp_mat, mat);
983 }
984
985 #[test]
987 #[should_panic]
988 fn submatrix_negative() {
989 let mut mat = MatZ::identity(10, 10);
990
991 let _ = mat.set_submatrix(0, 0, &mat.clone(), 0, 9, 9, 5);
992 }
993}