1 //------------------------------------------------------------------------------
2 // GB_mex_mxm_alias: C<C> = accum(C,C*C)
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 #include "GB_mex.h"
11 
12 #define USAGE "C = GB_mex_mxm_alias (C, accum, semiring, desc)"
13 
14 #define FREE_ALL                                    \
15 {                                                   \
16     GrB_Matrix_free_(&C) ;                          \
17     if (semiring != Complex_plus_times)             \
18     {                                               \
19         if (semiring != NULL)                       \
20         {                                           \
21             GrB_Monoid_free_(&(semiring->add)) ;    \
22         }                                           \
23         GrB_Semiring_free_(&semiring) ;             \
24     }                                               \
25     GrB_Descriptor_free_(&desc) ;                   \
26     GB_mx_put_global (true) ;                       \
27 }
28 
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])29 void mexFunction
30 (
31     int nargout,
32     mxArray *pargout [ ],
33     int nargin,
34     const mxArray *pargin [ ]
35 )
36 {
37 
38     bool malloc_debug = GB_mx_get_global (true) ;
39     GrB_Matrix C = NULL ;
40     GrB_Semiring semiring = NULL ;
41     GrB_Descriptor desc = NULL ;
42 
43     // check inputs
44     if (nargout > 1 || nargin < 3 || nargin > 4)
45     {
46         mexErrMsgTxt ("Usage: " USAGE) ;
47     }
48 
49     // get C (make a deep copy)
50     #define GET_DEEP_COPY \
51     C = GB_mx_mxArray_to_Matrix (pargin [0], "C input", true, true) ;
52     #define FREE_DEEP_COPY GrB_Matrix_free_(&C) ;
53     GET_DEEP_COPY ;
54     if (C == NULL)
55     {
56         FREE_ALL ;
57         mexErrMsgTxt ("C failed") ;
58     }
59 
60     bool user_complex = (Complex != GxB_FC64) && (C->type == Complex) ;
61 
62     // get semiring
63     if (!GB_mx_mxArray_to_Semiring (&semiring, pargin [2], "semiring",
64         C->type, user_complex))
65     {
66         FREE_ALL ;
67         mexErrMsgTxt ("semiring failed") ;
68     }
69 
70     // get accum, if present
71     GrB_BinaryOp accum ;
72     if (!GB_mx_mxArray_to_BinaryOp (&accum, pargin [1], "accum",
73         C->type, user_complex))
74     {
75         FREE_ALL ;
76         mexErrMsgTxt ("accum failed") ;
77     }
78 
79     // get desc
80     if (!GB_mx_mxArray_to_Descriptor (&desc, PARGIN (3), "desc"))
81     {
82         FREE_ALL ;
83         mexErrMsgTxt ("desc failed") ;
84     }
85 
86     // C<C> = accum(C,C*C)
87     METHOD (GrB_mxm (C, C, accum, semiring, C, C, desc)) ;
88 
89     // return C to MATLAB as a struct and free the GraphBLAS C
90     pargout [0] = GB_mx_Matrix_to_mxArray (&C, "C output", true) ;
91 
92     FREE_ALL ;
93 }
94 
95