sigmaepsilon.math 2.2.2__tar.gz → 2.3.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.
Files changed (56) hide show
  1. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/PKG-INFO +1 -1
  2. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/pyproject.toml +1 -1
  3. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/optimize/bga.py +6 -4
  4. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/optimize/ga.py +4 -5
  5. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/optimize/lp.py +65 -11
  6. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/LICENSE +0 -0
  7. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/README.md +0 -0
  8. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/__init__.py +0 -0
  9. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/approx/__init__.py +0 -0
  10. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/approx/functions.py +0 -0
  11. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/approx/lagrange.py +0 -0
  12. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/approx/ls.py +0 -0
  13. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/approx/ls_approx.py +0 -0
  14. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/approx/ls_poly.py +0 -0
  15. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/approx/ls_preproc.py +0 -0
  16. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/approx/mls.py +0 -0
  17. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/arraysetops.py +0 -0
  18. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/decorate.py +0 -0
  19. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/downloads.py +0 -0
  20. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/function/__init__.py +0 -0
  21. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/function/function.py +0 -0
  22. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/function/functions.py +0 -0
  23. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/function/metafunction.py +0 -0
  24. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/function/relation.py +0 -0
  25. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/function/symutils.py +0 -0
  26. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/function/testfunction.py +0 -0
  27. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/function/utils.py +0 -0
  28. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/graph/__init__.py +0 -0
  29. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/graph/graph.py +0 -0
  30. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/graph/utils.py +0 -0
  31. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/hist.py +0 -0
  32. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/knn.py +0 -0
  33. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/__init__.py +0 -0
  34. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/abstract.py +0 -0
  35. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/exceptions.py +0 -0
  36. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/frame.py +0 -0
  37. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/imap.py +0 -0
  38. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/logical.py +0 -0
  39. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/meta.py +0 -0
  40. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/solve.py +0 -0
  41. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/sparse/__init__.py +0 -0
  42. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/sparse/csr.py +0 -0
  43. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/sparse/jaggedarray.py +0 -0
  44. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/sparse/utils.py +0 -0
  45. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/tensor.py +0 -0
  46. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/testing.py +0 -0
  47. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/tr.py +0 -0
  48. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/utils.py +0 -0
  49. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/linalg/vector.py +0 -0
  50. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/logical.py +0 -0
  51. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/mathtypes.py +0 -0
  52. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/metautils.py +0 -0
  53. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/numint.py +0 -0
  54. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/optimize/__init__.py +0 -0
  55. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/optimize/state.py +0 -0
  56. {sigmaepsilon_math-2.2.2 → sigmaepsilon_math-2.3.0}/src/sigmaepsilon/math/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sigmaepsilon.math
3
- Version: 2.2.2
3
+ Version: 2.3.0
4
4
  Summary: A Python Library for Applied Mathematics in Physical Sciences.
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "sigmaepsilon.math"
7
- version = "2.2.2"
7
+ version = "2.3.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",
@@ -45,9 +45,9 @@ class BinaryGeneticAlgorithm(GeneticAlgorithm):
45
45
  The minimum number of iterations. Default is 100.
46
46
  elitism: float or int, Optional
47
47
  Determines the portion of the population designated as elite, which automatically survives
48
- to the next generation. If less than or equal to 1, it specifies a fraction of the population.
49
- If greater than 1, it indicates the exact number of individuals to be selected as elite.
50
- The default value of 1 assures that the reigning champion is always preserved. To turn this off,
48
+ to the next generation. If less than or equal to 1, it specifies a fraction of the population.
49
+ If greater than 1, it indicates the exact number of individuals to be selected as elite.
50
+ The default value of 1 assures that the reigning champion is always preserved. To turn this off,
51
51
  det the value to None. Default is 1.
52
52
  ftol: float, Optional
53
53
  Torelance for floating point operations. Default is 1e-12.
@@ -165,7 +165,9 @@ class BinaryGeneticAlgorithm(GeneticAlgorithm):
165
165
  p = np.random.rand(self.dim * self.length)
166
166
  return np.where(p > self.p_m, child, 1 - child)
167
167
 
168
- def select(self, genotypes: ndarray | None = None, phenotypes: ndarray | None = None) -> ndarray:
168
+ def select(
169
+ self, genotypes: ndarray | None = None, phenotypes: ndarray | None = None
170
+ ) -> ndarray:
169
171
  """
170
172
  Organizes a tournament and returns the genotypes of the winners.
171
173
 
@@ -74,6 +74,7 @@ class Genom(BaseModel):
74
74
  @property
75
75
  def fittness(self) -> float: # pragma: no cover
76
76
  import warnings
77
+
77
78
  warnings.warn(
78
79
  "'fittness' was a typo and is deprecated; it will be removed in a future version. Use 'fitness' instead.",
79
80
  DeprecationWarning,
@@ -276,7 +277,6 @@ class GeneticAlgorithm:
276
277
  self._phenotypes = self.decode(genotypes)
277
278
  return self._phenotypes
278
279
 
279
-
280
280
  @property
281
281
  def fitness(self) -> ndarray:
282
282
  """
@@ -290,8 +290,9 @@ class GeneticAlgorithm:
290
290
  return self._fitness
291
291
 
292
292
  @property
293
- def fittness(self) -> ndarray: # pragma: no cover
293
+ def fittness(self) -> ndarray: # pragma: no cover
294
294
  import warnings
295
+
295
296
  warnings.warn(
296
297
  "'fittness' was a typo and is deprecated; it will be removed in a future version. Use 'fitness' instead.",
297
298
  DeprecationWarning,
@@ -655,9 +656,7 @@ class GeneticAlgorithm:
655
656
  ...
656
657
 
657
658
  @abstractmethod
658
- def select(
659
- self, genotypes: ndarray, phenotypes: ndarray
660
- ) -> ndarray:
659
+ def select(self, genotypes: ndarray, phenotypes: ndarray) -> ndarray:
661
660
  """
662
661
  Ought to implement some kind of selection mechanism, e.g., a roulette wheel,
663
662
  tournament, or other. Both `genotypes` and `phenotypes` must be provided.
@@ -4,6 +4,7 @@ import numpy as np
4
4
  from numpy import ndarray
5
5
  from sympy import Symbol
6
6
  from scipy.optimize import linprog, OptimizeResult
7
+ from scipy import sparse
7
8
 
8
9
  from ..function import Function, InEquality, Equality
9
10
  from ..function.relation import Relations, Relation
@@ -36,6 +37,10 @@ class LinearProgrammingProblem:
36
37
  See the `bounds` parameter in `scipy.optimize.linprog` for more details.
37
38
  integrality : Iterable[int] | int, Optional
38
39
  See the `integrality` parameter in `scipy.optimize.linprog` for more details.
40
+ sparsify : bool, Optional
41
+ If `True`, the constraint matrices will be converted to sparse format before passing
42
+ them to the solver. This can improve performance for large problems with many zero
43
+ coefficients. Default is `True`.
39
44
 
40
45
  See Also
41
46
  --------
@@ -117,6 +122,7 @@ class LinearProgrammingProblem:
117
122
  "_variables",
118
123
  "bounds",
119
124
  "integrality",
125
+ "_sparsify",
120
126
  ]
121
127
 
122
128
  def __init__(
@@ -127,6 +133,7 @@ class LinearProgrammingProblem:
127
133
  variables: Sequence[Symbol] | None = None,
128
134
  bounds: BoundsLike = (0, None),
129
135
  integrality: Iterable[int] | int = None,
136
+ sparsify: bool = True,
130
137
  ):
131
138
  super().__init__()
132
139
  self.obj = None
@@ -134,6 +141,7 @@ class LinearProgrammingProblem:
134
141
  self._variables = []
135
142
  self.bounds = bounds
136
143
  self.integrality = integrality
144
+ self._sparsify = sparsify
137
145
 
138
146
  _variables = []
139
147
 
@@ -197,36 +205,82 @@ class LinearProgrammingProblem:
197
205
  SMALLNUM = np.nextafter(0, 1)
198
206
 
199
207
  if n_eq > 0:
200
- A_eq = np.zeros((n_eq, n_x))
208
+ if self._sparsify:
209
+ A_eq_data = []
210
+ A_eq_rows = []
211
+ A_eq_cols = []
212
+ else:
213
+ A_eq = np.zeros((n_eq, n_x))
214
+
201
215
  b_eq = np.zeros((n_eq,))
202
216
  equalities: Iterable[Equality] = filter(
203
217
  lambda c: isinstance(c, Equality), self.constraints
204
218
  )
205
219
  for i, eq in enumerate(equalities):
206
220
  coeffs = eq.linear_coefficients(normalize=True)
207
- A_eq[i] = [coeffs[x_] for x_ in self.variables]
221
+ if self._sparsify:
222
+ for j, x_ in enumerate(self.variables):
223
+ val = coeffs[x_]
224
+ if val != 0:
225
+ A_eq_data.append(val)
226
+ A_eq_rows.append(i)
227
+ A_eq_cols.append(j)
228
+ else:
229
+ A_eq[i] = [coeffs[x_] for x_ in self.variables]
230
+
208
231
  b_eq[i] = -eq(x_zero)
209
232
 
233
+ if self._sparsify:
234
+ A_eq = sparse.csr_matrix(
235
+ (A_eq_data, (A_eq_rows, A_eq_cols)), shape=(n_eq, n_x), dtype=float
236
+ )
237
+ del A_eq_data, A_eq_rows, A_eq_cols
238
+
210
239
  if n_ieq > 0:
211
- A_ub = np.zeros((n_ieq, n_x))
240
+ if self._sparsify:
241
+ A_ub_data = []
242
+ A_ub_rows = []
243
+ A_ub_cols = []
244
+ else:
245
+ A_ub = np.zeros((n_ieq, n_x))
246
+
212
247
  b_ub = np.zeros((n_ieq,))
213
248
  inequalities: Iterable[InEquality] = filter(
214
249
  lambda c: isinstance(c, InEquality), self.constraints
215
250
  )
216
251
  for i, ieq in enumerate(inequalities):
217
252
  coeffs = ieq.linear_coefficients(normalize=True)
218
- A_ub[i] = [coeffs[x_] for x_ in self.variables]
219
- b_ub[i] = -ieq(x_zero)
220
253
 
254
+ A_ub_multiplier = 1
255
+ b_ub_multiplier = 1
256
+ b_ub_adjustment = 0.0
221
257
  if ieq.op == Relations.ge:
222
- A_ub[i] *= -1
223
- b_ub[i] *= -1
258
+ A_ub_multiplier = -1
259
+ b_ub_multiplier = -1
224
260
  elif ieq.op == Relations.gt:
225
- A_ub[i] *= -1
226
- b_ub[i] *= -1
227
- b_ub[i] -= SMALLNUM
261
+ A_ub_multiplier = -1
262
+ b_ub_multiplier = -1
263
+ b_ub_adjustment = -SMALLNUM
228
264
  elif ieq.op == Relations.lt:
229
- b_ub[i] -= SMALLNUM
265
+ b_ub_adjustment = -SMALLNUM
266
+
267
+ if self._sparsify:
268
+ for j, x_ in enumerate(self.variables):
269
+ val = coeffs[x_] * A_ub_multiplier
270
+ if val != 0:
271
+ A_ub_data.append(val)
272
+ A_ub_rows.append(i)
273
+ A_ub_cols.append(j)
274
+ else:
275
+ A_ub[i] = [coeffs[x_] * A_ub_multiplier for x_ in self.variables]
276
+
277
+ b_ub[i] = -ieq(x_zero) * b_ub_multiplier + b_ub_adjustment
278
+
279
+ if self._sparsify:
280
+ A_ub = sparse.csr_matrix(
281
+ (A_ub_data, (A_ub_rows, A_ub_cols)), shape=(n_ieq, n_x), dtype=float
282
+ )
283
+ del A_ub_data, A_ub_rows, A_ub_cols
230
284
 
231
285
  integrality = self.integrality
232
286
  if integrality is None: