How can I squeeze only a subset of singleton dimensions of a matrix in Matlab? The squeeze function removes them all.
I keep the index to those dimensions in a vector called "dims".
How can I squeeze only a subset of singleton dimensions of a matrix in Matlab? The squeeze function removes them all.
I keep the index to those dimensions in a vector called "dims".
Code
%// Input matrix is assumed as A
sz = size(A)
t2 = sz~=1
t2(dims)=1
out = reshape(A,sz(t2)) %// out is the desired output
If you are crazy about dense codes, you can try this -
sz = size(A)
out = reshape(A,sz(sort([dims find(sz~=1)])))
In Matlab, there is no tailing singleton dimension. A n*m*1 matrix is automatically a n*m matrix. Knowing this, your problem could be solved permuting the dimensions you don't want to the end:
X=ones(2,1,2,1,2,1,2,1,2,1)
%dimensions you want to keep in any case
dims=[2:4];
%Notice, S is [2,1,2,1,2,1,2,1,2], last dimension already "gone"
S=size(X)
%keep if size>1
dimensions_to_keep=S>1
%and keep if in "dims" list
dimensions_to_keep(dims)=1
%now permute dimensions you don't want to the end
Y=permute(X,[find(dimensions_to_keep),find(~dimensions_to_keep)])
Code
%// Input matrix is assumed as A
sz = size(A)
t2 = sz~=1
t2(dims)=1
out = reshape(A,sz(t2)) %// out is the desired output
If you are crazy about dense codes, you can try this -
sz = size(A)
out = reshape(A,sz(sort([dims find(sz~=1)])))
@Divakar's answer takes dims
as being "what to keep". For "what to drop", below basically converts one into the other and pastes into that answer:
sz = size(A);
keepdims = 1:numel(sz);
keepdims = keepdims(~arrayfun(@(i)ismember(i, dims_user), keepdims));
no_squeeze = sz~=1;
no_squeeze(keepdims) = 1;
new_sz = sz(no_squeeze);
if numel(new_sz) == 1 % can't reshape into 1D
new_sz = [1 new_sz];
end
out = reshape(A, new_sz);
Example size(out)
s with A = randn(1, 1, 3, 1, 4)
dims_user = 1; % 1 3 1 4 | drops dim1
dims_user = 2; % 1 3 1 4 | drops dim2 (same effect)
dims_user = 3; % 1 1 3 1 4 | ignores drop request
dims_user = 4; % 1 1 3 4 | drops dim 4
dims_user = 1:2; % 3 1 4 | drops dims 1, 2
dims_user = 1:3; % 3 1 4 | drops dims 1, 2, ignores 3
dims_user = 1:5; % 3 4 | == `squeeze(A)`
The ignoring mimics Python's numpy.squeeze
. Also handles the 1D edge case.
© 2022 - 2024 — McMap. All rights reserved.
singleton
a good idea, given this is mainly based on that kind of tag? – Weismann