代码之家  ›  专栏  ›  技术社区  ›  Mathieu

从for循环到矩阵计算

  •  0
  • Mathieu  · 技术社区  · 8 年前

    我有一段代码接收输入并检查输入是否符合要求。输入由 list 对象的 S .

    class S:
        def __init__(self, f, t, tf, timeline):
            self.f = f
            self.t = t
            self.tf = tf
            self.timeline = timeline
    

    为了知道对象的组合是否满足要求,我有一个函数 列表 大小 N 对象和返回 True False .

    input1 = [S_1, ..., S_N]
    
    def c1(input1):
        if condition_c1_valid:
            return True
        else:
            return False
    

    现在让我们考虑这个例子:

    import itertools
    
    possible_objects = [S(f, t, tf, timeline) for f in [...] for t in [..] ...]
    inputs_to_check = list(itertools.combination_with_replacement(possible_objects, 5)
    
    results = list()
    for inp in inputs_to_check:
        if c1(inp):
             results.append(inp)
    

    现在,我的解决方案是使用 for 上的循环 n 我每次都在检查。 代码保留符合条件的输入。

    这能以矩阵的方式立即计算吗? (矢量化)

    我在想这样的事:(伪代码)

    Data[input, c1, ..., cN]
    return where(all(c1, ..., cN) is True)
    

    有谁能告诉我这是不是可以实现的,并能给我举一些例子吗?最后,我要检查的输入列表非常大。因此,将计算结果发送到gpu是很有意思的。我想也许这可以通过tensorflow来实现…

    谢谢你的提示:)

    编辑:上面的例子与现实相去甚远。我在用Nested 对于 set ,复杂度为6或7度。目前的解决方案是使用生成器进行优化,但我想进一步推动这一点。

    1 回复  |  直到 8 年前
        1
  •  2
  •   FHTMitchell    8 年前

    在最一般的意义上,你将无法将其矢量化。众所周知,由于gil,cpython在并行处理方面很差,它的主要矩阵矢量化库(numpy)用于处理灵长类类型(整数、浮点等),而不是python对象,如 S .

    有几件事可以帮上忙:

    1. 如果 f , t , tf , timeline 是数字(它们看起来像 可能是),然后可以形成四个numpy数组 通过矢量化版本的 c1 返回一个布尔数组。那你就可以了 np.asarray(input1)[c1_vec(f_vec, t_vec, tf_vec, timeline_vec)]

    2. 你说你用的是生成器而不是列表,但为了确保你的例子应该是:

      possible_objects = (S(f, t, tf, timeline) for f in (...) for t in (...) ...) inputs_to_check = itertools.combination_with_replacement(possible_objects, 5) results = [inp for inp in inputs_to_check if c1(inp)]

      这节省了大量将对象写入内存的时间,这是可以避免的。

    3. 使用pypy。它使用jit编译器大大加快python for循环的速度。对于非常大的回路,这将达到接近C的速度。


    你提到使用GPU。cpython甚至不在多个cpu核心上运行,除非使用另一个实现,否则在gpu上运行它是没有意义的。