-
Notifications
You must be signed in to change notification settings - Fork 4
/
spcl.m
154 lines (121 loc) · 4.24 KB
/
spcl.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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
function [clusters, evalues, evectors] = spcl(data, nbclusters, varargin)
%
% spcl(data, nbclusters, varargin) is a spectral clustering function to
% assemble random unknown data into clusters. after specifying the data and
% the number of clusters, next parameters can vary as wanted. This function
% will construct the fully connected similarity graph of the data.
%
% The first parameter of varargin is the name of the function to use.
%
% The second is the parameter to pass to the function.
% Third parameter is the type of the Laplacian matrix:
% 'unormalized' - unnormalized laplacian matrix
% 'sym' - normalized symmetric laplacian matrix
% 'rw' - normalized asymmetric laplacian matrix
% (if omitted the default will be 'unnormalized')
%
% then the algorithm used for organizing eigenvectors:
% 'np' - generally used for 2 clusters, one eigenvector must be used, if
% will put positive values in class 1 and negative values in class 2
% 'kmeans' - a k-mean algorithm will be used to cluster the given eigenvectors
%
% finally an eigenvector choice can be added, it can be a vector [vmin
% vmax] or a matrix defining several intervals. if not found the default
% will be [2 2]
plotchoices = {'bo','r+','md','k*','wv'};
lapmatrixchoices = {'unormalized', 'sym', 'rw'};
algochoices = {'np', 'kmeans'};
func = 'gaussdist';
count = 1;
%%get all the parameters%%%
if(ischar(varargin{count}))
func = varargin{count};
count = count + 1;
end
params = varargin{count};
count = count + 1;
if(length(varargin) >= count)
if(sum(strcmp(varargin{count}, lapmatrixchoices)) == 0)
lapmatrixchoice = 'unormalized';
else
lapmatrixchoice = varargin{count};
count = count + 1;
end
if(length(varargin) >= count)
if(sum(strcmp(varargin{count}, algochoices)) == 0)
clusteralgo = 'np';
else
clusteralgo = varargin{count};
count = count + 1;
end
if(length(varargin) >= count)
eigv = varargin{count};
else
eigv = [2 2];
end
else
clusteralgo = 'np';
eigv = [2 2];
end
else
lapmatrixchoice = 'unormalized';
clusteralgo = 'np';
eigv = [2 2];
end
%%all parameters are got%%%
if iscell(data)
data = cell2mat(data')'; %concatenate all the dims
else
data = data';
end
sprintf('Graph choice is fully connected\nLaplacian choice is %s\nCluster algorithm is %s', lapmatrixchoice, clusteralgo)
[nbsamples, dim] = size(data);
wmat = zeros(nbsamples);
for i = 1: nbsamples - 1
wmat(i, i + 1: end) = feval(func, repmat(data(i, :), nbsamples - i, 1), data(i + 1: end,:), params);
end
wmat = wmat + wmat';
dmat = diag(sum(wmat, 2));
if(strcmp(lapmatrixchoice, 'unormalized'))
laplacian = dmat - wmat;
else
if(strcmp(lapmatrixchoice, 'sym'))
laplacian = eye(nbsamples) - (dmat^-0.5) * wmat * (dmat^-0.5);
else
if(strcmp(lapmatrixchoice, 'rw'))
laplacian = eye(nbsamples) - (dmat^-1) * wmat;
end
end
end
% [evectors, evalues] = eig(laplacian);
% newspace = evectors(:, eigv(1,1): eigv(1,2));
% diff = eps;
% [evectors, evalues] = eigs(laplacian, eigv(1,2), diff);
diff = 0;
[evectors, evalues] = eigs(laplacian, eigv(1,2)+1, 'sm');
newspace = evectors(:,2:end);
n = size(eigv);
for i = 2: n(1) %for matrix case select which eigen vectors to construct the new space
% if the varible eigv is a vector that is more than 2 dims
newspace = [newspace evectors(:, eigv(i,1): eigv(i,2))];
end
% Normalize each row to be of unit length
sq_sum = sqrt(sum(newspace.*newspace, 2)) + 1e-20;
newspace = newspace ./ repmat(sq_sum, 1, nbclusters);
clear sq_sum V;
if(strcmp(clusteralgo, 'kmeans'))
clusters = kmeans(newspace, nbclusters);
else
clusters = 1 + (newspace > 0);
end
% if(dim == 2)
% figure;
% for i = 1: nbclusters
%
% points = data(clusters == i, :);
% plot(points(:,1), points(:,2), plotchoices{i});
% hold on;
% end
% title('clustered data using spectral clustering');
% grid on;
% end