1 //------------------------------------------------------------------------------
2 // GB_mex_diag: compute C=diag(A,k)
3 //------------------------------------------------------------------------------
4 
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7 
8 //------------------------------------------------------------------------------
9 
10 // C = diag (A,k), where A and C are double
11 // C is a matrix the same size as A, not a vector.
12 
13 #include "GB_mex.h"
14 
15 #define USAGE "C = GB_mex_diag (A,k)"
16 
17 #define FREE_ALL                        \
18 {                                       \
19     GxB_Scalar_free_(&Thunk) ;          \
20     GrB_Matrix_free_(&A) ;              \
21     GrB_Matrix_free_(&C) ;              \
22     GB_mx_put_global (true) ;           \
23 }
24 
25 
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])26 void mexFunction
27 (
28     int nargout,
29     mxArray *pargout [ ],
30     int nargin,
31     const mxArray *pargin [ ]
32 )
33 {
34 
35     bool malloc_debug = GB_mx_get_global (true) ;
36     GrB_Matrix A = NULL, C = NULL ;
37     GxB_Scalar Thunk = NULL ;
38 
39     // check inputs
40     if (nargout > 1 || nargin < 1 || nargin > 2)
41     {
42         mexErrMsgTxt ("Usage: " USAGE) ;
43     }
44 
45     #define GET_DEEP_COPY ;
46     #define FREE_DEEP_COPY ;
47 
48     // get A
49     A = GB_mx_mxArray_to_Matrix (pargin [0], "A", false, true) ;
50     if (A == NULL)
51     {
52         FREE_ALL ;
53         mexErrMsgTxt ("failed") ;
54     }
55 
56     int64_t k = 0 ;
57     // get k
58     if (nargin > 1)
59     {
60         k = (int64_t) mxGetScalar (pargin [1]) ;
61     }
62 
63     // construct C
64     METHOD (GrB_Matrix_new (&C, GrB_FP64, A->vlen, A->vdim)) ;
65 
66     #undef GET_DEEP_COPY
67     #undef FREE_DEEP_COPY
68 
69     #define GET_DEEP_COPY  GrB_Matrix_new (&C, GrB_FP64, A->vlen, A->vdim) ;
70     #define FREE_DEEP_COPY GrB_Matrix_free_(&C) ;
71 
72     GxB_Scalar_new (&Thunk, GrB_INT64) ;
73     GxB_Scalar_setElement_INT64_(Thunk, k) ;
74     GxB_Scalar_wait_(&Thunk) ;
75 
76     // C = diag (A,k)
77     METHOD (GxB_Matrix_select_(C, NULL, NULL, GxB_DIAG, A, Thunk, NULL)) ;
78 
79     // return C to MATLAB as a regular MATLAB sparse matrix
80     pargout [0] = GB_mx_Matrix_to_mxArray (&C, "C diag", false) ;
81 
82     FREE_ALL ;
83 }
84 
85