Reputation: 1784
I have a vector T
of length n
and m
other vectors of the same length with 0
or 1
used as condition to select elements of T
. The condition vectors are combined into a matrix I
of size n x m
.
Is there a one liner to extract a matrix M
of values from T
such that the i-th column of M
are those elements in T
that are selected by the condition elements of the i-th column in I
?
Example:
T = (1:10)'
I = mod(T,2) == 0
T(I)'
yields
2 4 6 8 10
However
I = mod(T,2:4) == 0
T(I)'
yields an error in the last statement. I see that the columns might select a different number of elements which results in vectors of different lengths (as in the example). However, even this example doesn't work:
I = zeros(10,2)
I(:,1) = mod(T,2)==0
I(:,2) = mod(T,2)==1
Is there any way to achieve the solution in a one liner?
Upvotes: 1
Views: 66
Reputation: 2802
The easiest way I can think of to do something like this is to take advantage of the element-wise multiplication operator .*
with your matrix I
. Take this as an example:
% these lines are just setup of your problem
m = 10;
n = 10;
T = [1:m]';
I = randi([0 1], m, n);
% 1 liner to create M
M = repmat(T, 1, n) .* I;
What this does is expand T
to be the same size as I
using repmat
and then multiplies all the elements together using .*
.
Upvotes: 3
Reputation: 1797
One line solution using cellfun
and mat2cell
nColumns = size(I,2); nRows = size(T,1); % Take the liberty of a line to write cleaner code
cellfun(@(i)T(i),mat2cell(I,nRows,ones(nColumns,1)),'uni',0)
What is going on:
@(i)T(i) % defines a function handle that takes a logical index and returns elements from T for those indexes
mat2cell(I,nRows,ones(nColumns,1)) % Split I such that every column is a cell
'uni',0 % Tell cellfun that the function returns non uniform output
Upvotes: 1
Reputation: 15857
Here is a one linear solution
mat2cell(T(nonzeros(bsxfun(@times,I,(1:numel(T)).'))),sum(I))
First logical index should be converted to numeric index for it we multiply T
by each column of I
idx = bsxfun(@times,I,(1:numel(T)).');
But that index contain zeros we should extract those values that correspond to 1s
in matrix I
:
idx = nonzeros(idx);
Then we extract repeated elements of T
:
T2 = T(idx);
so we need to split T2
to 3
parts size of each part is equal to sum of elements of corresponding column of I
and mat2cell
is very helpful
result = mat2cell(T2,sum(I));
result
ans =
{
[1,1] =
2
4
6
8
10
[2,1] =
3
6
9
[3,1] =
4
8
}
Upvotes: 1