How to create a sub-matrix in MATLAB - matlab

I have this work which I have to do by creating a sub-matrix out of a given data set. I will explain it below.
Suppose, I have the data set as:
100 200 300 400 500 600
101 201 301 401 501 601
102 202 302 402 502 602
So, I want to create sub-matrices as follows:
For the first iteration ->
[[101 201 301 401 501]
[102 202 302 402 502]]
and
[[601]
[602]]
For the second iteration ->
[[100 200 300 400 500]
[102 202 302 402 502]]
and
[[600]
[602]]
And so on... The process will continue till the number of rows in the main/starting matrix.
In short, I want a LOO (leave one out) implementation of this data set, so that I can further work on it.
If you guys have any idea on how to do it, please share it. :)

Assuming A is the main matrix, a1 and a2 will be your first set of sub-matrices and b1 and b2 will be the second set of sub-matrices.
>> A=[100 200 300 400 500 600
101 201 301 401 501 601
102 202 302 402 502 602];
>> a1=A(2:3,1:5)
a1 =
101 201 301 401 501
102 202 302 402 502
>> a2=A(2:3,6)
a2 =
601
602
>> b1=A(1:2,1:5)
b1 =
100 200 300 400 500
101 201 301 401 501
>> b2=A(1:2,6)
b2 =
600
601

A proper indexing is your friend here. For the given matrix:
X = [
100 200 300 400 500 600
101 201 301 401 501 601
102 202 302 402 502 602
];
The first subsets are:
S1A = X(2:3,1:end-1);
S1B = X(2:3,end);
and the second subsets are:
S2A = X(1:3,1:end-1);
S2B = X(1:3,end);
Since you want to perform this for all the two-rows combinations of the matrix, the rows indexing patten can be generated with the nchoosek function as follows:
X_seq = 1:numel(x);
idx = nchoosek(X_seq,2);
Then, with an iteration (just to keep things simple... althrough in Matlab is always recommended to vectorize as many computations as possile), you can extract all the matches:
idx_len = size(idx,1);
res = cell(idx_len,2);
for i = 1:idx_len
idx_curr = idx(i,:);
res(i,:) = {X(idx_curr,1:end-1) X(idx_curr,end)};
end

If you have the stats and ML toolbox then you can use their built-in cross validation functions. See cvpartition or crossvalind

Related

How to insert a value

I want to insert a number in the following matrix: n x 1 matrix
6
103
104
660
579
750
300
299
300
750
579
661
580
760
302
301
302
760
580
662
581
How to I insert it in the middle and shift the remaining numbers? I tried the following code:
Idx=[723];
c=false(1,length(Element_set2)+length(Idx));
c(Idx)=true;
result=nan(size(c));
result(~c)=Element_set2;
result(c)=8
You are complicating things. Simply find the middle index by finding the length of the array, dividing by 2 and truncating any decimal points, then using simply indexing to update the new matrix. Supposing that result is the column vector that was created by you and number is the value you want to insert in the middle, do the following:
number = 8; %// Change to suit whatever number you desire
middle = floor(numel(result) / 2);
result = [result(1:middle); number; result(middle+1:end)];
In the future, please read this great MATLAB tutorial on indexing directly from MathWorks: http://www.mathworks.com/company/newsletters/articles/matrix-indexing-in-matlab.html. It's a good resource on the kinds of indexing operations one expects from starting out in MATLAB.

Tallying coincidences of numbers (Part 2) - MATLAB

Following on from: Tallying co-incidences of numbers in columns of a matrix - MATLAB
I was wondering how best to go about the same task when the data is processed differently. Starting with a matrix of:
A =
201 202
203 204
201 203
201 203
205 201
I simply need a matrix that tallies the coincidence of each number from Column 1 to Column 2 i.e.
201 202
201 occurs with 202 once and so on (it ignores that 202 occurs with 201, removing duplicates). This is stored in a 2D matrix with min(A):max(A) running down both sides.
The desired output for the above example (A) would be:
201 202 203 204 205
201 0 1 2 0 0
202 0 0 0 0 0
203 0 0 0 1 0
204 0 0 0 0 0
205 1 0 0 0 0
See if this works for you -
A1 = A-min(A(:))+1 %// Get offsetted values
Aout = zeros(max(A1(:)))
%// For performance: Aout(max(A1(:)),max(A1(:)))=0;
%// But for this performance trick to work, make sure Aout isnt defined before.
%// Source - http://undocumentedmatlab.com/blog/preallocation-performance
idx = sub2ind(size(Aout),A1(:,1),A1(:,2))
%// For performance: idx = (A1(:,2)-1)*size(Aout,1) + A1(:,1)
unqidx = unique(idx) %// get unique indices
Aout(unqidx) = histc(idx,unqidx) %// put counts of indices into their places
Sample run with an extra added row of input data -
>> A
A =
201 202
203 204
201 203
201 203
205 201
202 201
>> Aout
Aout =
0 1 2 0 0
1 0 0 0 0
0 0 0 1 0
0 0 0 0 0
1 0 0 0 0

How to arrange pixel address as order under certain condition?

I am currently doing map processing in matlab. Now i solved the maze and get the path of maze. Now i have turning point in map. But this address pixel are not in correct order. So i want to order the incorrect order of pixel address in to correct order.
INCORRECT ORDER:
shape(1).cen=[28;136];
shape(2).cen=[122;136];
shape(3).cen=[344;391];
shape(4).cen=[548;493];
shape(5).cen=[548;191];
shape(6).cen=[344;191];
shape(7).cen=[122;391];
CORRECT ORDR:
map(1).cen=[28;136];
map(2).cen=[122;136];
map(3).cen=[122;391];
map(4).cen=[344;391];
map(5).cen=[344;191];
map(6).cen=[548;191];
map(7).cen=[548;493];
My code is below:-
`map(1).cen=[28;136];
o=0; order=1;xflag=0;yflag=0;
k=length(shape); %indicates the total elements in shape.cen structure
for (j=1:k)
order=order+1; o=o+1;
if (j==1)
x=map(1).cen(1,1);
y=map(1).cen(2,1);
for(i=1:k)
xi=shape(i).cen(1,1);
yi=shape(i).cen(2,1);
if((x==xi)||(y==yi))
if(x==xi)
map(order).cen(1,1)=xi;
map(order).cen(2,1)=yi;
xflag=1;
break;
else
(y==yi)
map(order).cen(1,1)=xi;
map(order).cen(2,1)=yi;
yflag=1;
break;
end
end
end
end
x=map(o).cen(1,1);
y=map(o).cen(2,1);
for(i=1:k)
xi=shape(i).cen(1,1);
yi=shape(i).cen(2,1);
if(xflag==1)
if(y==yi)
map(order).cen(1,1)=xi;
map(order).cen(2,1)=yi;
xflag=0;
yflag=1;
break;
end
end
if (yflag==1)
if(x==xi)
map(order).cen(1,1)=xi;
map(order).cen(2,1)=yi;
xflag=1;
yflag=0;
break;
end
end
end
end
`
[shape.cen]' will give you the following array:
ans =
28 136
122 136
344 391
548 493
548 191
344 191
122 391
Now that it's a regular numerical array, you can use sortrows, like this.
map = sortrows([shape.cen]')
to get:
map =
28 136
122 136
122 391
344 191
344 391
548 191
548 493
If you don't want it as a numerical array, but a struct similar to shape, you can do:
[~, ID] = sortrows([shape.cen]')
map = shape(ID)'

Getting different gray-level values from a matrix (Gray-level image)

I have this matrix:
image= [200 200 200 200 200 200 200;
200 180 180 180 180 180 200;
200 180 120 150 120 180 200;
200 180 150 40 150 180 200;
200 180 120 150 120 180 200;
200 180 180 180 180 180 200;
200 200 200 200 200 200 200];
I want to get the different gray-values and put them in an array, so my array will look like this:
Array= [40 120 150 180 200];
How can I do this in MATLAB?
The unique function does exactly what you are looking for.

Clustering data after linkage algorithm

I am not an expert in statistics and data analysis, hence I can't understand if the behavior which I obtain is correct or not. I am here looking for your help.
Assume I have these samples which I would like to cluster (10 points in the plane - reduced version of the problem):
[X Y] =
266 450
266 400
258 168
290 442
295 438
273 432
294 158
318 161
250 423
253 413
To cluster them I can use a cluster tree
Z = linkage([ X Y ],'complete');
which is (by dendrogram(Z,10))
Now I would like to extract clusters on the basis of the distance attached to the nodes of the tree.
Say that my distance is 150, I would expect that the call
T = cluster(Z,'Cutoff',150);
returns me 2 clusters. But it gives me just one (I suppose), i.e.
T =
1
1
1
1
1
1
1
1
1
1
What am I missing?
Use inconsistent(Z,150) and look at the values in column 4. Increasing the cutoff from a small positive number steps you along the tree.
E.g.
cluster(Z,'cutoff',0.7)
does not give you what you want (I think)
but
cluster(Z,'cutoff',0.8)
does.
The criterion for cluster is inconsistency ('inconsistent') by default.
Since the height in dendrogram is distance, you can change the criterion to 'distance',
i.e:
T = cluster(Z, 'Cutoff', 150, 'criterion', 'distance');