为什么 Pyinterval 算法会因 numpy.float64 而失败

Why does Pyinterval arithmetic fail with numpy.float64

我使用 Pyinterval,但由于某些原因,它与 numpy.float64 不兼容。基本上,每当在区间运算中使用 numpy.float64 而不是通常的 float 时,区间都会被转换为 numpy 数组。

下面的例子:

import interval as itv
import numpy as np
from math import sqrt

ival = itv.interval([1,2])
cons = 2

print("interval 1: ",sqrt(cons)*ival)
print("interval 2: ",np.sqrt(cons)*ival)

打印:

interval 1: interval([1.4142135623730951, 2.8284271247461903])

interval 2: [[ 1.41421356 2.82842712]]

并且类型相应。基本上,因为我经常使用 numpy,我的问题是我是否能以某种方式 强制 它永远不会使用它自己的 float64 类型,或者除了铸造之外是否还有其他方便的解决方案每次 numpy 计算后返回。

这可能是由于 numpy 试图将间隔转换为它知道如何相乘的值。这显然失败了。相反,您可以让间隔库进行转换,这在我的测试中似乎有效:

代码:

ival = itv.interval([1, 2])
cons = 2

print("interval 1: ", ival * sqrt(cons))
print("interval 2: ", ival * np.sqrt(cons))

结果:

('interval 1: ', interval([1.4142135623730951, 2.8284271247461903]))
('interval 2: ', interval([1.4142135623730951, 2.8284271247461903]))

但是为什么?

Python 使用 __mul__ dunder 实现 * 运算符。被调用的 dunder 是用于左手操作数的 dunder。通过将间隔放在左侧,您将使用它的转换,而不是 numpy 的转换。为什么 numpy 不开心,我目前不知道,但这似乎有效。

时间旅行者来了。斯蒂芬给出了一个很好的答案,但我可以回答他最后一个“为什么”的问题。如果 python 看到两个对象的乘积 A*B 它尝试调用 A.__mul__(B) 但是,如果对象 A 的方法 __mul__ 无法识别对象 B 的 class,python 尝试呼叫 B.__rmul__(A)。这是您需要在 interval class 中针对第二种情况实施的方法。

详情请看这里https://docs.python.org/3.8/reference/datamodel.html#emulating-numeric-types