Squeeze Some of Singleton Dimensions in Matlab
Asked Answered
M

3

5

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".

Mossgrown answered 16/5, 2014 at 19:45 Comment(7)
@Luis Was removing the tag - singleton a good idea, given this is mainly based on that kind of tag?Weismann
@Weismann That tag's definition says "The singleton is a design pattern to ensure that exactly one application-wide instance of a particular class exists". So obviously it refers to the OOP concept of singleton, not to singleton dimensions. But you may be right: is it correct to remove a tag based on its definition, when its name does apply to the answer? Feel free to roll my edit back if you find it appropriateInterdependent
@LuisMendo I am not too picky about it. It's okay as it is now I guess given the definition. Thanks on bring up the definition text though!Weismann
@Weismann I'll search/ask in Meta about this (the name applies, the definition doesn't: remove?)Interdependent
@LuisMendo Haven't got much idea about adding new tags or editing the definitions of the existing ones really.Weismann
For future reference: remove seems to be the best action, according to Meta @WeismannInterdependent
@LuisMendo I guess it makes sense to not add that tag for this question. Also creating a new tag for this specialized one doesn't make sense yet. Thank you for your efforts on checking with those meta folks.Weismann
W
4

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)])))
Weismann answered 16/5, 2014 at 20:6 Comment(0)
N
4

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)])
Needs answered 16/5, 2014 at 20:3 Comment(0)
W
4

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)])))
Weismann answered 16/5, 2014 at 20:6 Comment(0)
G
0

@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.

Geometry answered 19/9, 2023 at 15:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.