time | Calls | line |
---|
| | 175 | function [c,ia,ib] = setxorR2012a(a,b,options)
|
| | 176 | % 'R2012a' flag implementation
|
| | 177 |
|
| | 178 | % flagvals = {'rows' 'sorted' 'stable'};
|
< 0.001 | 2 | 179 | if nargin == 2
|
< 0.001 | 2 | 180 | byrow = false;
|
< 0.001 | 2 | 181 | order = 'sorted';
|
| | 182 | else
|
| | 183 | byrow = (options(1) > 0);
|
| | 184 | if options(3) > 0
|
| | 185 | order = 'stable';
|
| | 186 | else % if options(2) > 0 || sum(options(2:3)) == 0)
|
| | 187 | order = 'sorted';
|
| | 188 | end
|
< 0.001 | 2 | 189 | end
|
| | 190 |
|
| | 191 | % Check that one of A and B is double if A and B are non-homogeneous. Do a
|
| | 192 | % separate check if A is a heterogeneous object and only allow a B
|
| | 193 | % that is of the same root class.
|
< 0.001 | 2 | 194 | if ~(isa(a,'handle.handle') || isa(b,'handle.handle'))
|
< 0.001 | 2 | 195 | if ~strcmpi(class(a),class(b))
|
| | 196 | if isa(a,'matlab.mixin.Heterogeneous') && isa(b,'matlab.mixin.Heterogeneous')
|
| | 197 | rootClassA = meta.internal.findHeterogeneousRootClass(a);
|
| | 198 | if isempty(rootClassA) || ~isa(b,rootClassA.Name)
|
| | 199 | error(message('MATLAB:SETXOR:InvalidInputsDataType',class(a),class(b)));
|
| | 200 | end
|
| | 201 | elseif ~(strcmpi(class(a),'double') || strcmpi(class(b),'double'))
|
| | 202 | error(message('MATLAB:SETXOR:InvalidInputsDataType',class(a),class(b)));
|
| | 203 | end
|
< 0.001 | 2 | 204 | end
|
| 2 | 205 | end
|
| | 206 |
|
| | 207 | % Determine if A and B are both row vectors.
|
< 0.001 | 2 | 208 | rowvec = isrow(a) && isrow(b);
|
| | 209 |
|
< 0.001 | 2 | 210 | if ~byrow
|
| | 211 |
|
< 0.001 | 2 | 212 | numelA = numel(a);
|
< 0.001 | 2 | 213 | numelB = numel(b);
|
| | 214 | % Convert to columns.
|
< 0.001 | 2 | 215 | a = a(:);
|
< 0.001 | 2 | 216 | b = b(:);
|
| | 217 |
|
| | 218 | % Sort for sorted.
|
< 0.001 | 2 | 219 | if nargout <= 1
|
< 0.001 | 2 | 220 | if strcmp(order, 'sorted') % || strcmp(order, 'last')
|
< 0.001 | 2 | 221 | a = sort(a);
|
< 0.001 | 2 | 222 | b = sort(b);
|
< 0.001 | 2 | 223 | end
|
| | 224 | else
|
| | 225 | if ~strcmp(order, 'stable')
|
| | 226 | [a,ia] = sort(a);
|
| | 227 | else
|
| | 228 | ia = (1:numelA)';
|
| | 229 | end
|
| | 230 | if ~strcmp(order, 'stable')
|
| | 231 | [b,ib] = sort(b);
|
| | 232 | else
|
| | 233 | ib = (1:numelB)';
|
| | 234 | end
|
< 0.001 | 2 | 235 | end
|
| | 236 |
|
| | 237 | % Call ismember to find the elements in A which are not in B and
|
| | 238 | % vice versa
|
0.004 | 2 | 239 | tfa = ~ismember(a,b,'R2012a');
|
< 0.001 | 2 | 240 | tfb = ~ismember(b,a,'R2012a');
|
| | 241 |
|
| | 242 |
|
| | 243 | % a(tfa) now contains all members of A which are not in B
|
| | 244 | % b(tfb) now contains all members of B which are not in A
|
< 0.001 | 2 | 245 | if nargout <= 1
|
0.004 | 2 | 246 | c = unique([a(tfa);b(tfb)],order); % Remove duplicates from XOR list.
|
| | 247 | else
|
| | 248 | ia = ia(tfa);
|
| | 249 | ib = ib(tfb);
|
| | 250 | n = size(ia,1);
|
| | 251 | [c,ndx] = unique([a(tfa);b(tfb)],order); % NDX holds indices to generate C.
|
| | 252 | d = ndx > n; % Find indices of A and of B.
|
| | 253 | ia = ia(ndx(~d));
|
| | 254 | ib = ib(ndx(d) - n);
|
| | 255 | if isempty(ib)
|
| | 256 | ib = zeros(0,1);
|
| | 257 | end
|
| | 258 | if isempty(ia)
|
| | 259 | ia = zeros(0,1);
|
| | 260 | end
|
< 0.001 | 2 | 261 | end
|
| | 262 |
|
| | 263 | % If A and B are row vectors, return C as row vector.
|
< 0.001 | 2 | 264 | if rowvec
|
< 0.001 | 2 | 265 | c = c.';
|
< 0.001 | 2 | 266 | end
|
| | 267 |
|
| | 268 | else % 'rows' case
|
| | 269 | if ~(ismatrix(a) && ismatrix(b))
|
| | 270 | error(message('MATLAB:SETXOR:NotAMatrix'));
|
| | 271 | end
|
| | 272 |
|
| | 273 | [rowsA,colsA] = size(a);
|
| | 274 | [rowsB,colsB] = size(b);
|
| | 275 |
|
| | 276 | % Automatically pad strings with spaces
|
| | 277 | if ischar(a) && ischar(b)
|
| | 278 | b = [b repmat(' ',rowsB,colsA-colsB)];
|
| | 279 | a = [a repmat(' ',rowsA,colsB-colsA)];
|
| | 280 | elseif colsA ~= colsB
|
| | 281 | error(message('MATLAB:SETXOR:AandBColnumAgree'));
|
| | 282 | end
|
| | 283 |
|
| | 284 | % Make sure a and b contain unique elements.
|
| | 285 | [checkCast, cls] = needsCastingChecks(a, b);
|
| | 286 | if (nargout <= 1) && ~checkCast
|
| | 287 | uA = unique(a,'rows',order);
|
| | 288 | uB = unique(b,'rows',order);
|
| | 289 | else
|
| | 290 | % Get the unique elements of a and b.
|
| | 291 | [uA,ia] = unique(a,'rows',order);
|
| | 292 | [uB,ib] = unique(b,'rows',order);
|
| | 293 | end
|
| | 294 |
|
| | 295 | if checkCast
|
| | 296 | if ~strcmp(cls, class(a))
|
| | 297 | % Rows of a can lose precision when concatenating.
|
| | 298 | % Find all rows of a that are members of b only because of casting.
|
| | 299 | uAC = cast(uA,cls);
|
| | 300 | [lia, locb] = ismember(uAC, uB, 'rows');
|
| | 301 | lia = lia & any(cast(uAC,class(a)) ~= uA, 2);
|
| | 302 | % Remove those rows from uB so that we get the output indices
|
| | 303 | % correct.
|
| | 304 | uB(locb(lia),:) = [];
|
| | 305 | ib(locb(lia)) = [];
|
| | 306 | else
|
| | 307 | % Rows of b can lose precision when concatenating.
|
| | 308 | % Find all rows of b that are members of a only because of casting.
|
| | 309 | uBC = cast(uB,cls);
|
| | 310 | lib = ismember(uBC, uA, 'rows');
|
| | 311 | lib = lib & any(cast(uBC,class(b)) ~= uB, 2);
|
| | 312 | % Remove those rows from uB.
|
| | 313 | uB(lib,:) = [];
|
| | 314 | ib(lib) = [];
|
| | 315 | end
|
| | 316 | end
|
| | 317 |
|
| | 318 |
|
| | 319 | catuAuB = [uA;uB]; % Sort [uA;uB] in order to find matching entries
|
| | 320 | [sortuAuB,indSortuAuB] = sortrows(catuAuB);
|
| | 321 |
|
| | 322 | d = find(all(sortuAuB(1:end-1,:)==sortuAuB(2:end,:),2)); % d indicates the location of matching entries
|
| | 323 | indSortuAuB([d;d+1]) = []; % Remove all matching entries - indSortuAuB only contains elements not in intersect
|
| | 324 |
|
| | 325 | if strcmp(order, 'stable') % 'stable'
|
| | 326 | indSortuAuB = sort(indSortuAuB); % Sort the indices to get 'stable' order
|
| | 327 | end
|
| | 328 |
|
| | 329 | c = catuAuB(indSortuAuB,:); % Find C
|
| | 330 |
|
| | 331 | % Find indices if needed
|
| | 332 | if nargout > 1
|
| | 333 | n = size(uA,1);
|
| | 334 | d = indSortuAuB <= n; % Find indices in indSortuAuB that belong to A
|
| | 335 | if d == 0 % Force d to be correct shape if none of the elements
|
| | 336 | d = zeros(0,1); % in A are in C.
|
| | 337 | end
|
| | 338 | ia = ia(indSortuAuB(d));
|
| | 339 | if nargout > 2
|
| | 340 | d = indSortuAuB > n; % Find indices in indSortuAuB that belong to B
|
| | 341 | if d == 0 % Force d to be correct shape if none of the elements
|
| | 342 | d = zeros(0,1); % in B are in C
|
| | 343 | end
|
| | 344 | ib = ib(indSortuAuB(d)-n); % Find indices in indSortuAuB that belong to B
|
| | 345 | end
|
| | 346 | end
|
< 0.001 | 2 | 347 | end
|
< 0.001 | 2 | 348 | end
|
Other subfunctions in this file are not included in this listing.