Find node index of connected graph components using conncomp - matlab

Problem
I am trying to find the connected components of my undirected graph.
Matlabs function conncomp does exactly this. Mathworks - connected graph components
Example
Using the example given on matlabs webpage to keep it easy and repeatable:
G = graph([1 1 4],[2 3 5],[1 1 1],6);
plot(G)
bins = conncomp(G)
bins =
1 1 1 2 2 3
Two Question´s to this
First Question: Using this how can I find the initial node index, so that
cluster1 = (1 2 3); (instead of ( 1 1 1))
cluster2= (4 5); (instead of (2 2))
Second Question:
I am working on a big dataset and I know many nodes are not connected, so is there a way to only display clusters that contain more than one value ?
Thanks for your help, I am majorly stuck here.

You can use splitapply for the first part, like so:
clusters = splitapply(#(x) {x}, 1:numnodes(G), bins)
This returns a cell array where each cell contains the indices of the nodes in a group. You can filter this down in the usual way using cellfun
discard = cellfun(#isscalar, clusters);
clusters(discard) = [];
(Note that splitapply is new in R2015b - but the OP is using graph, also new in R2015b, so it should be fine for them)

Actually the first part of the question can be answered very simply as Matlabs conncomp provides a tool for this:
bins=conncomp(G,'OutputForm','cell');
Creates a cell array that contains the clusters, with all node names in the cells.
For the second part of the question I guess there are several ways but this one could be used as well:
clusters= bins(cellfun(#numel,bins)>1);

Related

Function which no longer exists

I am interested in using the function here:
http://uk.mathworks.com/help/nnet/ref/removerows.html
However, when I try to use it in Matlab it says: "Undefined function or variable 'removerows'"
I typed: exist removerows and returned a value of 0, suggesting that it's been removed. Has this function just been renamed? or is it part of a toolbox I may not have, the information does not detail this.
Much appreciated
According to the link that you posted, this function is part of the Neural Network Toolbox. So my guess is that you don't have this toolbox installed.
You can remove rows in a matrix by assigning an empty array to them.
This way you don't have to use functions belonging to toolboxes that require extra licences.
Example
A = [1 2; 3 4; 5 6]
A =
1 2
3 4
5 6
A(2,:) = [] %remove row 2
A =
1 2
5 6
Similarly you can provide an index array with the rows to be deleted in case you want to remove several ones.

Calculating value y for each XI and XII in MATLAB:

I am currently working in matlab to design a way to reconstruct 3D data. For this I have two pictures with black points. The difference in the amount of points per frame is key for the reconstruction, but MATLAB gives an error when matrixes are not equal. This is happening becaus the code is not doing what I want it to do, so can anyone hel me with the following?
I have two columns of Xdata: XLI and XRI
What matlab does when I do XLI-XRI is substracting the pairs i.e XLI(1)-XRI(1) etc, but I want to substract each value of XRI of every value of XLI. i.e
XLI(1)-XRI(1,2,3,4 etc)
XLI(2)-XRI(1 2 3 4 etc)
and so on
Can anyone help?
I think you are looking for a way to deduct all combinations from eachother. Here is an example of how you can do that with bsxfun:
xLI = [1 2 3]
xRI = [1 2]
bsxfun(#minus,xLI ,xRI')
I cannot comment on Dennis's post (not enough points on this website) : his solution should work, but depending on your version of Matlab you might get a "Error using ==> bsxfun" and need to transpose either xLI or xRI for that to work :
bsxfun(#minus,xLI' ,xRI)
Best,
Tepp

Cutting a 250000 value long vector into pieces of 50 and summing them with MATLAB [duplicate]

This question already has an answer here:
Summing up till a certain interval
(1 answer)
Closed 8 years ago.
I have a dataset (which is an hdf5 file) that contains a list of 250000 values, all quite small (sub 10). I want to cut this into 5000 pieces, so 50 each, and I want to individually sum the values in each of these 5000 pieces. I then want to create a histogram of these 5000 pieces, so I need to store them as well.
I am trying to do this using MATLAB, as my very limited programming skills have been developed using this, and it seems suitable for these purposes. Now, I haven't gotten very far, but what I have done so far is:
for n = 1:50:249951
% CR check before (before pumping?)
ROdata = h5read('hdf5file', '/data', [n], [n+49]);
sum(ROdata)
end
Of course, this does not yet store the values of the sum for each n. But more importantly, it does not work. For n = 1, all is fine, and I get the correct value. But already for n = 51, (so summing 51-100), I do not get the correct sum. What's going wrong here?
How should I store these (not working) sums?
Are you looking for something like this?
I assumed you already read your data and you have a 250000x1 vector.
%example data
data = randi(42,1,250000);
% rearranges your vector in groups of 50
A = reshape(data,[],5000);
% sums every column of your reshaped vector
sums = sum(A,1);
hist(sums,5000)

Why does crossvalind fail?

I am using cross valind function on a very small data... However I observe that it gives me incorrect results for the same. Is this supposed to happen ?
I have Matlab R2012a and here is my output
crossvalind('KFold',1:1:11,5)
ans =
2
5
1
3
2
1
5
3
5
1
5
Notice the absence of set 4.. Is this a bug ? I expected atleast 2 elements per set but it gives me 0 in one... and it happens a lot that is the values are not uniformly distributed in the sets.
The help for crossvalind says that the form you are using is: crossvalind(METHOD, GROUP, ...). In this case, GROUP is the e.g. the class labels of your data. So 1:11 as the second argument is confusing here, because it suggests no two examples have the same label. I think this is sufficiently unusual that you shouldn't be surprised if the function does something strange.
I tried doing:
numel(unique(crossvalind('KFold', rand(11, 1) > 0.5, 5)))
and it reliably gave 5 as a result, which is what I would expect; my example would correspond to a two-class problem (I would guess that, as a general rule, you'd want something like numel(unique(group)) <= numel(group) / folds) - my hypothesis would be that it tries to have one example of each class in the Kth fold, and at least 2 examples in every other, with a difference between fold sizes of no more than 1 - but I haven't looked in the code to verify this.
It is possible that you mean to do:
crossvalind('KFold', 11, 5);
which would compute 5 folds for 11 data points - this doesn't attempt to do anything clever with labels, so you would be sure that there will be K folds.
However, in your problem, if you really have very few data points, then it is probably better to do leave-one-out cross validation, which you could do with:
crossvalind('LeaveMOut', 11, 1);
although a better method would be:
for leave_out=1:11
fold_number = (1:11) ~= leave_out;
<code here; where fold_number is 0, this is the leave-one-out example. fold_number = 1 means that the example is in the main fold.>
end

Add node numbers/get node locations from MATLAB's treeplot

I have been working with MATLAB's treeplot function, but it seems to provide surprisingly little plotting functionality and/or extendibility.
I am plotting a tree like so:
tree = [0 1 2 2 2 2 2 1 8 8 1 11 11 1 14];
treeplot(tree)
Giving:
What I would like to do is add annotations or labels to specific nodes. A good starter would be to add the node numbers to each node, as in the example from the help file:
As they state, though:
These indices are shown only for the point of illustrating the example; they are not part of the treeplot output.
Is there a way to get the locations of the plotted nodes, or at the very least to plot the node numbers? I couldn't find any FEX submissions with more advanced tree plots.
Ultimately, I'd like to plot small pictures at the nodes (using methods from answers to a previous question of mine).
This should help you make a labeled tree:
(You supply the 'treeVec'.)
treeplot(treeVec);
count = size(treeVec,2);
[x,y] = treelayout(treeVec);
x = x';
y = y';
name1 = cellstr(num2str((1:count)'));
text(x(:,1), y(:,1), name1, 'VerticalAlignment','bottom','HorizontalAlignment','right')
title({'Level Lines'},'FontSize',12,'FontName','Times New Roman');
With your sample input, this gives
To get the position of the nodes, use treelayout
[x,y]=treelayout(tree);
The vectors x and y give you the positions, which you can then use to plot images at the nodes.