0001 function out = uniquetol(in, tol, varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 if ischar(in) && strcmp(in,'UNIT_TEST'); do_unit_test; return; end
0014
0015 DEBUG = eidors_debug('query','eidors:uniquetol');
0016
0017 if DEBUG==1 || exist('uniquetol','builtin')
0018 if DEBUG; disp('using builtin uniquetol'); end
0019 out = builtin('uniquetol',in, tol, varargin{:});
0020 return;
0021 end
0022
0023
0024 if length(varargin)<4
0025 error('ByRows and DataScale must be provided')
0026 end
0027 for i=1:2:length(varargin);
0028 switch varargin{i}
0029 case 'ByRows'
0030 if ~varargin{i+1}; error('Only support the ByRows option'); end
0031 case 'DataScale'
0032 if varargin{i+1}~=1; error('DataScale must by 1'); end
0033 otherwise
0034 error('Option %s not supported',varargin{i});
0035 end
0036 end
0037
0038 out = eidors_uniquetol(in, tol);
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 function out = eidors_uniquetol(in, tol)
0070
0071 out = unique(in,'rows');
0072
0073
0074 nRows = size(out,1);
0075 if nRows <= 1
0076 return
0077 end
0078 idx = nchoosek(1:nRows,2);
0079
0080
0081 d = out(idx(:,1),:) - out(idx(:,2),:);
0082 d = abs(d) <= tol;
0083
0084 same = all(d,2);
0085
0086 legacy = false; try unique([],'legacy'); catch, legacy = true; end
0087
0088
0089 if legacy
0090 [~,ii] = unique(idx(same,2),'first');
0091 else
0092 [~,ii] = unique(idx(same,2));
0093 end
0094 jj = find(same);
0095 ii = jj(ii);
0096
0097 out(idx(ii,2),:) = out(idx(ii,1),:);
0098
0099
0100 out = unique(out,'rows');
0101
0102
0103
0104
0105
0106 function [z,ii,jj] = uniquetol_repl(x,tol,varargin)
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122 if size(x,1) == 1, x = x(:); end
0123 if nargin < 2 || isempty(tol) || tol == 0
0124 [z,ii,jj] = unique(x,varargin{:});
0125 return;
0126 end
0127 [y,ii,jj] = unique(x,varargin{:});
0128 if size(x,2) > 1
0129 [~,ord] = sort(sum(x.^2,1),2,'descend');
0130 [y,io] = sortrows(y,ord);
0131 [~,jo] = sort(io);
0132 ii = ii(io);
0133 jj = jo(jj);
0134 end
0135 d = sum(abs(diff(y,1,1)),2);
0136
0137 isTol = [true;d > tol];
0138 z = y(isTol,:);
0139 bin = cumsum(isTol);
0140 jj = bin(jj);
0141 ii = ii(isTol);
0142
0143
0144
0145 function do_unit_test
0146 testvec{1} = [1 2; 1.06 2; 1.1 2; 1.1 2.03];
0147 testvec{2} = [ ...
0148 -0.488223373148967243473350663407, ...
0149 -0.488223373148967243473350663407, ...
0150 -0.488223373148967243473350663407, ...
0151 -0.488223373148967243473350663407, ...
0152 -0.488223373148967243473350663407, ...
0153 -0.488223373148967243473350663407;
0154 -0.999999999999999666933092612453, ...
0155 -0.999999999999999888977697537484, ...
0156 -0.999999999999999888977697537484, ...
0157 -0.999999999999999888977697537484, ...
0158 -0.999999999999999888977697537484, ...
0159 -0.905678339894304240687006313237;
0160 -0.232963663178817920185181833403, ...
0161 -0.232963663178818003451908680290, ...
0162 -0.116481831589409029481529955774, ...
0163 -0.232963663178818086718635527177, ...
0164 -0.116481831589409043359317763588, ...
0165 -0.156131398552380479261003642932]';
0166 testvec{3} = testvec{2}';
0167
0168
0169 for i=1:length(testvec)
0170 eidors_msg('TEST%d============',i,1);
0171 x = testvec{i};
0172 for tol = logspace(-4,1,6);
0173 uu = uniquetol(x,tol,'ByRows',true,'DataScale',1);
0174 ur = uniquetol_repl(x,tol,'rows','first');
0175 ue = eidors_uniquetol(x,tol);
0176 fprintf('Testing for tol=%f\n',tol);
0177 unit_test_cmp('uu=ur (not used)',uu,ur);
0178 unit_test_cmp('um=ue ',uu,ue);
0179 end
0180 end