I would like to provide "all" mathematical functions for the number-like objects created by a module (the uncertainties.py
module, which performs calculations with error propagation)—these objects are numbers with uncertainties.
What is the best way to do this?
Currently, I redefine most of the functions from math
in the module uncertainties.py
, so that they work on numbers with uncertainties. One drawback is that users who want to do from math import *
must do so after doing import uncertainties
.
The interaction with NumPy is, however, restricted to basic operations (an array of numbers with uncertainties can be added, etc.); it does not (yet) include more complex functions (e.g. sin()) that would work on NumPy arrays that contain numbers with uncertainties. The approach I have taken so far consists in suggesting that the user define sin = numpy.vectorize(math.sin)
, so that the new math.sin
function (which works on numbers with uncertainties) is broadcast to the elements of any Numpy array. One drawback is that this has to be done for each function of interest by the user, which is cumbersome.
So, what is the best way to extend mathematical functions such as sin()
so that they work conveniently with simple numbers and NumPy arrays?
The approach chosen by NumPy is to define its own numpy.sin
, rather than modifying math.sin
so that it works with Numpy arrays. Should I do the same for my uncertainties.py
module, and stop redefining math.sin
?
Furthermore, what would be the most efficient and correct way of defining sin
so that it works both for simple numbers, numbers with uncertainties, and Numpy arrays? My redefined math.sin
already handles simple numbers and numbers with uncertainties. However, vectorizing it with numpy.vectorize
is likely to be much slower on "regular" NumPy arrays than numpy.sin
.