为什么 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
我使用 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