【问题标题】:Infinite Summation in PythonPython中的无限求和
【发布时间】:2015-10-05 01:16:10
【问题描述】:

我有一个函数,我需要对(对所有整数)进行无限求和。总和并不总是需要收敛,因为我可以更改内部参数。函数看起来像,

m(g, x, q0) = sum(abs(g(x - n*q0))^2 for n in Integers)
m(g, q0) = minimize(m(g, x, q0) for x in [0, q0])

使用 Pythonic 伪代码

使用 Scipy 积分方法,我只是将 n 铺平并像固定 x 一样积分,

m(g, z, q0) = integrate.quad(lambda n:
                             abs(g(x - int(n)*q0))**2,
                             -inf, +inf)[0]

这工作得很好,但是我必须对 x 作为 x 的函数进行优化,然后对产生积分优化的积分进行另一次求和。这几乎需要很长时间。

您知道更快的求和更好的方法吗?手动编码似乎速度较慢。

目前,我正在与

g(x) = (2/sqrt(3))*pi**(-0.25)*(1 - x**2)*exp(-x**2/2)

但解决方案应该是通用的

本文来自 Daubechies (IEEE 1990) 的“The Wavelet Transform, Time-Frequency Localization and Signal Analysis”

谢谢

【问题讨论】:

  • beta(s) 只是一个标量常数吗? s 参数似乎没有做任何事情。
  • 另外,g(x) 是什么?
  • 哦,对不起,我复制了一个方程的一半和上面一个方程的另一半。让我解决这个问题。 g(x) 是任意的,目前在我的代码中它是高斯的二阶导数。

标签: python numpy scipy mathematical-optimization integral


【解决方案1】:

感谢所有有用的评论,我编写了自己的求和器,它似乎运行得很快。如果有人有任何改进它的建议,我很乐意采纳。

我将对我正在处理的问题进行测试,一旦证明成功,我将声称它可以正常工作。

def integers(blk_size=100):
    x = arange(0, blk_size)
    while True:
        yield x
        yield -x -1
        x += blk_size

#                                                                                                                                                                                                            
# For convergent summation                                                                                                                                                                                   
# on not necessarily finite sequences                                                                                                                                                                        
# processes in blocks which can be any size                                                                                                                                                                  
# shape that the function can handle                                                                                                                                                                         
#                                                                                                                                                                                                            
def converge_sum(f, x_strm, eps=1e-5, axis=0):
    total = sum(f(x_strm.next()), axis=axis)
    for x_blk in x_strm:
        diff = sum(f(x_blk), axis=axis)
        if abs(linalg.norm(diff)) <= eps:
            # Converged                                                                                                                                                                                      
            return total + diff
        else:
            total += diff

【讨论】:

  • 非常好。我刚刚修复了您缩进中的几个错误。
  • np.linalg.norm 相当慢 - 你可以通过自己采取规范来做得更好,例如np.sqrt(diff.dot(diff)) 一维
  • 谢谢。我决定坚持使用 linalg.norm,因为我使用的是更高维的结构(3、4、5 ndarray)。它可能很慢,但一切都运行得非常快。作为记录,上面的代码正常收敛,但并不完全健壮。我得到的数字中有 90% 与论文中的数字相等,但在某些情况下,我得到的值不同,就好像我在近似值中缺少高密度区域
  • 对于快速多维 L2 规范,您可以执行 np.sqrt(diff.ravel().dot(diff.ravel()))
  • 所以这个方法大部分时候收敛。我在我的网站上发布了我的代码,链接如下。我将它用于小波。 acsweb.ucsd.edu/~amacdona/notes/Waveletsacsweb.ucsd.edu/~amacdona/notes/Wavelets/…
【解决方案2】:

g(x) 几乎可以肯定是你的瓶颈。一个非常快速和肮脏的解决方案是将其矢量化以对整数数组进行操作,然后使用np.trapz 使用梯形规则估计积分:

import numpy as np

# appropriate range and step size depends on how accurate you need to be and how
# quickly the sum converges
xmin = -1000000
xmax = 1000000
dx = 1

x = np.arange(xmin, xmax + dx, dx)
gx = (2 / np.sqrt(3)) * np.pi**(-0.25)*(1 - x**2) * np.exp(-x**2 / 2)
sum_gx = np.trapz(gx, x, dx)

除此之外,您还可以使用 Cython 或 numba 重写 g(x) 以加快速度。

【讨论】:

  • 谢谢。我使用的是 g(x) 的矢量化版本,但优化步骤破坏了矢量性质。我正在研究使用另一个可以进行有界向量优化的优化器(scipy.optimize.differential_evolution)。然后我可以对所有内容进行矢量化。另外,我认为在数字上,最好只对 gx 向量求和。梯形积分可能会切边太多
  • 另外,我知道差分进化很慢,但我的问题不一定是凸的,所以我需要有界全局最小化
  • 如果您有兴趣,我发布了一个答案,其中包含对矢量化函数进行求和的解决方案。
【解决方案3】:

有机会NumBa显着提高速度 - http://numba.pydata.org

安装很痛苦,但非常易于使用。看一下: https://jakevdp.github.io/blog/2015/02/24/optimizing-python-with-numpy-and-numba/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-29
    • 1970-01-01
    • 2021-05-05
    • 2018-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    相关资源
    最近更新 更多