numpy向量化并行更新 [英] numpy vectorize a parallel update

查看:135
本文介绍了numpy向量化并行更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用以下简单规则实现一维元胞自动机:

I want to implement a one-dimensional cellular automaton with the following simple rules:

  1. 如果单元格为 1 ,而相邻单元格为 0 ,则向右移动
  2. 如果单元格为 1 而邻居单元格为 1 ,请不要移动
  3. 所有单元格都根据其状态同时更新.
  4. 我们有封闭边界条件.这意味着最后一个单元格的邻居是第一个单元格.
  1. If cell is 1 and neighbor cell is 0, move (to the right)
  2. if cell is 1 and neighbor cell is 1, don't move
  3. All cells update at the same time according to their state.
  4. We have closed boundary conditions. That means the neighbor of the last cell is the first cell.

例如:

0 1 1 0 1

更新后:

1 1 0 1 0

我的解决方法是

def update(cells):
    neighbors = np.roll(cells,-1)
    dim = len(cells)
    tmp_cells = np.zeros(dim)
    for i,j in  enumerate(cells):
        if j and not neighbors[i]:
            tmp_cells[i], tmp_cells[(i+1)%dim] = 0, 1
        elif j:
            tmp_cells[i] = 1
    return tmp_cells

这很好,但是该解决方案并未利用np.arrays的所有可能性,而是简化为简单的list-算法.

That works fine, but the solution do not exploit all the possibilities of np.arrays and reduces to a simple list-algorithm.

我以为我可以在cellsneighbors之间找到一个整齐的逻辑,但是显然我现在必须去睡觉.

I thought I could find a neat logic between cells and neighbors, but apparently I have to go sleep now.

有些想法?

推荐答案

要获取不循环的单元格值,您需要同时在 侧都知道它的邻居.您需要左边的,因为如果您是0,则新值取决于您的左邻居.

To get the value for a cell without looping, you need to know its neighbors on both sides. You need the left because if you're a 0 your new value depends on your left neighbor's, while if you're a 1 your new value depends on your right neighbor.

您可以详尽地编写所有3单元组合,对吗?换句话说:

You can exhaustively write all the 3-cell combinations, right? In other words:

000 -> 0
001 -> 0
010 -> 0 # move to the right
011 -> 1 # stay put
100 -> 1 # left neighbor has moved
101 -> 1 # left neighbor has moved
110 -> 0 # move to the right
111 -> 1 # stay put

您可以轻松地将该表转换为布尔函数.我们可以简化它,但是让我们愚蠢的开始于:-x & y & z | x & -y & -z | x & -y & z | x & y & z.

You can turn that table into a boolean function pretty easily. We could simplify it, but let's just be stupid to start with: -x & y & z | x & -y & -z | x & -y & z | x & y & z.

就是这样:

left = np.roll(cells, -1)
right = np.roll(cells, 1)
return (np.logical_not(left) & cells & right | # ...)

现在,您当然想简化布尔方程,*,但这应该可以帮助您入门.

Now of course you'll want to simplify the boolean equation,* but this should get you started.

*或者也许退后一步,重新思考规则.如果您是0,则总是从您的左邻居复制新值;如果您是1,则总是从您的正确邻居那里复制它.您可以使用布尔运算符的组合来编写该代码,但是使用带掩码的赋值可能更简单:result[cells] = left[cells]; result[notcells] = right[notcells].

* Or maybe step back and rethink the rules. If you're a 0, your new value is always copied from your left neighbor; if you're a 1, it's always copied from your right neighbor. You can write that with a combination of boolean operators, but it might be even simpler with masked assignment: result[cells] = left[cells]; result[notcells] = right[notcells].

这篇关于numpy向量化并行更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆