sigmaepsilon.math 2.2.2__tar.gz → 2.4.0__tar.gz
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.
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/PKG-INFO +1 -1
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/pyproject.toml +1 -1
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/__init__.py +2 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/approx/__init__.py +2 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/approx/functions.py +25 -15
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/approx/lagrange.py +6 -4
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/approx/ls.py +8 -5
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/approx/ls_approx.py +2 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/approx/ls_poly.py +2 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/approx/ls_preproc.py +2 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/approx/mls.py +13 -15
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/arraysetops.py +2 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/decorate.py +5 -2
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/downloads.py +3 -2
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/function/__init__.py +1 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/function/function.py +17 -21
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/function/functions.py +7 -10
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/function/metafunction.py +15 -9
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/function/relation.py +18 -22
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/function/symutils.py +8 -8
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/function/testfunction.py +14 -2
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/function/utils.py +4 -5
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/graph/__init__.py +2 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/graph/graph.py +7 -10
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/graph/utils.py +4 -5
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/hist.py +2 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/knn.py +7 -5
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/__init__.py +2 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/abstract.py +19 -4
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/exceptions.py +6 -4
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/frame.py +93 -99
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/imap.py +2 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/logical.py +20 -28
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/meta.py +73 -76
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/solve.py +5 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/sparse/__init__.py +1 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/sparse/csr.py +12 -15
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/sparse/jaggedarray.py +32 -43
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/sparse/utils.py +6 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/tensor.py +42 -43
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/testing.py +7 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/tr.py +2 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/utils.py +87 -53
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/linalg/vector.py +22 -28
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/logical.py +22 -32
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/mathtypes.py +2 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/metautils.py +3 -3
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/numint.py +8 -3
- sigmaepsilon_math-2.4.0/src/sigmaepsilon/math/optimize/__init__.py +25 -0
- sigmaepsilon_math-2.4.0/src/sigmaepsilon/math/optimize/bga.py +93 -0
- sigmaepsilon_math-2.4.0/src/sigmaepsilon/math/optimize/bitchromosome.py +123 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/optimize/ga.py +214 -97
- sigmaepsilon_math-2.4.0/src/sigmaepsilon/math/optimize/iga.py +111 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/optimize/lp.py +79 -21
- sigmaepsilon_math-2.4.0/src/sigmaepsilon/math/optimize/rga.py +149 -0
- sigmaepsilon_math-2.4.0/src/sigmaepsilon/math/optimize/selection.py +126 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/optimize/state.py +12 -3
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/utils.py +34 -34
- sigmaepsilon_math-2.2.2/src/sigmaepsilon/math/optimize/__init__.py +0 -10
- sigmaepsilon_math-2.2.2/src/sigmaepsilon/math/optimize/bga.py +0 -192
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/LICENSE +0 -0
- {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/README.md +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[tool.poetry]
|
|
6
6
|
name = "sigmaepsilon.math"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.4.0"
|
|
8
8
|
description = "A Python Library for Applied Mathematics in Physical Sciences."
|
|
9
9
|
classifiers=[ # https://pypi.org/classifiers/
|
|
10
10
|
"Development Status :: 5 - Production/Stable",
|
{sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/approx/functions.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Weight functions used by the moving least squares approximator."""
|
|
2
|
+
|
|
1
3
|
from typing import Tuple, Any, Iterable
|
|
2
4
|
from numbers import Number
|
|
3
5
|
|
|
@@ -9,9 +11,7 @@ from ..function import Function
|
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
class MLSWeightFunction(Function):
|
|
12
|
-
"""
|
|
13
|
-
Base class for weight functions for the moving least squares method.
|
|
14
|
-
"""
|
|
14
|
+
"""Base class for weight functions for the moving least squares method."""
|
|
15
15
|
|
|
16
16
|
def __init__(
|
|
17
17
|
self,
|
|
@@ -48,6 +48,7 @@ class MLSWeightFunction(Function):
|
|
|
48
48
|
|
|
49
49
|
@property
|
|
50
50
|
def core(self) -> ndarray | Iterable[Number] | None:
|
|
51
|
+
"""Return the core (center) of the weight function."""
|
|
51
52
|
return self._core
|
|
52
53
|
|
|
53
54
|
@core.setter
|
|
@@ -66,6 +67,7 @@ class MLSWeightFunction(Function):
|
|
|
66
67
|
|
|
67
68
|
@property
|
|
68
69
|
def supportdomain(self) -> ndarray | Iterable[Number] | None:
|
|
70
|
+
"""Return the support domain of the weight function."""
|
|
69
71
|
return self._supportdomain
|
|
70
72
|
|
|
71
73
|
@supportdomain.setter
|
|
@@ -81,6 +83,7 @@ class MLSWeightFunction(Function):
|
|
|
81
83
|
return
|
|
82
84
|
|
|
83
85
|
def preproc_evaluation(self, x: Iterable[Number]):
|
|
86
|
+
"""Validate and coerce the evaluation point `x` into a NumPy array."""
|
|
84
87
|
if not isinstance(x, (ndarray, float)):
|
|
85
88
|
if isinstance(x, Iterable):
|
|
86
89
|
x = np.array(x)
|
|
@@ -90,16 +93,17 @@ class MLSWeightFunction(Function):
|
|
|
90
93
|
)
|
|
91
94
|
|
|
92
95
|
def value(self, x: Iterable[Number]) -> float:
|
|
93
|
-
"""
|
|
94
|
-
Evaluates the function.
|
|
95
|
-
"""
|
|
96
|
+
"""Evaluate the function."""
|
|
96
97
|
raise NotImplementedError
|
|
97
98
|
|
|
98
99
|
|
|
99
100
|
def isMLSWeightFunction(f: Any) -> bool:
|
|
100
|
-
"""
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
"""Return `True` if the argument is a valid weight function for the moving least squares method.
|
|
102
|
+
|
|
103
|
+
Parameters
|
|
104
|
+
----------
|
|
105
|
+
f : Any
|
|
106
|
+
The object to check.
|
|
103
107
|
"""
|
|
104
108
|
c1 = isinstance(f, MLSWeightFunction)
|
|
105
109
|
c2 = MLSWeightFunction in list(type(f).__bases__)
|
|
@@ -107,9 +111,7 @@ def isMLSWeightFunction(f: Any) -> bool:
|
|
|
107
111
|
|
|
108
112
|
|
|
109
113
|
class ConstantWeightFunction(MLSWeightFunction):
|
|
110
|
-
"""
|
|
111
|
-
A constant weight function for the moving least squares method.
|
|
112
|
-
"""
|
|
114
|
+
"""A constant weight function for the moving least squares method."""
|
|
113
115
|
|
|
114
116
|
def __init__(self, *, value: Number = 1.0, **kwargs):
|
|
115
117
|
super().__init__(**kwargs)
|
|
@@ -117,6 +119,7 @@ class ConstantWeightFunction(MLSWeightFunction):
|
|
|
117
119
|
return
|
|
118
120
|
|
|
119
121
|
def value(self, x: Iterable[Number]) -> float:
|
|
122
|
+
"""Return the value of the weight function at `x`."""
|
|
120
123
|
if self.supportdomain is None:
|
|
121
124
|
return self._value
|
|
122
125
|
|
|
@@ -129,16 +132,16 @@ class ConstantWeightFunction(MLSWeightFunction):
|
|
|
129
132
|
return self._value
|
|
130
133
|
|
|
131
134
|
def gradient(self, x: Iterable[Number]) -> ndarray:
|
|
135
|
+
"""Return the gradient of the weight function at `x`."""
|
|
132
136
|
return np.zeros(self.dimension, dtype=float)
|
|
133
137
|
|
|
134
138
|
def Hessian(self, x: Iterable[Number]) -> ndarray:
|
|
139
|
+
"""Return the Hessian of the weight function at `x`."""
|
|
135
140
|
return np.zeros((self.dimension, self.dimension), dtype=float)
|
|
136
141
|
|
|
137
142
|
|
|
138
143
|
class SingularWeightFunction(MLSWeightFunction):
|
|
139
|
-
"""
|
|
140
|
-
A singular weight function for the moving least squares method.
|
|
141
|
-
"""
|
|
144
|
+
"""A singular weight function for the moving least squares method."""
|
|
142
145
|
|
|
143
146
|
def __init__(self, *, eps: Number = 1e-5, **kwargs):
|
|
144
147
|
super().__init__(**kwargs)
|
|
@@ -146,13 +149,16 @@ class SingularWeightFunction(MLSWeightFunction):
|
|
|
146
149
|
return
|
|
147
150
|
|
|
148
151
|
def value(self, x: Iterable[Number]):
|
|
152
|
+
"""Return the value of the weight function at `x`."""
|
|
149
153
|
self.preproc_evaluation(x)
|
|
150
154
|
return 1 / (norm(np.subtract(self.core, x)) ** 2 + self.eps**2)
|
|
151
155
|
|
|
152
156
|
def gradient(self, x: Iterable[Number]) -> ndarray:
|
|
157
|
+
"""Return the gradient of the weight function at `x`."""
|
|
153
158
|
return np.zeros(self.dimension, dtype=float)
|
|
154
159
|
|
|
155
160
|
def Hessian(self, x: Iterable[Number]) -> ndarray:
|
|
161
|
+
"""Return the Hessian of the weight function at `x`."""
|
|
156
162
|
return np.zeros((self.dimension, self.dimension), dtype=float)
|
|
157
163
|
|
|
158
164
|
|
|
@@ -170,6 +176,7 @@ class CubicWeightFunction(MLSWeightFunction):
|
|
|
170
176
|
"""
|
|
171
177
|
|
|
172
178
|
def evaluate(self, x: Iterable[Number]) -> Tuple[float, ndarray, ndarray]:
|
|
179
|
+
"""Return the value, gradient and Hessian of the weight function at `x`."""
|
|
173
180
|
if self.dimension == 1:
|
|
174
181
|
return self._evaluate_1d(x)
|
|
175
182
|
elif self.dimension == 2:
|
|
@@ -259,16 +266,19 @@ class CubicWeightFunction(MLSWeightFunction):
|
|
|
259
266
|
return val, grad, Hessian
|
|
260
267
|
|
|
261
268
|
def value(self, x: Iterable[Number]) -> float:
|
|
269
|
+
"""Return the value of the weight function at `x`."""
|
|
262
270
|
self.preproc_evaluation(x)
|
|
263
271
|
res, _, _ = self.evaluate(x)
|
|
264
272
|
return res
|
|
265
273
|
|
|
266
274
|
def gradient(self, x: Iterable[Number]) -> ndarray:
|
|
275
|
+
"""Return the gradient of the weight function at `x`."""
|
|
267
276
|
self.preproc_evaluation(x)
|
|
268
277
|
_, res, _ = self.evaluate(x)
|
|
269
278
|
return res
|
|
270
279
|
|
|
271
280
|
def Hessian(self, x: Iterable[Number]) -> ndarray:
|
|
281
|
+
"""Return the Hessian of the weight function at `x`."""
|
|
272
282
|
self.preproc_evaluation(x)
|
|
273
283
|
_, _, res = self.evaluate(x)
|
|
274
284
|
return res
|
{sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/approx/lagrange.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Lagrange polynomial generation and 1d approximation utilities."""
|
|
2
|
+
|
|
1
3
|
from typing import Iterable, Callable
|
|
2
4
|
|
|
3
5
|
import sympy as sy
|
|
@@ -33,8 +35,9 @@ def gen_Lagrange_1d(
|
|
|
33
35
|
lambdify: bool = False,
|
|
34
36
|
out: dict | None = None
|
|
35
37
|
) -> dict:
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
+
"""Generate Lagrange polynomials and their derivatives.
|
|
39
|
+
|
|
40
|
+
Generates polynomials and their derivatives up to 3rd order, for approximation
|
|
38
41
|
in 1d space, based on N input pairs of position and value. Geometrical parameters
|
|
39
42
|
can be numeric or symbolic.
|
|
40
43
|
|
|
@@ -165,8 +168,7 @@ def gen_Lagrange_1d(
|
|
|
165
168
|
def approx_Lagrange_1d(
|
|
166
169
|
points: Iterable, values: Iterable, lambdify: bool = False
|
|
167
170
|
) -> Callable:
|
|
168
|
-
"""
|
|
169
|
-
Returns a callable that maps from 'source' to 'target' in 1d.
|
|
171
|
+
"""Return a callable that maps from 'source' to 'target' in 1d.
|
|
170
172
|
|
|
171
173
|
Parameters
|
|
172
174
|
----------
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Least squares and moving least squares approximation."""
|
|
2
|
+
|
|
1
3
|
from typing import Callable, Iterable
|
|
2
4
|
|
|
3
5
|
import numpy as np
|
|
@@ -18,8 +20,9 @@ def moving_least_squares(
|
|
|
18
20
|
w: Callable | None = None,
|
|
19
21
|
**kwargs,
|
|
20
22
|
) -> Callable:
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
+
"""Perform moving least squares approximation.
|
|
24
|
+
|
|
25
|
+
The usage is the same as for the
|
|
23
26
|
:func:`~sigmaepsilon.math.approx.ls.weighted_least_squares` function.
|
|
24
27
|
"""
|
|
25
28
|
dim = 1 if len(points.shape) == 1 else points.shape[1]
|
|
@@ -50,7 +53,8 @@ def least_squares(
|
|
|
50
53
|
deg: int = 1,
|
|
51
54
|
order: int = 2,
|
|
52
55
|
) -> Callable:
|
|
53
|
-
"""
|
|
56
|
+
r"""Fit a polynomial to the given points and values in the least-squares sense.
|
|
57
|
+
|
|
54
58
|
Given :math:`N` points located at :math:`\mathbf{x}_i` in :math:`\mathbb{R}^d`
|
|
55
59
|
where :math:`i \in [1 \dots N]`. The returned fit function approximates the given
|
|
56
60
|
values :math:`f_i` at :math:`\mathbf{x}_i` in the least-squares sence with the
|
|
@@ -95,8 +99,7 @@ def weighted_least_squares(
|
|
|
95
99
|
order: int = 2,
|
|
96
100
|
w: Callable | None = None,
|
|
97
101
|
) -> Callable:
|
|
98
|
-
"""
|
|
99
|
-
Returns a Callable that can be used to approximate over datasets.
|
|
102
|
+
"""Return a Callable that can be used to approximate over datasets.
|
|
100
103
|
|
|
101
104
|
Parameters
|
|
102
105
|
----------
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""High performance, object oriented moving least squares approximation."""
|
|
2
|
+
|
|
1
3
|
from numbers import Number
|
|
2
4
|
|
|
3
5
|
from numpy import ndarray
|
|
@@ -33,9 +35,9 @@ def _approximate_nd(
|
|
|
33
35
|
|
|
34
36
|
|
|
35
37
|
class MLSApproximator:
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
"""Object oriented, high performance implementation of moving least squares.
|
|
39
|
+
|
|
40
|
+
This implementation is less flexible than the others,
|
|
39
41
|
but performes well for extremely large datasets too. If you want to experiment
|
|
40
42
|
with the hyperparameters of the MLS as a method, it is suggested to use the other
|
|
41
43
|
solutions offered by the library.
|
|
@@ -130,32 +132,28 @@ class MLSApproximator:
|
|
|
130
132
|
|
|
131
133
|
@property
|
|
132
134
|
def neighbours(self) -> ndarray | None:
|
|
133
|
-
"""
|
|
134
|
-
|
|
135
|
-
calculated yet, it returns None.
|
|
135
|
+
"""Return the neighbours of the target points.
|
|
136
|
+
|
|
137
|
+
If the neighbours are not calculated yet, it returns None.
|
|
136
138
|
"""
|
|
137
139
|
return self._neighbours
|
|
138
140
|
|
|
139
141
|
@neighbours.setter
|
|
140
142
|
def neighbours(self, val: ndarray) -> None:
|
|
141
|
-
"""
|
|
142
|
-
Sets the neighbours of the target points.
|
|
143
|
-
"""
|
|
143
|
+
"""Set the neighbours of the target points."""
|
|
144
144
|
self._neighbours = val
|
|
145
145
|
|
|
146
146
|
@property
|
|
147
147
|
def factors(self) -> ndarray | None:
|
|
148
|
-
"""
|
|
149
|
-
|
|
150
|
-
calculated yet, it returns None.
|
|
148
|
+
"""Return the factors of the target points.
|
|
149
|
+
|
|
150
|
+
If the factors are not calculated yet, it returns None.
|
|
151
151
|
"""
|
|
152
152
|
return self._factors
|
|
153
153
|
|
|
154
154
|
@factors.setter
|
|
155
155
|
def factors(self, val: ndarray) -> None:
|
|
156
|
-
"""
|
|
157
|
-
Sets the factors of the target points.
|
|
158
|
-
"""
|
|
156
|
+
"""Set the factors of the target points."""
|
|
159
157
|
self._factors = val
|
|
160
158
|
|
|
161
159
|
def _calc_factors_and_neighbours(self, X_S: ndarray, X_T: ndarray) -> None:
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Decorators shared across the package."""
|
|
2
|
+
|
|
1
3
|
from typing import Callable, Any
|
|
2
4
|
import numpy as np
|
|
3
5
|
|
|
@@ -10,8 +12,9 @@ def _squeeze_if_array(arr: Any) -> Any:
|
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
def squeeze(default: bool = True) -> Callable:
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
+
"""Return a decorator that squeezes outputs of a function.
|
|
16
|
+
|
|
17
|
+
Applies when
|
|
15
18
|
* the result is a NumPy array
|
|
16
19
|
* the result is a tuple of NumPy arrays
|
|
17
20
|
* the result is a dictionary of NumPy arrays as values
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Utilities for downloading test data used by the library."""
|
|
2
|
+
|
|
1
3
|
import numpy as np
|
|
2
4
|
|
|
3
5
|
from sigmaepsilon.core.downloads import download_file, delete_downloads
|
|
@@ -10,8 +12,7 @@ __all__ = [
|
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
def download_mls_testdata() -> np.ndarray:
|
|
13
|
-
"""
|
|
14
|
-
Downloads the data of a cloud of points.
|
|
15
|
+
"""Download the data of a cloud of points.
|
|
15
16
|
|
|
16
17
|
Returns
|
|
17
18
|
-------
|
{sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/function/function.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Base class for symbolic and numerical functions."""
|
|
2
|
+
|
|
1
3
|
from typing import TypeVar, Callable, Iterable
|
|
2
4
|
from collections import OrderedDict
|
|
3
5
|
import warnings
|
|
@@ -19,8 +21,9 @@ FunctionLike = TypeVar("FunctionLike", str, Callable, Expr)
|
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
class Function(MetaFunction):
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
+
"""Base class for all kinds of functions.
|
|
25
|
+
|
|
26
|
+
It can be used to represent
|
|
24
27
|
symbolic and numerical functions. The class is designed to be as
|
|
25
28
|
flexible as possible, so it can be used in a wide range of applications.
|
|
26
29
|
|
|
@@ -182,6 +185,7 @@ class Function(MetaFunction):
|
|
|
182
185
|
variables: Iterable | None = None,
|
|
183
186
|
**kwargs
|
|
184
187
|
):
|
|
188
|
+
"""Update the instance in place with new function definitions."""
|
|
185
189
|
self.from_str = None
|
|
186
190
|
|
|
187
191
|
if f0 is not None:
|
|
@@ -202,8 +206,8 @@ class Function(MetaFunction):
|
|
|
202
206
|
|
|
203
207
|
@property
|
|
204
208
|
def symbolic(self) -> bool:
|
|
205
|
-
"""
|
|
206
|
-
|
|
209
|
+
"""Return `True` if the function is a fit subject of symbolic manipulation.
|
|
210
|
+
|
|
207
211
|
This is probably only true if the object was created from a string or
|
|
208
212
|
`sympy` expression.
|
|
209
213
|
"""
|
|
@@ -217,9 +221,7 @@ class Function(MetaFunction):
|
|
|
217
221
|
|
|
218
222
|
@property
|
|
219
223
|
def linear(self) -> bool:
|
|
220
|
-
"""
|
|
221
|
-
Returns True if the function is at most linear in all of its variables.
|
|
222
|
-
"""
|
|
224
|
+
"""Return True if the function is at most linear in all of its variables."""
|
|
223
225
|
warnings.warn(
|
|
224
226
|
"The property `linear` is deprecated and will be removed in a future version. "
|
|
225
227
|
"Use `is_linear` instead.",
|
|
@@ -230,9 +232,7 @@ class Function(MetaFunction):
|
|
|
230
232
|
|
|
231
233
|
@property
|
|
232
234
|
def is_linear(self) -> bool:
|
|
233
|
-
"""
|
|
234
|
-
Returns `True` if the function is at most linear in all of its variables.
|
|
235
|
-
"""
|
|
235
|
+
"""Return `True` if the function is at most linear in all of its variables."""
|
|
236
236
|
if self.is_symbolic:
|
|
237
237
|
return all(
|
|
238
238
|
np.array([degree(self.expr, v) for v in self.variables], dtype=int) <= 1
|
|
@@ -242,25 +242,22 @@ class Function(MetaFunction):
|
|
|
242
242
|
|
|
243
243
|
@property
|
|
244
244
|
def is_symbolic(self) -> bool:
|
|
245
|
-
"""
|
|
246
|
-
|
|
245
|
+
"""Return `True` if the function is a fit subject of symbolic manipulation.
|
|
246
|
+
|
|
247
247
|
This is probably only true if the object was created from a string or
|
|
248
248
|
`SymPy` expression.
|
|
249
249
|
"""
|
|
250
250
|
return self.expr is not None
|
|
251
251
|
|
|
252
252
|
def simplify(self) -> None:
|
|
253
|
-
"""
|
|
254
|
-
Simplifies the symbolic expression of the instance.
|
|
255
|
-
"""
|
|
253
|
+
"""Simplify the symbolic expression of the instance."""
|
|
256
254
|
if self.is_symbolic:
|
|
257
255
|
self.expr = self.expr.simplify()
|
|
258
256
|
else:
|
|
259
257
|
raise TypeError("This is exclusive to symbolic functions.")
|
|
260
258
|
|
|
261
259
|
def linear_coefficients(self, normalize: bool = False) -> dict | None:
|
|
262
|
-
"""
|
|
263
|
-
Returns the linear coeffiecients, if the function is symbolic and linear.
|
|
260
|
+
"""Return the linear coeffiecients, if the function is symbolic and linear.
|
|
264
261
|
|
|
265
262
|
Parameters
|
|
266
263
|
----------
|
|
@@ -284,8 +281,7 @@ class Function(MetaFunction):
|
|
|
284
281
|
return None
|
|
285
282
|
|
|
286
283
|
def coefficients(self, normalize: bool = False) -> dict | None:
|
|
287
|
-
"""
|
|
288
|
-
Returns the coefficients if the function is symbolic.
|
|
284
|
+
"""Return the coefficients if the function is symbolic.
|
|
289
285
|
|
|
290
286
|
Parameters
|
|
291
287
|
----------
|
|
@@ -322,8 +318,8 @@ class Function(MetaFunction):
|
|
|
322
318
|
return None
|
|
323
319
|
|
|
324
320
|
def to_latex(self) -> str:
|
|
325
|
-
"""
|
|
326
|
-
|
|
321
|
+
"""Return the LaTeX code of the symbolic expression of the instance.
|
|
322
|
+
|
|
327
323
|
Only for symbolic functions.
|
|
328
324
|
|
|
329
325
|
Examples
|
{sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/function/functions.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Standard benchmark test functions for optimizers."""
|
|
2
|
+
|
|
1
3
|
import sympy as sy
|
|
2
4
|
|
|
3
5
|
from .testfunction import TestMinFunction2D
|
|
@@ -14,8 +16,7 @@ __all__ = [
|
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
def Rosenbrock(a: float = 1, b: float = 100) -> TestMinFunction2D:
|
|
17
|
-
"""
|
|
18
|
-
Implements the Rosenbrock function, aka. Banana function.
|
|
19
|
+
"""Implement the Rosenbrock function, aka. Banana function.
|
|
19
20
|
|
|
20
21
|
:math:`f(x, y) = (a - x)^2 + b (y - x^2)^2`
|
|
21
22
|
|
|
@@ -29,8 +30,7 @@ def Rosenbrock(a: float = 1, b: float = 100) -> TestMinFunction2D:
|
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
def Himmelblau() -> TestMinFunction2D:
|
|
32
|
-
"""
|
|
33
|
-
Creates the Himmelblau's function object.
|
|
33
|
+
"""Create the Himmelblau's function object.
|
|
34
34
|
|
|
35
35
|
:math:`f(x,y) = (x^2 + y - 11)^2 + (x + y^2 - 7)^2`
|
|
36
36
|
|
|
@@ -50,8 +50,7 @@ def Himmelblau() -> TestMinFunction2D:
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
def GoldsteinPrice() -> TestMinFunction2D:
|
|
53
|
-
"""
|
|
54
|
-
Creates the Goldstein-Price function object.
|
|
53
|
+
r"""Create the Goldstein-Price function object.
|
|
55
54
|
|
|
56
55
|
.. math::
|
|
57
56
|
:nowrap:
|
|
@@ -72,8 +71,7 @@ def GoldsteinPrice() -> TestMinFunction2D:
|
|
|
72
71
|
|
|
73
72
|
|
|
74
73
|
def Beale() -> TestMinFunction2D:
|
|
75
|
-
"""
|
|
76
|
-
Creates the Beale function object.
|
|
74
|
+
r"""Create the Beale function object.
|
|
77
75
|
|
|
78
76
|
.. math::
|
|
79
77
|
:nowrap:
|
|
@@ -93,8 +91,7 @@ def Beale() -> TestMinFunction2D:
|
|
|
93
91
|
|
|
94
92
|
|
|
95
93
|
def Matyas() -> TestMinFunction2D:
|
|
96
|
-
"""
|
|
97
|
-
Creates the Matyas function object.
|
|
94
|
+
"""Create the Matyas function object.
|
|
98
95
|
|
|
99
96
|
:math:`f(x, y) = 0.26 (x^2 + y^2) - 0.48 x y`
|
|
100
97
|
|
{sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.4.0}/src/sigmaepsilon/math/function/metafunction.py
RENAMED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Metaclass and base class shared by symbolic and numerical functions."""
|
|
2
|
+
|
|
1
3
|
from sympy import Expr
|
|
2
4
|
|
|
3
5
|
from sigmaepsilon.core.abstract import ABCMeta_Weak
|
|
@@ -5,11 +7,10 @@ from .symutils import symbolize
|
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
class ABCMeta_MetaFunction(ABCMeta_Weak):
|
|
8
|
-
"""
|
|
9
|
-
Metaclass for defining ABCs for algebraic structures.
|
|
10
|
-
"""
|
|
10
|
+
"""Metaclass for defining ABCs for algebraic structures."""
|
|
11
11
|
|
|
12
12
|
def __new__(metaclass, name, bases, namespace, /, **kwargs):
|
|
13
|
+
"""Create a new class, promoting `value`/`gradient`/`Hessian` to `f`/`g`/`G`."""
|
|
13
14
|
cls = super().__new__(metaclass, name, bases, namespace, **kwargs)
|
|
14
15
|
if "value" in namespace:
|
|
15
16
|
cls.f = namespace["value"]
|
|
@@ -24,14 +25,21 @@ class ABCMeta_MetaFunction(ABCMeta_Weak):
|
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class MetaFunction(metaclass=ABCMeta_MetaFunction):
|
|
28
|
+
"""Base class providing the `f`/`g`/`G` interface for functions.
|
|
29
|
+
|
|
30
|
+
Subclasses that define `value`, `gradient` and/or `Hessian` methods
|
|
31
|
+
automatically get those promoted to `f`, `g` and `G` respectively, via
|
|
32
|
+
:class:`ABCMeta_MetaFunction`.
|
|
33
|
+
"""
|
|
34
|
+
|
|
27
35
|
__slots__ = ("f0", "f1", "f2", "dimension", "domain", "expr", "variables", "vmap")
|
|
28
36
|
|
|
29
37
|
def __call__(self, *args, **kwargs):
|
|
38
|
+
"""Return the function value, equivalent to calling :meth:`f`."""
|
|
30
39
|
return self.f(*args, **kwargs)
|
|
31
40
|
|
|
32
41
|
def f(self, *args, **kwargs):
|
|
33
|
-
"""
|
|
34
|
-
Returns the function value.
|
|
42
|
+
"""Return the function value.
|
|
35
43
|
|
|
36
44
|
For this operation the object must have an implementation of
|
|
37
45
|
|
|
@@ -42,8 +50,7 @@ class MetaFunction(metaclass=ABCMeta_MetaFunction):
|
|
|
42
50
|
return self.f0(*args, **kwargs)
|
|
43
51
|
|
|
44
52
|
def g(self, *args, **kwargs):
|
|
45
|
-
"""
|
|
46
|
-
Returns the gradient vector if available.
|
|
53
|
+
"""Return the gradient vector if available.
|
|
47
54
|
|
|
48
55
|
For this operation the object must have an implementation of
|
|
49
56
|
|
|
@@ -54,8 +61,7 @@ class MetaFunction(metaclass=ABCMeta_MetaFunction):
|
|
|
54
61
|
return self.f1(*args, **kwargs)
|
|
55
62
|
|
|
56
63
|
def G(self, *args, **kwargs):
|
|
57
|
-
"""
|
|
58
|
-
Returns the Hessian matrix if available.
|
|
64
|
+
"""Return the Hessian matrix if available.
|
|
59
65
|
|
|
60
66
|
For this operation the object must have an implementation of
|
|
61
67
|
|