1function test108
2%TEST108 test boolean monoids
3
4% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
5% SPDX-License-Identifier: Apache-2.0
6
7% only well-defined if op is associative
8
9ops = {
10% 10 operators where x,y,z are all the same class
11% 'first',     % z = x
12% 'second',    % z = y
13'min',       % z = min(x,y)
14'max',       % z = max(x,y)
15'plus',      % z = x + y
16'minus',     % z = x - y
17'rminus',    % z = y - z
18'times',     % z = x * y
19% 'div',       % z = x / y
20% 'rdiv',      % z = y / x
21% 6 comparison operators where x,y,z are all the same class
22'iseq',      % z = (x == y)
23'isne',      % z = (x != y)
24% 'isgt',      % z = (x >  y)
25% 'islt',      % z = (x <  y)
26% 'isge',      % z = (x >= y)
27% 'isle',      % z = (x <= y)
28% 3 boolean operators where x,y,z are all the same class
29'or',        % z = x || y
30'and',       % z = x && y
31'xor'        % z = x != y
32%----------------------------
33% 6 comparison operators where x,y are all the same class, z is logical
34'eq',        % z = (x == y)
35'ne',        % z = (x != y)
36% 'gt',        % z = (x >  y)
37% 'lt',        % z = (x <  y)
38% 'ge',        % z = (x >= y)
39% 'le',        % z = (x <= y)
40} ;
41
42rng ('default') ;
43
44for d = 0:10
45
46    clear A
47    m = 4 ;
48    n = 4 ;
49    % d = 0.8 ;
50    A.matrix = spones (sprand (m, n, d/10)) ;
51    A.class = 'logical' ;
52    nz = nnz (A.matrix) ;
53    e = rand (nz, 1) ;
54    if (d == 3)
55        A.values = true (nz,1) ;
56    elseif (d == 4)
57        A.values = false (nz,1) ;
58    else
59        A.values = (e > 0.5) ;
60    end
61    X = A.values ;
62    n = length (X) ;
63
64%   fprintf ('\n============================================== %d: %d\n', d, nz) ;
65
66    nops = length (ops) ;
67    Results = nan (nops, 2, 2, 2) ;
68
69    for k = 1:length (ops)
70        op = ops {k} ;
71%       fprintf ('\n============================== %s\n', op) ;
72        for first = 0:1
73            for last = 0:1
74                A.values (1) = first ;
75                A.values (end) = last ;
76                X = A.values ;
77                for id = 0:1
78                    % no terminal
79                    identity = logical (id) ;
80                    result = GB_mex_reduce_bool (A, op, identity) ;
81
82                    % now compute in MATLAB
83
84                    % known identity values
85                    z = identity ;
86                    % 8 operators where x,y,z are all the same class
87                    if (isequal (op, 'first'))    z = identity      ; end
88                    if (isequal (op, 'second'))   z = identity      ; end
89                    if (isequal (op, 'min'))      z = true          ; end   % and
90                    if (isequal (op, 'max'))      z = false         ; end   % or
91                    if (isequal (op, 'plus'))     z = false         ; end   % or
92                    if (isequal (op, 'minus'))    z = false         ; end   % xor
93                    if (isequal (op, 'rminus'))   z = false         ; end   % xor
94                    if (isequal (op, 'times'))    z = true          ; end   % and
95                    if (isequal (op, 'div'))      z = identity      ; end   % first
96                    if (isequal (op, 'rdiv'))     z = identity      ; end   % second
97                    % 6 comparison operators where x,y,z are all the same class
98                    if (isequal (op, 'iseq'))     z = true          ; end   % eq
99                    if (isequal (op, 'isne'))     z = false         ; end   % xor
100                    if (isequal (op, 'isgt'))     z = identity      ; end   % gt
101                    if (isequal (op, 'islt'))     z = identity      ; end   % lt
102                    if (isequal (op, 'isge'))     z = identity      ; end   % ge
103                    if (isequal (op, 'isle'))     z = identity      ; end   % le
104                    % 3 boolean operators where x,y,z are all the same class
105                    if (isequal (op, 'or'))       z = false         ; end
106                    if (isequal (op, 'and'))      z = true          ; end
107                    if (isequal (op, 'xor'))      z = false         ; end
108                    %----------------------------
109                    % 6 comparison operators where x,y are all the same class, z is logical
110                    if (isequal (op, 'eq'))       z = true          ; end
111                    if (isequal (op, 'ne'))       z = false         ; end   % xor
112                    if (isequal (op, 'gt'))       z = identity      ; end
113                    if (isequal (op, 'lt'))       z = identity      ; end
114                    if (isequal (op, 'ge'))       z = identity      ; end
115                    if (isequal (op, 'le'))       z = identity      ; end
116
117                    for i = 1:n
118                        x = z ;
119                        y = X (i) ;
120
121                        % 8 operators where x,y,z are all the same class
122                        if (isequal (op, 'first'))    z = x             ; end
123                        if (isequal (op, 'second'))   z = y             ; end
124                        if (isequal (op, 'min'))      z = min(x,y)      ; end
125                        if (isequal (op, 'max'))      z = max(x,y)      ; end
126                        if (isequal (op, 'plus'))     z = or (x,y)      ; end
127                        if (isequal (op, 'minus'))    z = xor(x,y)      ; end
128                        if (isequal (op, 'rminus'))   z = xor(x,y)      ; end
129                        if (isequal (op, 'times'))    z = x * y         ; end
130                        if (isequal (op, 'div'))      z = x             ; end   % boolean division == first
131                        if (isequal (op, 'rdiv'))     z = y             ; end   % boolean division == second
132                        % 6 comparison operators where x,y,z are all the same class
133                        if (isequal (op, 'iseq'))     z = (x == y)      ; end
134                        if (isequal (op, 'isne'))     z = (x ~= y)      ; end
135                        if (isequal (op, 'isgt'))     z = (x >  y)      ; end
136                        if (isequal (op, 'islt'))     z = (x <  y)      ; end
137                        if (isequal (op, 'isge'))     z = (x >= y)      ; end
138                        if (isequal (op, 'isle'))     z = (x <= y)      ; end
139                        % 3 boolean operators where x,y,z are all the same class
140                        if (isequal (op, 'or'))       z = x || y        ; end
141                        if (isequal (op, 'and'))      z = x && y        ; end
142                        if (isequal (op, 'xor'))      z = xor(x,y)      ; end
143                        %----------------------------
144                        % 6 comparison operators where x,y are all the same class, z is logical
145                        if (isequal (op, 'eq'))       z = (x == y)      ; end
146                        if (isequal (op, 'ne'))       z = (x ~= y)      ; end
147                        if (isequal (op, 'gt'))       z = (x >  y)      ; end
148                        if (isequal (op, 'lt'))       z = (x <  y)      ; end
149                        if (isequal (op, 'ge'))       z = (x >= y)      ; end
150                        if (isequal (op, 'le'))       z = (x <= y)      ; end
151
152                    end
153
154                    assert (z == result) ;
155
156                    Results (k, 1+ first, 1+ last, 1+ id) = result ;
157                end
158            end
159        end
160    end
161
162    % fprintf ('\n=================================================== summary:\n') ;
163
164%{
165    for k = 1:length (ops)
166        op = ops {k} ;
167        fprintf ('\n============================== %s\n', op) ;
168        for first = 0:1
169            for last = 0:1
170                A.values (1) = first ;
171                A.values (end) = last ;
172                for id = 0:1
173                    % no terminal
174                    result = Results (k, 1+ first, 1+ last, 1+ id) ;
175                    fprintf ('first: %d  last: %d id: %d op: %6s result: %d\n', first, last, id, op, result) ;
176                end
177            end
178        end
179    end
180%}
181
182end
183
184fprintf ('\ntest108: all tests passed\n') ;
185