Creating an adjacency matrix from a cell array - matlab

I'm going to create an adjacency matrix from a cell array, but faced two main problems:
I don't know how to access to cell array's elements; so an adhoc method was used.
(and the most important) The code produces an error and the partial result is also a weird one!
The cell array is as the following image:
The code is as follows:
for i=1:N
L=size(Al{i});
Len=L(1,2);
for j=1:Len
elm=Al{i};
D=elm(i,j);
Adjm(i,D)=1;
end
end
The code produces this error:
and the output is as follows:
P.S.: The code is part of a program to construct adjacency matrix to represent superpixels adjacency within an image. There may be a specific solution for that!

There are lots of ways your code could be made better, but the specific error you are seeing is because you want D=elm(1,j); instead of D=elm(i,j);. Note the 1 instead of i.
A somewhat more efficient approach would be to do,
for i=1:numel(Al)
Adjm(i,Al{i})=1;
end
As with your code, this assumes that there are no empty elements in Al.

Related

How to assign one dimensional array values to two dimensional array in Matlab

I am quite new in Matlab, and I want to assign the value of 1D array to 2D array, and I searched most of the books but I didn't get what I want to know.help me out guys.The code is like
while (count1~=17)
while (count2~=257)
A[count1][count2]= fc1[count2];
count2=count2+1;
end
count1=count1+1;
end
And the error is saying in the line A[count1][count2]= fc1[count2];
First of a all you are using the wrong syntax for assigning matrices in MATALB. You should start reading the documentation for getting firm with the language fundamentals:
http://de.mathworks.com/help/matlab/language-fundamentals.html
You will see that the assignment of A has to look as follows:
A(count1,count2)= fc1(count2)
Furthermore you should have a look at the initialization of your variables. In the code above, the inner loop will only run once, until you don't reset count2

Creating functions in Matlab

Hi, I am trying to write a function as per the question. I have tried to create four sub-matrices which are the reverse of each other and then multiply to give the products demanded by the question. My attempt:
function T = custom_blocksT(n,m)
T(1:end,end-1:1);
T(1:end,end:-1:1)*2;
T(1:end,end:-1:1)*3;
T(1:end,end:-1:1)*4;
What I'm unsure of is
(i) What do the the indivual sub-matrices(T(1:end,end-1:1);)need to be equal to? I was thinking of(1:3)?
(ii) I tried to create a generic sub-matrix which can take any size matrix input using end was this correct or can't you do that? I keep getting this error
Undefined function or variable 'T'.
Error in custom_blocksT (line 2)
T(1:end,end-1:1);
I have searched the Matlab documentation and stacked overflow, but the problem is I'm not quite sure what I'm supposed to be looking for in terms of solving this question.
If someone could help me I would be very thankfull.
There are many problems with your function:
function T = custom_blocksT(n,m)
T(1:end,end-1:1);
T(1:end,end:-1:1)*2;
T(1:end,end:-1:1)*3;
T(1:end,end:-1:1)*4;
end
This is an extremely basic question, I highly recommend you find and work through some very basic MATLAB tutorials before continuing, even before reading this answer to be honest.
That said here is what you should have done and a bit of what you did wrong:
First, you are getting the error that T dos not exist because it doesn't. The only variables that exist in your function are those that you create in the function or those that are passed in as parameters. You should have passed in T as a parameter, but instead you passed in n and m which you don't use.
In the question, they call the function using the example:
custom_blocks([1:3;3:-1:1])
So you can see that they are only passing in one variable, your function takes two and that's already a problem. The one variable is the matrix, not it's dimensions. And the matrix they are passing in is [1:3;3:-1:1] which if you type in the command line you will see gives you
[1 2 3
3 2 1]
So for your first line to take in one argument which is that matrix it should rather read
function TOut = custom_blocks(TIn)
Now what they are asking you to do is create a matrix, TOut, which is just different multiples of TIn concatenated.
What you've done with say TIn(1:end,end-1:1)*2; is just ask MATLAB to multiple TIn by 2 (that's the only correct bit) but then do nothing with it. Furthermore, indexing the rows by 1:end will do what you want (i.e. request all the rows) but in MATLAB you can actually just use : for that. Indexing the columns by end-1:1 will also call all the columns, but in reverse order. So in effect you are flipping your matrix left-to-right which I'm sure is not what you wanted. So you could have just written TIn(:,:) but since that's just requesting the entire matrix unchanged you could actually just write TIn.
So now to multiply and concatenate (i.e. stick together) you do this
TOut = [TIn, TIn*2; TIn*3, TIn*4]
The [] is like a concatenate operation where , is for horizontal and ; is for vertical concatenation.
Putting it all together:
function TOut = custom_blocks(TIn)
TOut = [TIn, TIn*2; TIn*3, TIn*4];
end

MATLAB: If this value of 5x5 cell with vectors [106x1] are different to zeroes,count them e put the count in a matrix

I have matchcounts (5x5)cell, every cell has a vector of double [106x1]. The vectors of double have zeros and non zero values. I want to find non zero values for every cell, count them and put the result in a matrix.
I tried with this code:
a{i,j}(k,1)=[];
for k=1:106
for i=1:5
for j=1:5
if (matchcounts{i,j}(k,1))~=0
a{i,j}=a{i,j}(k,1)+1;
end
end
end
end
and others but it's not correct! Can you help me? Thanks
While it is possible to fix your answer above, I recommend to change the data structure to have a much simpler solution possible. Instead of having a 2D cell array which holds 1D data, choose a single 3D data structure.
For an optimal solution you would change your previous code code to directly write the 3D-matrix, instead of converting it. To get started, this code converts it so you can already see how the data structure should look like:
%convert to matrix
for idx=1:numel(matchcounts)
matchcounts{idx}=permute(matchcounts{idx},[3,2,1]);
end
matchcounts=cell2mat(matchcounts);
And finding the nonzero elements:
a=(matchcounts~=0)
To index the result, instead of a{k,l}(m,1) you use a(k,l,m)
To give you some rule to avoid complicated data structures in the future. Use cell arrays only for string data and data of different size. Whenever you have a cell array which contains only vectors or matrices of the same size, it should be a multidimensional matrix.

MATLAB: How to apply a vectorized function using sparsity structure?

I need to (repeatedly) build a vector of length 200 from a vector of length 2500. I can describe this operation using multiplication by a matrix which is extremely sparse: it is 200x2500 and has only one entry in each row. But I have very little control over where this entry is. My actual problem is that I need to apply this matrix not to the vector that I currently have, but rather to some componentwise function of this vector. Since I have all this sparsity, it is wasteful to apply this componentwise function to all 2500 components of my vector. Instead I would rather apply it only to the 200 components that actually contribute.
A program (with randomly chosen numbers replacing of my actual numbers) which would have a similar problem would be something like this:
ind=randi(2500,200,1);
coefficients=randn(200,1);
A=sparse(1:200,ind,coefficients,200,2500);
x=randn(2500,1);
y=A*subplus(x);
What I don't like here is applying subplus to all of x; I would rather only have to apply it to x(ind), since only that contributes to the matrix product.
Right now the only way I can see to work around this is to replace my sparse matrix with a 200-component vector of coefficients and a 200-component vector of indices. Working this way, the code above would become:
ind=randi(2500,200,1);
coefficients=randn(200,1);
x=randn(2500,1);
y=coefficients.*subplus(x(ind))
Is there a better way to do this, preferably one that would work when A contains a few elements per row instead of just one?
The code in your question throws an exception, I think it should be:
n=2500;
m=200;
ind=randi(n,m,1);
coefficients=randn(m,1);
A=sparse(1:m,ind,coefficients,m,n);
x=randn(n,1);
Your idea using x(ind) was basically right, but ind would reorder x which is not intended. Instead you could use sort(unique(ind)). I opted to use the sparse logical index any(A~=0) because I expect it to be faster, but you could compare both versions.
%original code
y=A*subplus(x);
.
%multiplication using sparse logical indexing:
relevant=any(A~=0);
y=A(:,relevant)*subplus(x(relevant));
.
%fixed version of your code
relevant=sort(unique(ind));
y=A(:,relevant)*subplus(x(relevant));

Matlab: Matrix of ClassificationKNN class objects

For classification I'm building a number of models for a classifier in MATLAB. I use the class ClassificationKNN for this.
I would very much like to store multiple models (or objects of this class) inside a matrix.
Normally you could access and create matrices inside a matrix with the curly braces ({}).
My loop looks like this:
models = []
for i = 1:length(x)
models = [models, {ClassificationKNN.fit(x,y)}]
end
Unfortunately this returns a matrix models of size (1,3) but all cells are empty which means the models are lost...
How can I make sure every model is stored in a matrix? I need to do this because I need all models later in my calculations and the position in the matrix is important...
Any ideas?
You want a cell array of models, right? It sure looks that way, if that will work try this:
models = {}
for ii = 1:length(x)
models = [models, {ClassificationKNN.fit(x,y)}]
end
Also, you loop through calling ClassificationKNN.fit(x,y) with the same arguments every time, is this just a test, or pseudo-code for an example. Like the comment says, it's best to preallocate like:
models = cell(length(x),1);
for ii = 1:length(x)
models{ii} = ClassificationKNN.fit(x,y);
end
But, either way is likely fine.
Thanks to macduffs post I finally figured out what was going on. Whilest reading his proposition I realised that that indeed should be the correct way if getting a cell array of objects.
After trying it, the array again seemed empty when opening it in the variable editor. I tried calling the first cell in the array to see if it was indeed empty and it was not. It returned the object I had stored in it. This means the question was answered.
I then reverted back to my own method to see if that worked as well and it did. When calling a cell it also returned an object.
Bottom line:
Do not trust the variable editor ^^.