1function test23(fulltest) 2%TEST23 test GrB_*_build 3 4% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved. 5% SPDX-License-Identifier: Apache-2.0 6 7[~, ~, ~, types, ~, ~] = GB_spec_opsall ; 8types = types.all ; 9 10if (nargin < 1) 11 % do a short test, by default 12 fulltest = 0 ; 13end 14 15ops = { 16'first', 0, % z = x 17'second', 0, % z = y 18'pair', 1, % z = 1 19'any', 1, % z = pick x or y 20'min', 1, % z = min(x,y) 21'max', 1, % z = max(x,y) 22'plus', 1, % z = x + y 23'times', 1, % z = x * y 24'iseq', 1, % z = x == y 25'or', 1, % z = x || y 26'and', 1, % z = x && y 27'xor' 1, % z = x != y 28} ; 29 30 31if (fulltest) 32 fprintf ('\n==== exhaustive test for GrB_Matrix_build and GrB_Vector_build:\n'); 33 problems = [ 34 10, 8, 40, -5, 100 35 100, 200, 1000, -99, 200 36 50, 50, 500, -2, 3 37 ] ; 38else 39 fprintf ('\n==== quick test for GrB_Matrix_build and GrB_Vector_build:\n'); 40 problems = [ 41 10, 8, 40, -5, 100 42 ] ; 43end 44 45% try several problems 46for k0 = 1:size (problems,1) ; 47 48 % create nnz triplets for a matrix of size nrows-by-nrows 49 nrows = problems (k0,1) ; 50 ncols = problems (k0,2) ; 51 nnz = problems (k0,3) ; 52 y1 = problems (k0,4) ; 53 y2 = problems (k0,5) ; 54 55 rng ('default') ; 56 I = irand (0, nrows-1, nnz, 1) ; 57 J = irand (0, ncols-1, nnz, 1) ; 58 Y = y2 * rand (nnz, 1) + y1 ; 59 60 fprintf ('\nnrows: %d ncols %d nnz %d ymin %g ymax %g\n', ... 61 nrows, ncols, nnz, min (Y), max (Y)) ; 62 63 % try every operator 64 for k1 = 1:size (ops,1) 65 op.opname = ops {k1,1} ; 66 is_associative = ops {k1,2} ; 67 op_is_any = isequal (op.opname, 'any') ; 68 69 fprintf ('\n%-14s ', op.opname) ; 70 71 % try every operator type 72 for k2 = 1:length (types) 73 op.optype = types {k2} ; 74 z = GB_mex_cast (1, op.optype) ; 75 opint = isinteger (z) || islogical (z) ; 76 77 try 78 GB_spec_operator (op) ; 79 catch 80 continue 81 end 82 83 % the non-boolean logical operators are not associative 84 if (isequal (op.opname, 'or') || ... 85 isequal (op.opname, 'and') || ... 86 isequal (op.opname, 'iseq') || ... 87 isequal (op.opname, 'xor')) 88 if (~isequal (op.optype, 'logical')) 89 is_associative = false ; 90 end 91 end 92 93 if (contains (op.optype, 'single')) 94 epsilon = 1e-5 ; 95 elseif (contains (op.optype, 'double')) 96 epsilon = 1e-12 ; 97 else 98 epsilon = 0 ; 99 end 100 101 if (fulltest) 102 k3list = 1:length(types) ; 103 else 104 k3list = unique ([k2 randperm(11,2)]) ; 105 end 106 107 % try every type for X 108 for k3 = k3list % 1:length (types) 109 xtype = types {k3} ; 110 X = GB_mex_cast (Y, xtype) ; 111 fprintf ('.') ; 112 113 if (fulltest) 114 k4list = 1:length(types) ; 115 else 116 k4list = unique ([k3 randperm(11,2)]) ; 117 end 118 119 % try every type for the result 120 for k4 = k4list % 1:length (types) 121 ctype = types {k4} ; 122 123 % build the matrix in the natural order 124 % fprintf ('\n-------------------------------op: %s ', ... 125 % op.opname) ; 126 % fprintf ('optype: %s ', op.optype) ; 127 % fprintf ('xtype: %s ', xtype) ; 128 129 for A_is_csc = 0:1 130 131 A = GB_mex_Matrix_build (I, J, X, nrows, ncols, op, ... 132 ctype, A_is_csc) ; 133 % A is sparse but may have explicit zeros 134 if (~GB_spok (A.matrix*1)) 135 fprintf ('test failure: invalid sparse matrix\n') ; 136 assert (false) ; 137 end 138 A.matrix = full (double (A.matrix)) ; 139 if (~op_is_any) 140 S = GB_spec_build (I, J, X, nrows, ncols, op, 'natural', ctype) ; 141 if (~isequalwithequalnans (A.matrix, double (S.matrix))) ; 142 fprintf ('test failure: does not match spec\n') ; 143 assert (false) ; 144 end 145 assert (isequal (S.class, A.class)) ; 146 end 147 148 % build in random order, for associative operators. 149 if (is_associative) 150 [S2 p] = GB_spec_build (I, J, X, nrows, ncols, ... 151 op, 'random', ctype) ; 152 if (op_is_any) 153 % 'any' reduction 154 elseif (opint) 155 % integers are perfectly associative 156 if (~isequal (A.matrix, double (S2.matrix))) 157 fprintf ('fail: int non-associative\n') ; 158 assert (false) ; 159 end 160 else 161 % floating point is approximately associative 162 tol = norm (double (S2.matrix)) * epsilon ; 163 ok = isequal (isnan (A.matrix), isnan (S2.matrix)) ; 164 A.matrix (isnan (A.matrix)) = 0 ; 165 S2.matrix (isnan (S2.matrix)) = 0 ; 166 ok = ok & (norm (double (A.matrix - double (S2.matrix))) < tol) ; 167 if (~ok) 168 fprintf ('fail: float non-associative\n') ; 169 assert (false) ; 170 end 171 end 172 end 173 end 174 175 % build a vector in the natural order (discard J) 176 % fprintf ('\n-------------------------------op: %s ', op) ; 177 % fprintf ('optype: %s ', optype) ; 178 % fprintf ('xtype: %s\n', xtype) ; 179 A = GB_mex_Vector_build (I, X, nrows, op, ctype) ; 180 % A is sparse but may have explicit zeros 181 if (~GB_spok (A.matrix*1)) 182 fprintf ('test failure: invalid sparse matrix\n') ; 183 assert (false) ; 184 end 185 if (~op_is_any) 186 A.matrix = full (double (A.matrix)) ; 187 S = GB_spec_build (I, [ ], X, nrows, 1, op, 'natural', ctype) ; 188 if (~isequalwithequalnans (A.matrix, double (S.matrix))) ; 189 fprintf ('test failure: does not match spec\n') ; 190 assert (false) ; 191 end 192 end 193 end 194 end 195 end 196 end 197end 198 199fprintf ('\ntest23: all tests passed\n') ; 200 201