Mercurial > octave-nkf
comparison scripts/general/private/__isequal__.m @ 9899:9f25290a35e8
more private function and subfunction changes
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 01 Dec 2009 22:40:37 -0500 |
parents | scripts/general/__isequal__.m@6f1ea8241c99 |
children | 14d5fee02b3b |
comparison
equal
deleted
inserted
replaced
9898:1ee24979591e | 9899:9f25290a35e8 |
---|---|
1 ## Copyright (C) 2000, 2005, 2006, 2007, 2009 Paul Kienzle | |
2 ## | |
3 ## This file is part of Octave. | |
4 ## | |
5 ## Octave is free software; you can redistribute it and/or modify it | |
6 ## under the terms of the GNU General Public License as published by | |
7 ## the Free Software Foundation; either version 3 of the License, or (at | |
8 ## your option) any later version. | |
9 ## | |
10 ## Octave is distributed in the hope that it will be useful, but | |
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 ## General Public License for more details. | |
14 ## | |
15 ## You should have received a copy of the GNU General Public License | |
16 ## along with Octave; see the file COPYING. If not, see | |
17 ## <http://www.gnu.org/licenses/>. | |
18 | |
19 ## Undocumented internal function. | |
20 | |
21 ## -*- texinfo -*- | |
22 ## @deftypefn {Function File} {} __isequal__ (@var{nans_compare_equal}, @var{x1}, @var{x2}, @dots{}) | |
23 ## Undocumented internal function. | |
24 ## @end deftypefn | |
25 | |
26 ## Return true if @var{x1}, @var{x2}, @dots{} are all equal and | |
27 ## @var{nans_compare_equal} evaluates to false. | |
28 ## | |
29 ## If @var{nans_compare_equal} evaluates to true, then assume NaN == NaN. | |
30 | |
31 ## Modified by: William Poetra Yoga Hadisoeseno | |
32 | |
33 ## Algorithm: | |
34 ## | |
35 ## 1. Determine the class of x | |
36 ## 2. If x is of the struct, cell, list or char class, for each | |
37 ## argument after x, determine whether it has the same class | |
38 ## and size as x. | |
39 ## Otherwise, for each argument after x, verify that it is not | |
40 ## of the struct, cell, list or char class, and that it has | |
41 ## the same size as x. | |
42 ## 3. For each argument after x, compare it for equality with x: | |
43 ## a. struct compare each member by name, not by order (recursive) | |
44 ## b. cell/list compare each member by order (recursive) | |
45 ## c. char compare each member with strcmp | |
46 ## d. <other> compare each nonzero member, and assume NaN == NaN | |
47 ## if nans_compare_equal is nonzero. | |
48 | |
49 function t = __isequal__ (nans_compare_equal, x, varargin) | |
50 | |
51 if (nargin < 3) | |
52 print_usage (); | |
53 endif | |
54 | |
55 l_v = nargin - 2; | |
56 | |
57 ## Generic tests. | |
58 | |
59 ## Give an error for a list (that will make the code simpler and lists | |
60 ## are deprecated anyway. | |
61 if (islist (x)) | |
62 error ("__isequal__: list objects are deprecated and cannot be tested for equality here; use cell arrays instead"); | |
63 endif | |
64 | |
65 ## All arguments must either be of the same class or they must be | |
66 ## numeric values. | |
67 t = (all (strcmp (class(x), | |
68 cellfun (@class, varargin, "UniformOutput", false))) | |
69 || ((isnumeric (x) || islogical (x)) | |
70 && all ((cellfun (@isnumeric, varargin) | cellfun (@islogical, varargin))))); | |
71 | |
72 if (t) | |
73 ## Test that everything has the same number of dimensions. | |
74 s_x = size (x); | |
75 s_v = cellfun (@size, varargin, "UniformOutput", false); | |
76 t = all (length (s_x) == cellfun (@length, s_v)); | |
77 endif | |
78 | |
79 if (t) | |
80 ## Test that everything is the same size since it has the same | |
81 ## dimensionality. | |
82 l_x = length (s_x); | |
83 s_v = reshape ([s_v{:}], length (s_x), []); | |
84 idx = 0; | |
85 while (t && idx < l_x) | |
86 idx++; | |
87 t = all (s_x(idx) == s_v(idx, :)); | |
88 endwhile | |
89 endif | |
90 | |
91 if (t) | |
92 ## Check individual classes. | |
93 if (isstruct (x)) | |
94 ## Test the number of fields. | |
95 fn_x = fieldnames (x); | |
96 l_fn_x = length (fn_x); | |
97 fn_v = cellfun (@fieldnames, varargin, "UniformOutput", false); | |
98 t = all (l_fn_x == cellfun (@length, fn_v)); | |
99 | |
100 ## Test that all the names are equal. | |
101 idx = 0; | |
102 s_fn_x = sort (fn_x); | |
103 while (t && idx < l_v) | |
104 idx++; | |
105 ## We'll allow the fieldnames to be in a different order. | |
106 t = all (strcmp (s_fn_x, sort (fn_v{idx}))); | |
107 endwhile | |
108 | |
109 idx = 0; | |
110 while (t && idx < l_fn_x) | |
111 ## Test that all field values are equal. | |
112 idx++; | |
113 args = {nans_compare_equal, {x.(fn_x{idx})}}; | |
114 for argn = 1:l_v | |
115 args{argn+2} = {varargin{argn}.(fn_x{idx})}; | |
116 endfor | |
117 ## Minimize function calls by calling for all the arguments at | |
118 ## once. | |
119 t = __isequal__ (args{:}); | |
120 endwhile | |
121 | |
122 elseif (iscell (x)) | |
123 ## Check that each element of a cell is equal. | |
124 l_x = numel (x); | |
125 idx = 0; | |
126 while (t && idx < l_x) | |
127 idx++; | |
128 args = {nans_compare_equal, x{idx}}; | |
129 for p = 1:l_v | |
130 args{p+2} = varargin{p}{idx}; | |
131 endfor | |
132 t = __isequal__ (args{:}); | |
133 endwhile | |
134 | |
135 elseif (ischar (x)) | |
136 | |
137 ## Sizes are equal already, so we can just make everything into a | |
138 ## row and test the rows. | |
139 for i = 1:l_v | |
140 strings{i} = reshape (varargin{i}, 1, []); | |
141 endfor | |
142 t = all (strcmp (reshape (x, 1, []), strings)); | |
143 | |
144 else | |
145 ## Check the numeric types. | |
146 | |
147 if (issparse (x)) | |
148 f_x = spfind (x); | |
149 else | |
150 f_x = find (x); | |
151 endif | |
152 l_f_x = length (f_x); | |
153 x = x(f_x); | |
154 for argn = 1:l_v | |
155 y = varargin{argn}; | |
156 if (issparse (y)) | |
157 f_y = spfind (y); | |
158 else | |
159 f_y = find (y); | |
160 endif | |
161 | |
162 t = (l_f_x == length (f_y)) && all (f_x == f_y); | |
163 if (!t) | |
164 return; | |
165 endif | |
166 | |
167 y = y(f_y); | |
168 m = (x == y); | |
169 t = all (m); | |
170 | |
171 if (!t) | |
172 if (nans_compare_equal) | |
173 t = isnan (x(!m)) && isnan (y(!m)); | |
174 else | |
175 return; | |
176 endif | |
177 endif | |
178 endfor | |
179 | |
180 endif | |
181 endif | |
182 | |
183 endfunction |