1function ok = GB_spec_compare (C_spec, C_mex, identity, tol) 2%GB_SPEC_COMPARE compare MATLAB mimic result with GraphBLAS result 3% ok = GB_spec_compare (C_spec, C_mex, identity, tol) 4% 5% compares two structs C_spec and C_mex. The C_spec struct contains a dense 6% matrix and is the output of a MATLAB mimic, C_spec = GB_spec_* (...) for 7% some GraphBLAS method. C_mex = GB_mex_* (...) is the output of the 8% corresponding MATLAB interface to the true GraphBLAS method, in C. 9 10% SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved. 11% SPDX-License-Identifier: Apache-2.0 12 13% get the semiring identity 14if (nargin < 3) 15 identity = 0 ; 16end 17if (isempty (identity)) 18 % results from the ANY monoid or operator cannot be checked with 19 % this function, since many results are possible. 20 ok = true ; 21 return 22end 23 24if (nargin < 4) 25 if (isfloat (identity)) 26 tol = 64*eps (class (identity)) ; % not GB_spec_type. 27 else 28 tol = 0 ; 29 end 30end 31 32% Convert C_mex from a sparse matrix into a dense matrix. It will have 33% explicit identity values where entries were not in the pattern of the sparse 34% C_mex.matrix. Entries outside the pattern are "don't care" values. They may 35% differ between C_spec and C_mex, because the latter works on dense matrices 36% and thus must compute the entries. With typecasting, an identity value may 37% get modified. C_mex, on the other hand, is computed in a GraphBLAS sparse 38% matrix, and never appears. It is only converted here to a dense matrix, with 39% the implicit entries being replaced with identity. C_spec is also converted, 40% using the same identity value. 41C1 = GB_spec_matrix (C_spec, identity) ; 42C2 = GB_spec_matrix (C_mex, identity) ; 43 44try 45 % ok_matrix = isequalwithequalnans (C1.matrix, C2.matrix) ; 46 ok_matrix = isequal_roundoff (C1.matrix, C2.matrix, tol) ; 47catch 48 ok_matrix = false ; 49end 50 51try 52 ok_pattern = isequal (C1.pattern, C2.pattern) ; 53catch 54 ok_pattern = false ; 55end 56 57try 58 ok_class = isequal (C1.class, C2.class) ; 59catch 60 ok_class = false ; 61end 62 63%{ 64if (~ok_class) 65 fprintf ('class is wrong:\n') ; 66 % C1.class 67 % C2.class 68end 69 70if (~ok_matrix) 71 fprintf ('matrix is wrong:\n') ; 72 identity 73 % C1.matrix 74 % C2.matrix 75end 76if (~ok_pattern) 77 fprintf ('pattern is wrong:\n') ; 78 C1.pattern 79 C2.pattern 80end 81%} 82 83if (~ok_class || ~ok_pattern || ~ok_matrix) 84 fprintf ('matrix: %d pattern: %d class %d\n', ... 85 ok_matrix, ok_pattern, ok_class) ; 86 norm (double (C1.matrix) - double (C2.matrix), 1) 87end 88 89% with no output, just assert that ok is true 90if (nargout == 0) 91 assert (ok_matrix && ok_pattern && ok_class) ; 92end 93 94