1
\$\begingroup\$

Suppose there is a very big matrix and and a small window is moving on the matrix. The small window will move right and down, step by step (means each time move one step right, or move one step down). After each move, set all the values covered by the small window to be the average value of all values covered by the small window.

The major idea of my code is to maintain the current sum, and when moving right, subtract one column sum value, and add the rightmost new column value, and get average then reset matrix values. Similarly, when moving down, subtract one row sum value, and add the bottom most new row value, and get average then reset matrix values.

import random
from collections import defaultdict
class BigMatrix:
    def __init__(self, matrix, window_left_top_row, window_left_top_col, window_width, window_height):
        self.matrix = matrix
        self.window_left_top_row = window_left_top_row
        self.window_left_top_col = window_left_top_col
        self.window_width = window_width
        self.window_height = window_height
        self.init_window_sum()
    def init_window_sum(self):
        result = 0
        for r in range(self.window_left_top_row, self.window_left_top_row+self.window_height):
            for c in range(self.window_left_top_col, self.window_left_top_col+self.window_width):
                result += self.matrix[r][c]
        self.sum_so_far = result
        a = result / (self.window_height * self.window_width)
        self.set_matrix_values(a)
    def set_matrix_values(self, v):
        for r in range(self.window_left_top_row, self.window_left_top_row+self.window_height):
            for c in range(self.window_left_top_col, self.window_left_top_col+self.window_width):
                self.matrix[r][c] = v
    def move_right(self):
        if (self.window_left_top_col + self.window_width) >= len(self.matrix[0]):
            raise Exception('invalid move!')
        self.window_left_top_col += 1
        # update sum so far
        self.sum_so_far -= self.sum_so_far / self.window_width
        for r in range(self.window_left_top_row, self.window_left_top_row+self.window_height):
            self.sum_so_far += self.matrix[r][self.window_left_top_col+self.window_width-1]
        a = self.sum_so_far / (self.window_height * self.window_width)
        self.set_matrix_values(a)
    def move_down(self):
        if (self.window_left_top_row + self.window_height) >= len(self.matrix):
            raise Exception('invalid move!')
        # update sum so far
        self.window_left_top_row += 1
        self.sum_so_far -= self.sum_so_far / self.window_height
        for c in range(self.window_left_top_col, self.window_left_top_col+self.window_width):
            self.sum_so_far += self.matrix[self.window_left_top_row+self.window_height-1][c]
        a = self.sum_so_far / (self.window_height * self.window_width)
        self.set_matrix_values(a)
if __name__ == "__main__":
    row = 10
    col = 10
    matrix = []
    for i in range(row):
        r = []
        for j in range(col):
            r.append(random.randint(0,9))
        matrix.append(r)
    window_row = 0
    window_col = 0
    window_width = 2
    window_height = 2
    for r in matrix:
        print r
    print "======"
    b = BigMatrix(matrix, window_row, window_col, window_width, window_height)
    for r in b.matrix:
        print r
    print "======"
    b.move_right()
    for r in b.matrix:
        print r
    print "======"
    b.move_down()
    for r in b.matrix:
        print r
\$\endgroup\$
  • \$\begingroup\$ Is it on purpose that it makes a difference if your algorithm goes from left to right or right to left? I would have assumed that you operate on an original image array and put it into a new array, so that the averaging does not see the already averaged values. \$\endgroup\$ – Graipher Apr 25 '17 at 8:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.