graphblas_sparse_linear_algebra/operators/
transpose.rs1use crate::collections::sparse_matrix::GetGraphblasSparseMatrix;
2use crate::context::CallGraphBlasContext;
3use crate::error::SparseLinearAlgebraError;
4use crate::graphblas_bindings::GrB_transpose;
5
6use crate::value_type::ValueType;
7
8use super::binary_operator::AccumulatorBinaryOperator;
9use super::mask::MatrixMask;
10use super::options::GetOptionsForOperatorWithMatrixArgument;
11
12#[derive(Debug, Clone)]
13pub struct MatrixTranspose {}
14
15unsafe impl Send for MatrixTranspose {}
19unsafe impl Sync for MatrixTranspose {}
20
21impl MatrixTranspose {
22 pub fn new() -> Self {
23 Self {}
24 }
25}
26
27pub trait TransposeMatrix<EvaluationDomain: ValueType> {
28 fn apply(
29 &self,
30 matrix: &impl GetGraphblasSparseMatrix,
31 accumulator: &impl AccumulatorBinaryOperator<EvaluationDomain>,
32 transpose: &mut impl GetGraphblasSparseMatrix,
33 mask: &impl MatrixMask,
34 options: &impl GetOptionsForOperatorWithMatrixArgument,
35 ) -> Result<(), SparseLinearAlgebraError>;
36}
37
38impl<EvaluationDomain: ValueType> TransposeMatrix<EvaluationDomain> for MatrixTranspose {
39 fn apply(
40 &self,
41 matrix: &impl GetGraphblasSparseMatrix,
42 accumulator: &impl AccumulatorBinaryOperator<EvaluationDomain>,
43 transpose: &mut impl GetGraphblasSparseMatrix,
44 mask: &impl MatrixMask,
45 options: &impl GetOptionsForOperatorWithMatrixArgument,
46 ) -> Result<(), SparseLinearAlgebraError> {
47 let context = transpose.context_ref();
48
49 context.call(
50 || unsafe {
51 GrB_transpose(
52 transpose.graphblas_matrix(),
53 mask.graphblas_matrix(),
54 accumulator.accumulator_graphblas_type(),
55 matrix.graphblas_matrix(),
56 options.graphblas_descriptor(),
57 )
58 },
59 unsafe { transpose.graphblas_matrix_ref() },
60 )?;
61
62 Ok(())
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69 use crate::collections::sparse_matrix::operations::{
70 FromMatrixElementList, GetSparseMatrixElementValue,
71 };
72 use crate::collections::sparse_matrix::{MatrixElementList, SparseMatrix};
73 use crate::context::Context;
74 use crate::operators::binary_operator::{Assignment, First};
75 use crate::operators::mask::SelectEntireMatrix;
76 use crate::operators::options::OptionsForOperatorWithMatrixArgument;
77
78 #[test]
79 fn test_transpose() {
80 let context = Context::init_default().unwrap();
81
82 let element_list = MatrixElementList::<u8>::from_element_vector(vec![
83 (0, 0, 1).into(),
84 (1, 0, 2).into(),
85 (0, 1, 3).into(),
86 (1, 1, 4).into(),
87 ]);
88
89 let matrix = SparseMatrix::<u8>::from_element_list(
90 context.clone(),
91 (2, 2).into(),
92 element_list.clone(),
93 &First::<u8>::new(),
94 )
95 .unwrap();
96
97 let mut matrix_transpose = SparseMatrix::<u8>::new(context.clone(), (2, 2).into()).unwrap();
98
99 let transpose_operator = MatrixTranspose::new();
100
101 transpose_operator
102 .apply(
103 &matrix,
104 &Assignment::<u8>::new(),
105 &mut matrix_transpose,
106 &SelectEntireMatrix::new(context.clone()),
107 &OptionsForOperatorWithMatrixArgument::new_default(),
108 )
109 .unwrap();
110
111 assert_eq!(matrix_transpose.element_value_or_default(0, 0).unwrap(), 1);
112 assert_eq!(matrix_transpose.element_value_or_default(1, 0).unwrap(), 3);
113 assert_eq!(matrix_transpose.element_value_or_default(0, 1).unwrap(), 2);
114 assert_eq!(matrix_transpose.element_value_or_default(1, 1).unwrap(), 4);
115 }
116}