0

我正在开发一个程序来查找函数的积分,其中用户指定矩形的数量、起点和终点。

注意:我使用的是矩形的左端点。

我的功能运行良好(至少,它看起来很完美)。但是,我想看看我是否可以为它写一个单行,但不确定如何,因为我正在使用eval(). 这是我的原始代码:

def integral(function, n=1000, start=0, stop=100):
    """Returns integral of function from start to stop with 'n' rectangles"""
    increment, rectangles, x = float((stop - start)) / n, [], start
    while x <= stop:
        num = eval(function)
        rectangles.append(num)
        if x >= stop: break
        x += increment
    return increment * sum(rectangles)

这工作正常:

>>> integral('x**2')
333833.4999999991

实际答案是1000000/3,所以我的函数给出了一个很好的估计(仅适用于 1000 个矩形)。

我对单线的尝试:

def integral2(function, n=1000, start=0, stop=100): rectangles = [(float(x) / n) for x in range(start*n, (stop*n)+1)]; return (float((stop-start))/n) * sum([eval(function) for x in rectangles])

但是,这并不是真正的单行,因为我使用的是分号。此外,它有点慢(需要几秒钟的时间,这非常重要)并且给出了错误的答案:

>>> integral2('x**2')
33333833.334999967

那么,是否可以为该功能使用单线解决方案?我不确定如何在eval()float(x)/n一个列表理解中实现。float(x)/n在函数中实现了一个虚拟的“步骤” range

谢谢!

4

3 回答 3

2
def integral2(function, n=1000, start=0, stop=100): return (float(1)/n) * sum([eval(function) for x in [(float(x) / n) for x in range(start*n, (stop*n)+1)]])

integral请注意,和之间有很大的区别integral2integral2制作(stop*n)+1-(start*n)矩形,而integral只制作n矩形。


In [64]: integral('x**2')
Out[64]: 333833.4999999991
In [68]: integral2('x**2')
Out[68]: 333338.33334999956

In [69]: %timeit integral2('x**2')
1 loops, best of 3: 704 ms per loop

In [70]: %timeit integral('x**2')
100 loops, best of 3: 7.32 ms per loop

也许更可比的翻译integral是:

def integral3(function, n=1000, start=0, stop=100): return (float(stop-start)/n) * sum([eval(function) for x in [start+(i*float(stop-start)/n) for i in range(n)]])

In [77]: %timeit integral3('x**2')
100 loops, best of 3: 7.1 ms per loop

当然,应该说除了(反常?)娱乐之外,没有任何目的使它成为单线:)

于 2013-02-08T03:06:55.657 回答
2

如果您作为 Python本身eval接收,则不需要使用您也可以使用函数来生成浮点值列表functioncallablenumpy.arange

案例1:function是一个Pythoncallable

def integrate(f, n, start, end):
    return sum([f(i)*(abs(start-end)/float(n)) for i in np.arange(start, end, abs(start-end)/float(n))])

案例2:function不是Pythoncallable

def integrate(f, n, start, end):
    return sum([eval(f)*(abs(start-end)/float(n)) for x in np.arange(start, end, abs(start-end)/float(n))])
于 2013-02-08T03:13:29.643 回答
0

使用 numpy 的 linspace 作弊怎么样?

integrate = lambda F, n0, nf: sum([F(x)*(abs(nf-n0)/(abs(nf-n0)*300))for x in np.linspace(n0, nf, abs(nf-n0)*300)])

它接受一个函数 F、一个下界 n0 和一个上界 nf。以下是 x**2 在 0 和 5 之间的工作原理:

In [31]: integrate(lambda x: x**2, 0, 5)
Out[31]: 41.68056482099179

它非常接近。

编辑:这是我的 linspace 一班轮。

linspace = lambda lo, hi, step:[lo + (hi-lo)/step*i + (hi-lo)/(step*step-1)*i for i in range(step)]

有一种方法可以将它融入到一个完整的单线集成器中。我把它留给你,我的朋友。

于 2016-08-13T07:38:44.360 回答