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