首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在数学运算中,np.int64的行为与int不同。

在数学运算中,np.int64的行为与int不同。
EN

Stack Overflow用户
提问于 2020-12-02 11:05:38
回答 1查看 292关注 0票数 1

我遇到了一个非常奇怪的问题,我做了很多数学运算,结果是infnan,当我的输入是<class 'numpy.int64'>类型时,但是当输入是<class 'int'>类型时,我得到了正确的(分析检查)结果。我使用的库函数只有np.math.factorial()np.sum()np.array()。我还使用生成器对象对级数和scipy.constants中的Boltzmann常数进行求和。

我的问题本质上是这样的:它们是否有已知的情况,即np.int64对象的行为将与int对象非常不同?

当我使用np.int64输入运行时,我得到了RuntimeWarnings:overflow encountered in long_scalarsdivide by zero encountered in double_scalarsinvalid value encountered in double_scalars。但是,插入阶乘函数的最大数目是36,使用int输入时不会收到这些警告。

下面是再现这种行为的代码。我无法更确切地知道它是从哪里来的。

代码语言:javascript
运行
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-02 11:16:51

  • Numpy的int64是一个 64位整数,这意味着它包含64个位置,它们要么是0,要么是1。
  • Python的int本质上是长度无限的,因此它可以表示任何值。它相当于Java中的BigInteger。它存储为一个int64的列表,本质上被认为是一个大的数字。

这里有一个经典的整数溢出。您提到“只”将36插入阶乘函数,但是阶乘函数增长非常快,36!= 3.7e41 > 9.2e18 = 2**63 - 1,因此您得到的数字比在int64中表示的要大!

由于int64s也称为longs,这正是警告overflow encountered in long_scalars试图告诉您的!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65106831

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档