-
Notifications
You must be signed in to change notification settings - Fork 9
/
sortrowstol.m
65 lines (65 loc) · 2.33 KB
/
sortrowstol.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
function [resMat,indSortVec,indRevSortVec]=sortrowstol(inpMat,tol)
% SORTROWSTOL sorts rows of input numeric matrix in ascending order with a
% specified precision i.e. sorting [1 2;1+1e-14 1] with tol>=1-14 would put
% the first row on the second position while the built-in sortrows function
% would keep the order of rows unchanged, the functions only looks at the
% neighboring values and doesn't calculate pairwise distances (as in pdist
% function) for speed
%
% Input:
% regular:
% inpMat: numeric[nRows,nCols] - input matrix
% tol: numeric[1,1] - tolerance used for sorting, values of inpMat
% are considered to be equal if their difference is less or equal
% than tol by an absolute value
%
% Output:
% resMat: numeric[nRows,nCols] - output of matrix
% indSortVec: double[nRows,1] - vector of indices such that
% inpMat(indSortVec,:)==resMat
% indRevSortVec: double[nRows,1] - vector of indices such that
% resMat(indRevSortVec,:)==inpMat
%
% $Author: Peter Gagarinov, PhD <[email protected]> $
% $Copyright: Peter Gagarinov, PhD,
% Moscow State University,
% Faculty of Computational Mathematics and Computer Science,
% System Analysis Department 2011-2016 $
%
% TODO: add support for clustering method based on
% clusterdata([1;1+1e-14;2;2+1e-14;2-1e-14],'criterion',...
% 'distance','cutoff',1e-14)
%
if tol<0
error('sortrowstol:wrongInput',...
'tol is expected to be a positive number');
end
if ~(ismatrix(inpMat)&&isnumeric(inpMat))
error('sortrowstol:wrongInput',...
'input is expected to be a numeric matrix');
end
nCols=size(inpMat,2);
nRows=size(inpMat,1);
if nRows>0
resMat=inpMat;%make a copy since inpMat is going to be changed
%
%cluster values in each column
for iCol=1:nCols
[colVec,indColSortVec]=sort(inpMat(:,iCol));
colDiffVec=diff(colVec);
isLessVec=abs(colDiffVec)<=tol;
colDiffVec(isLessVec)=0;
colVec=cumsum([colVec(1);colDiffVec],1);
[~,indColRevSortVec]=sort(indColSortVec);
inpMat(:,iCol)=colVec(indColRevSortVec);
end
%sort the original matrix copied to resMat
[~,indSortVec]=sortrows(inpMat);
resMat=resMat(indSortVec,:);
else
resMat=inpMat;
indSortVec=double.empty(0,1);
end
if nargout>2
[~,indRevSortVec]=sort(indSortVec);
end