I have a symmetric adjacency matrix with zero value on its diagonal. now i am looking for reordering method to show community which divides the matrix in two cliques with +1 and -1 values respectively. it would be appreciated if someone could help me in this regards.
for instance: matrix(10,10)
0 1 -1 1 1 -1 1 1 -1 -1
1 0 -1 1 1 -1 1 -1 -1 -1
-1 -1 0 -1 -1 1 1 1 1 -1
1 1 -1 0 1 -1 1 -1 -1 -1
1 1 -1 1 0 -1 1 1 -1 -1
-1 -1 1 -1 -1 0 -1 1 1 1
1 1 1 1 1 -1 0 1 1 1
1 -1 1 -1 1 1 1 0 -1 -1
-1 -1 1 -1 -1 1 1 -1 0 1
-1 -1 -1 -1 -1 1 1 -1 1 0
output must be :
1 1 1 1 1 -1 -1 -1 -1 -1
1 1 1 1 1 -1 -1 -1 -1 -1
1 1 1 1 1 1 -1 -1 -1 -1
1 1 1 1 1 -1 -1 -1 -1 -1
1 1 1 1 1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 1 1 1 1 1
-1 -1 -1 -1 -1 1 1 1 1 1
-1 -1 -1 -1 -1 1 1 1 1 1
-1 -1 -1 -1 -1 1 1 1 1 1
-1 -1 -1 -1 -1 1 1 1 1 1
zero entries can be considered as 1
Because of the example, I'm not certain how to deal with most cases, so I guessed.
a = round(3*rand(10) - 1.5);
a(logical(eye(size(a)))) = 0;
b = cliques(a);
This maintains the symmetry requirement and only needs to break from the "wings" of -1
's when there is one remaining after all the other filters (i.e. if the number of -1
's is odd then to maintain symmetry an element must go on the diagonal).
function b = cliques(a)
a(a == 0) = 1;
n = sum(a(:) == -1);
s = floor(sqrt(n/2));
b = ones(size(a));
b(end - s + 1:end, 1:s) = -1;
b(1:s, end - s + 1:end) = -1;
n = n - 2*s^2;
bands = floor(n/4);
b(s+1, end - bands + 1:end) = -1;
b(end - bands + 1:end, s+1) = -1;
b(end - s, 1:bands) = -1;
b(1:bands, end - s) = -1;
n = n - 4*bands;
dots = floor(n/2);
if dots
b(end - s, s + 1) = -1;
b(s + 1, end - s) = -1;
end
n = n - 2*dots;
if n
b(1,1) = -1;
end
contourf(b, 'LevelList', [-1,1]);
set(gca,'Ydir','reverse')
sum(a(:)) == sum(b(:))
end