Line data Source code
1 : //------------------------------------------------------------------------------
2 : // LAGraph_Vector_IsEqual: check two vectors 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_Vector_IsEqual: checks if two vectors are identically equal (same
19 : // size, type, structure, size, and values).
20 :
21 : // See also LAGraph_Matrix_IsEqual.
22 :
23 : // If the two vectors are GrB_FP32, GrB_FP64, or related, and have NaNs, then
24 : // this function will return false, since NaN == NaN is false. To check for
25 : // NaN equality (like isequalwithequalnans in MATLAB), use
26 : // LAGraph_Vector_IsEqualOp with a user-defined operator f(x,y) that returns
27 : // true if x and y are both NaN.
28 :
29 : #define LG_FREE_WORK GrB_free (&C) ;
30 :
31 : #include "LG_internal.h"
32 :
33 625 : int LAGraph_Vector_IsEqual
34 : (
35 : // output:
36 : bool *result, // true if A == B, false if A != B or error
37 : // input:
38 : const GrB_Vector A,
39 : const GrB_Vector B,
40 : char *msg
41 : )
42 : {
43 :
44 : //--------------------------------------------------------------------------
45 : // check inputs
46 : //--------------------------------------------------------------------------
47 :
48 625 : LG_CLEAR_MSG ;
49 625 : GrB_Vector C = NULL ;
50 625 : LG_ASSERT (result != NULL, GrB_NULL_POINTER) ;
51 :
52 : //--------------------------------------------------------------------------
53 : // check for NULL and aliased vectors
54 : //--------------------------------------------------------------------------
55 :
56 624 : if (A == NULL || B == NULL || A == B)
57 : {
58 : // two NULL vectors are identical, as are two aliased matrices
59 65 : (*result) = (A == B) ;
60 65 : return (GrB_SUCCESS) ;
61 : }
62 :
63 : //--------------------------------------------------------------------------
64 : // compare the type of A and B
65 : //--------------------------------------------------------------------------
66 :
67 : char atype_name [LAGRAPH_MAX_NAME_LEN] ;
68 : char btype_name [LAGRAPH_MAX_NAME_LEN] ;
69 559 : LG_TRY (LAGraph_Vector_TypeName (atype_name, A, msg)) ;
70 559 : LG_TRY (LAGraph_Vector_TypeName (btype_name, B, msg)) ;
71 559 : if (!MATCHNAME (atype_name, btype_name))
72 : {
73 : // types differ
74 1 : (*result) = false ;
75 1 : return (GrB_SUCCESS) ;
76 : }
77 :
78 : //--------------------------------------------------------------------------
79 : // compare the size of A and B
80 : //--------------------------------------------------------------------------
81 :
82 : GrB_Index nrows1, nrows2;
83 558 : GRB_TRY (GrB_Vector_size (&nrows1, A)) ;
84 558 : GRB_TRY (GrB_Vector_size (&nrows2, B)) ;
85 558 : if (nrows1 != nrows2)
86 : {
87 : // # of rows differ
88 4 : (*result) = false ;
89 4 : return (GrB_SUCCESS) ;
90 : }
91 :
92 : //--------------------------------------------------------------------------
93 : // compare the # entries in A and B
94 : //--------------------------------------------------------------------------
95 :
96 : GrB_Index nvals1, nvals2 ;
97 554 : GRB_TRY (GrB_Vector_nvals (&nvals1, A)) ;
98 554 : GRB_TRY (GrB_Vector_nvals (&nvals2, B)) ;
99 554 : if (nvals1 != nvals2)
100 : {
101 : // # of entries differ
102 78 : (*result) = false ;
103 78 : return (GrB_SUCCESS) ;
104 : }
105 :
106 : //--------------------------------------------------------------------------
107 : // get the GrB_EQ_type operator
108 : //--------------------------------------------------------------------------
109 :
110 : GrB_Type type ;
111 476 : LG_TRY (LAGraph_TypeFromName (&type, atype_name, msg)) ;
112 476 : GrB_BinaryOp op = NULL ;
113 : // select the comparator operator
114 476 : if (type == GrB_BOOL ) op = GrB_EQ_BOOL ;
115 462 : else if (type == GrB_INT8 ) op = GrB_EQ_INT8 ;
116 462 : else if (type == GrB_INT16 ) op = GrB_EQ_INT16 ;
117 462 : else if (type == GrB_INT32 ) op = GrB_EQ_INT32 ;
118 422 : else if (type == GrB_INT64 ) op = GrB_EQ_INT64 ;
119 422 : else if (type == GrB_UINT8 ) op = GrB_EQ_UINT8 ;
120 422 : else if (type == GrB_UINT16) op = GrB_EQ_UINT16 ;
121 422 : else if (type == GrB_UINT32) op = GrB_EQ_UINT32 ;
122 422 : else if (type == GrB_UINT64) op = GrB_EQ_UINT64 ;
123 420 : else if (type == GrB_FP32 ) op = GrB_EQ_FP32 ;
124 420 : else if (type == GrB_FP64 ) op = GrB_EQ_FP64 ;
125 : #if 0
126 : else if (type == GxB_FC32 ) op = GxB_EQ_FC32 ;
127 : else if (type == GxB_FC64 ) op = GxB_EQ_FC64 ;
128 : #endif
129 :
130 476 : LG_ASSERT_MSG (op != NULL, GrB_NOT_IMPLEMENTED, "type not supported") ;
131 :
132 : //--------------------------------------------------------------------------
133 : // C = A .* B, where the structure of C is the intersection of A and B
134 : //--------------------------------------------------------------------------
135 :
136 476 : GRB_TRY (GrB_Vector_new (&C, GrB_BOOL, nrows1)) ;
137 452 : GRB_TRY (GrB_eWiseMult (C, NULL, NULL, op, A, B, NULL)) ;
138 :
139 : //--------------------------------------------------------------------------
140 : // ensure C has the same number of entries as A and B
141 : //--------------------------------------------------------------------------
142 :
143 : GrB_Index nvals ;
144 429 : GRB_TRY (GrB_Vector_nvals (&nvals, C)) ;
145 429 : if (nvals != nvals1)
146 : {
147 : // structure of A and B are different
148 1 : LG_FREE_WORK ;
149 1 : (*result) = false ;
150 1 : return (GrB_SUCCESS) ;
151 : }
152 :
153 : //--------------------------------------------------------------------------
154 : // result = and (C)
155 : //--------------------------------------------------------------------------
156 :
157 428 : GRB_TRY (GrB_reduce (result, NULL, GrB_LAND_MONOID_BOOL, C, NULL)) ;
158 :
159 : //--------------------------------------------------------------------------
160 : // free workspace and return result
161 : //--------------------------------------------------------------------------
162 :
163 428 : LG_FREE_WORK ;
164 428 : return (GrB_SUCCESS) ;
165 : }
|