I have a list of coordinates I would like to sample from a Matrix.
Is there any elegant way to do it?
Ideally, something that looks like:
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
r = 1:5; % row coordinates
c = 5:-1:1; % column coordinates
A(r,c)
ans =
15 14 13 12 11
Which is equivalent to
for k=1:length(r)
A(r(k), c(k))
end
I am sure someone has asked that, but I couldn't find it anywhere.
Applying #excaza comment I was able to solve this with:
rc_ids = sub2ind(size(A), r,c);
A(rc_ids)
Related
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.
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
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
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,:);
I have a loop:
for i=1:size(A,1),
if A(i,4:6) == [0,0,3.4]
K = [K; A(i,:)];
end
end
and I would like to delete the last row in the matrix but I do not know what number row it will be. How do I delete the last row in the matrix in the loop? Or should I do it after the loop?
Why do you have loop? it is a one time action, not something you do several times.
check this out, I delete the last row:
>> a = magic(5);
>> a
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
>> a = a(1:end-1,:);
>> a
a =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
you can refer to last row by END keyword:
A= A(1:end-1, :)