Line data Source code
1 : //------------------------------------------------------------------------------
2 : // LAGraph_Matrix_IsEqual: check two matrices for exact equality
3 : //------------------------------------------------------------------------------
4 :
5 : // LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved.
6 : // SPDX-License-Identifier: BSD-2-Clause
7 : //
8 : // For additional details (including references to third party source code and
9 : // other files) see the LICENSE file or contact permission@sei.cmu.edu. See
10 : // Contributors.txt for a full list of contributors. Created, in part, with
11 : // funding and support from the U.S. Government (see Acknowledgments.txt file).
12 : // DM22-0790
13 :
14 : // Contributed by Timothy A. Davis, Texas A&M University
15 :
16 : //------------------------------------------------------------------------------
17 :
18 : // LAGraph_Matrix_IsEqual: check if two matrices are identically equal (same
19 : // size, type, structure, size, and values).
20 :
21 : // If the two matrices are GrB_FP32, GrB_FP64, GxB_FC32, or GxB_FC64 and have
22 : // NaNs, then these functions will return false, since NaN == NaN is false.
23 :
24 : #define LG_FREE_WORK GrB_free (&C) ;
25 :
26 : #include "LG_internal.h"
27 :
28 3235 : int LAGraph_Matrix_IsEqual
29 : (
30 : // output:
31 : bool *result, // true if A == B, false if A != B or error
32 : // input:
33 : const GrB_Matrix A,
34 : const GrB_Matrix B,
35 : char *msg
36 : )
37 : {
38 :
39 : //--------------------------------------------------------------------------
40 : // check inputs
41 : //--------------------------------------------------------------------------
42 :
43 3235 : LG_CLEAR_MSG ;
44 3235 : GrB_Matrix C = NULL ;
45 3235 : LG_ASSERT (result != NULL, GrB_NULL_POINTER) ;
46 :
47 : //--------------------------------------------------------------------------
48 : // check for NULL and aliased matrices
49 : //--------------------------------------------------------------------------
50 :
51 3230 : if (A == NULL || B == NULL || A == B)
52 : {
53 : // two NULL matrices are identical, as are two aliased matrices
54 33 : (*result) = (A == B) ;
55 33 : return (GrB_SUCCESS) ;
56 : }
57 :
58 : //--------------------------------------------------------------------------
59 : // compare the type of A and B
60 : //--------------------------------------------------------------------------
61 :
62 : char atype_name [LAGRAPH_MAX_NAME_LEN] ;
63 : char btype_name [LAGRAPH_MAX_NAME_LEN] ;
64 3197 : LG_TRY (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
65 3197 : LG_TRY (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
66 3197 : if (!MATCHNAME (atype_name, btype_name))
67 : {
68 : // types differ
69 12 : (*result) = false ;
70 12 : return (GrB_SUCCESS) ;
71 : }
72 :
73 : //--------------------------------------------------------------------------
74 : // compare the size of A and B
75 : //--------------------------------------------------------------------------
76 :
77 : GrB_Index nrows1, ncols1, nrows2, ncols2 ;
78 3185 : GRB_TRY (GrB_Matrix_nrows (&nrows1, A)) ;
79 3185 : GRB_TRY (GrB_Matrix_nrows (&nrows2, B)) ;
80 3185 : GRB_TRY (GrB_Matrix_ncols (&ncols1, A)) ;
81 3185 : GRB_TRY (GrB_Matrix_ncols (&ncols2, B)) ;
82 3185 : if (nrows1 != nrows2 || ncols1 != ncols2)
83 : {
84 : // dimensions differ
85 2 : (*result) = false ;
86 2 : return (GrB_SUCCESS) ;
87 : }
88 :
89 : //--------------------------------------------------------------------------
90 : // compare the # entries in A and B
91 : //--------------------------------------------------------------------------
92 :
93 : GrB_Index nvals1, nvals2 ;
94 3183 : GRB_TRY (GrB_Matrix_nvals (&nvals1, A)) ;
95 3183 : GRB_TRY (GrB_Matrix_nvals (&nvals2, B)) ;
96 3183 : if (nvals1 != nvals2)
97 : {
98 : // # of entries differ
99 2 : (*result) = false ;
100 2 : return (GrB_SUCCESS) ;
101 : }
102 :
103 : //--------------------------------------------------------------------------
104 : // get the GrB_EQ_type operator
105 : //--------------------------------------------------------------------------
106 :
107 : GrB_Type type ;
108 3181 : LG_TRY (LAGraph_TypeFromName (&type, atype_name, msg)) ;
109 3181 : GrB_BinaryOp op = NULL ;
110 3181 : if (type == GrB_BOOL ) op = GrB_EQ_BOOL ;
111 2556 : else if (type == GrB_INT8 ) op = GrB_EQ_INT8 ;
112 2425 : else if (type == GrB_INT16 ) op = GrB_EQ_INT16 ;
113 2292 : else if (type == GrB_INT32 ) op = GrB_EQ_INT32 ;
114 1979 : else if (type == GrB_INT64 ) op = GrB_EQ_INT64 ;
115 1486 : else if (type == GrB_UINT8 ) op = GrB_EQ_UINT8 ;
116 1442 : else if (type == GrB_UINT16) op = GrB_EQ_UINT16 ;
117 1398 : else if (type == GrB_UINT32) op = GrB_EQ_UINT32 ;
118 1240 : else if (type == GrB_UINT64) op = GrB_EQ_UINT64 ;
119 938 : else if (type == GrB_FP32 ) op = GrB_EQ_FP32 ;
120 804 : else if (type == GrB_FP64 ) op = GrB_EQ_FP64 ;
121 : #if 0
122 : else if (type == GxB_FC32 ) op = GxB_EQ_FC32 ;
123 : else if (type == GxB_FC64 ) op = GxB_EQ_FC64 ;
124 : #endif
125 :
126 3181 : LG_ASSERT_MSG (op != NULL, GrB_NOT_IMPLEMENTED, "type not supported") ;
127 :
128 : //--------------------------------------------------------------------------
129 : // C = A .* B, where the structure of C is the intersection of A and B
130 : //--------------------------------------------------------------------------
131 :
132 3181 : GRB_TRY (GrB_Matrix_new (&C, GrB_BOOL, nrows1, ncols1)) ;
133 2696 : GRB_TRY (GrB_eWiseMult (C, NULL, NULL, op, A, B, NULL)) ;
134 :
135 : //--------------------------------------------------------------------------
136 : // ensure C has the same number of entries as A and B
137 : //--------------------------------------------------------------------------
138 :
139 : GrB_Index nvals ;
140 2210 : GRB_TRY (GrB_Matrix_nvals (&nvals, C)) ;
141 2210 : if (nvals != nvals1)
142 : {
143 : // structure of A and B are different
144 615 : LG_FREE_WORK ;
145 615 : (*result) = false ;
146 615 : return (GrB_SUCCESS) ;
147 : }
148 :
149 : //--------------------------------------------------------------------------
150 : // result = and (C)
151 : //--------------------------------------------------------------------------
152 :
153 1595 : GRB_TRY (GrB_reduce (result, NULL, GrB_LAND_MONOID_BOOL, C, NULL)) ;
154 :
155 : //--------------------------------------------------------------------------
156 : // free workspace and return result
157 : //--------------------------------------------------------------------------
158 :
159 1595 : LG_FREE_WORK ;
160 1595 : return (GrB_SUCCESS) ;
161 : }
|