Steve on Image Processing and MATLAB

Concepts, algorithms & MATLAB

Even more information about the size function

I'm terrible at predicting what kind of topic will generate a lot of comments. I was sure that last week's post on size esoterica would put most everyone to sleep. But no, it quickly gathered quite a few comments containing several interesting ideas and questions. So I thought it would be useful to follow up with another post instead of replying with my own comments.

First, there was some discussion in the comments about the "best" way to call size. Let's quickly review the basic ways to call size:

The call sz = size(A) returns a size vector of length ndims(A).

A = rand(3,4,5);
sz = size(A)
sz =
     3     4     5

The call d = size(A,n) returns the size of the n-th dimension of A. n can be greater than ndims(A).

d = size(A,2)
d =
     4
d = size(A,6)
d =
     1

The call [m,n,p] = size(A) returns the sizes along the first three dimensions as m, n, and p. If A has more than three dimensions, then p is the product of the sizes along the third and all higher dimensions. If you call size(A) with more output arguments than ndims(A), the value of all the "extra" output arguments is 1.

[m,n,p] = size(A)
m =
     3
n =
     4
p =
     5
[m,n] = size(A)
m =
     3
n =
    20
[m,n,p,q,r] = size(A)
m =
     3
n =
     4
p =
     5
q =
     1
r =
     1

So which of these forms is best? I don't think there is a single best choice. I regularly use all three, and my particular choice in any one instance depends on how the output of size is used in the subsequent code. Also, keep in mind that every variable assignment is an opportunity to name something well (or not).

Sometimes, for example, I just need a size vector to pass to something like reshape, like this:

   size_in = size(in);
   % work with input as a single column vector
   in = in(:);
   ... lots o' code
   % reshape output to be the same size as input
   out = reshape(out,size_in);

Or I might need to refer several times in the code to the number of color-space components in an array, and I don't need other information about the size:

   num_components = size(in,3);
   for k = 1:num_components
      ... do something interesting with each component
   end

If I need to refer to the sizes along several dimensions separately in the code, then I'll do something like this in order to have readable names:

   [num_rows, num_cols, num_planes] = size(A);

Jonathan didn't want to use the tilde technique I showed because of code portability with older versions of MATLAB:

   [num_rows, num_cols, ~] = size(A);

I acknowledge that is sometimes a concern, but for any given feature this issue doesn't last forever. MATLAB xUnit Test Framework is by far my post popular contribution to the MATLAB Central File Exchange (147 downloads in the last 30 days), and it requires R2008a or later to run. When I started at MathWorks, there were no multidimensional arrays, integer arrays, cell arrays, structs, subfunctions, object-oriented programming, function handles, try/catch, etc.

João suggested that we enhance size so that the dim argument can be a vector. For example:

   sz = size(A,1:2);

I like this idea a lot in principle, but I would personally be cautious about putting it into MATLAB. There are a lot of functions that take dim arguments, and we want them to be as consistent as possible in the way they treat the dim argument. So making this change to size has possible implications well beyond size that we would have to consider.

If I think about the size-related code I've written many times for handling multidimensional arrays, I think I'd like to have a function that allows me to specify how many elements the output size vector should have. It would work something like this:

   sz = sizen(A,5);  % sz has five elements

Then, if I'm working with two multidimensional arrays, A and B, and I want size vectors that are guaranteed to be compatible, I could do it like this:

   num_dims = max(ndims(A), ndims(B));
   size_A = sizen(A, num_dims);
   size_B = sizen(B, num_dims);

I could even imagine a sizes function that would handle that logic for me automatically:

   [size_A, size_B] = sizes(A, B);

There were other comments that had to do with general multidimensional array manipulation and indexing techniques. I'll explore some of those ideas in a future post. While you're waiting, look at the code for flipdim and see if you can figure out how it works.




Published with MATLAB® 7.11

|

Comments

To leave a comment, please click here to sign in to your MathWorks Account or create a new one.