1function identity = GB_spec_identity (arg1,arg2)
2%GB_SPEC_IDENTITY the additive identity of a monoid
3%
4% identity = GB_spec_identity (add) ;
5% or
6% identity = GB_spec_identity (add_op, add_type) ; % both strings
7%
8% Returns the additive identity of an operator of a monoid.
9%
10% The identity is that value such that x == add (x,identity) == add
11% (identity,x).  For example, for 'plus', the value is zero.  for 'max' the
12% value of identity is -infinity.
13%
14% The addititive monoids supported are 'min', 'max', 'plus', 'times', 'or',
15% 'and', 'xor', 'eq', 'bitor', 'bitand', 'bitxor', and 'bitxnor'.
16% For the 'or', 'and', 'xor', and 'eq' the add_type must be 'logical'.
17% For the 'bit*' operators, the add_type must be unsigned integer.
18
19% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
20% SPDX-License-Identifier: Apache-2.0
21
22if (nargin == 1)
23    add = arg1 ;
24    [add_operator add_type ztype xtype ytype] = GB_spec_operator (add) ;
25else
26    add_operator = arg1 ;
27    add_type = arg2 ;
28end
29
30switch add_operator
31
32    case 'min'
33
34        % x == min (x, inf)
35        switch add_type
36            case 'logical'
37                identity = true ;
38            case 'int8'
39                identity = int8 (inf) ;
40            case 'uint8'
41                identity = uint8 (inf) ;
42            case 'int16'
43                identity = int16 (inf) ;
44            case 'uint16'
45                identity = uint16 (inf) ;
46            case 'int32'
47                identity = int32 (inf) ;
48            case 'uint32'
49                identity = uint32 (inf) ;
50            case 'int64'
51                identity = int64 (inf) ;
52            case 'uint64'
53                identity = uint64 (inf) ;
54            case 'single'
55                identity = single (inf) ;
56            case 'double'
57                identity = inf ;
58        end
59
60    case 'max'
61
62        % x == max (x, -inf)
63        switch add_type
64            case 'logical'
65                identity = false ;
66            case 'int8'
67                identity = int8 (-inf) ;
68            case 'uint8'
69                identity = 0 ;
70            case 'int16'
71                identity = int16 (-inf) ;
72            case 'uint16'
73                identity = 0 ;
74            case 'int32'
75                identity = int32 (-inf) ;
76            case 'uint32'
77                identity = 0 ;
78            case 'int64'
79                identity = int64 (-inf) ;
80            case 'uint64'
81                identity = 0 ;
82            case 'single'
83                identity = single (-inf) ;
84            case 'double'
85                identity = -inf ;
86        end
87
88    case 'plus'
89
90        % x == x + 0
91        identity = 0 ;
92
93    case 'times'
94
95        % x == x * 1
96        identity = 1 ;
97
98    case 'any'
99
100        identity = [ ] ;
101
102    case { 'or', 'lor'}
103
104        % x == x or false
105        identity = false ;
106
107        if (~isequal (add_type, 'logical'))
108            error ('OR monoid must be logical') ;
109        end
110
111    case { 'and', 'land' }
112
113        % x == x and true
114        identity = true ;
115
116        if (~isequal (add_type, 'logical'))
117            error ('AND monoid must be logical') ;
118        end
119
120    case { 'xor', 'lxor' }
121
122        % x == x xor false
123        identity = false ;
124
125        if (~isequal (add_type, 'logical'))
126            error ('XOR monoid must be logical') ;
127        end
128
129    case { 'eq', 'lxnor'}
130
131        % x == (x == true)
132        identity = true ;
133
134        if (~isequal (add_type, 'logical'))
135            error ('EQ monoid must be logical') ;
136        end
137
138    case { 'iseq', 'eq' }
139
140        % x == (x == true)
141        identity = true ;
142
143        if (~isequal (add_type, 'logical'))
144            error ('ISEQ monoid must be logical') ;
145        end
146
147    case { 'bitor', 'bor' }
148
149        switch add_type
150            case { 'uint8', 'uint16', 'uint32', 'uint64' }
151                identity = 0 ;
152            otherwise
153                error ('BIT* monoids must be unsigned int') ;
154        end
155
156    case { 'bitand', 'band' }
157
158        switch add_type
159            case { 'uint8', 'uint16', 'uint32', 'uint64' }
160                identity = intmax (add_type) ;
161            otherwise
162                error ('BIT* monoids must be unsigned int') ;
163        end
164
165    case { 'bitxor', 'bxor' }
166
167        switch add_type
168            case { 'uint8', 'uint16', 'uint32', 'uint64' }
169                identity = 0 ;
170            otherwise
171                error ('BIT* monoids must be unsigned int') ;
172        end
173
174    case { 'bitxnor', 'bxnor' }
175
176        switch add_type
177            case { 'uint8', 'uint16', 'uint32', 'uint64' }
178                identity = intmax (add_type) ;
179            otherwise
180                error ('BIT* monoids must be unsigned int') ;
181        end
182
183    otherwise
184
185        error ('unsupported additive monoid') ;
186end
187
188identity = GB_mex_cast (identity, add_type) ;
189
190