ライフゲーム / Python / 全セルのムーア近傍の和を求める / scipy.signal.convolve()

畳み込み演算の函数がいろいろあるのでそれを利用する。ここではscipy.signal.convolve()を使ってみる。

import numpy as np
from scipy.signal import convolve

def toTorus(mat, matTorused):
    mat        = np.array(mat       , dtype="uint8")
    matTorused = np.array(matTorused, dtype="uint8")

    matTorused[1:-1, 1:-1] = mat

    matTorused[0,:], matTorused[-1,:] = matTorused[-2,:], matTorused[1,:]
    matTorused[:,0], matTorused[:,-1] = matTorused[:,-2], matTorused[:,1]

    return matTorused

def mooreSum(matTorused):
    matTorused = np.array(matTorused, dtype="uint8")

    return convolve(matTorused, [[1,1,1],
                                 [1,0,1],
                                 [1,1,1]], mode="same")[1:-1, 1:-1] # 最外周を除いて返す。
    

if __name__ == "__main__":
    
    # この排列aを現世代排列とする。
    numOfRows, numOfCols = 5, 10
    a = np.random.randint(0, 2, [numOfRows, numOfCols], dtype="uint8")
    
    # 一回り大きい排列Aを用意しておく。
    A = np.empty(np.asarray(a.shape)+2, dtype="uint8")
    
    torused = toTorus(a, A)
    moore   = mooreSum(torused)

    print(a)
    print(moore)

実行結果:
f:id:ti-nspire:20181013114222p:plain:w350

ライフゲーム / Python / 2次元排列をトーラス接続にする / 上下左右にスタックする方法と一回り大きい排列に上書きする方法と

import numpy as np

# この排列をトーラス接続にする
numOfRows, numOfCol = 3, 5
a = np.arange(numOfRows * numOfCol).reshape(numOfRows, numOfCol).astype("uint16")

# 上下左右をそれぞれスタックし合う方法
def toTorus1(mat):
    mat = np.array(mat)

    mat = np.vstack([mat[-1]    , np.vstack([mat, mat[0]])])
    mat = np.hstack([mat[:,[-1]], np.hstack([mat, mat[:,[0]]])])

    return mat

# 一回り大きい排列をあらかじめ作っておいてそこに上書きする方法
A = np.empty([numOfRows+2, numOfCol+2]).astype("uint16")
def toTorus2(mat, matEnlarged):
    mat = np.array(mat)
    numOfRows, numOfCol = mat.shape

    matEnlarged[1:numOfRows+1,1:numOfCol+1] = mat

    matEnlarged[0]    , matEnlarged[-1]     = matEnlarged[-2]    , matEnlarged[1]
    matEnlarged[:,[0]], matEnlarged[:,[-1]] = matEnlarged[:,[-2]], matEnlarged[:,[1]]

    return matEnlarged

if __name__ == "__main__":
    %timeit toTorus1(a)
    %timeit toTorus2(a, A)
    
    print(a)
    print(toTorus1(a))
    print(toTorus2(a, A))

実行結果:
f:id:ti-nspire:20181013093001p:plain:w400