There is a problem in loop. Could anyone please correct my code.

I want to find the 1's in first column and compare it with all other columns and if there is a matching column then count 1 and then second column with remaining columns and so on, but it's not working in my code. I find the value of only one column in this code.
function CNmat=getCNMatrix(adj,col)
clc;
adj=[0 1 1 1 1 0; 1 0 1 1 0 1; 0 0 0 1 0 1; 1 0 1 0 0 1; 1 0 0 1 0 1; 0 0 0 0 1 0];
col=1;
[r,c]=size(adj);
%for col=1:c
[xi,xj]=find(adj(:,col)==1);
withOne=adj(xi,:);
[zr,zc]=find(withOne==1);
for j=1:c
if (j==col)
continue;
end
CNmat(j)=length(find(zc==j));
end
For eg:,
The result of this code is : ans =
0 0 2 2 0 3
It means that when I take the 1's of first column and compare it with other columns, there is no corresponding elements are same in column 2 with column 1.On the other hand, on columns 3 and 4 there are 2 1's same as in column 1 and on column 6 there are 3 1's matches with column 1.But, I want this as a matrix by taking each column's 1 and match it with succeeding columns.

1 comentario

What you want to compare? What you want to do after comparing? Your question is not clear.

Iniciar sesión para comentar.

 Respuesta aceptada

It is very hard to understand what it is you want as you don't tell us what result you want. Really, the best for you would be to give us an example input and the corresponding output that should be generated with an explanation of how you go from one to the other.
I'm completely guessing here, based on your hazy description and your incomplete code, that maybe you want this:
adj = [0 1 1 1 1 0; 1 0 1 1 0 1; 0 0 0 1 0 1; 1 0 1 0 0 1; 1 0 0 1 0 1; 0 0 0 0 1 0];
CNmat = zeros(size(adj, 2));
for col = 1:size(adj, 2)
filteredadj = adj .* adj(:, col); %only keep the ones whose rows match the ones in the current column
filteredadj(:, col) = 0; %ignore current column
CNmat(col, :) = sum(filteredadj); %sum the ones in each column
end
CNmat(col, :) is the count of 1 in each column of adj that are in the same row as column col. No idea if that's the result you want. You'll see that CNmat(1, :) matches the output of the code you've posted.

15 comentarios

Thank you for your reply Sir. But, when I run this an error occurs. Please help.
Error using .*
Matrix dimensions must agree.
Error in Untitled (line 4)
filteredadj = times(adj,adj(:, col)); %only keep the ones whose
rows match the ones in the current column
You're using an old version of matlab (<R2016b). In R2016a or earlier replace that line with:
filteradj = bsxfun(@times, adj, adj(:, col)); %only keep the ones whose rows match the ones in the current column
Thank you for your information.But, when I run the code this is not my desired output. I want to take 1's in first column check whether how many matches with next column and then take the next and compare it with succeeding column and so on to form a matrix.By using my code I only get the first column comparison and the first row of new matrix, like that I want to take all other column and compare and count how many matches and so form a 6 by 6 matrix from the above adjacency matrix.
As I said, your explanation is not clear. Show us the expected output and a better explanation of how it's arrived at.
SUNANNA S S
SUNANNA S S el 12 de Abr. de 2017
Editada: SUNANNA S S el 12 de Abr. de 2017
Sir, This is an example for my problem. By using my above code, I only get the first row of the expected matrix. This is the matrix I am working with:
adj = 0 1 1 1 1 0
1 0 1 1 0 1
0 0 0 1 0 1
1 0 1 0 0 1
1 0 0 1 0 1
0 0 0 0 1 0
The expected output is:
CNmat=
0 0 2 2 0 3
0 0 1 1 1 0
2 1 0 2 1 2
2 1 2 0 1 3
0 1 1 1 0 0
3 0 2 3 0 0
Here, for example, when I take the first column of adj and compare it with second column, there is no corresponding elements are same in second column, then on matrix CNmat(1,2)=0, like that, comparing columns 1 and 3, only its second and forth corresponding elements are same, so, CNmat(1,3)=2 and after comparing the first column with all other columns to get the first row of CNmat, then I want to move on to second column and compare it with 3rd,4th,5th and 6th columns and so on. Please help. Thanks in advance.
The code I wrote in my answer creates the exact same CNmat that you've just described, so I'm very puzzled.
If, as in your description you want to ignore all the columns before the one being considered, then you can simply take the upper triangle of the resulting CNmat with
triu(CNmat)
or change the line
filteredadj(:, col) = 0; %ignore current column
to
filteredadj(:, 1:col) = 0; %ignore current and previous columns
or use Andrei's latest update.
But when I tried this code I cannot get the result, I don't know why.
Huh?
clear
adj = [0 1 1 1 1 0; 1 0 1 1 0 1; 0 0 0 1 0 1; 1 0 1 0 0 1; 1 0 0 1 0 1; 0 0 0 0 1 0];
CNmat = zeros(size(adj, 2));
for col = 1:size(adj, 2)
filteredadj = bsxfun(@times, adj, adj(:, col)); %only keep the ones whose rows match the ones in the current column
filteredadj(:, col) = 0; %ignore current column
CNmat(col, :) = sum(filteredadj); %sum the ones in each column
end
>> CNmat
CNmat =
0 0 2 2 0 3
0 0 1 1 1 0
2 1 0 2 1 2
2 1 2 0 1 3
0 1 1 1 0 0
3 0 2 3 0 0
Works for me
SUNANNA S S
SUNANNA S S el 12 de Abr. de 2017
Editada: SUNANNA S S el 12 de Abr. de 2017
Sorry for the mistake Sir. When I run this code, I get the result. But, When I tried this code with a large matrix, it doesn't give me the sum as a matrix.Why is it so? This is my code.Please help to correct my code.
clear
X=BIS();
CNmat = zeros(size(X, 2));
for col = 1:size(X, 2)
filteredadj = bsxfun(@times, X, X(:, col)); %only keep the ones whose rows match the ones in the current column
filteredadj(:, col) = 0; %ignore current column
CNmat(col, :) = sum(filteredadj); %sum the ones in each column
triu(CNmat);
end
clear
X=BIS();
CNmat = zeros(size(X, 2));
for col = 1:size(X, 2)
filteredadj = bsxfun(@times, X, X(:, col)); %only keep the ones whose rows match the ones in the current column
filteredadj(:, col) = 0; %ignore current column
CNmat(col, :) = sum(filteredadj); %sum the ones in each column
triu(CNmat);
end
clear
X=BIS();
CNmat = zeros(size(X, 2));
for col = 1:size(X, 2)
filteredadj = bsxfun(@times, X, X(:, col)); %only keep the ones whose rows match the ones in the current column
filteredadj(:, col) = 0; %ignore current column
CNmat(col, :) = sum(filteredadj); %sum the ones in each column
end
CNmat_out = triu(CNmat);
Susanna, both Andrei's and my answer produce the same result. Andrei's is more concise but temporarily requires more memory.
As said, if you want to ignore all the columns before the one being considered, you can use triu after the loop as per Andrei's comment above, to filter out the lower triangle.
Or you can modify the loop to:
X=BIS();
CNmat = zeros(size(X, 2));
for col = 1:size(X, 2)
filteredadj = bsxfun(@times, X, X(:, col)); %only keep the ones whose rows match the ones in the current column
filteredadj(:, 1:col) = 0; %ignore current and previous columns
CNmat(col, :) = sum(filteredadj); %sum the ones in each column
end
or
CNmat = zeros(size(X, 2));
for col = 1:size(X, 2)
d = sum(bsxfun(@times, X(:,col:end), X(:, col)));
CNmat(col, col+1:end) = d(2:end);
end
Sir, I tried all these code as per your guidance, but I only get a zero matrix as output. I don't know what is the problem. I had attached my files with this.Please help me.
Oh! We're back to twitnet. A few comments then,
Your twitnet edge file appears to be for an undirected graph (the adjacency matrix is symmetric) since there's no direction information, whereas your example above is a directed graph (non-symmetric adjacency matrix).
For an undirected graph, it makes no sense to me to only keep the upper diagonal of CNmat. CNmat is going to be symmetric anyway.
If the only reason you're calculating the adjacency matrix is to obtain your CNmat, then you could just obtain CNmat directly and possibly faster from the edge matrix.
Anyway, "I only get a zero matrix as output". No, you don't.
find(CNmat)
will show you the location of all the non-zeros values in CNmat. There's not many but given your graph what else did you expect. First have a look at the graph of your twitnet:
There isn't a single cycle and it's extremely disconnected. Now what you are calculating with your CNmat is for each pair of nodes how many nodes do they both connect to. For the overwhelming majority of nodes pairs, that is zero. For the few that actually form a graph, since all these graphs are star shaped, the maximum number of common nodes for a pair is at most 1.
That's exactly the CNmat that Andrei's and my answer produce. For example, look at the 105th node (node '301180' in twitnet), which one of the point of one of the 7-pointed stars:
>> find(CNmat(105, :)
ans =
106 107 108 109 110 111
It connects exactly to one common node (104) with the other nodes (106, 107, etc.).
As advised in the other thread, I would recommend you upgrade to a newer version of matlab as plotting the graph as I've done above is trivial in R2015b or later:
plot(graph(X))

Iniciar sesión para comentar.

Más respuestas (1)

Andrei Bobrov
Andrei Bobrov el 11 de Abr. de 2017
Editada: Andrei Bobrov el 12 de Abr. de 2017
[EDIT]
CNmat =...
triu(squeeze(sum(adj.*permute(adj,[1 3 2]))).*~eye(size(adj,2)));%R2016b and later
CNmat = triu(squeeze(sum(...
bsxfun(@times,adj,permute(adj,[1 3 2])))).*~eye(size(adj,2))); % For early versions

4 comentarios

I have a large matrix(892 rows and 892 columns).Is this function suitable for that matrix?
Andrei Bobrov
Andrei Bobrov el 12 de Abr. de 2017
Editada: Andrei Bobrov el 12 de Abr. de 2017
of course
I got this error when I run this code.
Error using bsxfun
Out of memory. Type HELP MEMORY for your options.
Error in new (line 11)
CNmat = triu(squeeze(sum(bsxfun(@times,X,permute(X,[1 3 2])))).*~eye(size(X,2))); %sum
the ones in each column
Yes, error.
Please see answer by Guillaume.

Iniciar sesión para comentar.

Categorías

Más información sobre Performance and Memory en Centro de ayuda y File Exchange.

Etiquetas

Preguntada:

el 11 de Abr. de 2017

Comentada:

el 13 de Abr. de 2017

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by