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