Reputation: 947
Imaging that I have the following matrix A(5x20)
:
A = [6.4475 3.3487 Inf 6.4940 6.5480 3.4857 Inf 6.5030 6.5035 3.5732 Inf 6.4951 6.6372 3.3639 Inf 6.5371 Inf 4.4444 Inf Inf;
6.6761 2.3999 Inf 6.8620 6.5776 2.1963 Inf 6.8535 6.8733 3.1184 Inf 6.8688 6.5918 2.2900 Inf 6.8656 Inf 4.4667 Inf Inf;
5.9808 4.1965 Inf 5.8950 6.2467 4.5779 Inf 5.9116 5.9198 4.0071 Inf 5.8938 6.3981 4.3019 Inf 5.9570 Inf 4.3433 Inf Inf;
5.7438 1.5369 Inf 5.9868 5.5404 1.6374 Inf 5.9537 6.0332 2.1704 Inf 6.0024 5.5235 1.5035 Inf 5.9397 Inf 3.5727 Inf Inf;
4.0544 3.8845 Inf 4.1466 4.6749 4.6560 Inf 4.3833 3.7550 3.0591 Inf 4.0693 4.9586 4.1296 Inf 4.6826 Inf 2.5593 Inf Inf];
then I would like to extract the values in the following way:
so my output matrix is:
B = [6.4475 3.3487 Inf 6.4940;
6.5776 2.1963 Inf 6.8535;
5.9198 4.0071 Inf 5.8938;
5.5235 1.5035 Inf 5.9397;
Inf 2.5593 Inf Inf]
Upvotes: 0
Views: 60
Reputation: 23675
This should work fine:
% Define the data sample...
A = [
6.4475 3.3487 Inf 6.4940 6.5480 3.4857 Inf 6.5030 6.5035 3.5732 Inf 6.4951 6.6372 3.3639 Inf 6.5371 Inf 4.4444 Inf Inf;
6.6761 2.3999 Inf 6.8620 6.5776 2.1963 Inf 6.8535 6.8733 3.1184 Inf 6.8688 6.5918 2.2900 Inf 6.8656 Inf 4.4667 Inf Inf;
5.9808 4.1965 Inf 5.8950 6.2467 4.5779 Inf 5.9116 5.9198 4.0071 Inf 5.8938 6.3981 4.3019 Inf 5.9570 Inf 4.3433 Inf Inf;
5.7438 1.5369 Inf 5.9868 5.5404 1.6374 Inf 5.9537 6.0332 2.1704 Inf 6.0024 5.5235 1.5035 Inf 5.9397 Inf 3.5727 Inf Inf;
4.0544 3.8845 Inf 4.1466 4.6749 4.6560 Inf 4.3833 3.7550 3.0591 Inf 4.0693 4.9586 4.1296 Inf 4.6826 Inf 2.5593 Inf Inf
];
% Define the script parameters...
k = 4;
n = size(A,2) / k;
% Create the auxiliary matrix for indexing...
aux = repmat({ones(1,k)},1,n);
idx = blkdiag(aux{:});
% Extract the elements using the indexing and properly reshape the result...
B = reshape(A(logical(idx)),k,size(A,1)).'
The final output is:
B =
6.4475 3.3487 Inf 6.4940
6.5776 2.1963 Inf 6.8535
5.9198 4.0071 Inf 5.8938
5.5235 1.5035 Inf 5.9397
Inf 2.5593 Inf Inf
Upvotes: 1
Reputation: 4956
I assume that the number of elements per line is a parameter k
.
In one line, you can retrieve the elements like this:
B = A(sub2ind(size(A), repmat((1:size(A,1)).', 1, k), (1:k)+((1:k:size(A,2))-1).'));
Let's explain a little. You create the indexes of the elements you want to retrieve and convert them into linear indexing with sub2ind
. Line indexes are easy to create with repmat
.
For column indexing, one solution is to create a matrix with elements being the column indexes. Here I choose a long version:
(1:k)+((1:k:size(A,2))-1).'
It enables you to skip or duplicate elements (depending on size(A,2)
being a multiple of k
or not). Note that this construct works in recent Matlab versions, in old versions, you nned to call bsxfun(@plus, 1:k, ((1:k:size(A,2))-1).')
If you are sure to take exactly one element per column in the result, let's do it more efficiently: reshape(1:size(A,2), k,[]).'
Note that it does not take care of odd sizes of input matrix (if you have more rows for example).
Upvotes: 1