繁体   English   中英

辛普森规则永远在Python中运行

[英]Simpson's Rule Takes Forever to Run in Python

我编写了以下函数,用于使用辛普森规则估算函数的定积分:

def fnInt(func, a, b):
    if callable(func) and type(a) in [float] and type(b) in [float]:
        if a > b:
            return -1 * fnInt(func, b, a)
        else:
            y1 = nDeriv(func)
            y2 = nDeriv(y1)
            y3 = nDeriv(y2)
            y4 = nDeriv(y3)
            f = lambda t: abs(y4(t))
            k = f(max(f, a, b))
            n = ((1 / 0.00001) * k * (b - a) ** 5 / 180) ** 0.25
            if n > 0:
                n = math.ceil(n) if math.ceil(n) % 2 == 0 else math.ceil(n) + 1
            else:
                n = 2
            x = (b - a) / n
            ans = 0
            for i in range(int((n - 4) / 2 + 1)):
                ans += (x / 3) * (4 * func(a + x * (2 * i + 1)) + 2 * func(a + x * (2 * i + 2)))
            ans += (x / 3) * (func(a) + 4 * func(a + x * (n - 1)) + func(b))
            return ans
    else:
        raise TypeError('Data Type Error')

但是,似乎每当我尝试使用此功能时,都要花很长时间才能产生输出。 有没有一种方法可以重写我的代码以节省时间?

正如所提到的评论之一,对代码进行概要分析将向您显示速度变慢。 也许nDeriv很慢。 如果您没有分析工具,则可以在每个代码段周围放置time()调用并打印结果。 在此处获取更多信息: 衡量Python中经过的时间?

因此,如果减速最终出现在您的for循环中,可以尝试以下操作:

  1. Python可能会在每次迭代时计算循环条件:

    for i in range(int((n - 4) / 2 + 1)):

在循环之前计算一次int((n - 4) / 2 + 1)

  1. 不要重新计算循环内不变的内容。 例如,每次循环迭代都将重新计算x / 3 ,但它永远不会改变。 在循环开始之前执行此操作。

同样,您每次循环迭代都执行2 * i两次。

  1. 加法比乘法快。 func参数可以重写为:

    xi = x * i a1 = a + xi + xi + x a2 = a1 + x

然后再进一步,您还可以将xi重新用作累加器。 也就是说,从x = 0开始,然后每次迭代都简单地x += x

  1. 这可能很明显,但是如果func()难以计算,则此函数将呈指数级缓慢。

Python可能正在为您做很多简单的优化,所以这些可能无济于事,而只是想分享一些想法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM