1 //------------------------------------------------------------------------------
2 // gbmdiag: construct a diaogonal matrix from 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 // C = gbmdiag (v, k, desc)
13 
14 #include "gb_matlab.h"
15 
16 #define USAGE "usage: C = gbmdiag (v, 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 C = NULL ;
52     GrB_Matrix V = gb_get_shallow (pargin [0]) ;
53     int64_t k = 0 ;
54 
55     int64_t ncols ;
56     OK (GrB_Matrix_ncols (&ncols, V)) ;
57     CHECK_ERROR (ncols != 1, "v must be a column vector") ;
58 
59     int s ;
60     OK (GxB_Matrix_Option_get (V, GxB_SPARSITY_STATUS, &s)) ;
61     CHECK_ERROR (s == GxB_HYPERSPARSE, "v cannot be hypersparse") ;
62 
63     if (nargin > 1)
64     {
65         CHECK_ERROR (!gb_mxarray_is_scalar (pargin [1]), "k must be a scalar") ;
66         double x = mxGetScalar (pargin [1]) ;
67         k = (int64_t) x ;
68         CHECK_ERROR ((double) k != x, "k must be an integer scalar") ;
69     }
70 
71     //--------------------------------------------------------------------------
72     // construct C
73     //--------------------------------------------------------------------------
74 
75     GrB_Type ctype = NULL ;
76     int64_t n ;
77     OK (GxB_Matrix_type (&ctype, V)) ;
78     OK (GrB_Matrix_nrows (&n, V)) ;
79     n += GB_IABS (k) ;
80     fmt = gb_get_format (n, n, NULL, NULL, fmt) ;
81     C = gb_new (ctype, n, n, fmt, 0) ;
82 
83     //--------------------------------------------------------------------------
84     // compute C = diag (v, k)
85     //--------------------------------------------------------------------------
86 
87     OK1 (C, GxB_Matrix_diag (C, (GrB_Vector) V, k, desc)) ;
88 
89     //--------------------------------------------------------------------------
90     // free shallow copies
91     //--------------------------------------------------------------------------
92 
93     OK (GrB_Matrix_free (&V)) ;
94     OK (GrB_Descriptor_free (&desc)) ;
95 
96     //--------------------------------------------------------------------------
97     // export the output matrix C back to MATLAB
98     //--------------------------------------------------------------------------
99 
100     pargout [0] = gb_export (&C, kind) ;
101     pargout [1] = mxCreateDoubleScalar (kind) ;
102     GB_WRAPUP ;
103 }
104 
105