5549
|
1 ## Copyright (C) 2000 Paul Kienzle |
|
2 ## |
|
3 ## This program is free software; you can redistribute it and/or modify |
|
4 ## it under the terms of the GNU General Public License as published by |
|
5 ## the Free Software Foundation; either version 2 of the License, or |
|
6 ## (at your option) any later version. |
|
7 ## |
|
8 ## This program is distributed in the hope that it will be useful, |
|
9 ## but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 ## GNU General Public License for more details. |
|
12 ## |
|
13 ## You should have received a copy of the GNU General Public License |
5720
|
14 ## along with Octave; see the file COPYING. If not, write to the Free |
|
15 ## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
16 ## 02110-1301, USA. |
5549
|
17 |
|
18 ## -*- texinfo -*- |
5550
|
19 ## @deftypefn {Function File} {} __isequal__ (@var{nans_compare_equal}, @var{x1}, @var{x2}, @dots{}) |
|
20 ## Return true if @var{x1}, @var{x2}, @dots{} are all equal and |
5549
|
21 ## @var{nans_compare_equal} evaluates to false. |
|
22 ## |
|
23 ## If @var{nans_compare_equal} evaluates to true, then assume NaN == NaN. |
5642
|
24 ## @seealso{isequal, isequalwithequalnans} |
5549
|
25 ## @end deftypefn |
|
26 |
|
27 ## Modified by: William Poetra Yoga Hadisoeseno |
|
28 |
|
29 ## Algorithm: |
|
30 ## |
|
31 ## 1. Determine the class of x |
|
32 ## 2. If x is of the struct, cell, list or char class, for each |
|
33 ## argument after x, determine whether it has the same class |
|
34 ## and size as x. |
|
35 ## Otherwise, for each argument after x, verify that it is not |
|
36 ## of the struct, cell, list or char class, and that it has |
|
37 ## the same size as x. |
|
38 ## 3. For each argument after x, compare it for equality with x: |
|
39 ## a. struct compare each member by name, not by order (recursive) |
|
40 ## b. cell/list compare each member by order (recursive) |
|
41 ## c. char compare each member with strcmp |
|
42 ## d. <other> compare each nonzero member, and assume NaN == NaN |
|
43 ## if nans_compare_equal is nonzero. |
|
44 |
|
45 function t = __isequal__ (nans_compare_equal, x, varargin) |
|
46 |
|
47 if (nargin < 3) |
|
48 usage ("__isequal__ (nans_compare_equal, x1, x2, ...)"); |
|
49 endif |
|
50 |
|
51 l_v = nargin - 2; |
|
52 |
|
53 if (isstruct (x)) |
|
54 |
|
55 n_x = length (fieldnames (x)); |
|
56 |
|
57 t = true; |
|
58 for argn = 1:l_v |
|
59 y = varargin{argn}; |
|
60 t = t && isstruct (y) && (n_x == length (fieldnames (y))); |
|
61 endfor |
|
62 if (!t) |
|
63 return; |
|
64 endif |
|
65 |
|
66 for argn = 1:l_v |
|
67 y = varargin{argn}; |
|
68 for [v, k] = x |
5583
|
69 if (iscell (k)) |
|
70 fld = y (k{:}); |
|
71 else |
|
72 fld = y.(k); |
|
73 endif |
5549
|
74 t = t && struct_contains (y, k) \ |
5583
|
75 && __isequal__ (nans_compare_equal, v, fld); |
5549
|
76 endfor |
|
77 if (!t) |
|
78 return; |
|
79 endif |
|
80 endfor |
|
81 |
|
82 elseif ((iscell (x)) || (islist (x))) |
|
83 |
|
84 x = x(:); |
|
85 l_x = length (x); |
|
86 |
|
87 t = true; |
|
88 for argn = 1:l_v |
|
89 y = varargin{argn}(:); |
|
90 t = t && (iscell (y) || islist (y)) && (l_x == length (y)); |
|
91 endfor |
|
92 if (!t) |
|
93 return; |
|
94 endif |
|
95 |
|
96 for argn = 1:l_v |
|
97 y = varargin{argn}(:); |
|
98 for p = 1:l_x |
|
99 t = t && __isequal__ (nans_compare_equal, x{p}, y{p}); |
|
100 endfor |
|
101 if (!t) |
|
102 return; |
|
103 endif |
|
104 endfor |
|
105 |
|
106 elseif (ischar (x)) |
|
107 |
|
108 l_x = size (x); |
|
109 |
|
110 t = true; |
|
111 for argn = 1:l_v |
|
112 y = varargin{argn}; |
|
113 t = t && ischar (y) && (l_x == size (y)); |
|
114 endfor |
|
115 if (!t) |
|
116 return; |
|
117 endif |
|
118 |
|
119 for argn = 1:l_v |
|
120 t = t && strcmp (x, varargin{argn}); |
|
121 endfor |
|
122 |
|
123 else |
|
124 |
|
125 s_x = size (x); |
|
126 |
|
127 t = true; |
|
128 for argn = 1:l_v |
|
129 y = varargin{argn}; |
|
130 t = t && (! (isstruct (y) || iscell (y) || islist (y) || ischar (y))) \ |
|
131 && (s_x == size (y)); |
|
132 endfor |
|
133 if (!t) |
|
134 return; |
|
135 endif |
|
136 |
|
137 if (issparse (x)) |
|
138 f_x = spfind (x); |
|
139 else |
|
140 f_x = find (x); |
|
141 endif |
|
142 l_f_x = length (f_x); |
|
143 x = x(f_x); |
|
144 for argn = 1:l_v |
|
145 y = varargin{argn}; |
|
146 if (issparse (y)) |
|
147 f_y = spfind (y); |
|
148 else |
|
149 f_y = find (y); |
|
150 endif |
|
151 |
|
152 t = (l_f_x == length (f_y)) && all (f_x == f_y); |
|
153 if (!t) |
|
154 return; |
|
155 endif |
|
156 |
|
157 y = y(f_y); |
|
158 m = (x == y); |
|
159 t = all (m); |
|
160 |
|
161 if (!t) |
|
162 if (nans_compare_equal) |
|
163 t = isnan (x(!m)) && isnan (y(!m)); |
|
164 else |
|
165 return; |
|
166 endif |
|
167 endif |
|
168 endfor |
|
169 |
|
170 endif |
|
171 |
|
172 endfunction |
|
173 |
|
174 # test for equality |
|
175 %!assert(__isequal__(0,[1,2,3,4],[1,2,3,4])) |
|
176 %!assert(__isequal__(1,{1,2,NaN,4},{1,2,NaN,4})) |
|
177 %!assert(__isequal__(1,[1,2,NaN,4],[1,2,NaN,4])) |
|
178 %!assert(__isequal__(0,['a','b','c','d'],['a','b','c','d'])) |
|
179 # test for inequality |
|
180 %!assert(__isequal__(0,[1,2,3,4],[1;2;3;4]),false) |
|
181 %!assert(__isequal__(0,{1,2,3,4},[1,2,3,4]),false) |
|
182 %!assert(__isequal__(0,[1,2,3,4],{1,2,3,4}),false) |
|
183 %!assert(__isequal__(0,[1,2,NaN,4],[1,2,NaN,4]),false) |
|
184 %!assert(__isequal__(1,[1,2,NaN,4],[1,NaN,3,4]),false) |
|
185 %!assert(__isequal__(1,[1,2,NaN,4],[1,2,3,4]),false) |
|
186 %!assert(__isequal__(0,['a','b','c','d'],['a';'b';'c';'d']),false) |
|
187 # test for equality (struct) |
|
188 %!test |
|
189 %! A = struct (); |
|
190 %! A.char1 = "abcd"; |
|
191 %! A.int1 = 123; |
|
192 %! B = struct (); |
|
193 %! B.char1 = "abcd"; |
|
194 %! B.int1 = 123; |
|
195 %! C = struct (); |
|
196 %! C.char1 = "abcd"; |
|
197 %! C.int1 = 123; |
|
198 %! assert (__isequal__ (0, A, B, C)); |
|
199 # test for inequality (struct) |
|
200 %!test |
|
201 %! A = struct (); |
|
202 %! A.char1 = "abcd"; |
|
203 %! A.int1 = NaN; |
|
204 %! B = struct (); |
|
205 %! B.char1 = "abcd"; |
|
206 %! B.int1 = NaN; |
|
207 %! C = struct (); |
|
208 %! C.char1 = "abcd"; |
|
209 %! C.int1 = NaN; |
|
210 %! assert (__isequal__ (0, A, B, C), false); |