我想为模块(uncertainties.py
模块创建的类似数字的对象提供“全部”数学函数,该模块使用错误传播执行计算) - 这些对象是具有不确定性的数字。
这样做的最佳方式是什么?
目前,我重新定义了模块math
中uncertainties.py
的大部分功能,以便它们处理具有不确定性的数字。一个缺点是想要from math import *
的用户必须在执行import uncertainties
之后 。
然而,与NumPy的交互仅限于基本操作(可以添加一系列具有不确定性的数字等);它还没有(还)包含更复杂的函数(例如sin()),这些函数可以在包含具有不确定性的数字的NumPy数组上工作。到目前为止,我采用的方法是建议用户定义sin = numpy.vectorize(math.sin)
,以便将新的math.sin
函数(对具有不确定性的数字起作用)广播到任何Numpy数组的元素。一个缺点是必须由用户对每个感兴趣的功能进行此操作,这是麻烦的。
那么,扩展数学函数(如sin()
)的最佳方法是什么,以便它们可以方便地使用简单数字和NumPy数组?
NumPy选择的方法是定义自己的numpy.sin
,而不是修改math.sin
,以便它可以与Numpy数组一起使用。我是否应该对uncertainties.py
模块执行相同的操作,并停止重新定义math.sin
?
此外,定义sin
的最有效和最正确的方法是什么,以便它既适用于简单数字,也适用于具有不确定性的数字和Numpy数组?我重新定义的math.sin
已经处理了具有不确定性的简单数字和数字。但是,使用numpy.vectorize
对其进行矢量化可能在“常规”NumPy数组上比numpy.sin
慢得多。
答案 0 :(得分:0)
看起来跟随NumPy本身所做的事情保持清洁:对新对象起作用的“扩展”数学运算(sin ...)可以放在一个单独的名称空间中。因此,NumPy有numpy.sin
等。这些操作大多与math
的操作兼容,但也适用于NumPy数组。
因此,在我看来,应该对通常的数字和 NumPy数组和具有不确定性的对应物的数学函数最好在单独的名称空间中定义。例如,用户可以这样做:
from uncertainties import sin
或
from uncertainties import * # sin, cos, etc.
出于优化目的,另一种方法可能是提供两组不同的数学函数:将函数推广到具有不确定性的简单数,以及将它们推广到具有不确定性的数组的那些:
from uncertainties.math_ops import * # Work on scalars and scalars with uncertainty
或
from uncertainties.numpy_ops import * # Work on everything (scalars, arrays, numbers with uncertainties, arrays with uncertainties)