I'm having trouble calculating a summed area table (https://en.wikipedia.org/wiki/Summed_area_table) in Python. The most obvious algorithm involves updating list elements in place while referencing already written elements...but something about the in-place update seems to be confusing Python.
Here's some sample code:
def compute_summed_area_table(image):
# image is a 2-dimensional array containing ints or floats, with at least 1 element.
height = len(image)
width = len(image[0])
new_image = [([0.0] * width)] * height # Create an empty summed area table
for row in range(0, height):
for col in range(0, width):
if (row > 0) and (col > 0):
new_image[row][col] = image[row][col] + \
new_image[row][col - 1] + new_image[row - 1][col] - \
new_image[row - 1][col - 1]
elif row > 0:
new_image[row][col] = image[row][col] + new_image[row - 1][col]
elif col > 0:
new_image[row][col] = image[row][col] + new_image[row][col - 1]
else:
new_image[row][col] = image[row][col]
# Note that two-pass code gives the same kind of results, e.g.:
# for row in range(0, height):
# for col in range(0, width):
# if col > 0:
# new_image[row][col] = image[row][col] + new_image[row][col - 1]
# else:
# new_image[row][col] = image[row][col]
# for row in range(0, height):
# for col in range(0, height):
# if row > 0:
# new_image[row][col] += new_image[row - 1][col]
return new_image
small_image = [[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]]
small_sat = compute_summed_area_table(small_image)
print(small_sat)
Based on my own manual calculation (subject to error), this test code should give something like: [[1, 3, 6, 10, 15], [7, 16, 27, 40, 55], [18, 39, 63, 90, 120], [34, 72, 114, 160, 210], [55, 115, 180, 250, 325]]
Instead, it gives: [[55, 61, 68, 76, 85], [55, 61, 68, 76, 85], [55, 61, 68, 76, 85], [55, 61, 68, 76, 85], [55, 61, 68, 76, 85]]
It's obviously updating every single row during each row iteration, but I'm not sure exactly why or how. Does anyone know precisely what's going wrong? Is there another way to do an in-place update? If not, how would you approach this?