1function [multiply_op add_op identity ztype xtype ytype] = GB_spec_semiring (semiring) 2%GB_SPEC_SEMIRING create a semiring 3% 4% [multiply_op add_op identity ztype xtype ytype] = GB_spec_semiring (semiring) 5% 6% Given a semiring, extract the multiply operator, additive operator, additive 7% identity, and the ztype of z for z=multiply(...) and the monoid z=add(z,z). 8% 9% A semiring is a struct with 3 fields, each a string, with defaults used if 10% fields are not present. None of the content of the semiring should be 11% a struct. 12% 13% multiply a string with the name of the 'multiply' binary operator 14% (default is 'times'). 15% 16% add a string with the name of the 'add' operator (default is 'plus') 17% 18% class the MATLAB class of the operators (default is 'double', unless 19% the multiply operator is 'or', 'and, or 'xor'). Any logical or 20% numeric class is supported, which are the same as the 11 21% built-in GraphBLAS types: 22% 'logical' (boolean in GraphBLAS), 'int8', 'uint8', 'int16', 23% 'uint16', 'int32', 'uint32', 'int64', 'uint64', 'single' (FP43 24% in GraphBLAS), 'double' (FP64 in GraphBLAS), 25% 'single complex', and 'double complex' 26 27% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved. 28% SPDX-License-Identifier: Apache-2.0 29 30% set the default semiring 31if (isempty (semiring)) 32 semiring = struct ; 33end 34if (~isfield (semiring, 'multiply')) 35 semiring.multiply = 'times' ; 36end 37if (~isfield (semiring, 'add')) 38 semiring.add = 'plus' ; 39end 40if (~isfield (semiring, 'class')) 41 semiring.class = 'double' ; 42end 43 44% create the multiply operator. No error checks; it will be checked later 45% and can be any valid GraphBLAS binary operator. 46[mult mult_optype ztype xtype ytype] = GB_spec_operator (semiring.multiply, semiring.class); 47multiply_op.opname = mult ; 48multiply_op.optype = mult_optype ; 49 50if (isequal (ytype, 'none')) 51 error ('invalid multiply op') ; 52end 53 54% create the add operator 55[add_opname add_optype add_ztype add_xtype add_ytype] = GB_spec_operator (semiring.add, ztype) ; 56add_op.opname = add_opname ; 57add_op.optype = add_optype ; 58 59% get the identity of the add operator 60identity = GB_spec_identity (add_op) ; 61 62% make sure the monoid is valid 63if (~isequal (add_ztype, add_xtype) || ~isequal (add_ztype, add_xtype)) 64 error ('invalid monoid') ; 65end 66 67switch (add_opname) 68 case { 'min', 'max', 'plus', 'times', 'any', ... 69 'or', 'and', 'xor', 'eq', ... 70 'lor', 'land', 'lxor', 'lnxor', ... 71 'bitor', 'bitand', 'bitxor', 'bitxnor', ... 72 'bor', 'band', 'bxor', 'bxnor' } 73 % valid monoid 74 otherwise 75 error ('invalid monoid') ; 76end 77 78% make sure the monoid matches the operator ztype 79if (~isequal (add_ztype, ztype)) 80 error ('invalid monoid: must match ztype of multiplier') ; 81end 82 83% semiring 84% multiply_op 85% add_op 86% identity 87% ztype 88% xtype 89% ytype 90 91% make sure the semiring is built-in 92try 93 GB_mex_semiring (semiring, 0) ; 94catch 95 error ('not builtin semiring: %s.%s.%s', add_opname, mult, xtype) ; 96end 97 98