text: //------------------------------------------------------------------------------
  // gbtrans: sparse matrix transpose
  //------------------------------------------------------------------------------
  
  // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
  // SPDX-License-Identifier: Apache-2.0
  
  //------------------------------------------------------------------------------
  
  // gbtrans is an interface to GrB_transpose.
  
  // Usage:
  
  // C = gbtrans (A)
  // C = gbtrans (A, desc)
  // C = gbtrans (Cin, accum, A, desc)
  // C = gbtrans (Cin, M, A, desc)
  // C = gbtrans (Cin, M, accum, A, desc)
  
  // If Cin is not present then it is implicitly a matrix with no entries, of the
  // right size (which depends on A and the descriptor).  Note that if desc.in0
  // is 'transpose', then C<M>=A or C<M>+=A is computed, with A not transposed,
  // since the default behavior is to transpose the input matrix.
  
  #include "gb_matlab.h"
  
  #define USAGE "usage: C = GrB.trans (Cin, M, accum, A, desc)"
  
  void mexFunction
  (
      int nargout,
      mxArray *pargout [ ],
      int nargin,
      const mxArray *pargin [ ]
  )
  {
  
      //--------------------------------------------------------------------------
      // check inputs
      //--------------------------------------------------------------------------
  
      gb_usage (nargin >= 1 && nargin <= 5 && nargout <= 2, USAGE) ;
  
      //--------------------------------------------------------------------------
      // find the arguments
      //--------------------------------------------------------------------------
  
      mxArray *Matrix [4], *String [2], *Cell [2] ;
      base_enum_t base ;
      kind_enum_t kind ;
      GxB_Format_Value fmt ;
      int nmatrices, nstrings, ncells, sparsity ;
      GrB_Descriptor desc ;
      gb_get_mxargs (nargin, pargin, USAGE, Matrix, &nmatrices, String, &nstrings,
          Cell, &ncells, &desc, &base, &kind, &fmt, &sparsity) ;
  
      CHECK_ERROR (nmatrices < 1 || nmatrices > 3 || nstrings > 1 || ncells > 0,
          USAGE) ;
  
      //--------------------------------------------------------------------------
      // get the matrices
      //--------------------------------------------------------------------------
  
      GrB_Type atype, ctype = NULL ;
      GrB_Matrix C = NULL, M = NULL, A ;
  
      if (nmatrices == 1)
      { 
          A = gb_get_shallow (Matrix [0]) ;
      }
      else if (nmatrices == 2)
      { 
          C = gb_get_deep    (Matrix [0]) ;
          A = gb_get_shallow (Matrix [1]) ;
      }
      else // if (nmatrices == 3)
      { 
          C = gb_get_deep    (Matrix [0]) ;
          M = gb_get_shallow (Matrix [1]) ;
          A = gb_get_shallow (Matrix [2]) ;
      }
  
      OK (GxB_Matrix_type (&atype, A)) ;
      if (C != NULL)
      { 
          OK (GxB_Matrix_type (&ctype, C)) ;
      }
  
      //--------------------------------------------------------------------------
      // get the operator
      //--------------------------------------------------------------------------
  
      GrB_BinaryOp accum = NULL ;
  
      if (nstrings == 1)
      { 
          // if accum appears, then Cin must also appear
          CHECK_ERROR (C == NULL, USAGE) ;
          accum = gb_mxstring_to_binop (String [0], ctype, ctype) ;
      }
  
      //--------------------------------------------------------------------------
      // construct C if not present on input
      //--------------------------------------------------------------------------
  
      // If C is NULL, then it is not present on input.
      // Construct C of the right size and type.
  
      if (C == NULL)
      { 
          // get the descriptor contents to determine if A is transposed
          GrB_Desc_Value in0 ;
          OK (GxB_Desc_get (desc, GrB_INP0, &in0)) ;
          bool A_transpose = (in0 == GrB_TRAN) ;
  
          // get the size of A
          GrB_Index anrows, ancols ;
          OK (GrB_Matrix_nrows (&anrows, A)) ;
          OK (GrB_Matrix_ncols (&ancols, A)) ;
  
          // determine the size of C
          GrB_Index cnrows = (A_transpose) ? anrows : ancols ;
          GrB_Index cncols = (A_transpose) ? ancols : anrows ;
  
          // use the type of A
          OK (GxB_Matrix_type (&ctype, A)) ;
  
          // create the matrix C and set its format and sparsity
          fmt = gb_get_format (cnrows, cncols, A, NULL, fmt) ;
          sparsity = gb_get_sparsity (A, NULL, sparsity) ;
          C = gb_new (ctype, cnrows, cncols, fmt, sparsity) ;
      }
  
      //--------------------------------------------------------------------------
      // compute C<M> += A or A'
      //--------------------------------------------------------------------------
  
      OK1 (C, GrB_transpose (C, M, accum, A, desc)) ;
  
      //--------------------------------------------------------------------------
      // free shallow copies
      //--------------------------------------------------------------------------
  
      OK (GrB_Matrix_free (&M)) ;
      OK (GrB_Matrix_free (&A)) ;
      OK (GrB_Descriptor_free (&desc)) ;
  
      //--------------------------------------------------------------------------
      // export the output matrix C back to MATLAB
      //--------------------------------------------------------------------------
  
      pargout [0] = gb_export (&C, kind) ;
      pargout [1] = mxCreateDoubleScalar (kind) ;
      GB_WRAPUP ;
  }
  
  