forked from zzz123xyz/projectX2
-
Notifications
You must be signed in to change notification settings - Fork 1
/
KnnGraph.m
65 lines (51 loc) · 1.38 KB
/
KnnGraph.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 W = KnnGraph(M, k, Type, sigma)
if nargin < 3
ME = MException('InvalidCall:NotEnoughArguments', ...
'Function called with too few arguments');
throw(ME);
end
if ~any(Type == (1:2))
ME = MException('InvalidCall:UnknownType', ...
'Unknown similarity graph type');
throw(ME);
end
n = size(M, 2);
% Preallocate memory
indi = zeros(1, k * n);
indj = zeros(1, k * n);
inds = zeros(1, k * n);
for ii = 1:n
% Compute i-th column of distance matrix
dist = distEuclidean(repmat(M(:, ii), 1, n), M);
% Sort row by distance
[s, O] = sort(dist, 'ascend');
% Save indices and value of the k
indi(1, (ii-1)*k+1:ii*k) = ii;
indj(1, (ii-1)*k+1:ii*k) = O(1:k);
inds(1, (ii-1)*k+1:ii*k) = s(1:k);
end
% Create sparse matrix
W = sparse(indi, indj, inds, n, n);
clear indi indj inds dist s O;
% Construct either normal or mutual graph %very interesting trick
if Type == 1
% Normal
W = max(W, W');
else
% Mutual
W = min(W, W');
end
if nargin < 4 || isempty(sigma)
sigma = 1;
end
% Unweighted graph
if sigma == 0
W = (W ~= 0);
% Gaussian similarity function
elseif isnumeric(sigma)
W = spfun(@(W) (simGaussian(W, sigma)), W);
else
ME = MException('InvalidArgument:NotANumber', ...
'Parameter epsilon is not numeric');
throw(ME);
end