【问题标题】:Vectorized code for a function to generate vector values用于生成向量值的函数的向量化代码
【发布时间】:2017-05-22 03:40:56
【问题描述】:

假设我们有一个如下定义的函数,并且我们想iterate over n from 1 to L,我为向量化代码受了很多苦,因为这段代码相当慢,因为调用这个函数需要外部循环。

详细信息:L, K 是大整数,例如1000 和 H_n 是浮点值。

def multifrac_Brownian_motion(n, L, K, list_hurst, ind_hurst):

    t_ks = np.asarray(sorted(-np.array(range(1, K + 1))*(1./L)))

    t_ns = np.linspace(0, 1, num=L+1)
    t_n = t_ns[n]

    chi_k = np.random.randn(K)
    chi_lminus1 = np.random.randn(L)

    H_n = get_hurst_value(t_n, list_hurst, ind_hurst)

    part1 = 1./(np.random.gamma(0.5 + H_n))

    sums1 = np.dot((t_n - t_ks)**(H_n - 0.5) - ((-t_ks)**(H_n - 0.5)), chi_k)
    sums2 = np.dot((t_n - t_ns[:n])**(H_n - 0.5), chi_lminus1[:n])

    return part1*(1./np.sqrt(L))*(sums1 + sums2)

for n in range(1, L + 1):
        onelist.append(multifrac_Brownian_motion(n, L, K, list_hurst, ind_hurst=ind_hurst))

更新:

def list_hurst_funcs(M, seg_size=10):
    """Generate a list of Hurst function components

    Args:
        M: Int, number of hurst functions
        seg_size: Int, number of segmentations of interval [0, 1]
    Returns:
        list_hurst: List, list of hurst function components
    """

    list_hurst = []

    for i in range(M):
        seg_points = sorted(np.random.uniform(size=seg_size))
        funclist = np.random.uniform(size=seg_size + 1)
        list_hurst.append((seg_points, funclist))

    return list_hurst


def get_hurst_value(x, list_hurst, ind):
    if np.isscalar(x):
        x = np.array(float(x), ndmin=1)

    seg_points, funclist = list_hurst[ind]

    condlist = [x < seg_points[0]] +\
                [(x >= seg_points[s] and x < seg_points[s + 1]) 
                                          for s in range(len(seg_points) - 1)] +\
                [x >= seg_points[-1]]

    return np.piecewise(x, condlist=condlist, funclist=funclist)

【问题讨论】:

  • 能分享一下get_hurst_value的实现吗?
  • @Divakar 代码更新了。
  • 您在此处需要/可能需要不同级别的矢量化。我建议逐步对其进行矢量化。所以,从矢量化get_hurst_value 开始。我建议发布一个新问题,其中包含示例输入和输出。

标签: python performance numpy vectorization


【解决方案1】:

解决此类问题的一种方法是(尝试)了解全局,并采用另一种方法将所有内容视为 2d 或更大(LxK 数组)。另一种方法是检查multifrac_Brownian_motion,尝试加快速度,并在可能的情况下消除依赖于标量或一维数组的步骤。换句话说,由内而外地工作。如果我们获得足够的速度改进,那么我们必须在循环中调用它可能并不重要。更好的是,改进表明了高维操作的方法。

从内到外,我建议将 t_ks calc 替换为:

t_ks = -np.arange(K,0,-1)/L    # 1./L if required by Py2 integer division

由于list_hurstind_hurst 对于所有n 都是相同的,我怀疑您可以将get_hurst_value 的一些耗时部分移到循环之外。

但我会尽最大努力改进 condlist 构造。这是深埋在你的外循环中的列表理解。

piecewise 也循环遍历那些 seg_points

【讨论】:

    猜你喜欢
    • 2016-11-21
    • 1970-01-01
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多