subset matrix using find function in Matlab - matlab

I made a matrix in Matlab, say,
A = magic(5);
A =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
Now I found the indices I want using the find function as:
ind = find(A(:,5)>3 & A(:,4)>= 8);
ind =
1
2
3
Now if I want to get a subset of matrix A for those indices using B = A(ind) function, I only get the first column of the matrix:
B = A(ind)
B =
17
23
4
How can I get all the columns as subset??

Oops ... I got it
B = A(ind,:);

Related

Vectorising a Matlab code to pick specific indices of a matrix

I have a matrix A in Matlab of dimension Nx(N-1), e.g.
N=5;
A=[1 2 3 4;
5 6 7 8;
9 10 11 12;
13 14 15 16;
17 18 19 20];
I want to rearrange the elements of A in a certain way. Specifically I want to create a matrix B of dimension (N-1)xN such that:
for i=1,...,N,
B(:,i) collects
1) the first i-1 elements of the i-1th column of A and
2) the last N-i elements of the ith column of A.
Notice that for i=1 the i-1th column of A does not exist and therefore 1) is skipped; similarly, for i=N theith column of A does not exist and therefore 2) is skipped.
In the example above
B=[5 1 2 3 4
9 10 6 7 8
13 14 15 11 12
17 18 19 20 16];
This code does what I want. I am asking your help to vectorise it in an efficient way.
B=zeros(N-1,N);
for i=1:N
if i>1 && i<N
step1=A(1:i-1,i-1);
step2=A(i+1:N,i);
B(:,i)=[step1;step2];
elseif i==1
B(:,i)=A(i+1:N,i);
elseif i==N
B(:,i)=A(1:i-1,i-1);
end
end
Extract the lower and upper triangular matrices of A. Then reassemble them with a "diagonal shift":
u = triu(A);
l = tril(A,-1);
B = padarray(u(1:end-1,:),[0 1],'pre') + padarray(l(2:end,:),[0 1],'post');
Another valid approach using logical indexing combined with tril and triu:
B = zeros(size(A'));
B(tril(true(size(B)))) = A(tril(true(size(A)), -1));
B(triu(true(size(B)), 1)) = A(triu(true(size(A))));
Result:
>> B
B =
5 1 2 3 4
9 10 6 7 8
13 14 15 11 12
17 18 19 20 16

How to efficiently reshape one column matrix to many specific length columns by moving specific interval

The input is an N-by-1 matrix. I need to reshape it to L-by-M matrix. The following is an example.
Input:
b =
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Set length = 18, Output:
X =
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
8 9 10
9 10 11
10 11 12
11 12 13
12 13 14
13 14 15
14 15 16
15 16 17
16 17 18
17 18 19
18 19 20
Because I have a very big matrix, using a loop to reshape is very inefficient. How can I improve the reshape speed?
Your example output matrix X is the perfect matrix to index a vector of length N to get what you want. It's also very easy to create using bsxfun:
N = 20;
b = rand(N,1);
M = 3; %// number of columns
L = N-M; %// Note that N-M is an upper limit for L!
idx = bsxfun(#plus, (0:L)', 1:M)
X = b(idx)
That's exactly what im2col (from the Image Processing Toolbox) does:
b = (1:20).'; %'// example data
L = 18; % // desired length of sliding blocks
x = im2col(b, [L 1]); % // result
I'd use horzcat. For example:
function X = reshaper(b,len)
diff = length(b) - len + 1;
X = b(1:len);
for i=2:diff
X = horzcat(X,b(i:len+(i-1)));
end
You could probably remove the for loop with some further thought.

How to select different row in a matrix in Matlab every time?

I want to create a matrix which has distinct rows selected from another matrix.
For Example, I have a 10x3 matrix A
A =
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
16 17 18
19 20 21
22 23 24
25 26 27
28 29 30
Now I want to create a new matrix B of size 2 X 3 from A in a iterative process in such a way that the matrix B should consist different rows in each iteration (max iteration = 5)
My Pseudo-code:
for j=1:5
create matrix 'B' by selecting 2 rows randomly from 'A', which should be different
end
You could use randperm to mess up the rows randomly and then take two rows in each iteration successively in order.
iterations = 4;
permu = randperm(size(A,1));
out = A(permu(1:iterations*2),:);
for ii = 1:iterations
B = out(2*ii - 1:2*ii,:)
end
Results:
B =
22 23 24
25 26 27
B =
1 2 3
13 14 15
B =
19 20 21
16 17 18
B =
7 8 9
10 11 12

How can I discard some unwanted rows from a matrix in Matlab?

I have a matrix
A= [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16; 17 18 19 20]
I want to do some calculation on this matrix. But actually I do not need all the rows. So I have to discard some of the rows from the above matrix before doing a calculation. After discarding 3 rows, we will have a new matrix.
B= [1 2 3 4; 9 10 11 12; 17 18 19 20];
Now I have to use B to make some other calculations. So how can I discard some of the unwanted rows from a matrix in matlab? Any suggestion will be helpful. Thanks.
Try this: (Use when no. of rows to keep is lesser)
%// Input A
A = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16; 17 18 19 20];
%// Rows (1-3,5) you wanted to keep
B = A([1:3, 5],:)
Output:
B =
1 2 3 4
5 6 7 8
9 10 11 12
17 18 19 20
Alternative: (Use when no. of rows to discard is lesser)
%// rows 2 and 3 discarded
A([2,3],:) = [];
Output:
>> A
A =
1 2 3 4
13 14 15 16
17 18 19 20
Note: Here (in the alternate method), the output replaces the original A. So you need to back up A if you need it afterwards. You could do this before discarding operation to backup Input matrix
%// Input A is backed up in B
B = A;
You can select the indices of the rows you want to keep:
A([1,3,5],:)
ans =
1 2 3 4
9 10 11 12
17 18 19 20

Extracting values along a row, column or diagonal of a 2D matrix

I have a 2 dimensional matrix and I want to get the data along a particular line. Similar to what 'Slice' does to a 3D matrix. Is there a a way to do a similar thing on a 2D matrix.
Thanks in advance.
Extracting all values of a column or a line:
>> M = magic(4)
M =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
>> particular_row = 3;
>> M(particular_row,:)
ans =
9 7 6 12
>> particular_column = 2;
>> M(:,particular_column)
ans =
2
11
7
14
Extracting values along a diagonal:
What if I want to get the data along any direction say along a line joining matrix index (1,1) to (4,4) of a 5x5 matrix?
I'd use linear indexing and the sub2ind function for this task. Demo:
(1,1) to (4,4):
>> M = magic(5)
M =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
>> M(sub2ind(size(M), 1:4, 1:4))
ans =
17 5 13 21
Another example: (1,2) to (3,4):
M(sub2ind(size(M), 1:3, 2:4))
ans =
24 7 20