MATLAB submatrix over variable dimensions
I have a variable dimension matrix, X. I want a function that will get the first half of X in one dimension. I.E., I want something like this:
开发者_运维百科function x = variableSubmatrix(x, d)
if d == 1
switch ndims(x)
case 1
x = x(1:end/2);
case 2
x = x(1:end/2, :);
case 3
x = x(1:end/2, :, :);
(...)
end
elseif d == 2
switch ndims(x)
case 2
x = x(:, 1:end/2);
case 3
x = x(:, 1:end/2, :);
(...)
end
elseif (...)
end
end
I'm not quite sure how to do this. I need it to be fast, as this will be used many times in computation.
This should do the trick:
function x = variableSubmatrix(x, d)
index = repmat({':'},1,ndims(x)); %# Create a 1-by-ndims(x) cell array
%# containing ':' in each cell
index{d} = 1:size(x,d)/2; %# Create an index for dimension d
x = x(index{:}); %# Index with a comma separated list
end
The above first creates a 1-by-ndims(x)
cell array with ':'
in each cell. The cell corresponding to dimension d
is then replaced with a vector containing the numbers 1 through half the size of dimension d
. Then, the contents of the cell array are output as a comma-separated list (using the {:}
syntax) and used as the indices into x
. This works because ':'
and :
are treated the same way (i.e. "all elements of this dimension") when used in an indexing statement.
You can use s = size(X)
to get the dimensions of X
, and then try X(1:floor(s(1)),:)
to get half of the matrix.
Note that size
returns a vector array containing the length in each dimension (e.g., a 2x3 matrix will return a size of [2 3]
). As such, you may want to change s(1)
to whichever dimension you require.
Example:
a = [1 2 3 4; 5 6 7 8;]
s = size(a); % s = [2 4]
b = a(1:s(1)/2,:); % b = [1 2 3 4];
c = a(:,1:s(2)/2); % c = [1 2; 5 6];
For what it's worth, here is the solution in Python (with numpy
):
To halve dimension i
:
def halve(x,i):
return x[(slice(None),)*i+(slice(x.shape[i]/2),)]
x = zeros([2,4,6,8])
y = halve(x,2) # dimension 2 was 6
y.shape # (2,4,3,8) # dimension 2 is now 3
If you just want to halve the first dimension, then x[:len(x)/2]
is sufficient.
Edit
I got some sceptic comments, on my previous solution, x[:len(x)/2]
, so here is an example:
x=zeros([4,2,5,6,2,3]) # first dimension is 4
len(x) # 4
x.shape # 4,2,5,6,2,3
x[:len(x)/2].shape # 2,2,5,6,2,3 <- first dimension divided by two
精彩评论