0

We have a matrix N x N consisting of n x n blocks. So we have (N/n) x (N/n) blocks. We further divide it into large blocks so that each large block contains m x m number of smaller blocks. And then we need to sum (block-wise) smaller blocks inside each larger block. For example here each A is nxn and m = 2. enter image description here

What is the simplest and possibly fast way of doing that with numpy array?

Pasha
  • 101
  • 2
  • Is it that `N / m = n`, where `m` is the number of blocks and `n` is the block size? – norok2 Oct 22 '19 at 06:01
  • No. N is matrix size. n is block size. m is completely differenet. we need to add blockwise. – Pasha Oct 22 '19 at 15:50
  • In our case, N/n is some multiple of m. – Pasha Oct 22 '19 at 15:52
  • Could you make same example? Right now I do not see how `N` is not divisible by `n` without introducing imperfect blocking. – norok2 Oct 22 '19 at 15:55
  • And this is not a duplicate of the above question. There you just add entries inside a block. Here it is block of blocks. – Pasha Oct 22 '19 at 15:59
  • I dont say that N is not divisible by n, of course it is. But what is the relation to m. – Pasha Oct 22 '19 at 16:00
  • Oh I see. Then you would need to do a slicing on the `m` dimension before the `sum`. You should really provide some example, otherwise this is just guesswork on the reader side. – norok2 Oct 22 '19 at 16:04

1 Answers1

1

One fast way of doing this is to reshape your (N, N) array into (m, n, m, n) and then sum along the axes of size m:

import numpy as np

m = 3
n = 2
N = m * n

arr = np.arange((N * N)).reshape((N, N))
print(arr)
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]
#  [24 25 26 27 28 29]
#  [30 31 32 33 34 35]]

reshaped = arr.reshape((m, n, m, n))
summed = np.sum(reshaped, axis=(0, 2))

print(summed)
# [[126 135]
#  [180 189]]


# ...checking a couple of blocks
# the "first m" (index 0) identifies blocks along rows
# the "second m" (index 2) identifies blocks along columns
print(reshaped[0, :, 0, :])
# [[0 1]
#  [6 7]]
print(reshaped[1, :, 2, :])
# [[16 17]
#  [22 23]]

# ...manually checking that the (0, 0) element of `summed` is correct
sum([0, 2, 4, 12, 14, 16, 24, 26, 28])
# 126
norok2
  • 25,683
  • 4
  • 73
  • 99
  • Thank you for the answer. I think it is for single entries, but I need blockwise addition. It is kind of a block of blocks. – Pasha Oct 22 '19 at 16:03