1 //------------------------------------------------------------------------------
2 // GB_mx_mxArray_to_Semiring
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 // Get a semiring struct from MATLAB and convert it into a GraphBLAS semiring.
11 //
12 // The semiring MATLAB struct must contain the following strings:
13 //
14 //      multiply    a string with the name of the 'multiply' binary operator.
15 //      add         a string with the name of the 'add' binary operator.
16 //                  The operator must be commutative.
17 //      type        the type of x and y for the multiply operator.
18 //                  ('logical', 'int8', ... 'double complex').  optional.
19 
20 #include "GB_mex.h"
21 
GB_mx_mxArray_to_Semiring(GrB_Semiring * handle,const mxArray * semiring_matlab,const char * name,const GrB_Type default_optype,const bool user_complex)22 bool GB_mx_mxArray_to_Semiring         // true if successful
23 (
24     GrB_Semiring *handle,               // the semiring
25     const mxArray *semiring_matlab,     // MATLAB version of semiring
26     const char *name,                   // name of the argument
27     const GrB_Type default_optype,      // default operator type
28     const bool user_complex         // if true, use user-defined Complex op
29 )
30 {
31 
32     (*handle) = NULL ;
33     const mxArray *multiply_mx = NULL, *type_mx = NULL, *add_mx = NULL ;
34 
35     if (semiring_matlab == NULL || mxIsEmpty (semiring_matlab))
36     {
37         // semiring is not present; defaults will be used
38         ;
39     }
40     else if (mxIsStruct (semiring_matlab))
41     {
42         // look for semiring.multiply
43         int fieldnumber = mxGetFieldNumber (semiring_matlab, "multiply") ;
44         if (fieldnumber >= 0)
45         {
46             multiply_mx = mxGetFieldByNumber (semiring_matlab, 0, fieldnumber) ;
47         }
48         // look for semiring.class
49         fieldnumber = mxGetFieldNumber (semiring_matlab, "class") ;
50         if (fieldnumber >= 0)
51         {
52             type_mx = mxGetFieldByNumber (semiring_matlab, 0, fieldnumber) ;
53         }
54         // look for semiring.add
55         fieldnumber = mxGetFieldNumber (semiring_matlab, "add") ;
56         if (fieldnumber >= 0)
57         {
58             add_mx = mxGetFieldByNumber (semiring_matlab, 0, fieldnumber) ;
59         }
60     }
61     else
62     {
63         mexWarnMsgIdAndTxt ("GB:warn","invalid semiring") ;
64         return (false) ;
65     }
66 
67     // find the corresponding GraphBLAS multiply operator
68     GrB_BinaryOp multiply = NULL ;
69     if (!GB_mx_string_to_BinaryOp (&multiply, default_optype,
70         multiply_mx, type_mx, user_complex) || multiply == NULL)
71     {
72         mexWarnMsgIdAndTxt ("GB:warn","mult missing or failed") ;
73         return (false) ;
74     }
75 
76     ASSERT_BINARYOP_OK (multiply, "semiring multiply", GB0) ;
77 
78     // find the corresponding GraphBLAS add operator
79     GrB_BinaryOp add = NULL ;
80     if (!GB_mx_string_to_BinaryOp (&add, multiply->ztype,
81         add_mx, NULL, user_complex) || add == NULL)
82     {
83         mexWarnMsgIdAndTxt ("GB:warn", "add missing or failed") ;
84         return (false) ;
85     }
86 
87     ASSERT_BINARYOP_OK (add, "semiring add", GB0) ;
88     ASSERT_BINARYOP_OK (multiply, "semiring multiply", GB0) ;
89 
90     // create the monoid with the add operator and its identity value
91     GrB_Monoid monoid = GB_mx_BinaryOp_to_Monoid (add) ;
92     if (monoid == NULL)
93     {
94         mexWarnMsgIdAndTxt ("GB:warn", "monoid missing or failed") ;
95         return (false) ;
96     }
97 
98     // create the semiring
99     GrB_Semiring semiring = GB_mx_semiring (monoid, multiply) ;
100     if (semiring == NULL)
101     {
102         return (false) ;
103     }
104 
105     ASSERT_SEMIRING_OK (semiring, "semiring", GB0) ;
106 
107     (*handle) = semiring ;
108     return (true) ;
109 }
110 
111