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