optimtool 2.8.3__tar.gz → 2.9.1__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 (38) hide show
  1. {optimtool-2.8.3 → optimtool-2.9.1}/PKG-INFO +14 -4
  2. {optimtool-2.8.3 → optimtool-2.9.1}/README.md +13 -3
  3. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/__init__.py +1 -1
  4. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/_drive.py +11 -18
  5. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/_search.py +17 -34
  6. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/_utils.py +3 -5
  7. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/_version.py +1 -1
  8. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/constrain/equal.py +6 -4
  9. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/constrain/mixequal.py +14 -9
  10. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/constrain/unequal.py +10 -6
  11. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/example/Lasso.py +10 -7
  12. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/hybrid/approt.py +2 -1
  13. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/hybrid/fista.py +7 -4
  14. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/hybrid/nesterov.py +4 -2
  15. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/unconstrain/gradient_descent.py +9 -6
  16. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/unconstrain/newton.py +11 -8
  17. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/unconstrain/newton_quasi.py +12 -9
  18. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/unconstrain/nonlinear_least_square.py +6 -4
  19. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/unconstrain/trust_region.py +1 -1
  20. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool.egg-info/PKG-INFO +14 -4
  21. {optimtool-2.8.3 → optimtool-2.9.1}/setup.py +1 -1
  22. {optimtool-2.8.3 → optimtool-2.9.1}/LICENSE +0 -0
  23. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/_convert.py +0 -0
  24. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/_kernel.py +0 -0
  25. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/_proxim.py +0 -0
  26. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/_typing.py +0 -0
  27. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/base.py +0 -0
  28. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/constrain/__init__.py +0 -0
  29. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/example/WanYuan.py +0 -0
  30. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/example/__init__.py +0 -0
  31. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/hybrid/__init__.py +0 -0
  32. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool/unconstrain/__init__.py +0 -0
  33. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool.egg-info/SOURCES.txt +0 -0
  34. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool.egg-info/dependency_links.txt +0 -0
  35. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool.egg-info/not-zip-safe +0 -0
  36. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool.egg-info/requires.txt +0 -0
  37. {optimtool-2.8.3 → optimtool-2.9.1}/optimtool.egg-info/top_level.txt +0 -0
  38. {optimtool-2.8.3 → optimtool-2.9.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: optimtool
3
- Version: 2.8.3
3
+ Version: 2.9.1
4
4
  Summary: The fundamental package for scientific research in optimization.
5
5
  Home-page: https://github.com/linjing-lab/optimtool
6
6
  Download-URL: https://github.com/linjing-lab/optimtool/tags
@@ -52,12 +52,22 @@ License-File: LICENSE
52
52
 
53
53
  ## 项目介绍
54
54
 
55
-   optimtool采用了北京大学出版的《最优化:建模、算法与理论》这本书中的部分理论方法框架,运用了`Numpy`包高效处理数组间运算等的特性,巧妙地应用了`Sympy`内部支持的jacobian等方法,并结合Python内置函数dict与zip实现了Sympy矩阵到Numpy矩阵的转换,最终设计的用在最优化科学研究的Python工具包。
55
+   optimtool采用了北京大学出版的《最优化:建模、算法与理论》这本书中的部分理论方法框架,运用了`Numpy`包高效处理数组间运算等的特性,巧妙地应用了`Sympy`内部支持的jacobian等方法,并结合sp.lambdify实现了高效地数值矩阵的运算,最终设计的用在最优化科学研究的Python工具包。
56
56
 
57
57
  如果你在研究中使用 **optimtool**,欢迎引用它在你的参考资料中(按照下面的格式)。
58
58
 
59
- ```text
60
- 林景. optimtool: The fundamental package for scientific research in optimization. 2021. https://pypi.org/project/optimtool/.
59
+ ```bibtex
60
+ @software{Lin2021optimtool,
61
+ author = {Lin, Jing},
62
+ title = {optimtool: The fundamental package for scientific research in optimization.},
63
+ year = {2021},
64
+ version = {2.9.1},
65
+ publisher = {PyPI},
66
+ organization = {linjing-lab},
67
+ url = {https://pypi.org/project/optimtool/},
68
+ license = {MIT},
69
+ note = {Source code available at \url{https://github.com/linjing-lab/optimtool}},
70
+ }
61
71
  ```
62
72
 
63
73
  下载最新版:
@@ -23,12 +23,22 @@
23
23
 
24
24
  ## 项目介绍
25
25
 
26
-   optimtool采用了北京大学出版的《最优化:建模、算法与理论》这本书中的部分理论方法框架,运用了`Numpy`包高效处理数组间运算等的特性,巧妙地应用了`Sympy`内部支持的jacobian等方法,并结合Python内置函数dict与zip实现了Sympy矩阵到Numpy矩阵的转换,最终设计的用在最优化科学研究的Python工具包。
26
+   optimtool采用了北京大学出版的《最优化:建模、算法与理论》这本书中的部分理论方法框架,运用了`Numpy`包高效处理数组间运算等的特性,巧妙地应用了`Sympy`内部支持的jacobian等方法,并结合sp.lambdify实现了高效地数值矩阵的运算,最终设计的用在最优化科学研究的Python工具包。
27
27
 
28
28
  如果你在研究中使用 **optimtool**,欢迎引用它在你的参考资料中(按照下面的格式)。
29
29
 
30
- ```text
31
- 林景. optimtool: The fundamental package for scientific research in optimization. 2021. https://pypi.org/project/optimtool/.
30
+ ```bibtex
31
+ @software{Lin2021optimtool,
32
+ author = {Lin, Jing},
33
+ title = {optimtool: The fundamental package for scientific research in optimization.},
34
+ year = {2021},
35
+ version = {2.9.1},
36
+ publisher = {PyPI},
37
+ organization = {linjing-lab},
38
+ url = {https://pypi.org/project/optimtool/},
39
+ license = {MIT},
40
+ note = {Source code available at \url{https://github.com/linjing-lab/optimtool}},
41
+ }
32
42
  ```
33
43
 
34
44
  下载最新版:
@@ -32,4 +32,4 @@ from .base import MATPLOTLIB_VERSION
32
32
  from ._version import __version__
33
33
 
34
34
  if sys.version_info < (3, 7, 0):
35
- raise OSError(f'optimtool-2.8.2 requires Python >=3.7, but yours is {sys.version}')
35
+ raise OSError(f'optimtool-2.9.1 requires Python >=3.7, but yours is {sys.version}')
@@ -26,16 +26,14 @@ def Q_k(eta: float,
26
26
  assert k >= 0
27
27
  return 1 if k == 0 else eta * Q_k(eta, k-1) + 1
28
28
 
29
- def C_k(funcs: SympyMutableDenseMatrix,
30
- args: SympyMutableDenseMatrix,
29
+ def C_k(funcs_num,
31
30
  point: List[IterPointType],
32
31
  eta: float,
33
32
  k: int) -> DataType:
34
33
  assert k >= 0
35
- funcs_num = sp.lambdify(args, funcs, modules='numpy')
36
34
  temp0 = funcs_num(*point[0])
37
35
  tempk = funcs_num(*point[k])
38
- return temp0 if k == 0 else (1 / (Q_k(eta, k))) * (eta * Q_k(eta, k-1) * C_k(funcs, args, point, eta, k-1) + tempk)
36
+ return temp0 if k == 0 else (1 / (Q_k(eta, k))) * (eta * Q_k(eta, k-1) * C_k(funcs_num, point, eta, k-1) + tempk)
39
37
  # return np.array(funcs.subs(dict(zip(args, point[0])))).astype(DataType) if k == 0 else (1 / (Q_k(eta, k))) * (eta * Q_k(eta, k-1) * C_k(funcs, args, point, eta, k-1) + np.array(funcs.subs(dict(zip(args, point[k])))).astype(DataType))
40
38
 
41
39
  def get_f_delta_gradient(resv: NDArray,
@@ -169,40 +167,35 @@ def cons_unequal_L(cons_unequal: SympyMutableDenseMatrix,
169
167
  sub = sub - (muk[i] / sigma)**2
170
168
  return sp.Matrix([sub])
171
169
 
172
- def v_k(cons_equal: SympyMutableDenseMatrix,
173
- cons_unequal: SympyMutableDenseMatrix,
174
- args: SympyMutableDenseMatrix,
170
+ def v_k(cons_equal_num,
171
+ cons_unequal_num,
172
+ len_cons: int,
175
173
  muk: NDArray,
176
174
  sigma: float,
177
175
  x_0: IterPointType) -> DataType:
178
176
  sub = 0.
179
177
  # reps = dict(zip(args, x_0))
180
- len_unequal = cons_unequal.shape[0]
181
- cons_unequal_num = sp.lambdify(args, cons_unequal, modules='numpy')
182
178
  consv_unequal = cons_unequal_num(*x_0)
183
179
  # consv_unequal = np.array(cons_unequal.subs(reps)).astype(DataType)
184
- if cons_equal is not None:
185
- cons_equal_num = sp.lambdify(args, cons_equal, modules='numpy')
180
+ if cons_equal_num is not None:
186
181
  consv_equal = cons_equal_num(*x_0)
187
182
  # consv_equal = np.array(cons_equal.subs(reps)).astype(DataType)
188
183
  sub += (consv_equal.T).dot(consv_equal)
189
- for i in range(len_unequal):
184
+ for i in range(len_cons):
190
185
  sub += (max(consv_unequal[i], - muk[i] / sigma))**2
191
186
  else:
192
- for i in range(len_unequal):
187
+ for i in range(len_cons):
193
188
  sub += (max(consv_unequal[i], - muk[i] / sigma))**2
194
189
  return np.sqrt(sub)
195
190
 
196
- def renew_mu_k(cons_unequal: SympyMutableDenseMatrix,
197
- args: SympyMutableDenseMatrix,
191
+ def renew_mu_k(cons_unequal_num,
192
+ len_cons: int,
198
193
  muk: NDArray,
199
194
  sigma: float,
200
195
  x_0: IterPointType) -> NDArray:
201
196
  # reps = dict(zip(args, x_0))
202
- len_unequal = cons_unequal.shape[0]
203
- cons_unequal_num = sp.lambdify(args, cons_unequal, modules='numpy')
204
197
  consv_unequal = cons_unequal_num(*x_0)
205
- for i in range(len_unequal):
198
+ for i in range(len_cons):
206
199
  muk[i] = max(muk[i] + sigma * consv_unequal[i], 0)
207
200
  return muk
208
201
 
@@ -23,17 +23,15 @@ from ._typing import List, NDArray, SympyMutableDenseMatrix, DataType, IterPoint
23
23
 
24
24
  __all__ = ["armijo", "goldstein", "wolfe", "Grippo", "ZhangHanger"]
25
25
 
26
- def armijo(funcs: SympyMutableDenseMatrix,
27
- res: SympyMutableDenseMatrix,
28
- args: SympyMutableDenseMatrix,
26
+ def armijo(funcs_num,
27
+ res_num,
29
28
  x_0: IterPointType,
30
29
  d: NDArray,
31
30
  gamma: float=0.5,
32
31
  c: float=0.1) -> float:
33
32
  '''
34
- :param funcs: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
35
- :param res: SympyMutableDenseMatrix, gradient function computed by .jacobian function.
36
- :param args: SympyMutableDenseMatrix, symbolic set with order in a list to construct `dict(zip(args, x_0))`.
33
+ :param funcs_num, objective function with `convert` process used for search alpha.
34
+ :param res_num:, gradient function computed by .jacobian function.
37
35
  :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
38
36
  :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
39
37
  :param gamma: float, factor used to adjust alpha with interval at (0, 1). default: float=0.5.
@@ -46,9 +44,7 @@ def armijo(funcs: SympyMutableDenseMatrix,
46
44
  assert c > 0
47
45
  assert c < 1
48
46
  alpha = 1
49
- funcs_num = sp.lambdify(args, funcs, modules='numpy')
50
47
  f0 = funcs_num(*x_0)
51
- res_num = sp.lambdify(args, res, modules='numpy')
52
48
  res0 = res_num(*x_0)
53
49
  # reps = dict(zip(args, x_0))
54
50
  # f0 = np.array(funcs.subs(reps)).astype(DataType)
@@ -63,9 +59,8 @@ def armijo(funcs: SympyMutableDenseMatrix,
63
59
  alpha *= gamma
64
60
  return alpha
65
61
 
66
- def goldstein(funcs: SympyMutableDenseMatrix,
67
- res: SympyMutableDenseMatrix,
68
- args: SympyMutableDenseMatrix,
62
+ def goldstein(funcs_num,
63
+ res_num,
69
64
  x_0: IterPointType,
70
65
  d: NDArray,
71
66
  c: float=0.2,
@@ -74,8 +69,8 @@ def goldstein(funcs: SympyMutableDenseMatrix,
74
69
  t: float=1.2,
75
70
  eps: float=1e-3) -> float:
76
71
  '''
77
- :param funcs: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
78
- :param res: SympyMutableDenseMatrix, gradient function computed by .jacobian function.
72
+ :param funcs_num: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
73
+ :param res_num: SympyMutableDenseMatrix, gradient function computed by .jacobian function.
79
74
  :param args: SympyMutableDenseMatrix, symbolic set with order in a list to construct `dict(zip(args, x_0))`.
80
75
  :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
81
76
  :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
@@ -94,9 +89,7 @@ def goldstein(funcs: SympyMutableDenseMatrix,
94
89
  assert t > 0
95
90
  assert eps > 0
96
91
  alpha = 1
97
- funcs_num = sp.lambdify(args, funcs, modules='numpy')
98
92
  f0 = funcs_num(*x_0)
99
- res_num = sp.lambdify(args, res, modules='numpy')
100
93
  res0 = res_num(*x_0)
101
94
  # reps = dict(zip(args, x_0))
102
95
  # f0 = np.array(funcs.subs(reps)).astype(DataType)
@@ -122,9 +115,8 @@ def goldstein(funcs: SympyMutableDenseMatrix,
122
115
  break
123
116
  return alpha
124
117
 
125
- def wolfe(funcs: SympyMutableDenseMatrix,
126
- res: SympyMutableDenseMatrix,
127
- args: SympyMutableDenseMatrix,
118
+ def wolfe(funcs_num,
119
+ res_num,
128
120
  x_0: IterPointType,
129
121
  d: NDArray,
130
122
  c1: float=0.3,
@@ -133,9 +125,8 @@ def wolfe(funcs: SympyMutableDenseMatrix,
133
125
  alphae: float=2.,
134
126
  eps: float=1e-3) -> float:
135
127
  '''
136
- :param funcs: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
137
- :param res: SympyMutableDenseMatrix, gradient function computed by .jacobian function.
138
- :param args: SympyMutableDenseMatrix, symbolic set with order in a list to construct `dict(zip(args, x_0))`.
128
+ :param funcs_num, objective function with `convert` process used for search alpha.
129
+ :param res_num, gradient function computed by .jacobian function.
139
130
  :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
140
131
  :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
141
132
  :param c1: float, first constant used to constrain alpha adjusted frequency with interval at (0, 1). default: float=0.3.
@@ -155,9 +146,7 @@ def wolfe(funcs: SympyMutableDenseMatrix,
155
146
  assert alphas < alphae
156
147
  assert eps > 0
157
148
  alpha = 1
158
- funcs_num = sp.lambdify(args, funcs, modules='numpy')
159
149
  f0 = funcs_num(*x_0)
160
- res_num = sp.lambdify(args, res, modules='numpy')
161
150
  res0 = res_num(*x_0)
162
151
  # reps = dict(zip(args, x_0))
163
152
  # f0 = np.array(funcs.subs(reps)).astype(DataType)
@@ -182,8 +171,7 @@ def wolfe(funcs: SympyMutableDenseMatrix,
182
171
  return alpha
183
172
 
184
173
  # coordinate with `barzilar_borwein`.
185
- def Grippo(funcs: SympyMutableDenseMatrix,
186
- args: SympyMutableDenseMatrix,
174
+ def Grippo(funcs_num,
187
175
  x_0: IterPointType,
188
176
  d: NDArray,
189
177
  k: int,
@@ -193,8 +181,7 @@ def Grippo(funcs: SympyMutableDenseMatrix,
193
181
  alpha: float,
194
182
  M: int) -> float:
195
183
  '''
196
- :param funcs: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
197
- :param args: SympyMutableDenseMatrix, symbolic set with order in a list to construct `dict(zip(args, x_0))`.
184
+ :param funcs_num, objective function with `convert` process used for search alpha.
198
185
  :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
199
186
  :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
200
187
  :param k: int, current number of iterative process in `barzilar_borwein` method.
@@ -211,7 +198,6 @@ def Grippo(funcs: SympyMutableDenseMatrix,
211
198
  assert c1 < 1
212
199
  assert beta > 0
213
200
  assert beta < 1
214
- funcs_num = sp.lambdify(args, funcs, modules='numpy')
215
201
  while 1:
216
202
  x = x_0 + (alpha*d)[0]
217
203
  f1 = funcs_num(*x)
@@ -227,8 +213,7 @@ def Grippo(funcs: SympyMutableDenseMatrix,
227
213
  alpha *= beta
228
214
  return alpha
229
215
 
230
- def ZhangHanger(funcs: SympyMutableDenseMatrix,
231
- args: SympyMutableDenseMatrix,
216
+ def ZhangHanger(funcs_num,
232
217
  x_0: IterPointType,
233
218
  d: NDArray,
234
219
  k: int,
@@ -238,8 +223,7 @@ def ZhangHanger(funcs: SympyMutableDenseMatrix,
238
223
  alpha: float,
239
224
  eta: float) -> float:
240
225
  '''
241
- :param funcs: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
242
- :param args: SympyMutableDenseMatrix, symbolic set with order in a list to construct `dict(zip(args, x_0))`.
226
+ :param funcs_num, objective function with `convert` process used for search alpha.
243
227
  :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
244
228
  :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
245
229
  :param k: int, current number of iterative process in `barzilar_borwein` method.
@@ -259,12 +243,11 @@ def ZhangHanger(funcs: SympyMutableDenseMatrix,
259
243
  assert beta > 0
260
244
  assert beta < 1
261
245
  from ._drive import C_k
262
- funcs_num = sp.lambdify(args, funcs, modules='numpy')
263
246
  while 1:
264
247
  x = x_0 + (alpha*d)[0]
265
248
  f1 = funcs_num(*x)
266
249
  # f1 = np.array(funcs.subs(dict(zip(args, x)))).astype(DataType)
267
- Ck = C_k(funcs, args, point, eta, k)
250
+ Ck = C_k(funcs_num, point, eta, k)
268
251
  if f1 <= Ck + c1 * alpha * (-d).dot(d.T):
269
252
  break
270
253
  else:
@@ -19,21 +19,19 @@
19
19
  # SOFTWARE.
20
20
 
21
21
  from .base import np, sp, plt
22
- from ._typing import DataType, Optional, SympyMutableDenseMatrix, List, IterPointType
22
+ from ._typing import DataType, Optional, List, IterPointType
23
23
 
24
24
  __all__ = ["get_value", "plot_iteration"]
25
25
 
26
- def get_value(funcs: SympyMutableDenseMatrix, args: SympyMutableDenseMatrix, x_0: IterPointType, mu: Optional[float]=None, proxim: Optional[str]=None) -> DataType:
26
+ def get_value(funcs_num, x_0: IterPointType, mu: Optional[float]=None, proxim: Optional[str]=None) -> DataType:
27
27
  '''
28
- :param funcs: SympyMutableDenseMatrix, objective function after `convert`.
29
- :param args: SympyMutableDenseMatrix, symbolic set after `convert` with order.
28
+ :param funcs_num, objective function after `convert`.
30
29
  :param x_0: IterPointType, numpy.ndarray or List[PointType] or Tuple[PointType].
31
30
  :param mu: float | None, parameters collaborate with the problems applied in `Lasso`. default=None.
32
31
  :param proxim: str | None, parameter indicate the type of proximity operators. default=None.
33
32
 
34
33
  :return: functional value with DataType.
35
34
  '''
36
- funcs_num = sp.lambdify(args, funcs, modules='numpy')
37
35
  funcsv = funcs_num(*x_0)
38
36
  # funcsv = np.array(funcs.subs(dict(zip(args, x_0)))).astype(DataType)
39
37
  if mu is not None:
@@ -18,4 +18,4 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
19
  # SOFTWARE.
20
20
 
21
- __version__ = '2.8.3'
21
+ __version__ = '2.9.1'
@@ -60,12 +60,13 @@ def penalty_quadratice(funcs: FuncArray,
60
60
  assert p > 1
61
61
  from .._kernel import kernel
62
62
  funcs, args, x_0, cons = f2m(funcs), a2m(args), p2t(x_0), f2m(cons)
63
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
63
64
  search, point, f = kernel(method), [], []
64
65
  sig = sp.symbols("sig")
65
66
  pen = funcs + (sig / 2) * cons.T * cons
66
67
  while 1:
67
68
  point.append(np.array(x_0))
68
- f.append(get_value(funcs, args, x_0))
69
+ f.append(get_value(funcs_num, x_0))
69
70
  if verbose:
70
71
  print("{}\t{}\t{}".format(x_0, f[-1], k))
71
72
  pe = pen.subs(sig, sigma)
@@ -74,7 +75,7 @@ def penalty_quadratice(funcs: FuncArray,
74
75
  sigma *= p
75
76
  if np.linalg.norm(x_0 - point[k - 1]) < epsilon:
76
77
  point.append(np.array(x_0))
77
- f.append(get_value(funcs, args, x_0))
78
+ f.append(get_value(funcs_num, x_0))
78
79
  if verbose:
79
80
  print("{}\t{}\t{}".format(x_0, f[-1], k))
80
81
  break
@@ -118,10 +119,11 @@ def lagrange_augmentede(funcs: FuncArray,
118
119
  from .._kernel import kernel
119
120
  search, f = kernel(method), []
120
121
  funcs, args, x_0, cons = f2m(funcs), a2m(args), p2t(x_0), f2m(cons)
122
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
121
123
  lamk = np.array([lamk for _ in range(cons.shape[0])]).reshape(cons.shape[0], 1)
122
124
  cons_num = sp.lambdify(args, cons, modules='numpy')
123
125
  while 1:
124
- f.append(get_value(funcs, args, x_0))
126
+ f.append(get_value(funcs_num, x_0))
125
127
  if verbose:
126
128
  print("{}\t{}\t{}".format(x_0, f[-1], k))
127
129
  L = sp.Matrix([funcs + (sigma / 2) * cons.T * cons + cons.T * lamk])
@@ -133,7 +135,7 @@ def lagrange_augmentede(funcs: FuncArray,
133
135
  k += 1
134
136
  sigma *= p
135
137
  if np.linalg.norm(consv) <= epsilon:
136
- f.append(get_value(funcs, args, x_0))
138
+ f.append(get_value(funcs_num, x_0))
137
139
  if verbose:
138
140
  print("{}\t{}\t{}".format(x_0, f[-1], k))
139
141
  break
@@ -62,11 +62,12 @@ def penalty_quadraticm(funcs: FuncArray,
62
62
  assert p > 0
63
63
  from .._kernel import kernel
64
64
  funcs, args, cons_equal, cons_unequal, x_0 = f2m(funcs), a2m(args), f2m(cons_equal), f2m(cons_unequal), p2t(x_0)
65
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
65
66
  search, point, f = kernel(method), [], []
66
67
  cons_unequal_num = sp.lambdify(args, cons_unequal, modules='numpy')
67
68
  while 1:
68
69
  point.append(np.array(x_0))
69
- f.append(get_value(funcs, args, x_0))
70
+ f.append(get_value(funcs_num, x_0))
70
71
  if verbose:
71
72
  print("{}\t{}\t{}".format(x_0, f[-1], k))
72
73
  # reps = dict(zip(args, x_0))
@@ -80,7 +81,7 @@ def penalty_quadraticm(funcs: FuncArray,
80
81
  sigma *= p
81
82
  if np.linalg.norm(x_0 - point[k - 1]) < epsilon:
82
83
  point.append(np.array(x_0))
83
- f.append(get_value(funcs, args, x_0))
84
+ f.append(get_value(funcs_num, x_0))
84
85
  if verbose:
85
86
  print("{}\t{}\t{}".format(x_0, f[-1], k))
86
87
  break
@@ -123,15 +124,16 @@ def penalty_L1(funcs: FuncArray,
123
124
  assert p > 0
124
125
  from .._kernel import kernel
125
126
  funcs, args, cons_equal, cons_unequal, x_0 = f2m(funcs), a2m(args), f2m(cons_equal), f2m(cons_unequal), p2t(x_0)
127
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
126
128
  search, point, f = kernel(method), [], []
127
129
  cons_unequal_num = sp.lambdify(args, cons_unequal, modules='numpy')
128
130
  cons_equal_num = sp.lambdify(args, cons_equal, modules='numpy')
129
131
  while 1:
130
132
  point.append(np.array(x_0))
131
- f.append(get_value(funcs, args, x_0))
133
+ f.append(get_value(funcs_num, x_0))
132
134
  if verbose:
133
135
  print("{}\t{}\t{}".format(x_0, f[-1], k))
134
- reps = dict(zip(args, x_0))
136
+ # reps = dict(zip(args, x_0))
135
137
  consv_unequal = cons_unequal_num(*x_0)
136
138
  # consv_unequal = np.array(cons_unequal.subs(reps)).astype(DataType)
137
139
  consv_unequal = np.where(consv_unequal <= 0, consv_unequal, 1)
@@ -146,7 +148,7 @@ def penalty_L1(funcs: FuncArray,
146
148
  sigma *= p
147
149
  if np.linalg.norm(x_0 - point[k - 1]) < epsilon:
148
150
  point.append(np.array(x_0))
149
- f.append(get_value(funcs, args, x_0))
151
+ f.append(get_value(funcs_num, x_0))
150
152
  if verbose:
151
153
  print("{}\t{}\t{}".format(x_0, f[-1], k))
152
154
  break
@@ -201,12 +203,15 @@ def lagrange_augmentedm(funcs: FuncArray,
201
203
  from .._kernel import kernel
202
204
  from .._drive import cons_unequal_L, v_k, renew_mu_k
203
205
  funcs, args, cons_equal, cons_unequal, x_0 = f2m(funcs), a2m(args), f2m(cons_equal), f2m(cons_unequal), p2t(x_0)
206
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
204
207
  search, f = kernel(method), []
205
208
  lamk = np.array([lamk for _ in range(cons_equal.shape[0])]).reshape(cons_equal.shape[0], 1)
206
209
  muk = np.array([muk for _ in range(cons_unequal.shape[0])]).reshape(cons_unequal.shape[0], 1)
207
210
  cons_equal_num = sp.lambdify(args, cons_equal, modules='numpy')
211
+ len_cons_unequal = len(cons_unequal)
212
+ cons_unequal_num = sp.lambdify(args, cons_unequal, modules='numpy')
208
213
  while 1:
209
- f.append(get_value(funcs, args, x_0))
214
+ f.append(get_value(funcs_num, x_0))
210
215
  if verbose:
211
216
  print("{}\t{}\t{}".format(x_0, f[-1], k))
212
217
  etak = 1 / sigma
@@ -215,19 +220,19 @@ def lagrange_augmentedm(funcs: FuncArray,
215
220
  L = sp.Matrix([funcs + (sigma / 2) * (cons_equal.T * cons_equal + cons_uneuqal_modifyed) + cons_equal.T * lamk])
216
221
  x_0, _ = search(L, args, tuple(x_0), draw=False, epsilon=epsilonk)
217
222
  k += 1
218
- vkx = v_k(cons_equal, cons_unequal, args, muk, sigma, x_0)
223
+ vkx = v_k(cons_equal_num, cons_unequal_num, len_cons_unequal, muk, sigma, x_0)
219
224
  if vkx <= epsilonk:
220
225
  res = L.jacobian(args)
221
226
  res_num = sp.lambdify(args, res, modules='numpy')
222
227
  if (vkx <= epsilon) and (np.linalg.norm(res_num(*x_0)) <= etak):
223
- f.append(get_value(funcs, args, x_0))
228
+ f.append(get_value(funcs_num, x_0))
224
229
  if verbose:
225
230
  print("{}\t{}\t{}".format(x_0, f[-1], k))
226
231
  break
227
232
  else:
228
233
  consv_equal = cons_equal_num(*x_0)
229
234
  lamk += sigma * consv_equal
230
- muk = renew_mu_k(cons_unequal, args, muk, sigma, x_0)
235
+ muk = renew_mu_k(cons_unequal_num, len_cons_unequal, muk, sigma, x_0)
231
236
  etak /= sigma
232
237
  epsilonk /= sigma**beta
233
238
  else:
@@ -61,11 +61,12 @@ def penalty_quadraticu(funcs: FuncArray,
61
61
  assert p < 1
62
62
  from .._kernel import kernel
63
63
  funcs, args, x_0, cons = f2m(funcs), a2m(args), p2t(x_0), f2m(cons)
64
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
64
65
  search, point, f = kernel(method), [], []
65
66
  cons_num = sp.lambdify(args, cons, modules='numpy')
66
67
  while 1:
67
68
  point.append(np.array(x_0))
68
- f.append(get_value(funcs, args, x_0))
69
+ f.append(get_value(funcs_num, x_0))
69
70
  if verbose:
70
71
  print("{}\t{}\t{}".format(x_0, f[-1], k))
71
72
  # reps = dict(zip(args, x_0))
@@ -79,7 +80,7 @@ def penalty_quadraticu(funcs: FuncArray,
79
80
  sigma *= p
80
81
  if np.linalg.norm(x_0 - point[k - 1]) < epsilon:
81
82
  point.append(np.array(x_0))
82
- f.append(get_value(funcs, args, x_0))
83
+ f.append(get_value(funcs_num, x_0))
83
84
  if verbose:
84
85
  print("{}\t{}\t{}".format(x_0, f[-1], k))
85
86
  break
@@ -131,10 +132,13 @@ def lagrange_augmentedu(funcs: FuncArray,
131
132
  from .._kernel import kernel
132
133
  from .._drive import cons_unequal_L, renew_mu_k, v_k
133
134
  funcs, args, x_0, cons = f2m(funcs), a2m(args), p2t(x_0), f2m(cons)
135
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
134
136
  search, f = kernel(method), []
135
137
  muk = np.array([muk for _ in range(cons.shape[0])]).reshape(cons.shape[0], 1)
138
+ len_cons = len(cons)
139
+ cons_unequal_num = sp.lambdify(args, cons, modules='numpy')
136
140
  while 1:
137
- f.append(get_value(funcs, args, x_0))
141
+ f.append(get_value(funcs_num, x_0))
138
142
  if verbose:
139
143
  print("{}\t{}\t{}".format(x_0, f[-1], k))
140
144
  etak = 1 / sigma
@@ -143,17 +147,17 @@ def lagrange_augmentedu(funcs: FuncArray,
143
147
  L = sp.Matrix([funcs + (sigma / 2) * cons_uneuqal_modifyed])
144
148
  x_0, _ = search(L, args, tuple(x_0), draw=False, epsilon=epsilonk)
145
149
  k += 1
146
- vkx = v_k(None, cons, args, muk, sigma, x_0)
150
+ vkx = v_k(None, cons_unequal_num, len_cons, muk, sigma, x_0)
147
151
  if vkx <= epsilonk:
148
152
  res = L.jacobian(args)
149
153
  res_num = sp.lambdify(args, res, modules='numpy')
150
154
  if (vkx <= epsilon) and (np.linalg.norm(res_num(*x_0)) <= eta):
151
- f.append(get_value(funcs, args, x_0))
155
+ f.append(get_value(funcs_num, x_0))
152
156
  if verbose:
153
157
  print("{}\t{}\t{}".format(x_0, f[-1], k))
154
158
  break
155
159
  else:
156
- muk = renew_mu_k(cons, args, muk, sigma, x_0)
160
+ muk = renew_mu_k(cons_unequal_num, len_cons, muk, sigma, x_0)
157
161
  etak /= sigma
158
162
  epsilonk /= sigma**beta
159
163
  else:
@@ -60,6 +60,7 @@ def gradient(A: NDArray,
60
60
  args, x_0 = a2m(args), p2t(x_0)
61
61
  assert args.shape[0] == len(x_0)
62
62
  funcs = sp.Matrix([0.5*((A*args - b).T)*(A*args - b)])
63
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
63
64
  res = funcs.jacobian(args)
64
65
  res_num = sp.lambdify(args, res, modules='numpy')
65
66
  args_num = sp.lambdify(args, args, modules='numpy')
@@ -69,7 +70,7 @@ def gradient(A: NDArray,
69
70
  while 1:
70
71
  # reps = dict(zip(args, x_0))
71
72
  point.append(np.array(x_0))
72
- f.append(get_value(funcs, args, x_0, mu, "L1"))
73
+ f.append(get_value(funcs_num, x_0, mu, "L1"))
73
74
  if verbose:
74
75
  print("{}\t{}\t{}".format(x_0, f[-1], k))
75
76
  resv = res_num(*x_0)
@@ -79,7 +80,7 @@ def gradient(A: NDArray,
79
80
  k = k + 1
80
81
  if np.linalg.norm(x_0 - point[k - 1]) <= epsilon:
81
82
  point.append(np.array(x_0))
82
- f.append(get_value(funcs, args, x_0, mu, "L1"))
83
+ f.append(get_value(funcs_num, x_0, mu, "L1"))
83
84
  if verbose:
84
85
  print("{}\t{}\t{}".format(x_0, f[-1], k))
85
86
  break
@@ -117,14 +118,15 @@ def subgradient(A: NDArray,
117
118
  args, x_0 = a2m(args), p2t(x_0)
118
119
  assert args.shape[0] == len(x_0)
119
120
  funcs = sp.Matrix([0.5*((A*args - b).T)*(A*args - b)])
121
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
120
122
  res = funcs.jacobian(args)
121
123
  res_num = sp.lambdify(args, res, modules='numpy')
122
124
  args_num = sp.lambdify(args, args, modules='numpy')
123
125
  point, f = [], []
124
126
  while 1:
125
- reps = dict(zip(args, x_0))
127
+ # reps = dict(zip(args, x_0))
126
128
  point.append(np.array(x_0))
127
- f.append(get_value(funcs, args, x_0, mu, "L1"))
129
+ f.append(get_value(funcs_num, x_0, mu, "L1"))
128
130
  if verbose:
129
131
  print("{}\t{}\t{}".format(x_0, f[-1], k))
130
132
  resv = res_num(*x_0)
@@ -135,7 +137,7 @@ def subgradient(A: NDArray,
135
137
  k = k + 1
136
138
  if np.linalg.norm(x_0 - point[k - 1]) <= epsilon:
137
139
  point.append(np.array(x_0))
138
- f.append(get_value(funcs, args, x_0, mu, "L1"))
140
+ f.append(get_value(funcs_num, x_0, mu, "L1"))
139
141
  if verbose:
140
142
  print("{}\t{}\t{}".format(x_0, f[-1], k))
141
143
  break
@@ -172,13 +174,14 @@ def approximate_point(A: NDArray,
172
174
  lambda_ma = max(values)
173
175
  tk = 1 / np.real(lambda_ma) if isinstance(lambda_ma, complex) else 1 / lambda_ma
174
176
  funcs = sp.Matrix([0.5*((A*args - b).T)*(A*args - b)])
177
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
175
178
  res = funcs.jacobian(args)
176
179
  res_num = sp.lambdify(args, res, modules='numpy')
177
180
  point, f = [], []
178
181
  while 1:
179
182
  # reps = dict(zip(args, x_0))
180
183
  point.append(x_0)
181
- f.append(get_value(funcs, args, x_0, mu, "L1"))
184
+ f.append(get_value(funcs_num, x_0, mu, "L1"))
182
185
  if verbose:
183
186
  print("{}\t{}\t{}".format(x_0, f[-1], k))
184
187
  grad = res_num(*x_0)
@@ -187,7 +190,7 @@ def approximate_point(A: NDArray,
187
190
  k = k + 1
188
191
  if np.linalg.norm(x_0 - point[k - 1]) < epsilon:
189
192
  point.append(x_0)
190
- f.append(get_value(funcs, args, x_0, mu, "L1"))
193
+ f.append(get_value(funcs_num, x_0, mu, "L1"))
191
194
  if verbose:
192
195
  print("{}\t{}\t{}".format(x_0, f[-1], k))
193
196
  break
@@ -58,11 +58,12 @@ def grad(funcs: FuncArray,
58
58
  assert all(funcs.shape) == 1 and args.shape[0] == len(x_0)
59
59
  from .._kernel import set_proxim
60
60
  proximo, f = set_proxim(proxim), []
61
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
61
62
  res = funcs.jacobian(args) # gradient
62
63
  res_num = sp.lambdify(args, res, modules='numpy')
63
64
  while 1:
64
65
  # reps = dict(zip(args, x_0))
65
- f.append(get_value(funcs, args, x_0, mu, proxim))
66
+ f.append(get_value(funcs_num, x_0, mu, proxim))
66
67
  if verbose:
67
68
  print("{}\t{}\t{}".format(x_0, f[-1], k))
68
69
  dk = -res_num(*x_0)
@@ -58,11 +58,12 @@ def normal(funcs: FuncArray,
58
58
  assert all(funcs.shape) == 1 and args.shape[0] == len(x_0)
59
59
  from .._kernel import set_proxim
60
60
  proximo, point, f = set_proxim(proxim), [], []
61
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
61
62
  res = funcs.jacobian(args) # gradient
62
63
  res_num = sp.lambdify(args, res, modules='numpy')
63
64
  while 1:
64
65
  point.append(np.array(x_0))
65
- f.append(get_value(funcs, args, x_0, mu, proxim))
66
+ f.append(get_value(funcs_num, x_0, mu, proxim))
66
67
  if verbose:
67
68
  print("{}\t{}\t{}".format(x_0, f[-1], k))
68
69
  dk = -res_num(*x_0)
@@ -110,12 +111,13 @@ def variant(funcs: FuncArray,
110
111
  from .._kernel import set_proxim
111
112
  from .._drive import gammak
112
113
  proximo, point, f = set_proxim(proxim), [], []
114
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
113
115
  res = funcs.jacobian(args) # gradient
114
116
  res_num = sp.lambdify(args, res, modules='numpy')
115
117
  vkx = lambda k: x_0 if k == 0 else point[k-1] + (x_0 - point[k-1]) / gk
116
118
  while 1:
117
119
  point.append(np.array(x_0))
118
- f.append(get_value(funcs, args, x_0, mu, proxim))
120
+ f.append(get_value(funcs_num, x_0, mu, proxim))
119
121
  if verbose:
120
122
  print("{}\t{}\t{}".format(x_0, f[-1], k))
121
123
  dk = -res_num(*x_0)
@@ -164,12 +166,13 @@ def decline(funcs: FuncArray,
164
166
  from .._kernel import set_proxim
165
167
  from .._drive import gammak
166
168
  proximo, point, f = set_proxim(proxim), [], []
169
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
167
170
  res = funcs.jacobian(args) # gradient
168
171
  res_num = sp.lambdify(args, res, modules='numpy')
169
172
  vkx = lambda k: x_0 if k == 0 else point[k-1] + (x_0 - point[k-1]) / gk
170
173
  while 1:
171
174
  point.append(np.array(x_0))
172
- f.append(get_value(funcs, args, x_0, mu, proxim))
175
+ f.append(get_value(funcs_num, x_0, mu, proxim))
173
176
  if verbose:
174
177
  print("{}\t{}\t{}".format(x_0, f[-1], k))
175
178
  dk = -res_num(*x_0)
@@ -179,7 +182,7 @@ def decline(funcs: FuncArray,
179
182
  dky = -res_num(*yk)
180
183
  delta = yk + tk * dky[0]
181
184
  u = proximo(delta, mu, tk)
182
- phiu = get_value(funcs, args, u, mu, proxim)
185
+ phiu = get_value(funcs_num, u, mu, proxim)
183
186
  x_0 = u if phiu <= f[-1] else x_0
184
187
  k += 1
185
188
  else:
@@ -59,10 +59,11 @@ def seckin(funcs: FuncArray,
59
59
  from .._kernel import set_proxim
60
60
  from .._drive import gammak
61
61
  proximo, f = set_proxim(proxim), []
62
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
62
63
  res, yk = funcs.jacobian(args), x_0 # gradient
63
64
  res_num = sp.lambdify(args, res, modules='numpy')
64
65
  while 1:
65
- f.append(get_value(funcs, args, x_0, mu, proxim))
66
+ f.append(get_value(funcs_num, x_0, mu, proxim))
66
67
  if verbose:
67
68
  print("{}\t{}\t{}".format(x_0, f[-1], k))
68
69
  dk = -res_num(*x_0)
@@ -115,10 +116,11 @@ def accer(funcs: FuncArray,
115
116
  from .._kernel import set_proxim
116
117
  from .._drive import gammak
117
118
  proximo, f = set_proxim(proxim), []
119
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
118
120
  res, yk = funcs.jacobian(args), x_0 # gradient
119
121
  res_num = sp.lambdify(args, res, modules='numpy')
120
122
  while 1:
121
- f.append(get_value(funcs, args, x_0, mu, proxim))
123
+ f.append(get_value(funcs_num, x_0, mu, proxim))
122
124
  if verbose:
123
125
  print("{}\t{}\t{}".format(x_0, f[-1], k))
124
126
  dk = -res_num(*x_0)
@@ -48,13 +48,14 @@ def solve(funcs: FuncArray,
48
48
  '''
49
49
  funcs, args, x_0 = f2m(funcs), a2m(args), p2t(x_0)
50
50
  assert all(funcs.shape) == 1 and args.shape[0] == len(x_0)
51
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
51
52
  res = funcs.jacobian(args) # gradient
52
53
  m = sp.symbols("m")
53
54
  arg, f = sp.Matrix([m]), []
54
55
  res_num = sp.lambdify(args, res, modules='numpy')
55
56
  while 1:
56
57
  # reps = dict(zip(args, x_0))
57
- f.append(get_value(funcs, args, x_0))
58
+ f.append(get_value(funcs_num, x_0))
58
59
  if verbose:
59
60
  print("{}\t{}\t{}".format(x_0, f[-1], k))
60
61
  dk = -res_num(*x_0)
@@ -96,17 +97,18 @@ def steepest(funcs: FuncArray,
96
97
  assert all(funcs.shape) == 1 and args.shape[0] == len(x_0)
97
98
  from .._kernel import linear_search
98
99
  search, f = linear_search(method), []
100
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
99
101
  res = funcs.jacobian(args) # gradient
100
102
  res_num = sp.lambdify(args, res, modules='numpy')
101
103
  while 1:
102
104
  # reps = dict(zip(args, x_0))
103
- f.append(get_value(funcs, args, x_0))
105
+ f.append(get_value(funcs_num, x_0))
104
106
  if verbose:
105
107
  print("{}\t{}\t{}".format(x_0, f[-1], k))
106
108
  dk = -res_num(*x_0)
107
109
  # dk = -np.array(res.subs(reps)).astype(DataType)
108
110
  if np.linalg.norm(dk) >= epsilon:
109
- alpha = search(funcs, res, args, x_0, dk)
111
+ alpha = search(funcs_num, res_num, x_0, dk)
110
112
  x_0 += alpha * dk[0]
111
113
  k += 1
112
114
  else:
@@ -157,25 +159,26 @@ def barzilar_borwein(funcs: FuncArray,
157
159
  funcs, args, x_0 = f2m(funcs), a2m(args), p2t(x_0)
158
160
  assert all(funcs.shape) == 1 and args.shape[0] == len(x_0)
159
161
  from .._kernel import nonmonotonic_search
162
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
160
163
  search, constant = nonmonotonic_search(method, M, eta)
161
164
  res, point, f = funcs.jacobian(args), [], []
162
165
  res_num = sp.lambdify(args, res, modules='numpy')
163
166
  while 1: # while k < max_iters when constraint optimization
164
167
  point.append(x_0)
165
168
  # reps = dict(zip(args, x_0))
166
- f.append(get_value(funcs, args, x_0))
169
+ f.append(get_value(funcs_num, x_0))
167
170
  if verbose:
168
171
  print("{}\t{}\t{}".format(x_0, f[-1], k))
169
172
  dk = -res_num(*x_0)
170
173
  # dk = -np.array(res.subs(reps)).astype(DataType)
171
174
  if np.linalg.norm(dk) >= epsilon:
172
- alpha = search(funcs, args, x_0, dk, k, point, c1, beta, alpha, constant)
175
+ alpha = search(funcs_num, x_0, dk, k, point, c1, beta, alpha, constant)
173
176
  delta = alpha * dk[0]
174
177
  x_0 = x_0 + delta
175
178
  yk = res_num(*x_0) + dk
176
179
  alpha_up = delta.dot(delta.T)
177
180
  alpha_down = (delta.dot(yk.T))[0]
178
- if alpha_down != 0:
181
+ if alpha_down > 0:
179
182
  alpha = alpha_up / alpha_down
180
183
  k += 1
181
184
  else:
@@ -48,13 +48,14 @@ def classic(funcs: FuncArray,
48
48
  '''
49
49
  funcs, args, x_0 = f2m(funcs), a2m(args), p2t(x_0)
50
50
  assert all(funcs.shape) == 1 and args.shape[0] == len(x_0)
51
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
51
52
  res = funcs.jacobian(args) # gradient
52
53
  res_num = sp.lambdify(args, res, modules='numpy')
53
- hes, f = res.jacobian(args), []
54
+ hes, f = sp.hessian(funcs, args), []
54
55
  hes_num = sp.lambdify(args, hes, modules='numpy')
55
56
  while 1:
56
57
  # reps = dict(zip(args, x_0))
57
- f.append(get_value(funcs, args, x_0))
58
+ f.append(get_value(funcs_num, x_0))
58
59
  if verbose:
59
60
  print("{}\t{}\t{}".format(x_0, f[-1], k))
60
61
  gradient = res_num(*x_0)
@@ -95,14 +96,15 @@ def modified(funcs: FuncArray,
95
96
  from .._kernel import linear_search
96
97
  funcs, args, x_0 = f2m(funcs), a2m(args), p2t(x_0)
97
98
  assert all(funcs.shape) == 1 and args.shape[0] == len(x_0)
99
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
98
100
  search, f = linear_search(method), []
99
101
  res = funcs.jacobian(args) # graident
100
102
  res_num = sp.lambdify(args, res, modules='numpy')
101
- hes = res.jacobian(args) # hessian
103
+ hes = sp.hessian(funcs, args) # hessian
102
104
  hes_num = sp.lambdify(args, hes, modules='numpy')
103
105
  while 1:
104
106
  # reps = dict(zip(args, x_0))
105
- f.append(get_value(funcs, args, x_0))
107
+ f.append(get_value(funcs_num, x_0))
106
108
  if verbose:
107
109
  print("{}\t{}\t{}".format(x_0, f[-1], k))
108
110
  gradient = res_num(*x_0)
@@ -112,7 +114,7 @@ def modified(funcs: FuncArray,
112
114
  hessian = h2h(hessian)
113
115
  dk = -np.linalg.inv(hessian).dot(gradient.T).reshape(1, -1)
114
116
  if np.linalg.norm(dk) >= epsilon:
115
- alpha = search(funcs, res, args, x_0, dk)
117
+ alpha = search(funcs_num, res_num, x_0, dk)
116
118
  x_0 += alpha * dk[0]
117
119
  k += 1
118
120
  else:
@@ -148,14 +150,15 @@ def CG(funcs: FuncArray,
148
150
  from .._kernel import linear_search
149
151
  funcs, args, x_0 = f2m(funcs), a2m(args), p2t(x_0)
150
152
  assert all(funcs.shape) == 1 and args.shape[0] == len(x_0)
153
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
151
154
  search, f = linear_search(method), []
152
155
  res = funcs.jacobian(args) # gradient
153
156
  res_num = sp.lambdify(args, res, modules='numpy')
154
- hes, dk0 = res.jacobian(args), np.zeros((args.shape[0], 1)) # hessian and initial dk
157
+ hes, dk0 = sp.hessian(funcs, args), np.zeros((args.shape[0], 1)) # hessian and initial dk
155
158
  hes_num = sp.lambdify(args, hes, modules='numpy')
156
159
  while 1: # while k < max_iters when constraint optimization
157
160
  # reps = dict(zip(args, x_0))
158
- f.append(get_value(funcs, args, x_0))
161
+ f.append(get_value(funcs_num, x_0))
159
162
  if verbose:
160
163
  print("{}\t{}\t{}".format(x_0, f[-1], k))
161
164
  gradient = res_num(*x_0)
@@ -164,7 +167,7 @@ def CG(funcs: FuncArray,
164
167
  hessian = hes_num(*x_0)
165
168
  dk = conjugate(hessian, -gradient, dk0, eps).reshape(1, -1)
166
169
  if np.linalg.norm(dk) >= epsilon:
167
- alpha = search(funcs, res, args, x_0, dk)
170
+ alpha = search(funcs_num, res_num, x_0, dk)
168
171
  x_0 += alpha * dk[0]
169
172
  k += 1
170
173
  else:
@@ -51,24 +51,25 @@ def bfgs(funcs: FuncArray,
51
51
  from .._kernel import linear_search
52
52
  funcs, args, x_0 = f2m(funcs), a2m(args), p2t(x_0)
53
53
  assert all(funcs.shape) == 1 and args.shape[0] == len(x_0)
54
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
54
55
  search, f = linear_search(method), []
55
56
  res = funcs.jacobian(args)
56
57
  res_num = sp.lambdify(args, res, modules='numpy')
57
- hes = res.jacobian(args)
58
+ hes = sp.hessian(funcs, args)
58
59
  hes_num = sp.lambdify(args, hes, modules='numpy')
59
60
  hessian = hes_num(*x_0)
60
61
  # hessian = np.array(hes.subs(dict(zip(args, x_0)))).astype(DataType)
61
62
  hessian = h2h(hessian)
62
63
  while 1: # while k < max_iters when constraint optimization
63
64
  # reps = dict(zip(args, x_0))
64
- f.append(get_value(funcs, args, x_0))
65
+ f.append(get_value(funcs_num, x_0))
65
66
  if verbose:
66
67
  print("{}\t{}\t{}".format(x_0, f[-1], k))
67
68
  gradient = res_num(*x_0)
68
69
  # gradient = np.array(res.subs(reps)).astype(DataType)
69
70
  dk = -np.linalg.inv(hessian).dot(gradient.T).reshape(1, -1)
70
71
  if np.linalg.norm(dk) >= epsilon:
71
- alpha = search(funcs, res, args, x_0, dk)
72
+ alpha = search(funcs_num, res_num, x_0, dk)
72
73
  delta = alpha * dk # sk
73
74
  x_0 += delta[0]
74
75
  yk = res_num(*x_0) - gradient
@@ -106,10 +107,11 @@ def dfp(funcs: FuncArray,
106
107
  from .._kernel import linear_search
107
108
  funcs, args, x_0 = f2m(funcs), a2m(args), p2t(x_0)
108
109
  assert all(funcs.shape) == 1 and args.shape[0] == len(x_0)
110
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
109
111
  search, f = linear_search(method), []
110
112
  res = funcs.jacobian(args)
111
113
  res_num = sp.lambdify(args, res, modules='numpy')
112
- hes = res.jacobian(args)
114
+ hes = sp.hessian(funcs, args)
113
115
  hes_num = sp.lambdify(args, hes, modules='numpy')
114
116
  hessian = hes_num(*x_0)
115
117
  # hessian = np.array(hes.subs(dict(zip(args, x_0)))).astype(DataType)
@@ -117,13 +119,13 @@ def dfp(funcs: FuncArray,
117
119
  hessiani = np.linalg.inv(hessian)
118
120
  while 1:
119
121
  # reps = dict(zip(args, x_0))
120
- f.append(get_value(funcs, args, x_0))
122
+ f.append(get_value(funcs_num, x_0))
121
123
  if verbose:
122
124
  print("{}\t{}\t{}".format(x_0, f[-1], k))
123
125
  gradient = res_num(*x_0)
124
126
  dk = -hessiani.dot(gradient.T).reshape(1, -1)
125
127
  if np.linalg.norm(dk) >= epsilon:
126
- alpha = search(funcs, res, args, x_0, dk)
128
+ alpha = search(funcs_num, res_num, x_0, dk)
127
129
  delta = alpha * dk # sk
128
130
  x_0 += delta[0]
129
131
  yk = res_num(*x_0) - gradient
@@ -165,17 +167,18 @@ def L_BFGS(funcs: FuncArray,
165
167
  from .._kernel import linear_search
166
168
  funcs, args, x_0 = f2m(funcs), a2m(args), p2t(x_0)
167
169
  assert all(funcs.shape) == 1 and args.shape[0] == len(x_0)
170
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
168
171
  search = linear_search(method)
169
172
  res = funcs.jacobian(args)
170
173
  res_num = sp.lambdify(args, res, modules='numpy')
171
- hes = res.jacobian(args)
174
+ hes = sp.hessian(funcs, args)
172
175
  l = hes.shape[0]
173
176
  f, s, y, p = [], [], [], []
174
177
  gamma = []
175
178
  gamma.append(1)
176
179
  while 1:
177
180
  # reps = dict(zip(args, x_0))
178
- f.append(get_value(funcs, args, x_0))
181
+ f.append(get_value(funcs_num, x_0))
179
182
  if verbose:
180
183
  print("{}\t{}\t{}".format(x_0, f[-1], k))
181
184
  Hkm = gamma[k] * np.identity(l)
@@ -183,7 +186,7 @@ def L_BFGS(funcs: FuncArray,
183
186
  # grad = np.array(res.subs(reps)).astype(DataType)
184
187
  dk = -double_loop(grad, p, s, y, m, k, Hkm).reshape(1, -1)
185
188
  if np.linalg.norm(dk) >= epsilon:
186
- alphak = search(funcs, res, args, x_0, dk)
189
+ alphak = search(funcs_num, res_num, x_0, dk)
187
190
  delta = alphak * dk # sk
188
191
  x_0 += delta[0]
189
192
  if k > m:
@@ -53,14 +53,16 @@ def gauss_newton(funcr: FuncArray,
53
53
  assert funcr.shape[0] > 1 and funcr.shape[1] ==1 and args.shape[0] == len(x_0)
54
54
  search, f = linear_search(method), []
55
55
  resr, funcs = funcr.jacobian(args), sp.Matrix([(1/2)*funcr.T*funcr])
56
+ funcs_num = sp.lambdify(args, funcs, modules='numpy')
56
57
  funcr_num = sp.lambdify(args, funcr, modules='numpy')
57
58
  res = funcs.jacobian(args)
59
+ res_num = sp.lambdify(args, res, modules='numpy')
58
60
  resr_num = sp.lambdify(args, resr, modules='numpy')
59
61
  while 1:
60
62
  # reps = dict(zip(args, x_0))
61
63
  rk = funcr_num(*x_0)
62
64
  # rk = np.array(funcr.subs(reps)).astype(DataType)
63
- f.append(get_value(funcs, args, x_0))
65
+ f.append(get_value(funcs_num, x_0))
64
66
  if verbose:
65
67
  print("{}\t{}\t{}".format(x_0, f[-1], k))
66
68
  jk = resr_num(*x_0)
@@ -68,7 +70,7 @@ def gauss_newton(funcr: FuncArray,
68
70
  q, r = np.linalg.qr(jk)
69
71
  dk = np.linalg.inv(r).dot(-(q.T).dot(rk)).reshape(1,-1) # operate with x_0
70
72
  if np.linalg.norm(dk) > epsilon:
71
- alpha = search(funcs, res, args, x_0, dk)
73
+ alpha = search(funcs_num, res_num, x_0, dk)
72
74
  x_0 += alpha * dk[0]
73
75
  k += 1
74
76
  else:
@@ -121,7 +123,7 @@ def levenberg_marquardt(funcr: FuncArray,
121
123
  assert funcr.shape[0] > 1 and funcr.shape[1] ==1 and args.shape[0] == len(x_0)
122
124
  res, funcs = funcr.jacobian(args), sp.Matrix([(1/2)*funcr.T*funcr])
123
125
  resf = funcs.jacobian(args)
124
- hess, dk0, f = resf.jacobian(args), np.zeros((args.shape[0], 1)), []
126
+ hess, dk0, f = sp.hessian(funcs, args), np.zeros((args.shape[0], 1)), []
125
127
  funcr_num = sp.lambdify(args, funcr, modules='numpy')
126
128
  res_num = sp.lambdify(args, res, modules='numpy')
127
129
  funcs_num = sp.lambdify(args, funcs, modules='numpy')
@@ -131,7 +133,7 @@ def levenberg_marquardt(funcr: FuncArray,
131
133
  # reps = dict(zip(args, x_0))
132
134
  rk = funcr_num(*x_0)
133
135
  # rk = np.array(funcr.subs(reps)).astype(DataType)
134
- f.append(get_value(funcs, args, x_0))
136
+ f.append(get_value(funcs_num, x_0))
135
137
  if verbose:
136
138
  print("{}\t{}\t{}".format(x_0, f[-1], k))
137
139
  jk = res_num(*x_0)
@@ -73,7 +73,7 @@ def steihaug_CG(funcs: FuncArray,
73
73
  funcs, args, x_0 = f2m(funcs), a2m(args), p2t(x_0)
74
74
  assert all(funcs.shape) == 1 and args.shape[0] == len(x_0)
75
75
  res = funcs.jacobian(args)
76
- hes = res.jacobian(args)
76
+ hes = sp.hessian(funcs, args)
77
77
  s0, f = [0 for _ in range(args.shape[0])], []
78
78
  funcs_num = sp.lambdify(args, funcs, modules='numpy')
79
79
  res_num = sp.lambdify(args, res, modules='numpy')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: optimtool
3
- Version: 2.8.3
3
+ Version: 2.9.1
4
4
  Summary: The fundamental package for scientific research in optimization.
5
5
  Home-page: https://github.com/linjing-lab/optimtool
6
6
  Download-URL: https://github.com/linjing-lab/optimtool/tags
@@ -52,12 +52,22 @@ License-File: LICENSE
52
52
 
53
53
  ## 项目介绍
54
54
 
55
- &emsp;&emsp;optimtool采用了北京大学出版的《最优化:建模、算法与理论》这本书中的部分理论方法框架,运用了`Numpy`包高效处理数组间运算等的特性,巧妙地应用了`Sympy`内部支持的jacobian等方法,并结合Python内置函数dict与zip实现了Sympy矩阵到Numpy矩阵的转换,最终设计的用在最优化科学研究的Python工具包。
55
+ &emsp;&emsp;optimtool采用了北京大学出版的《最优化:建模、算法与理论》这本书中的部分理论方法框架,运用了`Numpy`包高效处理数组间运算等的特性,巧妙地应用了`Sympy`内部支持的jacobian等方法,并结合sp.lambdify实现了高效地数值矩阵的运算,最终设计的用在最优化科学研究的Python工具包。
56
56
 
57
57
  如果你在研究中使用 **optimtool**,欢迎引用它在你的参考资料中(按照下面的格式)。
58
58
 
59
- ```text
60
- 林景. optimtool: The fundamental package for scientific research in optimization. 2021. https://pypi.org/project/optimtool/.
59
+ ```bibtex
60
+ @software{Lin2021optimtool,
61
+ author = {Lin, Jing},
62
+ title = {optimtool: The fundamental package for scientific research in optimization.},
63
+ year = {2021},
64
+ version = {2.9.1},
65
+ publisher = {PyPI},
66
+ organization = {linjing-lab},
67
+ url = {https://pypi.org/project/optimtool/},
68
+ license = {MIT},
69
+ note = {Source code available at \url{https://github.com/linjing-lab/optimtool}},
70
+ }
61
71
  ```
62
72
 
63
73
  下载最新版:
@@ -4,7 +4,7 @@ import sys
4
4
  from setuptools import setup
5
5
 
6
6
  if sys.version_info < (3, 7, 0):
7
- raise OSError(f'optimtool-2.8.2 requires Python >=3.7, but yours is {sys.version}')
7
+ raise OSError(f'optimtool-2.9.1 requires Python >=3.7, but yours is {sys.version}')
8
8
 
9
9
  if (3, 7, 0) <= sys.version_info < (3, 8, 0):
10
10
  # https://github.com/pypa/setuptools/issues/926#issuecomment-294369342
File without changes
File without changes
File without changes