np.int64 在数学运算中的行为与 int 不同
np.int64 behaves differently from int in math-operations
我遇到了一个非常奇怪的问题,我做了很多数学运算,当我的输入类型为 <class 'numpy.int64'>
时,结果是 inf
或 nan
,但我得到当我的输入类型为 <class 'int'>
时,正确的(分析检查)结果。我使用的唯一库函数是 np.math.factorial()
、np.sum()
和 np.array()
。我还使用生成器对象对级数和来自 scipy.constants
.
的玻尔兹曼常数求和
我的问题本质上是这样的:他们是否有任何已知案例,其中 np.int64
对象的行为与 int
对象的行为非常不同?
当我 运行 和 np.int64
输入时,我得到 RuntimeWarnings:overflow encountered in long_scalars
、divide by zero encountered in double_scalars
和 invalid value encountered in double_scalars
。但是,我插入阶乘函数的最大数字是 36,当我使用 int
输入时,我没有收到这些警告。
下面是重现该行为的代码。我无法更准确地找到它的来源。
import numpy as np
import scipy.constants as const
# Some representible numbers
sigma = np.array([1, 2])
sigma12 = 1.5
mole_weights = np.array([10,15])
T = 100
M1, M2 = mole_weights/np.sum(mole_weights)
m0 = np.sum(mole_weights)
fac = np.math.factorial
def summation(start, stop, func, args=None):
#sum over the function func for all ints from start to and including stop, pass 'args' as additional arguments
if args is not None:
return sum(func(i, args) for i in range(start, stop + 1))
else:
return sum(func(i) for i in range(start, stop + 1))
def delta(i, j):
#kronecker delta
if i == j:
return 1
else:
return 0
def w(l, r):
# l,r are ints, return a float
return 0.25 * (2 - ((1 / (l + 1)) * (1 + (-1) ** l))) * np.math.factorial(r + 1)
def omega(ij, l, r):
# l, r are int, ij is and ID, returns float
if ij in (1, 2):
return sigma[ij - 1] ** 2 * np.sqrt(
(np.pi * const.Boltzmann * T) / mole_weights[ij - 1]) * w(l, r)
elif ij in (12, 21):
return 0.5 * sigma12 ** 2 * np.sqrt(
2 * np.pi * const.Boltzmann * T / (m0 * M1 * M2)) * w(l, r)
else:
raise ValueError('(' + str(ij) + ', ' + str(l) + ', ' + str(r) + ') are non-valid arguments for omega.')
def A_prime(p, q, r, l):
'''
p, q, r, l are ints. returns a float
'''
F = (M1 ** 2 + M2 ** 2) / (2 * M1 * M2)
G = (M1 - M2) / M2
def inner(w, args):
i, k = args
return ((8 ** i * fac(p + q - 2 * i - w) * (-1) ** (r + i) * fac(r + 1) * fac(
2 * (p + q + 2 - i - w)) * 2 ** (2 * r) * F ** (i - k) * G ** w) /
(fac(p - i - w) * fac(q - i - w) * fac(r - i) * fac(p + q + 1 - i - r - w) * fac(2 * r + 2) * fac(
p + q + 2 - i - w)
* 4 ** (p + q + 1) * fac(k) * fac(i - k) * fac(w))) * (
2 ** (2 * w - 1) * M1 ** i * M2 ** (p + q - i - w)) * 2 * (
M1 * (p + q + 1 - i - r - w) * delta(k, l) - M2 * (r - i) * delta(k, l - 1))
def sum_w(k, i):
return summation(0, min(p, q, p + q + 1 - r) - i, inner, args=(i, k))
def sum_k(i):
return summation(l - 1, min(l, i), sum_w, args=i)
return summation(l - 1, min(p, q, r, p + q + 1 - r), sum_k)
def H_i(p, q):
'''
p, q are ints. Returns a float
'''
def inner(r, l):
return A_prime(p, q, r, l) * omega(12, l, r)
def sum_r(l):
return summation(l, p + q + 2 - l, inner, args=l)
val = 8 * summation(1, min(p, q) + 1, sum_r)
return val
p, q = np.int64(8), np.int64(8)
print(H_i(p,q)) #nan
print(H_i(int(p) ,int(q))) #1.3480582058153066e-08
- Numpy 的
int64
是一个 64 位整数,这意味着它由 64 个位置组成,要么是 0 要么是 1。因此最小的可表示值是 -2**63
最大的是 2**63 - 1
- Python的
int
本质上是无限长度,所以它可以表示任何值。它相当于Java中的一个BigInteger
。它存储为 int64
的列表,本质上被认为是一个大数字。
你这里的是经典integer overflow。您提到您“仅”将 36 代入阶乘函数,但阶乘函数增长 非常快 ,结果是 36! = 3.7e41 > 9.2e18 = 2**63 - 1,所以你得到的数字大于你可以用 int64 表示的数字!
由于 int64
也称为 long
s 这正是警告 overflow encountered in long_scalars
试图告诉您的内容!
我遇到了一个非常奇怪的问题,我做了很多数学运算,当我的输入类型为 <class 'numpy.int64'>
时,结果是 inf
或 nan
,但我得到当我的输入类型为 <class 'int'>
时,正确的(分析检查)结果。我使用的唯一库函数是 np.math.factorial()
、np.sum()
和 np.array()
。我还使用生成器对象对级数和来自 scipy.constants
.
我的问题本质上是这样的:他们是否有任何已知案例,其中 np.int64
对象的行为与 int
对象的行为非常不同?
当我 运行 和 np.int64
输入时,我得到 RuntimeWarnings:overflow encountered in long_scalars
、divide by zero encountered in double_scalars
和 invalid value encountered in double_scalars
。但是,我插入阶乘函数的最大数字是 36,当我使用 int
输入时,我没有收到这些警告。
下面是重现该行为的代码。我无法更准确地找到它的来源。
import numpy as np
import scipy.constants as const
# Some representible numbers
sigma = np.array([1, 2])
sigma12 = 1.5
mole_weights = np.array([10,15])
T = 100
M1, M2 = mole_weights/np.sum(mole_weights)
m0 = np.sum(mole_weights)
fac = np.math.factorial
def summation(start, stop, func, args=None):
#sum over the function func for all ints from start to and including stop, pass 'args' as additional arguments
if args is not None:
return sum(func(i, args) for i in range(start, stop + 1))
else:
return sum(func(i) for i in range(start, stop + 1))
def delta(i, j):
#kronecker delta
if i == j:
return 1
else:
return 0
def w(l, r):
# l,r are ints, return a float
return 0.25 * (2 - ((1 / (l + 1)) * (1 + (-1) ** l))) * np.math.factorial(r + 1)
def omega(ij, l, r):
# l, r are int, ij is and ID, returns float
if ij in (1, 2):
return sigma[ij - 1] ** 2 * np.sqrt(
(np.pi * const.Boltzmann * T) / mole_weights[ij - 1]) * w(l, r)
elif ij in (12, 21):
return 0.5 * sigma12 ** 2 * np.sqrt(
2 * np.pi * const.Boltzmann * T / (m0 * M1 * M2)) * w(l, r)
else:
raise ValueError('(' + str(ij) + ', ' + str(l) + ', ' + str(r) + ') are non-valid arguments for omega.')
def A_prime(p, q, r, l):
'''
p, q, r, l are ints. returns a float
'''
F = (M1 ** 2 + M2 ** 2) / (2 * M1 * M2)
G = (M1 - M2) / M2
def inner(w, args):
i, k = args
return ((8 ** i * fac(p + q - 2 * i - w) * (-1) ** (r + i) * fac(r + 1) * fac(
2 * (p + q + 2 - i - w)) * 2 ** (2 * r) * F ** (i - k) * G ** w) /
(fac(p - i - w) * fac(q - i - w) * fac(r - i) * fac(p + q + 1 - i - r - w) * fac(2 * r + 2) * fac(
p + q + 2 - i - w)
* 4 ** (p + q + 1) * fac(k) * fac(i - k) * fac(w))) * (
2 ** (2 * w - 1) * M1 ** i * M2 ** (p + q - i - w)) * 2 * (
M1 * (p + q + 1 - i - r - w) * delta(k, l) - M2 * (r - i) * delta(k, l - 1))
def sum_w(k, i):
return summation(0, min(p, q, p + q + 1 - r) - i, inner, args=(i, k))
def sum_k(i):
return summation(l - 1, min(l, i), sum_w, args=i)
return summation(l - 1, min(p, q, r, p + q + 1 - r), sum_k)
def H_i(p, q):
'''
p, q are ints. Returns a float
'''
def inner(r, l):
return A_prime(p, q, r, l) * omega(12, l, r)
def sum_r(l):
return summation(l, p + q + 2 - l, inner, args=l)
val = 8 * summation(1, min(p, q) + 1, sum_r)
return val
p, q = np.int64(8), np.int64(8)
print(H_i(p,q)) #nan
print(H_i(int(p) ,int(q))) #1.3480582058153066e-08
- Numpy 的
int64
是一个 64 位整数,这意味着它由 64 个位置组成,要么是 0 要么是 1。因此最小的可表示值是-2**63
最大的是2**63 - 1
- Python的
int
本质上是无限长度,所以它可以表示任何值。它相当于Java中的一个BigInteger
。它存储为int64
的列表,本质上被认为是一个大数字。
你这里的是经典integer overflow。您提到您“仅”将 36 代入阶乘函数,但阶乘函数增长 非常快 ,结果是 36! = 3.7e41 > 9.2e18 = 2**63 - 1,所以你得到的数字大于你可以用 int64 表示的数字!
由于 int64
也称为 long
s 这正是警告 overflow encountered in long_scalars
试图告诉您的内容!