Skip to Main Content Skip to Search
File Exchange
MATLAB Newsgroup
Link Exchange
  Blogs  
 Contest 
MathWorks.com

Loren on the Art of MATLAB

June 29th, 2007

sum Things to Consider

I was just helping someone debug a piece of code that was giving an incorrect answer. The code returned an output with a shape different than the coder expected. I made sure the workspace browser was showing while we worked, and as we stepped through the algorithm, we were able to see exactly where the problem occurred. And it was the call to sum.

Contents

By Default, Column-wise Operations

By default, MATLAB performs many operations by treating the columns as individual vectors and acting on them. However, if the array has only a single element per column, then MATLAB performs the operation along the first non-singleton dimension.

User Issue and Solution

So, that's the default behavior. However, for this user's application, he always wanted the sum to be along the first dimension (down the columns), even if there was only a single entry per column.

To accomplish this, the altered code used the optional second input argument, dimension. This works similarly with other functions that typically reduce the dimensionality from the input to the output, such as

Here's the relevant portion of the help for sum. I happen to know that I only need to go up through the second instance of DIM.

h = help('sum');
f = strfind(h,'DIM');
disp(h(1:f(2)+5))
 SUM Sum of elements.
    S = SUM(X) is the sum of the elements of the vector X. If
    X is a matrix, S is a row vector with the sum over each
    column. For N-D arrays, SUM(X) operates along the first
    non-singleton dimension.
    If X is floating point, that is double or single, S is
    accumulated natively, that is in the same class as X,
    and S has the same class as X. If X is not floating point,
    S is accumulated in double and S has class double.
 
    S = SUM(X,DIM) sums along the dimension DIM. 

Examples

Let's see this behavior in action.

n = 4;
A = cat(3, pascal(4), magic(4), invhilb(4), hadamard(4), hilb(4))
A(:,:,1) =
     1     1     1     1
     1     2     3     4
     1     3     6    10
     1     4    10    20
A(:,:,2) =
    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1
A(:,:,3) =
          16        -120         240        -140
        -120        1200       -2700        1680
         240       -2700        6480       -4200
        -140        1680       -4200        2800
A(:,:,4) =
     1     1     1     1
     1    -1     1    -1
     1     1    -1    -1
     1    -1    -1     1
A(:,:,5) =
    1.0000    0.5000    0.3333    0.2500
    0.5000    0.3333    0.2500    0.2000
    0.3333    0.2500    0.2000    0.1667
    0.2500    0.2000    0.1667    0.1429

Sum A down the columns.

sumA = sum(A)
sumA(:,:,1) =
     4    10    20    35
sumA(:,:,2) =
    34    34    34    34
sumA(:,:,3) =
    -4    60  -180   140
sumA(:,:,4) =
     4     0     0     0
sumA(:,:,5) =
    2.0833    1.2833    0.9500    0.7595

Sum A along the rows.

sumA2 = sum(A,2)
sumA2(:,:,1) =
     4
    10
    20
    35
sumA2(:,:,2) =
    34
    34
    34
    34
sumA2(:,:,3) =
    -4
    60
  -180
   140
sumA2(:,:,4) =
     4
     0
     0
     0
sumA2(:,:,5) =
    2.0833
    1.2833
    0.9500
    0.7595

Sum A across the third dimension.

sumA3 = sum(A,3)
sumA3 =
  1.0e+003 *
    0.0350   -0.1155    0.2453   -0.1248
   -0.1125    1.2123   -2.6858    1.6912
    0.2513   -2.6888    6.4912   -4.1788
   -0.1338    1.6972   -4.1758    2.8221

Try summing A along the 7th dimension.

sumA7 = sum(A,7)
sumA7(:,:,1) =
     1     1     1     1
     1     2     3     4
     1     3     6    10
     1     4    10    20
sumA7(:,:,2) =
    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1
sumA7(:,:,3) =
          16        -120         240        -140
        -120        1200       -2700        1680
         240       -2700        6480       -4200
        -140        1680       -4200        2800
sumA7(:,:,4) =
     1     1     1     1
     1    -1     1    -1
     1     1    -1    -1
     1    -1    -1     1
sumA7(:,:,5) =
    1.0000    0.5000    0.3333    0.2500
    0.5000    0.3333    0.2500    0.2000
    0.3333    0.2500    0.2000    0.1667
    0.2500    0.2000    0.1667    0.1429

How Can That Be?

Why did I get no error for summing along dimension 7 when I only have a 3 dimensional array? The reason is that MATLAB treats all arrays as having an infinite number of dimensions, most of them trailing singletons. So if I sum along the 7th dimension here, I am only summing single elements, or effectively in this case just returning the original array.

Ever Used Dimension to Your Advantage?

Have you ever used the dimension argument to your advantage? Or tripped over the issue of having an unexpected singleton dimension? Any thoughts, please post them here.


Get the MATLAB code

Published with MATLAB® 7.4

11 Responses to “sum Things to Consider”

  1. Michel Slivitzky replied on :

    I may be off topic but would like to make suggestion for a future issue.

    It would be nice to have the option of a confirmation dialog window when closing the editor.

    I can’t remember how many times I have lost all current files by inadvertently clicking on close (instead of minimize) and having to rebuild the list.

  2. Loren replied on :

    Michel-

    Thanks for the suggestion. I’ll pass it along. For the future, the best place for items like this is here .

    –Loren

  3. Mathias replied on :

    Hi Loren,
    I once tripped over it when using struct2cell. On a structure
    s(1).x = 1;
    s(2).x = 2;
    I used struct2cell(s) and was surprised to see a 3 dimensional cell array (1×1x2). struct2cell(s’) did what I wanted it to do by dropping the third dimension (1×2). In that context: Is there a particular reason that data(i) goes along the second dimension instead of the first or is the reason historical?
    -Mathias

  4. Loren replied on :

    Mathias-

    The data starts in the second dimension so the first dimension can cover the possible structure fields. In your case there’s only one. Consider adding this to your struct:

    s(2).y = 41
    s(2).z = 19
    

    Then c is 3×1x2 since there are now 3 fields. We’ve always thought of fields as the logical first dimension of a struct.

    –Loren

  5. Yehuda S replied on :

    Hi Loren,

    Can you explain this strange behavior of the case you referred to above ?
    Executing the following lines at the command line, goes thru fine. However, when running it as a script, the combination of idim=2 (for this singleton), uint16, and two arguments for bitcmp gives the error message quoted later on.
    Using sum(uint16([0,1]),idim,’native’) instead of uint16(sum([0,1],idim)) exhibits the same behavior

    idim=1;
    bitcmp(uint16(sum([0,1],idim)))
    bitcmp(uint16(sum([0,1],idim)),4)
    idim=2;
    bitcmp(uint16(sum([0,1],idim)))
    bitcmp(uint16(sum([0,1],idim)),4)

    ??? The BIT argument to BITCMP must be a real integer in the appropriate range.

    Error in ==> foo1 at 6
    bitcmp(uint16(sum([0,1],idim)),4)

  6. Loren replied on :

    Yehuda-

    I don’t get the same results running R2007b:

    >> idim=1;
    bitcmp(uint16(sum([0,1],idim)))
    bitcmp(uint16(sum([0,1],idim)),4)
    idim=2;
    bitcmp(uint16(sum([0,1],idim)))
    bitcmp(uint16(sum([0,1],idim)),4)
    ans =
      65535  65534
    ans =
         15     14
    ans =
      65534
    ans =
         14
    

    Perhaps MATLAB had a bug that got fixed since the version you are running???

    –Loren

  7. Yehuda S replied on :

    Loren -

    I’m running R2007b.
    Did you run it straight at the command window ?
    Then I also don’t have any problems.
    The problem arises when running those lines from a script.

  8. Loren replied on :

    Yehuda-

    It works from a script if you first type

    feature accel off

    I will report the bug. Thank you.\

    –Loren

  9. Yehuda S. replied on :

    Loren -

    Thank you - and that explains why it runs longer from the command line compared to some work arounds I tried on the
    script.

  10. Clare J replied on :

    R2007a - Student Version

    When I use sum to sum a vector of type double I get this error message:
    ??? Subscript indices must either be real positive integers or logicals.

    The values in my vector range from 0.6 to 0.9 - so they are all positive but are floats (not integers). Maybe that is the problem…

    But your example here seems to work with floats…

    My question is: Can I use sum to sum floats? (I know cumsum works…)

    Thanks. Btw, your blog has taught me a lot.

  11. Loren replied on :

    Clare-

    Yes, sum can sum a double vector:

    
    x = [.3 .4 pi/3]
    y = sum(x)
    x =
              0.3          0.4       1.0472
    y =
           1.7472
    
    

    You must have something else going on your code w.r.t. indexing. It looks like your indices into the data you want to sum aer not valid ones.

    –Loren

Leave a Reply


Loren Shure works on design of the MATLAB language at The MathWorks. She writes here about once a week on MATLAB programming and related topics.

  • J.B. Brown: Ah, and I am at fault for simply testing collinearity with the origin in the example above.
  • J.B. Brown: Indeed, > collinear( [0 3],[0 8],[0 -1e21+2e-15] ) ans = 1 > collinear( [0 3],[0 8],[0 -1e22+2e-15]...
  • OkinawaDolphin: Loren, thank you for telling me where to download timeit. Here are the two functions I just tested...
  • Loren: JB- It looks to me like Ilya’s solution and therefore yours are equivalent to the determinant. As Tim...
  • Loren: OkinawaDolphin, timeit can be downloaded from the File Exchange. Steve Eddins is the author. It does not ship...
  • OkinawaDolphin: It seems that neither R2007a nor R2007b have the function timeit, but I investigated computation time...
  • J.B. Brown: It would appear to me that Ilya Rozenfeld’s solution would be the cleanest. Just to help those who...
  • Loren: Markus- Congratulations on winning! And a nice illustration of how the size matters. Small enough, and the...
  • Markus: Hi Loren, which version is fastest also depends very much on the matrix dimensions. Look at my test function:...
  • Duncan: OkinawaDolphin, Regarding why your third example is slower than your second example, the result is in fact...

These postings are the author's and don't necessarily represent the opinions of The MathWorks.

Related Topics