I have an array A
with the shape (3,3)
which can be thought of as the sliding window view of an unkown array with the shape (5,)
. I want to compute the inverse of windowing the array with the shape (5,)
. The adjoint operation of this will be summation. What I mean is that I want to accumulate the values in each corresponding window with the related position in the array with the shape (5,)
. Ofcourse, my expected output of this inverse function and the input A
are not related and are just ordinary arrays. I have two examples which I hope explains this better.
A = np.array([[0, 0, 1],
[0, 0, 1],
[0, 0, 1]], dtype=np.float32)
I expect this output:
np.array([0, 0, 1, 1, 1])
The other example:
A = np.array([[1, 2, 3],
[2, 3, 4],
[3, 4, 5]], dtype=np.float32)
I expect this output:
np.array([1, 2+2, 3+3+3, 4+4, 5]) = np.array([1, 4, 9, 8, 5])
The solution I have which is quite slow (result stored in out
)
out = np.zeros(5, dtype=np.float32)
windows = np.lib.stride_tricks.as_strided(out, shape=(3,3), strides=(4,4))
for i in np.ndindex(windows.shape):
windows[i] += A[i]
Writing to a strided view feels a bit hacky and I am sure there is a better solution.
Is there any way to write this in a vectorized manner, without the for-loop? (which also generalizes for multiple dimensions)
EDIT
In terms of generalizing for higher dimensions, I have cases where the windows are taken from an image (2d array), instead of a 1d array like the example above. For the 2d case, A
can for example be windows of size 3
. This means that from an image (output) with the shape (4,4)
, The windows A
will have the shape (2,2,3,3)
.
A = np.array([[[[0, 0, 0],
[0, 1, 0],
[0, 0, 0]],
[[0, 0, 0],
[1, 0, 0],
[0, 0, 0]]],
[[[0, 1, 0],
[0, 0, 0],
[0, 0, 0]],
[[1, 0, 0],
[0, 0, 0],
[0, 0, 0]]]], dtype=np.float32)
Using the solution given by Pablo, I get the following error
value array of shape (2,2,3,3) could not be broadcast to indexing result of shape (2,2)
Using a slightly modified version of my stride solution:
def inverse_sliding_windows(A, window_sz, image_sz):
out = np.zeros(image_sz, dtype=np.float32)
windows = np.lib.stride_tricks.sliding_window_view(out, window_sz, writeable=True)
for i in np.ndindex(windows.shape):
windows[i] += A[i]
window_sz = (3,3)
image_sz = (4,4)
inverse_sliding_windows(A, window_sz, image_sz)
Output:
array([[0., 0., 0., 0.],
[0., 4., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]], dtype=float32)
To clarify, the window size and output shape is known beforehand, see inverse_sliding_windows
.
from Accumulate sliding windows relative to origin
No comments:
Post a Comment