1 //------------------------------------------------------------------------------
2 // GB_mex_mxm: C<Mask> = accum(C,A*B)
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 // c = prod (A) with terminal times monoid (terminal value is 0)
11
12 #include "GB_mex.h"
13
14 #define USAGE "c = GB_mex_reduce_complex (A, hack)"
15
16 #define FREE_ALL \
17 { \
18 GrB_Matrix_free_(&A) ; \
19 GrB_Monoid_free_(&Times_terminal) ; \
20 GB_mx_put_global (true) ; \
21 }
22
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])23 void mexFunction
24 (
25 int nargout,
26 mxArray *pargout [ ],
27 int nargin,
28 const mxArray *pargin [ ]
29 )
30 {
31
32 bool malloc_debug = GB_mx_get_global (true) ;
33 GrB_Info info ;
34 GrB_Matrix A = NULL ;
35 GrB_Monoid Times_terminal = NULL ;
36
37 // check inputs
38 if (nargout > 1 || nargin < 1 || nargin > 2)
39 {
40 mexErrMsgTxt ("Usage: " USAGE) ;
41 }
42
43 // get A (shallow copy; must be complex)
44 A = GB_mx_mxArray_to_Matrix (pargin [0], "A input", false, true) ;
45 if (A == NULL)
46 {
47 FREE_ALL ;
48 mexErrMsgTxt ("A failed") ;
49 }
50
51 if (A->type != Complex)
52 {
53 FREE_ALL ;
54 mexErrMsgTxt ("A must be complex") ;
55 }
56
57 GxB_FC64_t one = GxB_CMPLX (1,0) ;
58 GxB_FC64_t zero = GxB_CMPLX (0,0) ;
59
60 // create the monoid
61 if (Complex == GxB_FC64)
62 {
63 Times_terminal = GxB_TIMES_FC64_MONOID ;
64 }
65 else
66 {
67 info = GxB_Monoid_terminal_new_UDT (&Times_terminal,
68 Complex_times, &one, &zero) ;
69 if (info != GrB_SUCCESS)
70 {
71 FREE_ALL ;
72 mexErrMsgTxt ("Times_terminal failed") ;
73 }
74 }
75
76 int64_t GET_SCALAR (1, int64_t, hack, -1) ;
77 if (hack >= 0)
78 {
79 GxB_FC64_t *Ax = A->x ;
80 Ax [hack] = GxB_CMPLX (0,0) ;
81 }
82
83 // allocate the MATLAB output scalar
84 pargout [0] = GB_mx_create_full (1, 1, GxB_FC64) ;
85 GxB_FC64_t *c = (GxB_FC64_t *) mxGetComplexDoubles (pargout [0]) ;
86
87 // reduce to a scalar
88 if (Complex == GxB_FC64)
89 {
90 info = GxB_Matrix_reduce_FC64_(c, NULL, Times_terminal, A, NULL) ;
91 }
92 else
93 {
94 info = GrB_Matrix_reduce_UDT (c, NULL, Times_terminal, A, NULL) ;
95 }
96 if (info != GrB_SUCCESS)
97 {
98 FREE_ALL ;
99 mexErrMsgTxt ("reduce failed") ;
100 }
101
102 FREE_ALL ;
103 }
104
105