如何将 scipy convolve2d 应用为带有环绕的矩阵乘法

问题描述

tl;dr -- scipy 的 convolve2d 实际上是如何进行卷积运算的?我找到了 Toeplitz 矩阵的方法,但我对如何实际创建 Toeplitz 矩阵感到困惑。

前几天我正在阅读康威的[生命游戏](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life规则),我突然想到游戏中的所有约束都是线性约束,这意味着生命游戏应该适合线性规划形式,因为未来的董事会状态必须遵循以下线性约束:

def life_step(game_board):
    board = np.copy(game_board)
    neighbor_sums = sp.signal.convolve2d(game_board,kernel,mode='same',boundary="wrap")

    # If fewer than 2 neighbors,cell is dead.
    board[neighbor_sums < 2] = 0
    # If 2 neighbors,cell stays in its state.
    # If 3 neighbors,cell becomes or stays active.
    board[neighbor_sums == 3] = 1
    # If >3 neighbors,cell dies
    board[neighbor_sums > 3] = 0    
    return board

游戏板是一个 NxM 矩阵。
计算游戏板中每个节点的邻居所需的内核是一个 3x3 矩阵。

因此我们可以将这个内核应用到游戏板上的每个位置,以计算每个节点的活动邻居的数量。然后我们可以对邻居计数应用约束,这将决定给定节点是打开还是关闭生成一个板状态。

但是,要使用凸求解器,例如cvx,您不能传入像 convolve2d 这样的函数,而是需要传入该函数对自身进行编码的矩阵。

为了得到我们的线性运算符,我们可以从一个简单的版本开始。我们可以手动提取 game_board(一个 nxm 矩阵)的正确组件并将其与邻居内核相乘:https://imgur.com/a/desSZAd。但这看起来真的很脆弱,需要大量的手工计算。

所以,我想,如果我们把 game_board 弄平怎么办?然后我们仍然需要将我们的内核应用于每个正确的权重,但这应该有一些关于内核如何移动游戏板的结构。

https://imgur.com/a/oTHlxx1

一个图像是展平。第二张图片是循环和堆叠内核向量以将卷积应用为一个 MM。第三张图是平移后的核与游戏板的乘积。

我又做了几个 Gamma 项,显然有一些结构,但我没有看到如何以编程方式创建它。

所有这些使我找到了 Toeplitz 矩阵,这似乎正是我正在寻找的。我正在应用这里找到的方法https://stackoverflow.com/a/51865516/8334507 但是当我这样做时我没有得到 wrap-ing 功能,它也将我的输出矩阵的维度扩展到 (N+2)x(M+2) 所以,一个8x8 板变成 10x10。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)