1 //------------------------------------------------------------------------------
2 // GB_mex_vdiag: compute v=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 // v = diag (A,k,vtype)
11
12 #include "GB_mex.h"
13
14 #define USAGE "v = GB_mex_vdiag (A,k,vtype)"
15
16 #define FREE_ALL \
17 { \
18 GrB_Vector_free_(&V) ; \
19 GrB_Matrix_free_(&A) ; \
20 GB_mx_put_global (true) ; \
21 }
22
23
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])24 void mexFunction
25 (
26 int nargout,
27 mxArray *pargout [ ],
28 int nargin,
29 const mxArray *pargin [ ]
30 )
31 {
32
33 bool malloc_debug = GB_mx_get_global (true) ;
34 GrB_Matrix A = NULL ;
35 GrB_Vector V = NULL ;
36
37 // check inputs
38 if (nargout > 1 || nargin < 1 || nargin > 3)
39 {
40 mexErrMsgTxt ("Usage: " USAGE) ;
41 }
42
43 #define GET_DEEP_COPY ;
44 #define FREE_DEEP_COPY ;
45
46 // get A
47 A = GB_mx_mxArray_to_Matrix (pargin [0], "A", false, true) ;
48 if (A == NULL)
49 {
50 FREE_ALL ;
51 mexErrMsgTxt ("A failed") ;
52 }
53
54 // get k
55 int64_t k = 0 ;
56 if (nargin > 1)
57 {
58 k = (int64_t) mxGetScalar (pargin [1]) ;
59 }
60
61 // get the type
62 GrB_Type vtype ;
63 GxB_Matrix_type (&vtype, A) ;
64 vtype = GB_mx_string_to_Type (PARGIN (2), vtype) ;
65
66 // construct V
67 int64_t n, nrows, ncols ;
68 GrB_Matrix_nrows (&nrows, A) ;
69 GrB_Matrix_ncols (&ncols, A) ;
70 if (k >= ncols || k <= -nrows)
71 {
72 // output vector V must have zero length
73 n = 0 ;
74 }
75 else if (k >= 0)
76 {
77 // if k is in range 0 to n-1, V must have length min (m,n-k)
78 n = GB_IMIN (nrows, ncols - k) ;
79 }
80 else
81 {
82 // if k is in range -1 to -m+1, V must have length min (m+k,n)
83 n = GB_IMIN (nrows + k, ncols) ;
84 }
85
86 #undef GET_DEEP_COPY
87 #undef FREE_DEEP_COPY
88
89 #define GET_DEEP_COPY GrB_Vector_new (&V, vtype, n) ;
90 #define FREE_DEEP_COPY GrB_Vector_free_(&V) ;
91
92 GET_DEEP_COPY ;
93
94 // V = diag (A,k)
95 METHOD (GxB_Vector_diag (V, A, k, NULL)) ;
96
97 // return V to MATLAB as a struct
98 pargout [0] = GB_mx_Matrix_to_mxArray ((GrB_Matrix *) &V, "V=diag(A,k)",
99 true) ;
100 FREE_ALL ;
101 }
102
103