Line data Source code
1 : //------------------------------------------------------------------------------
2 : // LAGraph_Matrix_IsEqual: check two matrices for exact equality
3 : //------------------------------------------------------------------------------
4 :
5 : // LAGraph, (c) 2019-2023 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 have any floating point type 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 3411 : 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 3411 : LG_CLEAR_MSG ;
44 3411 : GrB_Matrix C = NULL ;
45 3411 : LG_ASSERT (result != NULL, GrB_NULL_POINTER) ;
46 :
47 : //--------------------------------------------------------------------------
48 : // check for NULL and aliased matrices
49 : //--------------------------------------------------------------------------
50 :
51 3406 : 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 : GrB_Type atype ;
63 : char atype_name [LAGRAPH_MAX_NAME_LEN] ;
64 : char btype_name [LAGRAPH_MAX_NAME_LEN] ;
65 3373 : LG_TRY (LAGraph_Matrix_TypeName (atype_name, A, msg)) ;
66 3373 : LG_TRY (LAGraph_Matrix_TypeName (btype_name, B, msg)) ;
67 3373 : LG_TRY (LAGraph_TypeFromName (&atype, atype_name, msg)) ;
68 3373 : if (!MATCHNAME (atype_name, btype_name))
69 : {
70 : // types differ
71 12 : (*result) = false ;
72 12 : return (GrB_SUCCESS) ;
73 : }
74 :
75 : //--------------------------------------------------------------------------
76 : // compare the size of A and B
77 : //--------------------------------------------------------------------------
78 :
79 : GrB_Index nrows1, ncols1, nrows2, ncols2 ;
80 3361 : GRB_TRY (GrB_Matrix_nrows (&nrows1, A)) ;
81 3361 : GRB_TRY (GrB_Matrix_nrows (&nrows2, B)) ;
82 3361 : GRB_TRY (GrB_Matrix_ncols (&ncols1, A)) ;
83 3361 : GRB_TRY (GrB_Matrix_ncols (&ncols2, B)) ;
84 3361 : if (nrows1 != nrows2 || ncols1 != ncols2)
85 : {
86 : // dimensions differ
87 2 : (*result) = false ;
88 2 : return (GrB_SUCCESS) ;
89 : }
90 :
91 : //--------------------------------------------------------------------------
92 : // compare the # entries in A and B
93 : //--------------------------------------------------------------------------
94 :
95 : GrB_Index nvals1, nvals2 ;
96 3359 : GRB_TRY (GrB_Matrix_nvals (&nvals1, A)) ;
97 3359 : GRB_TRY (GrB_Matrix_nvals (&nvals2, B)) ;
98 3359 : if (nvals1 != nvals2)
99 : {
100 : // # of entries differ
101 2 : (*result) = false ;
102 2 : return (GrB_SUCCESS) ;
103 : }
104 :
105 : //--------------------------------------------------------------------------
106 : // get the GrB_EQ_type operator
107 : //--------------------------------------------------------------------------
108 :
109 3357 : GrB_BinaryOp op = NULL ;
110 3357 : if (atype == GrB_BOOL ) op = GrB_EQ_BOOL ;
111 2709 : else if (atype == GrB_INT8 ) op = GrB_EQ_INT8 ;
112 2574 : else if (atype == GrB_INT16 ) op = GrB_EQ_INT16 ;
113 2437 : else if (atype == GrB_INT32 ) op = GrB_EQ_INT32 ;
114 2120 : else if (atype == GrB_INT64 ) op = GrB_EQ_INT64 ;
115 1619 : else if (atype == GrB_UINT8 ) op = GrB_EQ_UINT8 ;
116 1575 : else if (atype == GrB_UINT16) op = GrB_EQ_UINT16 ;
117 1531 : else if (atype == GrB_UINT32) op = GrB_EQ_UINT32 ;
118 1367 : else if (atype == GrB_UINT64) op = GrB_EQ_UINT64 ;
119 970 : else if (atype == GrB_FP32 ) op = GrB_EQ_FP32 ;
120 832 : else if (atype == GrB_FP64 ) op = GrB_EQ_FP64 ;
121 : // else if (atype == GxB_FC32 ) op = GxB_EQ_FC32 ;
122 : // else if (atype == GxB_FC64 ) op = GxB_EQ_FC64 ;
123 :
124 3357 : LG_ASSERT_MSG (op != NULL, GrB_NOT_IMPLEMENTED, "type not supported") ;
125 :
126 : //--------------------------------------------------------------------------
127 : // C = A .* B, where the structure of C is the intersection of A and B
128 : //--------------------------------------------------------------------------
129 :
130 3357 : GRB_TRY (GrB_Matrix_new (&C, GrB_BOOL, nrows1, ncols1)) ;
131 2872 : GRB_TRY (GrB_eWiseMult (C, NULL, NULL, op, A, B, NULL)) ;
132 :
133 : //--------------------------------------------------------------------------
134 : // ensure C has the same number of entries as A and B
135 : //--------------------------------------------------------------------------
136 :
137 : GrB_Index nvals ;
138 2386 : GRB_TRY (GrB_Matrix_nvals (&nvals, C)) ;
139 2386 : if (nvals != nvals1)
140 : {
141 : // structure of A and B are different
142 615 : LG_FREE_WORK ;
143 615 : (*result) = false ;
144 615 : return (GrB_SUCCESS) ;
145 : }
146 :
147 : //--------------------------------------------------------------------------
148 : // result = and (C)
149 : //--------------------------------------------------------------------------
150 :
151 1771 : GRB_TRY (GrB_reduce (result, NULL, GrB_LAND_MONOID_BOOL, C, NULL)) ;
152 :
153 : //--------------------------------------------------------------------------
154 : // free workspace and return result
155 : //--------------------------------------------------------------------------
156 :
157 1771 : LG_FREE_WORK ;
158 1771 : return (GrB_SUCCESS) ;
159 : }
|