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 1091 : 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 1091 : LG_CLEAR_MSG ;
49 1091 : GrB_Vector C = NULL ;
50 1091 : LG_ASSERT (result != NULL, GrB_NULL_POINTER) ;
51 :
52 : //--------------------------------------------------------------------------
53 : // check for NULL and aliased vectors
54 : //--------------------------------------------------------------------------
55 :
56 1090 : 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 : GrB_Type atype ;
68 : char atype_name [LAGRAPH_MAX_NAME_LEN] ;
69 : char btype_name [LAGRAPH_MAX_NAME_LEN] ;
70 1025 : LG_TRY (LAGraph_Vector_TypeName (atype_name, A, msg)) ;
71 1025 : LG_TRY (LAGraph_Vector_TypeName (btype_name, B, msg)) ;
72 1025 : LG_TRY (LAGraph_TypeFromName (&atype, atype_name, msg)) ;
73 1025 : if (!MATCHNAME (atype_name, btype_name))
74 : {
75 : // types differ
76 1 : (*result) = false ;
77 1 : return (GrB_SUCCESS) ;
78 : }
79 :
80 : //--------------------------------------------------------------------------
81 : // compare the size of A and B
82 : //--------------------------------------------------------------------------
83 :
84 : GrB_Index nrows1, nrows2;
85 1024 : GRB_TRY (GrB_Vector_size (&nrows1, A)) ;
86 1024 : GRB_TRY (GrB_Vector_size (&nrows2, B)) ;
87 1024 : if (nrows1 != nrows2)
88 : {
89 : // # of rows differ
90 4 : (*result) = false ;
91 4 : return (GrB_SUCCESS) ;
92 : }
93 :
94 : //--------------------------------------------------------------------------
95 : // compare the # entries in A and B
96 : //--------------------------------------------------------------------------
97 :
98 : GrB_Index nvals1, nvals2 ;
99 1020 : GRB_TRY (GrB_Vector_nvals (&nvals1, A)) ;
100 1020 : GRB_TRY (GrB_Vector_nvals (&nvals2, B)) ;
101 1020 : if (nvals1 != nvals2)
102 : {
103 : // # of entries differ
104 78 : (*result) = false ;
105 78 : return (GrB_SUCCESS) ;
106 : }
107 :
108 : //--------------------------------------------------------------------------
109 : // get the GrB_EQ_type operator
110 : //--------------------------------------------------------------------------
111 :
112 942 : GrB_BinaryOp op = NULL ;
113 : // select the comparator operator
114 942 : if (atype == GrB_BOOL ) op = GrB_EQ_BOOL ;
115 904 : else if (atype == GrB_INT8 ) op = GrB_EQ_INT8 ;
116 880 : else if (atype == GrB_INT16 ) op = GrB_EQ_INT16 ;
117 856 : else if (atype == GrB_INT32 ) op = GrB_EQ_INT32 ;
118 792 : else if (atype == GrB_INT64 ) op = GrB_EQ_INT64 ;
119 575 : else if (atype == GrB_UINT8 ) op = GrB_EQ_UINT8 ;
120 551 : else if (atype == GrB_UINT16) op = GrB_EQ_UINT16 ;
121 527 : else if (atype == GrB_UINT32) op = GrB_EQ_UINT32 ;
122 503 : else if (atype == GrB_UINT64) op = GrB_EQ_UINT64 ;
123 468 : else if (atype == GrB_FP32 ) op = GrB_EQ_FP32 ;
124 444 : else if (atype == GrB_FP64 ) op = GrB_EQ_FP64 ;
125 : // else if (atype == GxB_FC32 ) op = GxB_EQ_FC32 ;
126 : // else if (atype == GxB_FC64 ) op = GxB_EQ_FC64 ;
127 :
128 942 : LG_ASSERT_MSG (op != NULL, GrB_NOT_IMPLEMENTED, "type not supported") ;
129 :
130 : //--------------------------------------------------------------------------
131 : // C = A .* B, where the structure of C is the intersection of A and B
132 : //--------------------------------------------------------------------------
133 :
134 942 : GRB_TRY (GrB_Vector_new (&C, GrB_BOOL, nrows1)) ;
135 918 : GRB_TRY (GrB_eWiseMult (C, NULL, NULL, op, A, B, NULL)) ;
136 :
137 : //--------------------------------------------------------------------------
138 : // ensure C has the same number of entries as A and B
139 : //--------------------------------------------------------------------------
140 :
141 : GrB_Index nvals ;
142 895 : GRB_TRY (GrB_Vector_nvals (&nvals, C)) ;
143 895 : if (nvals != nvals1)
144 : {
145 : // structure of A and B are different
146 1 : LG_FREE_WORK ;
147 1 : (*result) = false ;
148 1 : return (GrB_SUCCESS) ;
149 : }
150 :
151 : //--------------------------------------------------------------------------
152 : // result = and (C)
153 : //--------------------------------------------------------------------------
154 :
155 894 : GRB_TRY (GrB_reduce (result, NULL, GrB_LAND_MONOID_BOOL, C, NULL)) ;
156 :
157 : //--------------------------------------------------------------------------
158 : // free workspace and return result
159 : //--------------------------------------------------------------------------
160 :
161 894 : LG_FREE_WORK ;
162 894 : return (GrB_SUCCESS) ;
163 : }
|