pynumerics 2.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pynumerics/__init__.py +73 -0
- pynumerics/_bin/Microsoft.CodeAnalysis.CSharp.dll +0 -0
- pynumerics/_bin/Microsoft.CodeAnalysis.LICENSE.txt +27 -0
- pynumerics/_bin/Microsoft.CodeAnalysis.dll +0 -0
- pynumerics/_bin/Numerics.dll +0 -0
- pynumerics/_bin/pynumerics.runtimeconfig.json +15 -0
- pynumerics/_coverage.py +3825 -0
- pynumerics/_util.py +237 -0
- pynumerics/_version.py +40 -0
- pynumerics/bootstrap.py +593 -0
- pynumerics/callbacks.py +791 -0
- pynumerics/copulas.py +910 -0
- pynumerics/data.py +2233 -0
- pynumerics/differentiation.py +348 -0
- pynumerics/distributions.py +4043 -0
- pynumerics/download.py +623 -0
- pynumerics/enums.py +119 -0
- pynumerics/errors.py +245 -0
- pynumerics/functions.py +1142 -0
- pynumerics/goodness_of_fit.py +699 -0
- pynumerics/graphs.py +556 -0
- pynumerics/hypothesis_tests.py +445 -0
- pynumerics/identity.py +144 -0
- pynumerics/integration.py +677 -0
- pynumerics/linalg.py +1408 -0
- pynumerics/machine_learning.py +1335 -0
- pynumerics/marshal.py +733 -0
- pynumerics/mathematics.py +1053 -0
- pynumerics/mcmc.py +1406 -0
- pynumerics/multivariate.py +1539 -0
- pynumerics/ode.py +156 -0
- pynumerics/optimization.py +1736 -0
- pynumerics/probability.py +966 -0
- pynumerics/py.typed +0 -0
- pynumerics/regional.py +522 -0
- pynumerics/roots.py +274 -0
- pynumerics/runtime.py +384 -0
- pynumerics/sampling.py +1758 -0
- pynumerics/special.py +1079 -0
- pynumerics/statistics.py +1958 -0
- pynumerics/timeseries.py +1326 -0
- pynumerics-2.3.0.dist-info/METADATA +142 -0
- pynumerics-2.3.0.dist-info/RECORD +46 -0
- pynumerics-2.3.0.dist-info/WHEEL +5 -0
- pynumerics-2.3.0.dist-info/licenses/LICENSE +10 -0
- pynumerics-2.3.0.dist-info/top_level.txt +1 -0
pynumerics/enums.py
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""Python enums mirroring the Numerics enums the wrappers accept.
|
|
2
|
+
|
|
3
|
+
Every wrapper argument typed with one of these enums also accepts the member value or
|
|
4
|
+
the .NET member name as a string, matched case-insensitively with underscores ignored. The
|
|
5
|
+
enums themselves resolve the same spellings: ``Transform("normal_z")``, ``Transform("NORMAL_Z")``
|
|
6
|
+
and ``Transform("NormalZ")`` are all ``Transform.NORMAL_Z``. Enums added elsewhere in the package
|
|
7
|
+
derive from :class:`NetEnum` to get that lookup.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import enum
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
from pynumerics._util import fold_name
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class NetEnum(enum.Enum):
|
|
19
|
+
"""Base of the pynumerics enums: values are .NET member names, looked up by folded spelling.
|
|
20
|
+
|
|
21
|
+
A value that is not a member value exactly is matched against the member values and names
|
|
22
|
+
with underscores removed and case ignored, the rule ``net_enum`` applies to .NET enums, so
|
|
23
|
+
snake-case spellings kept in configuration files resolve.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
@classmethod
|
|
27
|
+
def _missing_(cls, value: Any) -> NetEnum | None:
|
|
28
|
+
if not isinstance(value, str):
|
|
29
|
+
return None
|
|
30
|
+
key = fold_name(value)
|
|
31
|
+
for member in cls:
|
|
32
|
+
if fold_name(str(member.value)) == key or fold_name(member.name) == key:
|
|
33
|
+
return member
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class EstimationMethod(NetEnum):
|
|
38
|
+
"""Parameter estimation methods (``Numerics.Distributions.ParameterEstimationMethod``)."""
|
|
39
|
+
|
|
40
|
+
MAXIMUM_LIKELIHOOD = "MaximumLikelihood"
|
|
41
|
+
METHOD_OF_MOMENTS = "MethodOfMoments"
|
|
42
|
+
METHOD_OF_LINEAR_MOMENTS = "MethodOfLinearMoments"
|
|
43
|
+
METHOD_OF_PERCENTILES = "MethodOfPercentiles"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class SortOrder(NetEnum):
|
|
47
|
+
"""Sort orders (``Numerics.Data.SortOrder``)."""
|
|
48
|
+
|
|
49
|
+
ASCENDING = "Ascending"
|
|
50
|
+
DESCENDING = "Descending"
|
|
51
|
+
NONE = "None"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class Transform(NetEnum):
|
|
55
|
+
"""Interpolation transforms (``Numerics.Data.Transform``)."""
|
|
56
|
+
|
|
57
|
+
NONE = "None"
|
|
58
|
+
LOGARITHMIC = "Logarithmic"
|
|
59
|
+
NORMAL_Z = "NormalZ"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class Extrapolation(NetEnum):
|
|
63
|
+
"""Extrapolation sides (``Numerics.Data.ExtrapolationSides``)."""
|
|
64
|
+
|
|
65
|
+
NONE = "None"
|
|
66
|
+
BELOW = "Below"
|
|
67
|
+
ABOVE = "Above"
|
|
68
|
+
BOTH = "Both"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class PlottingPosition(NetEnum):
|
|
72
|
+
"""Plotting-position formulas (``PlottingPositions.PlottingPostionType``)."""
|
|
73
|
+
|
|
74
|
+
WEIBULL = "Weibull"
|
|
75
|
+
MEDIAN = "Median"
|
|
76
|
+
BLOM = "Blom"
|
|
77
|
+
CUNNANE = "Cunnane"
|
|
78
|
+
GRINGORTEN = "Gringorten"
|
|
79
|
+
HAZEN = "Hazen"
|
|
80
|
+
KAPLAN_MEIER = "KaplanMeier"
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class ImportanceDistribution(NetEnum):
|
|
84
|
+
"""Stratification importance distributions (``Stratify.ImportanceDistribution``)."""
|
|
85
|
+
|
|
86
|
+
GUMBEL = "Gumbel"
|
|
87
|
+
NORMAL = "Normal"
|
|
88
|
+
UNIFORM = "Uniform"
|
|
89
|
+
LOG10_UNIFORM = "Log10Uniform"
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class WeightType(NetEnum):
|
|
93
|
+
"""Weight interpretations for weighted statistics (``Numerics.Data.Statistics.WeightType``)."""
|
|
94
|
+
|
|
95
|
+
FREQUENCY = "Frequency"
|
|
96
|
+
RELIABILITY = "Reliability"
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class KernelType(NetEnum):
|
|
100
|
+
"""Kernel density kernels (``Numerics.Distributions.KernelDensity.KernelType``)."""
|
|
101
|
+
|
|
102
|
+
EPANECHNIKOV = "Epanechnikov"
|
|
103
|
+
GAUSSIAN = "Gaussian"
|
|
104
|
+
TRIANGULAR = "Triangular"
|
|
105
|
+
UNIFORM = "Uniform"
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class AutocorrelationType(NetEnum):
|
|
109
|
+
"""Autocorrelation function kinds (``Numerics.Data.Statistics.Autocorrelation.Type``)."""
|
|
110
|
+
|
|
111
|
+
CORRELATION = "Correlation"
|
|
112
|
+
COVARIANCE = "Covariance"
|
|
113
|
+
PARTIAL = "Partial"
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
__all__ = [
|
|
117
|
+
"AutocorrelationType", "EstimationMethod", "Extrapolation", "ImportanceDistribution", "KernelType", "NetEnum",
|
|
118
|
+
"PlottingPosition", "SortOrder", "Transform", "WeightType",
|
|
119
|
+
]
|
pynumerics/errors.py
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"""Map the exceptions Numerics throws onto the Python exceptions callers expect.
|
|
2
|
+
|
|
3
|
+
pythonnet raises a .NET exception as a Python exception of the .NET type, which ``except ValueError``
|
|
4
|
+
does not catch. Every public wrapper in this package translates them, keeping the .NET message
|
|
5
|
+
text exactly and chaining the .NET exception as the cause:
|
|
6
|
+
|
|
7
|
+
======================================================== ========================
|
|
8
|
+
.NET exception Python exception
|
|
9
|
+
======================================================== ========================
|
|
10
|
+
``ArgumentException`` (``ArgumentOutOfRangeException``) ``ValueError``
|
|
11
|
+
``OverflowException`` ``OverflowError``
|
|
12
|
+
``DivideByZeroException`` ``ZeroDivisionError``
|
|
13
|
+
``ArithmeticException`` (any other) ``ArithmeticError``
|
|
14
|
+
``NotImplementedException``, ``NotSupportedException`` ``NotImplementedError``
|
|
15
|
+
any other ``System.Exception`` ``RuntimeError``
|
|
16
|
+
======================================================== ========================
|
|
17
|
+
|
|
18
|
+
A ``TargetInvocationException``, or an ``AggregateException`` with one inner exception, is
|
|
19
|
+
translated by its inner exception. A Python exception, including one raised inside a Python
|
|
20
|
+
callback that Numerics invoked, propagates unchanged.
|
|
21
|
+
|
|
22
|
+
:func:`net_errors` applies the translation to a block of code, :func:`translated` to a function,
|
|
23
|
+
and :func:`translate_public` to every public function and class of a module.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
import enum
|
|
29
|
+
import functools
|
|
30
|
+
import inspect
|
|
31
|
+
from collections.abc import Callable, Iterator, MutableMapping
|
|
32
|
+
from contextlib import contextmanager
|
|
33
|
+
from typing import Any, TypeVar
|
|
34
|
+
|
|
35
|
+
from pynumerics import runtime
|
|
36
|
+
|
|
37
|
+
F = TypeVar("F", bound=Callable[..., Any])
|
|
38
|
+
|
|
39
|
+
_MARKER = "__net_errors__"
|
|
40
|
+
|
|
41
|
+
_WRAPPED_DUNDERS = frozenset({"__init__", "__call__", "__getitem__", "__setitem__", "__len__", "__contains__",
|
|
42
|
+
"__iter__", "__eq__", "__hash__"})
|
|
43
|
+
"""Special methods that call into .NET in the wrappers and so are translated as well."""
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _system() -> Any:
|
|
47
|
+
"""Return the ``System`` namespace, or None while the runtime is not running."""
|
|
48
|
+
if not runtime.is_initialized():
|
|
49
|
+
return None
|
|
50
|
+
import System # noqa: PLC0415 - the runtime is running
|
|
51
|
+
|
|
52
|
+
return System
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def translate(error: BaseException) -> BaseException | None:
|
|
56
|
+
"""Return the Python exception for a .NET exception.
|
|
57
|
+
|
|
58
|
+
Parameters
|
|
59
|
+
----------
|
|
60
|
+
error : BaseException
|
|
61
|
+
The raised exception.
|
|
62
|
+
|
|
63
|
+
Returns
|
|
64
|
+
-------
|
|
65
|
+
BaseException or None
|
|
66
|
+
A new ``ValueError``, ``OverflowError``, ``ZeroDivisionError``, ``ArithmeticError``,
|
|
67
|
+
``NotImplementedError`` or ``RuntimeError`` carrying the .NET message, or None when
|
|
68
|
+
``error`` is not a .NET exception.
|
|
69
|
+
"""
|
|
70
|
+
system = _system()
|
|
71
|
+
if system is None or not isinstance(error, system.Exception):
|
|
72
|
+
return None
|
|
73
|
+
inner = error
|
|
74
|
+
while True:
|
|
75
|
+
if isinstance(inner, system.Reflection.TargetInvocationException) and inner.InnerException is not None:
|
|
76
|
+
inner = inner.InnerException
|
|
77
|
+
elif isinstance(inner, system.AggregateException) and inner.InnerExceptions.Count == 1:
|
|
78
|
+
inner = inner.InnerExceptions[0]
|
|
79
|
+
else:
|
|
80
|
+
break
|
|
81
|
+
message = str(inner.Message)
|
|
82
|
+
if isinstance(inner, system.ArgumentException):
|
|
83
|
+
return ValueError(message)
|
|
84
|
+
if isinstance(inner, system.OverflowException):
|
|
85
|
+
return OverflowError(message)
|
|
86
|
+
if isinstance(inner, system.DivideByZeroException):
|
|
87
|
+
return ZeroDivisionError(message)
|
|
88
|
+
if isinstance(inner, system.ArithmeticException):
|
|
89
|
+
return ArithmeticError(message)
|
|
90
|
+
if isinstance(inner, (system.NotImplementedException, system.NotSupportedException)):
|
|
91
|
+
return NotImplementedError(message)
|
|
92
|
+
return RuntimeError(message)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@contextmanager
|
|
96
|
+
def net_errors() -> Iterator[None]:
|
|
97
|
+
"""Re-raise .NET exceptions raised in the block as their Python counterparts.
|
|
98
|
+
|
|
99
|
+
Yields
|
|
100
|
+
------
|
|
101
|
+
None
|
|
102
|
+
Nothing; the body runs inside the translation.
|
|
103
|
+
|
|
104
|
+
Examples
|
|
105
|
+
--------
|
|
106
|
+
>>> from pynumerics.distributions import Normal
|
|
107
|
+
>>> from pynumerics.errors import net_errors
|
|
108
|
+
>>> try:
|
|
109
|
+
... with net_errors():
|
|
110
|
+
... Normal().net.InverseCDF(1.5)
|
|
111
|
+
... except ValueError as error:
|
|
112
|
+
... print("refused")
|
|
113
|
+
refused
|
|
114
|
+
"""
|
|
115
|
+
try:
|
|
116
|
+
yield
|
|
117
|
+
except Exception as error:
|
|
118
|
+
mapped = translate(error)
|
|
119
|
+
if mapped is None:
|
|
120
|
+
raise
|
|
121
|
+
raise mapped from error
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def translated(func: F) -> F:
|
|
125
|
+
"""Return ``func`` wrapped so that .NET exceptions it raises surface as Python exceptions.
|
|
126
|
+
|
|
127
|
+
The wrapper keeps the name, docstring and signature of ``func`` (``functools.wraps``) and adds
|
|
128
|
+
one Python call to a call that does not raise. Wrapping an already translated function
|
|
129
|
+
returns it unchanged.
|
|
130
|
+
|
|
131
|
+
Parameters
|
|
132
|
+
----------
|
|
133
|
+
func : callable
|
|
134
|
+
The function to wrap.
|
|
135
|
+
|
|
136
|
+
Returns
|
|
137
|
+
-------
|
|
138
|
+
callable
|
|
139
|
+
The wrapped function.
|
|
140
|
+
"""
|
|
141
|
+
if getattr(func, _MARKER, False):
|
|
142
|
+
return func
|
|
143
|
+
|
|
144
|
+
@functools.wraps(func)
|
|
145
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
146
|
+
try:
|
|
147
|
+
return func(*args, **kwargs)
|
|
148
|
+
except Exception as error:
|
|
149
|
+
mapped = translate(error)
|
|
150
|
+
if mapped is None:
|
|
151
|
+
raise
|
|
152
|
+
raise mapped from error
|
|
153
|
+
|
|
154
|
+
setattr(wrapper, _MARKER, True)
|
|
155
|
+
return wrapper # type: ignore[return-value]
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def is_translated(obj: Any) -> bool:
|
|
159
|
+
"""Return whether a function, property or class member translates .NET exceptions.
|
|
160
|
+
|
|
161
|
+
Parameters
|
|
162
|
+
----------
|
|
163
|
+
obj : object
|
|
164
|
+
A function, ``property``, ``classmethod`` or ``staticmethod``.
|
|
165
|
+
|
|
166
|
+
Returns
|
|
167
|
+
-------
|
|
168
|
+
bool
|
|
169
|
+
True when every function the object runs is wrapped by :func:`translated`.
|
|
170
|
+
"""
|
|
171
|
+
if isinstance(obj, property):
|
|
172
|
+
return all(f is None or getattr(f, _MARKER, False) for f in (obj.fget, obj.fset, obj.fdel))
|
|
173
|
+
if isinstance(obj, (classmethod, staticmethod)):
|
|
174
|
+
return bool(getattr(obj.__func__, _MARKER, False))
|
|
175
|
+
return bool(getattr(obj, _MARKER, False))
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _translate_member(value: Any) -> Any:
|
|
179
|
+
"""Return a class-dictionary entry with its functions wrapped by :func:`translated`."""
|
|
180
|
+
if isinstance(value, property):
|
|
181
|
+
if is_translated(value):
|
|
182
|
+
return value
|
|
183
|
+
return property(*(None if f is None else translated(f) for f in (value.fget, value.fset, value.fdel)),
|
|
184
|
+
doc=value.__doc__)
|
|
185
|
+
if isinstance(value, (classmethod, staticmethod)):
|
|
186
|
+
return value if is_translated(value) else type(value)(translated(value.__func__))
|
|
187
|
+
if inspect.isfunction(value):
|
|
188
|
+
return translated(value)
|
|
189
|
+
return value
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def translate_class(klass: type) -> type:
|
|
193
|
+
"""Wrap the methods and properties a class defines so .NET exceptions surface as Python exceptions.
|
|
194
|
+
|
|
195
|
+
Covers the functions, properties, class methods and static methods in the class's own
|
|
196
|
+
dictionary whose names are public, plus ``__init__``, ``__call__``, ``__getitem__``,
|
|
197
|
+
``__setitem__``, ``__len__``, ``__contains__``, ``__iter__``, ``__eq__`` and ``__hash__``.
|
|
198
|
+
Enums and exception classes are returned unchanged.
|
|
199
|
+
|
|
200
|
+
Parameters
|
|
201
|
+
----------
|
|
202
|
+
klass : type
|
|
203
|
+
The class to update in place.
|
|
204
|
+
|
|
205
|
+
Returns
|
|
206
|
+
-------
|
|
207
|
+
type
|
|
208
|
+
``klass``.
|
|
209
|
+
"""
|
|
210
|
+
if issubclass(klass, (enum.Enum, BaseException)):
|
|
211
|
+
return klass
|
|
212
|
+
for name, value in list(vars(klass).items()):
|
|
213
|
+
if (name.startswith("_") and name not in _WRAPPED_DUNDERS) or value is None:
|
|
214
|
+
continue
|
|
215
|
+
member = _translate_member(value)
|
|
216
|
+
if member is not value:
|
|
217
|
+
setattr(klass, name, member)
|
|
218
|
+
return klass
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def translate_public(namespace: MutableMapping[str, Any]) -> None:
|
|
222
|
+
"""Apply :func:`translated` and :func:`translate_class` to the public objects a module defines.
|
|
223
|
+
|
|
224
|
+
Called at the end of a wrapper module as ``translate_public(globals())``. The objects are
|
|
225
|
+
the module's ``__all__`` (or every public name when it has none) whose ``__module__`` is the
|
|
226
|
+
module itself; re-exported objects are left to their own module.
|
|
227
|
+
|
|
228
|
+
Parameters
|
|
229
|
+
----------
|
|
230
|
+
namespace : MutableMapping
|
|
231
|
+
The module's ``globals()``.
|
|
232
|
+
"""
|
|
233
|
+
module = namespace.get("__name__")
|
|
234
|
+
names = namespace.get("__all__") or [n for n in list(namespace) if not n.startswith("_")]
|
|
235
|
+
for name in names:
|
|
236
|
+
obj = namespace.get(name)
|
|
237
|
+
if getattr(obj, "__module__", None) != module:
|
|
238
|
+
continue
|
|
239
|
+
if inspect.isclass(obj):
|
|
240
|
+
translate_class(obj)
|
|
241
|
+
elif inspect.isfunction(obj):
|
|
242
|
+
namespace[name] = translated(obj)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
__all__ = ["is_translated", "net_errors", "translate", "translate_class", "translate_public", "translated"]
|