Summing block vector of matrices in MATLAB

Let A be a (m x j*m) matrix, A1=A(1:m,1:m) and A2=A(1:m,(m+1):2*m), and so on.

What would some easy code be to compute A1+...+Aj for some integer j>1.

Thanks

Upvotes: 2

Views: 47

Answers (1)

rayryeng
rayryeng

Reputation: 104525

One way to do this could be to reshape the matrix into 3D so that each block is a slice, then sum along the third dimension:

B = reshape(A, m, m, []);
out = sum(B, 3);

... or in one line if don't want to use a temporary variable:

out = sum(reshape(A, m, m, []), 3);

reshape takes columns of your matrix and stacks them to ensure that the output is reshaped into the right dimensions that you want. Therefore, we want m rows and m columns and the third dimension is left dynamic, or empty [], so that we can determine how many slices we need automatically. Technically this should be j, but we'll let MATLAB figure that out on its own. This reshaped result will give you a 3D matrix where each slice is a block. m columns that are m rows long are made and we have j of them. What's left is to sum along all blocks, which is summing along the third dimension.

Here's a quick example to make sure we have this right. Let's assume m = 6 and j = 3. I'm going to create a matrix that is going to be 6 x 18 in that case:

>> m = 6;
>> j = 3;
>> A = reshape(1 : (m*(j*m)), m, [])

>> A

A =

     1     7    13    19    25    31    37    43    49    55    61    67    73    79    85    91    97   103
     2     8    14    20    26    32    38    44    50    56    62    68    74    80    86    92    98   104
     3     9    15    21    27    33    39    45    51    57    63    69    75    81    87    93    99   105
     4    10    16    22    28    34    40    46    52    58    64    70    76    82    88    94   100   106
     5    11    17    23    29    35    41    47    53    59    65    71    77    83    89    95   101   107
     6    12    18    24    30    36    42    48    54    60    66    72    78    84    90    96   102   108

Using reshape thus gives us a 3D matrix with 3 slices and we should be able to segment out the blocks nicely per slice:

>> B = reshape(A, m, m, [])

B(:,:,1) =

     1     7    13    19    25    31
     2     8    14    20    26    32
     3     9    15    21    27    33
     4    10    16    22    28    34
     5    11    17    23    29    35
     6    12    18    24    30    36


B(:,:,2) =

    37    43    49    55    61    67
    38    44    50    56    62    68
    39    45    51    57    63    69
    40    46    52    58    64    70
    41    47    53    59    65    71
    42    48    54    60    66    72


B(:,:,3) =

    73    79    85    91    97   103
    74    80    86    92    98   104
    75    81    87    93    99   105
    76    82    88    94   100   106
    77    83    89    95   101   107
    78    84    90    96   102   108

Finally, since each block is in a slice in this 3D matrix, just sum along the third dimension:

>> out = sum(B, 3)

out =

   111   129   147   165   183   201
   114   132   150   168   186   204
   117   135   153   171   189   207
   120   138   156   174   192   210
   123   141   159   177   195   213
   126   144   162   180   198   216

We can verify that this is correct as the first row, first column of the output is the sum of 1 + 37 + 73 = 111. Similarly, the first row, second column is 7 + 43 + 79 = 129. You can perform similar checks with the rest of the output to verify the correctness of the result. Obviously, you must make sure that the dimensions of your matrix are compatible in order to do this reshaping or an error will occur.

Upvotes: 3

Related Questions