1 //------------------------------------------------------------------------------
2 // gbvdiag: extract a diaogonal of a matrix, as a vector
3 //------------------------------------------------------------------------------
4
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: GPL-3.0-or-later
7
8 //------------------------------------------------------------------------------
9
10 // Usage:
11
12 // v = gbvdiag (A, k, desc)
13
14 #include "gb_matlab.h"
15
16 #define USAGE "usage: v = gbvdiag (A, k, desc)"
17
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])18 void mexFunction
19 (
20 int nargout,
21 mxArray *pargout [ ],
22 int nargin,
23 const mxArray *pargin [ ]
24 )
25 {
26
27 //--------------------------------------------------------------------------
28 // check inputs
29 //--------------------------------------------------------------------------
30
31 gb_usage (nargin >= 1 && nargin <= 3 && nargout <= 2, USAGE) ;
32
33 //--------------------------------------------------------------------------
34 // get the descriptor
35 //--------------------------------------------------------------------------
36
37 base_enum_t base ;
38 kind_enum_t kind ;
39 GxB_Format_Value fmt ;
40 int sparsity ;
41 GrB_Descriptor desc = NULL ;
42 desc = gb_mxarray_to_descriptor (pargin [nargin-1], &kind, &fmt,
43 &sparsity, &base) ;
44 // if present, remove the descriptor from consideration
45 if (desc != NULL) nargin-- ;
46
47 //--------------------------------------------------------------------------
48 // get the inputs
49 //--------------------------------------------------------------------------
50
51 GrB_Matrix V = NULL ;
52 GrB_Matrix A = gb_get_shallow (pargin [0]) ;
53 int64_t k = 0 ;
54
55 if (nargin > 1)
56 {
57 CHECK_ERROR (!gb_mxarray_is_scalar (pargin [1]), "k must be a scalar") ;
58 double x = mxGetScalar (pargin [1]) ;
59 k = (int64_t) x ;
60 CHECK_ERROR ((double) k != x, "k must be an integer scalar") ;
61 }
62
63 //--------------------------------------------------------------------------
64 // construct V
65 //--------------------------------------------------------------------------
66
67 GrB_Type vtype = NULL ;
68 int64_t n, nrows, ncols ;
69 OK (GxB_Matrix_type (&vtype, A)) ;
70 OK (GrB_Matrix_nrows (&nrows, A)) ;
71 OK (GrB_Matrix_ncols (&ncols, A)) ;
72
73 if (k >= ncols || k <= -nrows)
74 {
75 // output vector V must have zero length
76 n = 0 ;
77 }
78 else if (k >= 0)
79 {
80 // if k is in range 0 to n-1, V must have length min (m,n-k)
81 n = GB_IMIN (nrows, ncols - k) ;
82 }
83 else
84 {
85 // if k is in range -1 to -m+1, V must have length min (m+k,n)
86 n = GB_IMIN (nrows + k, ncols) ;
87 }
88
89 V = gb_new (vtype, n, 1, GxB_BY_COL, 0) ;
90
91 //--------------------------------------------------------------------------
92 // compute v = diag (A, k)
93 //--------------------------------------------------------------------------
94
95 OK1 (V, GxB_Vector_diag ((GrB_Vector) V, A, k, desc)) ;
96
97 //--------------------------------------------------------------------------
98 // free shallow copies
99 //--------------------------------------------------------------------------
100
101 OK (GrB_Matrix_free (&A)) ;
102 OK (GrB_Descriptor_free (&desc)) ;
103
104 //--------------------------------------------------------------------------
105 // export the output matrix V back to MATLAB
106 //--------------------------------------------------------------------------
107
108 pargout [0] = gb_export (&V, kind) ;
109 pargout [1] = mxCreateDoubleScalar (kind) ;
110 GB_WRAPUP ;
111 }
112
113