Почему np.array() неверно просчитывает значение полинома?
x = np.array(6208)
y = x**5 + 2*x**4 + 7*x**3 + 14*x**2 + 3*x + 10
print(y)
# y = -9223185457808594742
x = 6208
y = x**5 + 2*x**4 + 7*x**3 + 14*x**2 + 3*x + 10
print(y)
# y = 9223558615900956874
Очевидно, что NumPy посчитал значение неверно, т.к значение данного полинома не может быть отрицательным. Предполагаю, что это из-за того, что np.dtype("int64") и не хватает памяти для просчета.
Но почему тогда минус? И как сделать так, чтобы y был просчитан правильно через np.array?
Ответы (4 шт):
Происходит переполнение для переменной типа np.int64. Допустимый диапазон значений можно проверить так:
In [46]: np.iinfo(x.dtype)
Out[46]: iinfo(min=-9223372036854775808, max=9223372036854775807, dtype=int64)
Можно явно указать тип данных - беззнаковое целое 64-бит:
In [47]: x = np.array(6208, dtype="uint64")
In [48]: y = x**5 + 2*x**4 + 7*x**3 + 14*x**2 + 3*x + 10
In [49]: print(f"{y:19.0f}")
9223558615900956672
Но и это не панацея для слишком больших значений:
In [50]: np.iinfo(x.dtype)
Out[50]: iinfo(min=0, max=18446744073709551615, dtype=uint64)
Предлагаю воспользоваться библиотекой sympy:
from sympy import Array
a = Array([6208])
y = a.applyfunc(lambda x: x**5 + 2*x**4 + 7*x**3 + 14*x**2 + 3*x + 10)
print(y) # [9223558615900956874]
Однако я не проверял производительность такого подхода, поэтому не могу сказать, насколько это эффективно.
Может быть потому, что np.array() ничего и не должен считать? Вы вообще в формулу полинома вставляете массив, вектор, чего вы вообще ожидали? С математической точки зрения это бессмыслица какая-то, x = np.array(6208) это не одно и то же, что x=6208
Полиномы в numpy лучше считать так:
from numpy.polynomial.polynomial import polyval
print(polyval(6208, [10,3,14,7,2,1]))
результат в np.float64:
9.223558615900957e+18