项目Euler#101 - 如何解决numpy多项式溢出?

时间:2010-01-08 20:12:46

标签: python numpy

Project Euler #101

我刚开始学习Numpy,到目前为止看起来很简单。

我遇到的一件事是,当我评估多项式时,结果是int32,因此会发生溢出。

u = numpy.poly1d([1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1])
for i in xrange(1, 11):
    print(i, u(i))

结果是:

(1, 1)
(2, 683)
(3, 44287)
(4, 838861)
(5, 8138021)
(6, 51828151)
(7, 247165843)
(8, 954437177)
(9, -1156861335)
(10, 500974499)

最后两项显然不正确。

我能想到的工作是将系数分解为100

u = numpy.poly1d([0.01, -0.01, 0.01, -0.01, 0.01, -0.01, 0.01, -0.01, 0.01, -0.01, 0.01])
for i in xrange(1, 11):
    print(i, int(u(i) * 100))

这次结果是正确的

(1, 1)
(2, 682)
(3, 44286)
(4, 838860)
(5, 8138020)
(6, 51828151)
(7, 247165843)
(8, 954437177)
(9, 3138105961L)
(10, 9090909091L)

有更好的方法吗? Numpy允许我更改数据类型吗?感谢。

2 个答案:

答案 0 :(得分:4)

100的缩放并没有帮助,但是给出的数字是浮点数而不是整数,因此具有更高的范围。由于浮点计算,如您所见,计算中引入了一些不准确性。

您可以像这样手动指定类型:

u = numpy.poly1d(numpy.array([1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1], dtype=numpy.int64))

此问题的计算符合64位整数,因此可行。

列出了支持的类型here

答案 1 :(得分:0)

Interjay在我写这篇文章的时候发布了一个更好的答案,但我想你无论如何都可能想要一个替代品。

以下是您展示的示例的简单实现:

class Poly(object):
    def __init__(self, coefficients):
        assert len(coefficients) > 0
        self.coefficients = coefficients
    def __call__(self, value):
        total = self.coefficients[0]
        for c in self.coefficients[1:]:
            total = total * value + c
        return total

以及一些测试

assert Poly([5])(1) == 5
assert Poly([7])(1) == 7
assert Poly([2,3])(5) == 13
assert Poly([1,0,0,0,0])(-2) == 16
u = Poly([1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1])
for i in range(1, 11):
    print (i, u(i))

而且相当无用

assert Poly([2,"!"])("Hello ") == "Hello Hello !"