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