time | Calls | line |
---|
| | 1 | function varargout = setdiff(varargin)
|
| | 2 | %SETDIFF Set difference.
|
| | 3 | % C = SETDIFF(A,B) for vectors A and B, returns the values in A that
|
| | 4 | % are not in B with no repetitions. C will be sorted.
|
| | 5 | %
|
| | 6 | % C = SETDIFF(A,B,'rows') for matrices A and B with the same number of
|
| | 7 | % columns, returns the rows from A that are not in B. The rows of the
|
| | 8 | % matrix C will be in sorted order.
|
| | 9 | %
|
| | 10 | % [C,IA] = SETDIFF(A,B) also returns an index vector IA such that
|
| | 11 | % C = A(IA). If there are repeated values in A that are not in B, then
|
| | 12 | % the index of the first occurrence of each repeated value is returned.
|
| | 13 | %
|
| | 14 | % [C,IA] = SETDIFF(A,B,'rows') also returns an index vector IA such that
|
| | 15 | % C = A(IA,:).
|
| | 16 | %
|
| | 17 | % [C,IA] = SETDIFF(A,B,'stable') for arrays A and B, returns the values
|
| | 18 | % of C in the order that they appear in A.
|
| | 19 | % [C,IA] = SETDIFF(A,B,'sorted') returns the values of C in sorted order.
|
| | 20 | % If A is a row vector, then C will be a row vector as well, otherwise C
|
| | 21 | % will be a column vector. IA is a column vector. If there are repeated
|
| | 22 | % values in A that are not in B, then the index of the first occurrence of
|
| | 23 | % each repeated value is returned.
|
| | 24 | %
|
| | 25 | % [C,IA] = SETDIFF(A,B,'rows','stable') returns the rows of C in the
|
| | 26 | % same order that they appear in A.
|
| | 27 | % [C,IA] = SETDIFF(A,B,'rows','sorted') returns the rows of C in sorted
|
| | 28 | % order.
|
| | 29 | %
|
| | 30 | % The behavior of SETDIFF has changed. This includes:
|
| | 31 | % - occurrence of indices in IA switched from last to first
|
| | 32 | % - orientation of vector C
|
| | 33 | % - IA will always be a column index vector
|
| | 34 | % - tighter restrictions on combinations of classes
|
| | 35 | %
|
| | 36 | % If this change in behavior has adversely affected your code, you may
|
| | 37 | % preserve the previous behavior with:
|
| | 38 | %
|
| | 39 | % [C,IA] = SETDIFF(A,B,'legacy')
|
| | 40 | % [C,IA] = SETDIFF(A,B,'rows','legacy')
|
| | 41 | %
|
| | 42 | % Examples:
|
| | 43 | %
|
| | 44 | % a = [9 9 9 9 9 9 8 8 8 8 7 7 7 6 6 6 5 5 4 2 1]
|
| | 45 | % b = [1 1 1 3 3 3 3 3 4 4 4 4 4 10 10 10]
|
| | 46 | %
|
| | 47 | % [c1,ia1] = setdiff(a,b)
|
| | 48 | % % returns
|
| | 49 | % c1 = [2 5 6 7 8 9]
|
| | 50 | % ia1 = [20 17 14 11 7 1]'
|
| | 51 | %
|
| | 52 | % [c2,ia2] = setdiff(a,b,'stable')
|
| | 53 | % % returns
|
| | 54 | % c2 = [9 8 7 6 5 2]
|
| | 55 | % ia2 = [1 7 11 14 17 20]'
|
| | 56 | %
|
| | 57 | % c = setdiff([1 NaN 2 3],[3 4 NaN 1])
|
| | 58 | % % NaNs compare as not equal, so this returns
|
| | 59 | % c = [2 NaN]
|
| | 60 | %
|
| | 61 | % Class support for inputs A and B, where A and B must be of the same
|
| | 62 | % class unless stated otherwise:
|
| | 63 | % - logical, char, all numeric classes (may combine with double arrays)
|
| | 64 | % - cell arrays of strings (may combine with char arrays)
|
| | 65 | % -- 'rows' option is not supported for cell arrays
|
| | 66 | % - objects with methods SORT (SORTROWS for the 'rows' option), EQ and NE
|
| | 67 | % -- including heterogeneous arrays derived from the same root class
|
| | 68 | %
|
| | 69 | % See also UNIQUE, UNION, INTERSECT, SETXOR, ISMEMBER, SORT, SORTROWS.
|
| | 70 |
|
| | 71 | % Copyright 1984-2019 The MathWorks, Inc.
|
| | 72 |
|
| | 73 | % Determine the number of outputs requested.
|
< 0.001 | 108 | 74 | if nargout == 0
|
| | 75 | nlhs = 1;
|
< 0.001 | 108 | 76 | else
|
< 0.001 | 108 | 77 | nlhs = nargout;
|
< 0.001 | 108 | 78 | end
|
| | 79 |
|
< 0.001 | 108 | 80 | narginchk(2,4);
|
| | 81 | % Convert string flags to char flags to dispatch to the right method
|
< 0.001 | 108 | 82 | if (nargin == 3) && isstring(varargin{3})
|
| | 83 | varargin{3} = convertFlag(varargin{3});
|
| | 84 | [varargout{1:nlhs}] = setdiff(varargin{:});
|
| | 85 | return;
|
< 0.001 | 108 | 86 | end
|
< 0.001 | 108 | 87 | if (nargin == 4) && (isstring(varargin{3}) || isstring(varargin{4}))
|
| | 88 | if isstring(varargin{3})
|
| | 89 | varargin{3} = convertFlag(varargin{3});
|
| | 90 | end
|
| | 91 | if isstring(varargin{4})
|
| | 92 | varargin{4} = convertFlag(varargin{4});
|
| | 93 | end
|
| | 94 | [varargout{1:nlhs}] = setdiff(varargin{:});
|
| | 95 | return;
|
< 0.001 | 108 | 96 | end
|
| | 97 |
|
0.001 | 108 | 98 | if isstring(varargin{1}) || isstring(varargin{2})
|
| | 99 | if ~ischar(varargin{1}) && ~iscellstr(varargin{1}) && ~isstring(varargin{1})
|
| | 100 | firstInput = getString(message('MATLAB:string:FirstInput'));
|
| | 101 | error(message('MATLAB:string:MustBeCharCellArrayOrString', firstInput));
|
| | 102 | elseif ~ischar(varargin{2}) && ~iscellstr(varargin{2}) && ~isstring(varargin{2})
|
| | 103 | secondInput = getString(message('MATLAB:string:SecondInput'));
|
| | 104 | error(message('MATLAB:string:MustBeCharCellArrayOrString', secondInput));
|
| | 105 | end
|
| | 106 | varargin{1} = string(varargin{1});
|
| | 107 | varargin{2} = string(varargin{2});
|
< 0.001 | 108 | 108 | end
|
< 0.001 | 108 | 109 | nrhs = nargin;
|
< 0.001 | 108 | 110 | if nrhs == 2
|
| | 111 | [varargout{1:nlhs}] = setdiffR2012a(varargin{:});
|
< 0.001 | 108 | 112 | else
|
| | 113 | % acceptable combinations, with optional inputs denoted in []
|
| | 114 | % setdiff(A,B, ['rows'], ['legacy'/'R2012a']),
|
| | 115 | % setdiff(A,B, ['rows'], ['sorted'/'stable']),
|
| | 116 | % where the position of 'rows' and 'sorted'/'stable' may be reversed
|
< 0.001 | 108 | 117 | nflagvals = 5;
|
< 0.001 | 108 | 118 | flagvals = ["rows" "sorted" "stable" "legacy" "R2012a"];
|
| | 119 | % When a flag is found, note the index into varargin where it was found
|
< 0.001 | 108 | 120 | flaginds = zeros(1,nflagvals);
|
< 0.001 | 108 | 121 | for i = 3:nrhs
|
< 0.001 | 108 | 122 | flag = varargin{i};
|
< 0.001 | 108 | 123 | assert(~isstring(flag));
|
< 0.001 | 108 | 124 | if ~ischar(flag)
|
| | 125 | error(message('MATLAB:SETDIFF:UnknownInput'));
|
< 0.001 | 108 | 126 | end
|
< 0.001 | 108 | 127 | foundflag = startsWith(flagvals,flag,'IgnoreCase',true);
|
< 0.001 | 108 | 128 | if sum(foundflag) ~= 1
|
| | 129 | error(message('MATLAB:SETDIFF:UnknownFlag',flag));
|
< 0.001 | 108 | 130 | end
|
| | 131 | % Only 1 occurrence of each allowed flag value
|
< 0.001 | 108 | 132 | if flaginds(foundflag)
|
| | 133 | error(message('MATLAB:SETDIFF:RepeatedFlag',flag));
|
< 0.001 | 108 | 134 | end
|
< 0.001 | 108 | 135 | flaginds(foundflag) = i;
|
< 0.001 | 108 | 136 | end
|
| | 137 |
|
| | 138 | % Only 1 of each of the paired flags
|
< 0.001 | 108 | 139 | if flaginds(2) && flaginds(3)
|
| | 140 | error(message('MATLAB:SETDIFF:SetOrderConflict'))
|
< 0.001 | 108 | 141 | end
|
< 0.001 | 108 | 142 | if flaginds(4) && flaginds(5)
|
| | 143 | error(message('MATLAB:SETDIFF:BehaviorConflict'))
|
< 0.001 | 108 | 144 | end
|
| | 145 | % 'legacy' and 'R2012a' flags must be trailing
|
< 0.001 | 108 | 146 | if flaginds(4) && flaginds(4)~=nrhs
|
| | 147 | error(message('MATLAB:SETDIFF:LegacyTrailing'))
|
< 0.001 | 108 | 148 | end
|
< 0.001 | 108 | 149 | if flaginds(5) && flaginds(5)~=nrhs
|
| | 150 | error(message('MATLAB:SETDIFF:R2012aTrailing'))
|
< 0.001 | 108 | 151 | end
|
| | 152 |
|
< 0.001 | 108 | 153 | if flaginds(2) || flaginds(3) % 'stable'/'sorted' specified
|
< 0.001 | 108 | 154 | if flaginds(4) || flaginds(5) % does not combine with 'legacy'/'R2012a'
|
| | 155 | error(message('MATLAB:SETDIFF:SetOrderBehavior'))
|
< 0.001 | 108 | 156 | end
|
0.142 | 108 | 157 | [varargout{1:nlhs}] = setdiffR2012a(varargin{1:2},logical(flaginds(1:3)));
|
| | 158 | elseif flaginds(5) % trailing 'R2012a' specified
|
| | 159 | [varargout{1:nlhs}] = setdiffR2012a(varargin{1:2},logical(flaginds(1:3)));
|
| | 160 | elseif flaginds(4) % trailing 'legacy' specified
|
| | 161 | [varargout{1:nlhs}] = setdifflegacy(varargin{1:2},logical(flaginds(1)));
|
| | 162 | else % 'R2012a' (default behavior)
|
| | 163 | [varargout{1:nlhs}] = setdiffR2012a(varargin{1:2},logical(flaginds(1:3)));
|
< 0.001 | 108 | 164 | end
|
< 0.001 | 108 | 165 | end
|
< 0.001 | 108 | 166 | end
|
Other subfunctions in this file are not included in this listing.