Skip to content

Commit

Permalink
new version of umath
Browse files Browse the repository at this point in the history
  • Loading branch information
jagerber48 committed Jul 17, 2024
1 parent 1c121a7 commit a602f84
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 9 deletions.
28 changes: 19 additions & 9 deletions uncertainties/core_new.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from math import sqrt, isnan
from numbers import Real
import sys
from typing import Callable, Collection, Dict, Optional, Tuple, Union, TYPE_CHECKING
from typing import Any, Callable, Collection, Dict, Optional, Tuple, Union, TYPE_CHECKING
import uuid

if TYPE_CHECKING:
Expand Down Expand Up @@ -322,13 +322,18 @@ def wrapped(*args, **kwargs):
return wrapped


def func_str_to_positional_func(func_str, nargs):
def func_str_to_positional_func(func_str, nargs, eval_locals=None):
if eval_locals is None:
eval_locals = {}
if nargs == 1:
def pos_func(x): # noqa
return eval(func_str)
def pos_func(x):
eval_locals['x'] = x
return eval(func_str, None, eval_locals)
elif nargs == 2:
def pos_func(x, y): # noqa
return eval(func_str)
def pos_func(x, y):
eval_locals['x'] = x
eval_locals['y'] = y
return eval(func_str, None, eval_locals)
else:
raise ValueError(f'Only nargs=1 or nargs=2 is supported, not {nargs=}.')

Check warning on line 338 in uncertainties/core_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/core_new.py#L338

Added line #L338 was not covered by tests
return pos_func
Expand All @@ -339,6 +344,7 @@ def pos_func(x, y): # noqa

def deriv_func_dict_positional_helper(
deriv_funcs: Tuple[Optional[PositionalDerivFunc]],
eval_locals=None,
):
nargs = len(deriv_funcs)
deriv_func_dict = {}
Expand All @@ -349,7 +355,7 @@ def deriv_func_dict_positional_helper(
elif callable(deriv_func):
pass
elif isinstance(deriv_func, str):
deriv_func = func_str_to_positional_func(deriv_func, nargs)
deriv_func = func_str_to_positional_func(deriv_func, nargs, eval_locals)
else:
raise ValueError(

Check warning on line 360 in uncertainties/core_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/core_new.py#L360

Added line #L360 was not covered by tests
f'Invalid deriv_func: {deriv_func}. Must be None, callable, or a '
Expand All @@ -373,9 +379,13 @@ class ToUFuncPositional(ToUFunc):
and binary functions should use 'x' and 'y' as the two parameters respectively.
An entry of None will cause the partial derivative to be calculated numerically.
"""
def __init__(self, deriv_funcs: Tuple[Optional[PositionalDerivFunc]]):
def __init__(
self,
deriv_funcs: Tuple[Optional[PositionalDerivFunc]],
eval_locals: Optional[Dict[str, Any]] = None,
):
ufloat_params = tuple(range(len(deriv_funcs)))
deriv_func_dict = deriv_func_dict_positional_helper(deriv_funcs)
deriv_func_dict = deriv_func_dict_positional_helper(deriv_funcs, eval_locals)
super().__init__(ufloat_params, deriv_func_dict)


Expand Down
113 changes: 113 additions & 0 deletions uncertainties/umath_new.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import math
from numbers import Real
import sys
from typing import Union

Check warning on line 4 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L1-L4

Added lines #L1 - L4 were not covered by tests

from uncertainties.core_new import UFloat, ToUFuncPositional

Check warning on line 6 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L6

Added line #L6 was not covered by tests


UReal = Union[Real, UFloat]

Check warning on line 9 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L9

Added line #L9 was not covered by tests


def acos(value: UReal) -> UReal: ...

Check warning on line 12 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L12

Added line #L12 was not covered by tests


def acosh(value: UReal) -> UReal: ...

Check warning on line 15 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L15

Added line #L15 was not covered by tests


def asinh(value: UReal) -> UReal: ...

Check warning on line 18 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L18

Added line #L18 was not covered by tests


def atan(value: UReal) -> UReal: ...

Check warning on line 21 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L21

Added line #L21 was not covered by tests


def atan2(x: UReal, y: UReal) -> UReal: ...

Check warning on line 24 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L24

Added line #L24 was not covered by tests


def atanh(value: UReal) -> UReal: ...

Check warning on line 27 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L27

Added line #L27 was not covered by tests


def cos(value: UReal) -> UReal: ...

Check warning on line 30 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L30

Added line #L30 was not covered by tests


def cosh(value: UReal) -> UReal: ...

Check warning on line 33 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L33

Added line #L33 was not covered by tests


def degrees(value: UReal) -> UReal: ...

Check warning on line 36 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L36

Added line #L36 was not covered by tests


def erf(value: UReal) -> UReal: ...

Check warning on line 39 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L39

Added line #L39 was not covered by tests


def erfc(value: UReal) -> UReal: ...

Check warning on line 42 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L42

Added line #L42 was not covered by tests


def exp(value: UReal) -> UReal: ...

Check warning on line 45 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L45

Added line #L45 was not covered by tests


# def log(value: UReal) -> UReal: ...


def log10(value: UReal) -> UReal: ...

Check warning on line 51 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L51

Added line #L51 was not covered by tests


def radians(value: UReal) -> UReal: ...

Check warning on line 54 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L54

Added line #L54 was not covered by tests


def sin(value: UReal) -> UReal: ...

Check warning on line 57 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L57

Added line #L57 was not covered by tests


def sinh(value: UReal) -> UReal: ...

Check warning on line 60 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L60

Added line #L60 was not covered by tests


def sqrt(value: UReal) -> UReal: ...

Check warning on line 63 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L63

Added line #L63 was not covered by tests


def tan(value: UReal) -> UReal: ...

Check warning on line 66 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L66

Added line #L66 was not covered by tests


def tanh(value: UReal) -> UReal: ...

Check warning on line 69 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L69

Added line #L69 was not covered by tests


def log_der0(*args):

Check warning on line 72 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L72

Added line #L72 was not covered by tests
"""
Derivative of math.log() with respect to its first argument.
Works whether 1 or 2 arguments are given.
"""
if len(args) == 1:
return 1 / args[0]

Check warning on line 79 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L78-L79

Added lines #L78 - L79 were not covered by tests
else:
return 1 / args[0] / math.log(args[1]) # 2-argument form

Check warning on line 81 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L81

Added line #L81 was not covered by tests


deriv_dict = {

Check warning on line 84 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L84

Added line #L84 was not covered by tests
# In alphabetical order, here:
"acos": ("-1/math.sqrt(1-x**2)",),
"acosh": ("1/math.sqrt(x**2-1)",),
"asinh": ("1/math.sqrt(1+x**2)",),
"atan": ("1/(1+x**2)",),
"atan2": ('x/(x**2+y**2)', "-y/(x**2+y**2)"),
"atanh": ("1/(1-x**2)",),
"cos": ("-math.sin(x)",),
"cosh": ("math.sinh(x)",),
"degrees": ("math.degrees(1)",),
"erf": ("(2/math.sqrt(math.pi))*math.exp(-(x**2))",),
"erfc": ("-(2/math.sqrt(math.pi))*math.exp(-(x**2))",),
"exp": ("math.exp(x)",),
# "log": (log_der0, "-math.log(x, y) / y / math.log(y)"),
"log10": ("1/x/math.log(10)",),
"radians": ("math.radians(1)",),
"sin": ("math.cos(x)",),
"sinh": ("math.cosh(x)",),
"sqrt": ("0.5/math.sqrt(x)",),
"tan": ("1 + math.tan(x)**2",),
"tanh": ("1 - math.tanh(x)**2",),
}

this_module = sys.modules[__name__]

Check warning on line 108 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L108

Added line #L108 was not covered by tests

for func_name, deriv_funcs in deriv_dict.items():
func = getattr(math, func_name)
ufunc = ToUFuncPositional(deriv_funcs, eval_locals={"math": math})(func)
setattr(this_module, func_name, ufunc)

Check warning on line 113 in uncertainties/umath_new.py

View check run for this annotation

Codecov / codecov/patch

uncertainties/umath_new.py#L110-L113

Added lines #L110 - L113 were not covered by tests

0 comments on commit a602f84

Please sign in to comment.