-
Notifications
You must be signed in to change notification settings - Fork 0
/
my_kmeans.m
executable file
·105 lines (95 loc) · 3.87 KB
/
my_kmeans.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
%% Implement the k-means algorithm to cluster the SAR matrices
function [SAR_cluster, CENTS] = my_kmeans(matrix_Q, similiarity_nan, core_idx, numCluster, maxiters)
% We only use one slice as one observation
% USAGE:
% [SAR_cluster, CENTS] = my_kmeans(squeeze(matrix_Q_10g(:,:,79,:)), similiarity_nan(:,79), core_idx, numCluster, maxiters)
Nc = size(matrix_Q, 1);
if Nc ~= size(matrix_Q, 2)
error('matrix size mismatch!');
end
numPoints = size(matrix_Q, 3); % number of points
% CENTS = matrix_Q( :,:, ceil(rand(numCluster,1)*numPoints)); % Random location for Cluster Centers
CENTS = matrix_Q( :,:, core_idx); % Initial location for Cluster Centers
CENTS_NEW = zeros(size(CENTS)); % Random location for Cluster Centers
DAL = zeros(numPoints,numCluster+2); % Distances and Labels
CurrentDist = Inf;
similiarity_nan(isnan(similiarity_nan)) = -Inf;
for n = 1:maxiters
printf('%d / %d', n, maxiters);
%% Calculate the current label and Distance
for i = 1:numPoints
for j = 1:numCluster
DAL(i,j) = norm(FindPSD(matrix_Q(:,:,i), CENTS(:,:,j), Nc));
end
[Distance, CN] = nanmin(DAL(i,1:numCluster)); % 1:K are Distance from Cluster Centers 1:K
if ~(isequal(matrix_Q(:,:,i), zeros(Nc, Nc)))
DAL(i,numCluster+1) = CN; % K+1 is Cluster Label
end
DAL(i,numCluster+2) = Distance; % K+2 is Minimum Distance
end
%% Determine if use the last centroid or the new centroid
printf('Current Dist: %f', CurrentDist);
printf('NEW Dist: %f', max(DAL(:, numCluster+2)));
CurrentLabel = DAL(:, numCluster+1);
CurrentDist = nanmax(DAL(:, numCluster+2));
%% Look for the next possible cluster centers
for i = 1:numCluster
A = find(CurrentLabel == i); % Cluster K Points
if isempty(A)
CENTS_NEW(:,:, i) = zeros(Nc, Nc);
else
[dummy, idxMaxtoMin] = sort(similiarity_nan(A), 'descend');
minlimit = min([100, size(idxMaxtoMin,1)]);
CENTS_NEW(:,:,i) = FindMinDist(matrix_Q(:,:,A), idxMaxtoMin(1:minlimit), Nc); % New Cluster Centers
end
while (isequal(CENTS_NEW(:,:,i), zeros(Nc, Nc))) % If CENTS(:,:,i) Is zero Then Replace It With Random Point
CENTS_NEW(:,:,i) = matrix_Q(:,:,randi(numPoints));
end
end
if isequal(CENTS, CENTS_NEW) % check to see if it converge
break;
else
CENTS = CENTS_NEW;
end
end
SAR_cluster = CurrentLabel;
end
%% Find if there exists Q+Z-B is psd
function [ Z ] = FindPSD(B_current, B_core, Nc)
% disp 'Finding the PSD matrix Z';
Z = zeros(Nc, Nc);
maxInters = 300;
for ii = 1: maxInters
% printf('%d / %d', ii, maxInters);
alleigs = eig(B_core+Z-B_current);
if (all(alleigs >=0) || all(-real(alleigs(alleigs<0)) <= 1e-5) )
break;
else
% Find the next possible Z
[V, D] = eig(B_core+Z-B_current);
D_orig = D;
D(D<=0)=0;
D_new = D - D_orig;
B_new = V*D_new*V';
Z = Z + B_new;
end
end
end
%% Find minimum sum_r||Q(r)+Z-CENTS||
function [CENTS] = FindMinDist(matrix_Q, setA, Nc)
% Find CENTS in the cluster such that sum_r||Q(r)+Z-CENTS|| is
% minimum
DAL = zeros(1, size(setA,1));
currentMin = Inf;
idx_min = 0;
for ii = 1: size(setA,1)
for jj = 1: size(matrix_Q,3)
DAL(jj) = norm(FindPSD(matrix_Q(:,:,jj), matrix_Q(:,:,setA(ii)), Nc));
end
if currentMin > max(DAL(:))
currentMin = max(DAL(:));
idx_min = setA(ii);
end
end
CENTS = matrix_Q(:,:,idx_min);
end