optimtool 2.8.0__tar.gz → 2.8.2__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.0 → optimtool-2.8.2}/PKG-INFO +1 -1
  2. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/__init__.py +1 -1
  3. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/_convert.py +1 -1
  4. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/_drive.py +1 -1
  5. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/_search.py +250 -251
  6. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/_utils.py +1 -1
  7. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/_version.py +1 -1
  8. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/unconstrain/gradient_descent.py +1 -1
  9. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/unconstrain/newton.py +2 -2
  10. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/unconstrain/newton_quasi.py +3 -3
  11. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/unconstrain/nonlinear_least_square.py +4 -3
  12. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool.egg-info/PKG-INFO +1 -1
  13. {optimtool-2.8.0 → optimtool-2.8.2}/setup.py +1 -1
  14. {optimtool-2.8.0 → optimtool-2.8.2}/LICENSE +0 -0
  15. {optimtool-2.8.0 → optimtool-2.8.2}/README.md +0 -0
  16. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/_kernel.py +0 -0
  17. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/_proxim.py +0 -0
  18. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/_typing.py +0 -0
  19. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/base.py +0 -0
  20. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/constrain/__init__.py +0 -0
  21. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/constrain/equal.py +0 -0
  22. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/constrain/mixequal.py +0 -0
  23. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/constrain/unequal.py +0 -0
  24. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/example/Lasso.py +0 -0
  25. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/example/WanYuan.py +0 -0
  26. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/example/__init__.py +0 -0
  27. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/hybrid/__init__.py +0 -0
  28. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/hybrid/approt.py +0 -0
  29. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/hybrid/fista.py +0 -0
  30. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/hybrid/nesterov.py +0 -0
  31. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/unconstrain/__init__.py +0 -0
  32. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool/unconstrain/trust_region.py +0 -0
  33. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool.egg-info/SOURCES.txt +0 -0
  34. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool.egg-info/dependency_links.txt +0 -0
  35. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool.egg-info/not-zip-safe +0 -0
  36. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool.egg-info/requires.txt +0 -0
  37. {optimtool-2.8.0 → optimtool-2.8.2}/optimtool.egg-info/top_level.txt +0 -0
  38. {optimtool-2.8.0 → optimtool-2.8.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: optimtool
3
- Version: 2.8.0
3
+ Version: 2.8.2
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
@@ -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.0 requires Python >=3.7, but yours is {sys.version}')
35
+ raise OSError(f'optimtool-2.8.2 requires Python >=3.7, but yours is {sys.version}')
@@ -66,7 +66,7 @@ def h2h(hessian: NDArray) -> NDArray:
66
66
  '''
67
67
  :param hessian: NDArray, hessian matrix with format at `numpy.ndarray`.
68
68
 
69
- :return: returns a reversible hessian matrix.
69
+ :return: returns a positive definite and reversible hessian matrix.
70
70
  '''
71
71
  l = hessian.shape[0] # hessian.shape = (l, l)
72
72
  while 1:
@@ -32,7 +32,7 @@ def C_k(funcs: SympyMutableDenseMatrix,
32
32
  eta: float,
33
33
  k: int) -> DataType:
34
34
  assert k >= 0
35
- 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))
35
+ 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))
36
36
 
37
37
  def get_f_delta_gradient(resv: NDArray,
38
38
  argsv: NDArray,
@@ -1,252 +1,251 @@
1
- # Copyright (c) 2021 linjing-lab
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in all
11
- # copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
- # SOFTWARE.
20
-
21
- from .base import np
22
- from ._typing import List, NDArray, SympyMutableDenseMatrix, DataType, IterPointType
23
-
24
- __all__ = ["armijo", "goldstein", "wolfe", "Grippo", "ZhangHanger"]
25
-
26
- def armijo(funcs: SympyMutableDenseMatrix,
27
- args: SympyMutableDenseMatrix,
28
- x_0: IterPointType,
29
- d: NDArray,
30
- gamma: float=0.5,
31
- c: float=0.1) -> float:
32
- '''
33
- :param funcs: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
34
- :param args: SympyMutableDenseMatrix, symbolic set with order in a list to construct `dict(zip(args, x_0))`.
35
- :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
36
- :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
37
- :param gamma: float, factor used to adjust alpha with interval at (0, 1). default: float=0.5.
38
- :param c: float, constant used to constrain alpha adjusted frequency with interval at (0, 1). default: float=0.1.
39
-
40
- :return: best alpha with format at `float`.
41
- '''
42
- assert gamma > 0
43
- assert gamma < 1
44
- assert c > 0
45
- assert c < 1
46
- alpha = 1
47
- res = funcs.jacobian(args)
48
- reps = dict(zip(args, x_0))
49
- f0 = np.array(funcs.subs(reps)).astype(DataType)
50
- res0 = np.array(res.subs(reps)).astype(DataType)
51
- while 1:
52
- x = x_0 + (alpha*d)[0]
53
- f1 = np.array(funcs.subs(dict(zip(args, x)))).astype(DataType)
54
- if f1 <= f0 + c*alpha*res0.dot(d.T):
55
- break
56
- else:
57
- alpha *= gamma
58
- return alpha
59
-
60
- def goldstein(funcs: SympyMutableDenseMatrix,
61
- args: SympyMutableDenseMatrix,
62
- x_0: IterPointType,
63
- d: NDArray,
64
- c: float=0.2,
65
- alphas: float=0.,
66
- alphae: float=10.,
67
- t: float=1.2,
68
- eps: float=1e-3) -> float:
69
- '''
70
- :param funcs: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
71
- :param args: SympyMutableDenseMatrix, symbolic set with order in a list to construct `dict(zip(args, x_0))`.
72
- :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
73
- :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
74
- :param c: float, constant used to constrain alpha adjusted frequency with interval at (0, 0.5). default: float=0.2.
75
- :param alphas: float, left search endpoint for alpha with value assert as `> 0`. default: float=0.
76
- :param alphae: float, right search endpoint for alpha with value assert as `> alphas`. default: float=10.
77
- :param t: float, factor used to expand alpha for adapting to alphas interval. default: float=1.2.
78
- :param eps: float, the precision set to stopp search alpha in (alphas, alphae). default: float=1e-3.
79
-
80
- :return: best alpha with format at `float`.
81
- '''
82
- assert c > 0
83
- assert c < 0.5
84
- assert alphas >= 0
85
- assert alphas < alphae
86
- assert t > 0
87
- assert eps > 0
88
- alpha = 1
89
- res = funcs.jacobian(args)
90
- reps = dict(zip(args, x_0))
91
- f0 = np.array(funcs.subs(reps)).astype(DataType)
92
- res0 = np.array(res.subs(reps)).astype(DataType)
93
- while alphas < alphae:
94
- x = x_0 + (alpha*d)[0]
95
- f1 = np.array(funcs.subs(dict(zip(args, x)))).astype(DataType)
96
- if f1 <= f0 + c*alpha*res0.dot(d.T):
97
- if f1 >= f0 + (1 - c)*alpha*res0.dot(d.T):
98
- break
99
- else:
100
- alphas = alpha
101
- alpha = 0.5 * (alphas + alphae)
102
- if alphae < np.inf:
103
- alpha = 0.5 * (alphas + alphae)
104
- else:
105
- alpha *= t
106
- else:
107
- alphae = alpha
108
- alpha = 0.5 * (alphas + alphae)
109
- if np.abs(alphas - alphae) < eps:
110
- break
111
- return alpha
112
-
113
- def wolfe(funcs: SympyMutableDenseMatrix,
114
- args: SympyMutableDenseMatrix,
115
- x_0: IterPointType,
116
- d: NDArray,
117
- c1: float=0.3,
118
- c2: float=0.5,
119
- alphas: float=0.,
120
- alphae: float=2.,
121
- eps: float=1e-3) -> float:
122
- '''
123
- :param funcs: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
124
- :param args: SympyMutableDenseMatrix, symbolic set with order in a list to construct `dict(zip(args, x_0))`.
125
- :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
126
- :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
127
- :param c1: float, first constant used to constrain alpha adjusted frequency with interval at (0, 1). default: float=0.3.
128
- :param c2: float, second constant used to constrain alpha adjusted frequency with interval at (0, 1). default: float=0.5.
129
- :param alphas: float, left search endpoint for alpha with value assert as `> 0`. default: float=0.
130
- :param alphae: float, right search endpoint for alpha with value assert as `> alphas`. default: float=2.
131
- :param eps: float, the precision set to stopp search alpha in (alphas, alphae). default: float=1e-3.
132
-
133
- :return: best alpha with format at `float`.
134
- '''
135
- assert c1 > 0
136
- assert c1 < 1
137
- assert c2 > 0
138
- assert c2 < 1
139
- assert c1 < c2
140
- assert alphas >= 0
141
- assert alphas < alphae
142
- assert eps > 0
143
- alpha = 1
144
- res = funcs.jacobian(args)
145
- reps = dict(zip(args, x_0))
146
- f0 = np.array(funcs.subs(reps)).astype(DataType)
147
- res0 = np.array(res.subs(reps)).astype(DataType)
148
- while alphas < alphae:
149
- x = x_0 + (alpha*d)[0]
150
- f1 = np.array(funcs.subs(dict(zip(args, x)))).astype(DataType)
151
- if f1 <= f0 + c1*alpha*res0.dot(d.T):
152
- res1 = np.array(res.subs(dict(zip(args, x)))).astype(DataType)
153
- if res1.dot(d.T) >= c2*res0.dot(d.T):
154
- break
155
- else:
156
- alphas = alpha
157
- alpha = 0.5 * (alphas + alphae)
158
- else:
159
- alphae = alpha
160
- alpha = 0.5 * (alphas + alphae)
161
- if np.abs(alphas - alphae) < eps:
162
- break
163
- return alpha
164
-
165
- # coordinate with `barzilar_borwein`.
166
- def Grippo(funcs: SympyMutableDenseMatrix,
167
- args: SympyMutableDenseMatrix,
168
- x_0: IterPointType,
169
- d: NDArray,
170
- k: int,
171
- point: List[IterPointType],
172
- c1: float,
173
- beta: float,
174
- alpha: float,
175
- M: int) -> float:
176
- '''
177
- :param funcs: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
178
- :param args: SympyMutableDenseMatrix, symbolic set with order in a list to construct `dict(zip(args, x_0))`.
179
- :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
180
- :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
181
- :param k: int, current number of iterative process in `barzilar_borwein` method.
182
- :param c1: float, constant used to constrain alpha adjusted frequency with interval at (0, 1).
183
- :param beta: float, factor used to expand alpha for adapting to alphas interval.
184
- :param alpha: float, initial step size for nonmonotonic line search method with assert `> 0`.
185
- :param M: int, constant to control the inner `max` proccess with assert `>= 0`.
186
-
187
- :return: best alpha with format at `float`.
188
- '''
189
- assert M > 0
190
- assert alpha > 0
191
- assert c1 > 0
192
- assert c1 < 1
193
- assert beta > 0
194
- assert beta < 1
195
- reps = dict(zip(args, x_0))
196
- res = funcs.jacobian(args)
197
- res0 = np.array(res.subs(reps)).astype(DataType)
198
- while 1:
199
- x = x_0 + (alpha*d)[0]
200
- f1 = np.array(funcs.subs(dict(zip(args, x)))).astype(DataType)
201
- fk = -np.inf
202
- for j in range(min(k, M) + 1):
203
- fk = max(fk, np.array(funcs.subs(dict(zip(args, point[k-j])))).astype(DataType))
204
- if f1 <= fk + c1 * alpha * res0.dot(d.T):
205
- break
206
- else:
207
- alpha *= beta
208
- return alpha
209
-
210
- def ZhangHanger(funcs: SympyMutableDenseMatrix,
211
- args: SympyMutableDenseMatrix,
212
- x_0: IterPointType,
213
- d: NDArray,
214
- k: int,
215
- point: List[IterPointType],
216
- c1: float,
217
- beta: float,
218
- alpha: float,
219
- eta: float) -> float:
220
- '''
221
- :param funcs: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
222
- :param args: SympyMutableDenseMatrix, symbolic set with order in a list to construct `dict(zip(args, x_0))`.
223
- :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
224
- :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
225
- :param k: int, current number of iterative process in `barzilar_borwein` method.
226
- :param c1: float, constant used to constrain alpha adjusted frequency with interval at (0, 1).
227
- :param beta: float, factor used to expand alpha for adapting to alphas interval.
228
- :param alpha: float, initial step size for nonmonotonic line search method with assert `> 0`.
229
- :param eta: float, constant used to control `C_k` process with interval at (0, 1).
230
-
231
- :return: best alpha with format at `float`.
232
- '''
233
- assert alpha > 0
234
- assert eta > 0
235
- assert eta < 1
236
- assert c1 > 0
237
- assert c1 < 1
238
- assert beta > 0
239
- assert beta < 1
240
- from ._drive import C_k
241
- reps = dict(zip(args, x_0))
242
- res = funcs.jacobian(args)
243
- res0 = np.array(res.subs(reps)).astype(DataType)
244
- while 1:
245
- x = x_0 + (alpha*d)[0]
246
- f1 = np.array(funcs.subs(dict(zip(args, x)))).astype(DataType)
247
- Ck = C_k(funcs, args, point, eta, k)
248
- if f1 <= Ck + c1 * alpha * res0.dot(d.T):
249
- break
250
- else:
251
- alpha *= beta
1
+ # Copyright (c) 2021 linjing-lab
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ from .base import np
22
+ from ._typing import List, NDArray, SympyMutableDenseMatrix, DataType, IterPointType
23
+
24
+ __all__ = ["armijo", "goldstein", "wolfe", "Grippo", "ZhangHanger"]
25
+
26
+ def armijo(funcs: SympyMutableDenseMatrix,
27
+ res: SympyMutableDenseMatrix,
28
+ args: SympyMutableDenseMatrix,
29
+ x_0: IterPointType,
30
+ d: NDArray,
31
+ gamma: float=0.5,
32
+ c: float=0.1) -> float:
33
+ '''
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))`.
37
+ :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
38
+ :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
39
+ :param gamma: float, factor used to adjust alpha with interval at (0, 1). default: float=0.5.
40
+ :param c: float, constant used to constrain alpha adjusted frequency with interval at (0, 1). default: float=0.1.
41
+
42
+ :return: best alpha with format at `float`.
43
+ '''
44
+ assert gamma > 0
45
+ assert gamma < 1
46
+ assert c > 0
47
+ assert c < 1
48
+ alpha = 1
49
+ reps = dict(zip(args, x_0))
50
+ f0 = np.array(funcs.subs(reps)).astype(DataType)
51
+ res0 = np.array(res.subs(reps)).astype(DataType)
52
+ while 1:
53
+ x = x_0 + (alpha*d)[0]
54
+ f1 = np.array(funcs.subs(dict(zip(args, x)))).astype(DataType)
55
+ if f1 <= f0 + c*alpha*res0.dot(d.T):
56
+ break
57
+ else:
58
+ alpha *= gamma
59
+ return alpha
60
+
61
+ def goldstein(funcs: SympyMutableDenseMatrix,
62
+ res: SympyMutableDenseMatrix,
63
+ args: SympyMutableDenseMatrix,
64
+ x_0: IterPointType,
65
+ d: NDArray,
66
+ c: float=0.2,
67
+ alphas: float=0.,
68
+ alphae: float=10.,
69
+ t: float=1.2,
70
+ eps: float=1e-3) -> float:
71
+ '''
72
+ :param funcs: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
73
+ :param res: SympyMutableDenseMatrix, gradient function computed by .jacobian function.
74
+ :param args: SympyMutableDenseMatrix, symbolic set with order in a list to construct `dict(zip(args, x_0))`.
75
+ :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
76
+ :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
77
+ :param c: float, constant used to constrain alpha adjusted frequency with interval at (0, 0.5). default: float=0.2.
78
+ :param alphas: float, left search endpoint for alpha with value assert as `> 0`. default: float=0.
79
+ :param alphae: float, right search endpoint for alpha with value assert as `> alphas`. default: float=10.
80
+ :param t: float, factor used to expand alpha for adapting to alphas interval. default: float=1.2.
81
+ :param eps: float, the precision set to stopp search alpha in (alphas, alphae). default: float=1e-3.
82
+
83
+ :return: best alpha with format at `float`.
84
+ '''
85
+ assert c > 0
86
+ assert c < 0.5
87
+ assert alphas >= 0
88
+ assert alphas < alphae
89
+ assert t > 0
90
+ assert eps > 0
91
+ alpha = 1
92
+ reps = dict(zip(args, x_0))
93
+ f0 = np.array(funcs.subs(reps)).astype(DataType)
94
+ res0 = np.array(res.subs(reps)).astype(DataType)
95
+ while alphas < alphae:
96
+ x = x_0 + (alpha*d)[0]
97
+ f1 = np.array(funcs.subs(dict(zip(args, x)))).astype(DataType)
98
+ if f1 <= f0 + c*alpha*res0.dot(d.T):
99
+ if f1 >= f0 + (1 - c)*alpha*res0.dot(d.T):
100
+ break
101
+ else:
102
+ alphas = alpha
103
+ alpha = 0.5 * (alphas + alphae)
104
+ if alphae < np.inf:
105
+ alpha = 0.5 * (alphas + alphae)
106
+ else:
107
+ alpha *= t
108
+ else:
109
+ alphae = alpha
110
+ alpha = 0.5 * (alphas + alphae)
111
+ if np.abs(alphas - alphae) < eps:
112
+ break
113
+ return alpha
114
+
115
+ def wolfe(funcs: SympyMutableDenseMatrix,
116
+ res: SympyMutableDenseMatrix,
117
+ args: SympyMutableDenseMatrix,
118
+ x_0: IterPointType,
119
+ d: NDArray,
120
+ c1: float=0.3,
121
+ c2: float=0.5,
122
+ alphas: float=0.,
123
+ alphae: float=2.,
124
+ eps: float=1e-3) -> float:
125
+ '''
126
+ :param funcs: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
127
+ :param res: SympyMutableDenseMatrix, gradient function computed by .jacobian function.
128
+ :param args: SympyMutableDenseMatrix, symbolic set with order in a list to construct `dict(zip(args, x_0))`.
129
+ :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
130
+ :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
131
+ :param c1: float, first constant used to constrain alpha adjusted frequency with interval at (0, 1). default: float=0.3.
132
+ :param c2: float, second constant used to constrain alpha adjusted frequency with interval at (0, 1). default: float=0.5.
133
+ :param alphas: float, left search endpoint for alpha with value assert as `> 0`. default: float=0.
134
+ :param alphae: float, right search endpoint for alpha with value assert as `> alphas`. default: float=2.
135
+ :param eps: float, the precision set to stopp search alpha in (alphas, alphae). default: float=1e-3.
136
+
137
+ :return: best alpha with format at `float`.
138
+ '''
139
+ assert c1 > 0
140
+ assert c1 < 1
141
+ assert c2 > 0
142
+ assert c2 < 1
143
+ assert c1 < c2
144
+ assert alphas >= 0
145
+ assert alphas < alphae
146
+ assert eps > 0
147
+ alpha = 1
148
+ reps = dict(zip(args, x_0))
149
+ f0 = np.array(funcs.subs(reps)).astype(DataType)
150
+ res0 = np.array(res.subs(reps)).astype(DataType)
151
+ while alphas < alphae:
152
+ x = x_0 + (alpha*d)[0]
153
+ f1 = np.array(funcs.subs(dict(zip(args, x)))).astype(DataType)
154
+ if f1 <= f0 + c1*alpha*res0.dot(d.T):
155
+ res1 = np.array(res.subs(dict(zip(args, x)))).astype(DataType)
156
+ if res1.dot(d.T) >= c2*res0.dot(d.T):
157
+ break
158
+ else:
159
+ alphas = alpha
160
+ alpha = 0.5 * (alphas + alphae)
161
+ else:
162
+ alphae = alpha
163
+ alpha = 0.5 * (alphas + alphae)
164
+ if np.abs(alphas - alphae) < eps:
165
+ break
166
+ return alpha
167
+
168
+ # coordinate with `barzilar_borwein`.
169
+ def Grippo(funcs: SympyMutableDenseMatrix,
170
+ args: SympyMutableDenseMatrix,
171
+ x_0: IterPointType,
172
+ d: NDArray,
173
+ k: int,
174
+ point: List[IterPointType],
175
+ c1: float,
176
+ beta: float,
177
+ alpha: float,
178
+ M: int) -> float:
179
+ '''
180
+ :param funcs: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
181
+ :param args: SympyMutableDenseMatrix, symbolic set with order in a list to construct `dict(zip(args, x_0))`.
182
+ :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
183
+ :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
184
+ :param k: int, current number of iterative process in `barzilar_borwein` method.
185
+ :param point: List[IterPointType], contains current iteration points in a list.
186
+ :param c1: float, constant used to constrain alpha adjusted frequency with interval at (0, 1).
187
+ :param beta: float, factor used to expand alpha for adapting to alphas interval.
188
+ :param alpha: float, initial step size for nonmonotonic line search method with assert `> 0`.
189
+ :param M: int, constant to control the inner `max` proccess with assert `>= 0`.
190
+
191
+ :return: best alpha with format at `float`.
192
+ '''
193
+ assert M > 0
194
+ assert alpha > 0
195
+ assert c1 > 0
196
+ assert c1 < 1
197
+ assert beta > 0
198
+ assert beta < 1
199
+ while 1:
200
+ x = x_0 + (alpha*d)[0]
201
+ f1 = np.array(funcs.subs(dict(zip(args, x)))).astype(DataType)
202
+ fk = -np.inf
203
+ for j in range(min(k, M) + 1):
204
+ fk = max(fk, np.array(funcs.subs(dict(zip(args, point[k-j])))).astype(DataType))
205
+ if f1 <= fk + c1 * alpha * (-d).dot(d.T):
206
+ break
207
+ else:
208
+ alpha *= beta
209
+ return alpha
210
+
211
+ def ZhangHanger(funcs: SympyMutableDenseMatrix,
212
+ args: SympyMutableDenseMatrix,
213
+ x_0: IterPointType,
214
+ d: NDArray,
215
+ k: int,
216
+ point: List[IterPointType],
217
+ c1: float,
218
+ beta: float,
219
+ alpha: float,
220
+ eta: float) -> float:
221
+ '''
222
+ :param funcs: SympyMutableDenseMatrix, objective function with `convert` process used for search alpha.
223
+ :param args: SympyMutableDenseMatrix, symbolic set with order in a list to construct `dict(zip(args, x_0))`.
224
+ :param x_0: IterPointType, numerical values in a 'list` or 'tuple` according to the order of `args`.
225
+ :param d: NDArray, current gradient descent direction with format at `numpy.ndarray`.
226
+ :param k: int, current number of iterative process in `barzilar_borwein` method.
227
+ :param point: List[IterPointType], contains current iteration points in a list.
228
+ :param c1: float, constant used to constrain alpha adjusted frequency with interval at (0, 1).
229
+ :param beta: float, factor used to expand alpha for adapting to alphas interval.
230
+ :param alpha: float, initial step size for nonmonotonic line search method with assert `> 0`.
231
+ :param eta: float, constant used to control `C_k` process with interval at (0, 1).
232
+
233
+ :return: best alpha with format at `float`.
234
+ '''
235
+ assert alpha > 0
236
+ assert eta > 0
237
+ assert eta < 1
238
+ assert c1 > 0
239
+ assert c1 < 1
240
+ assert beta > 0
241
+ assert beta < 1
242
+ from ._drive import C_k
243
+ while 1:
244
+ x = x_0 + (alpha*d)[0]
245
+ f1 = np.array(funcs.subs(dict(zip(args, x)))).astype(DataType)
246
+ Ck = C_k(funcs, args, point, eta, k)
247
+ if f1 <= Ck + c1 * alpha * (-d).dot(d.T):
248
+ break
249
+ else:
250
+ alpha *= beta
252
251
  return alpha
@@ -29,7 +29,7 @@ def get_value(funcs: SympyMutableDenseMatrix, args: SympyMutableDenseMatrix, x_0
29
29
  :param args: SympyMutableDenseMatrix, symbolic set after `convert` with order.
30
30
  :param x_0: IterPointType, numpy.ndarray or List[PointType] or Tuple[PointType].
31
31
  :param mu: float | None, parameters collaborate with the problems applied in `Lasso`. default=None.
32
- :param proxim: str | None, parameter indicate the type of proximity operators. default==None.
32
+ :param proxim: str | None, parameter indicate the type of proximity operators. default=None.
33
33
 
34
34
  :return: functional value with DataType.
35
35
  '''
@@ -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.0'
21
+ __version__ = '2.8.2'
@@ -102,7 +102,7 @@ def steepest(funcs: FuncArray,
102
102
  print("{}\t{}\t{}".format(x_0, f[-1], k))
103
103
  dk = -np.array(res.subs(reps)).astype(DataType)
104
104
  if np.linalg.norm(dk) >= epsilon:
105
- alpha = search(funcs, args, x_0, dk)
105
+ alpha = search(funcs, res, args, x_0, dk)
106
106
  x_0 += alpha * dk[0]
107
107
  k += 1
108
108
  else:
@@ -104,7 +104,7 @@ def modified(funcs: FuncArray,
104
104
  hessian = h2h(hessian)
105
105
  dk = -np.linalg.inv(hessian).dot(gradient.T).reshape(1, -1)
106
106
  if np.linalg.norm(dk) >= epsilon:
107
- alpha = search(funcs, args, x_0, dk)
107
+ alpha = search(funcs, res, args, x_0, dk)
108
108
  x_0 += alpha * dk[0]
109
109
  k += 1
110
110
  else:
@@ -152,7 +152,7 @@ def CG(funcs: FuncArray,
152
152
  hessian = np.array(hes.subs(reps)).astype(DataType)
153
153
  dk = conjugate(hessian, -gradient, dk0, eps).reshape(1, -1)
154
154
  if np.linalg.norm(dk) >= epsilon:
155
- alpha = search(funcs, args, x_0, dk)
155
+ alpha = search(funcs, res, args, x_0, dk)
156
156
  x_0 += alpha * dk[0]
157
157
  k += 1
158
158
  else:
@@ -64,7 +64,7 @@ def bfgs(funcs: FuncArray,
64
64
  gradient = np.array(res.subs(reps)).astype(DataType)
65
65
  dk = -np.linalg.inv(hessian).dot(gradient.T).reshape(1, -1)
66
66
  if np.linalg.norm(dk) >= epsilon:
67
- alpha = search(funcs, args, x_0, dk)
67
+ alpha = search(funcs, res, args, x_0, dk)
68
68
  delta = alpha * dk # sk
69
69
  x_0 += delta[0]
70
70
  yk = np.array(res.subs(dict(zip(args, x_0)))).astype(DataType) - np.array(res.subs(reps)).astype(DataType)
@@ -116,7 +116,7 @@ def dfp(funcs: FuncArray,
116
116
  gradient = np.array(res.subs(reps)).astype(DataType)
117
117
  dk = -hessiani.dot(gradient.T).reshape(1, -1)
118
118
  if np.linalg.norm(dk) >= epsilon:
119
- alpha = search(funcs, args, x_0, dk)
119
+ alpha = search(funcs, res, args, x_0, dk)
120
120
  delta = alpha * dk # sk
121
121
  x_0 += delta[0]
122
122
  yk = np.array(res.subs(dict(zip(args, x_0)))).astype(DataType) - np.array(res.subs(reps)).astype(DataType)
@@ -174,7 +174,7 @@ def L_BFGS(funcs: FuncArray,
174
174
  grad = np.array(res.subs(reps)).astype(DataType)
175
175
  dk = -double_loop(grad, p, s, y, m, k, Hkm).reshape(1, -1)
176
176
  if np.linalg.norm(dk) >= epsilon:
177
- alphak = search(funcs, args, x_0, dk)
177
+ alphak = search(funcs, res, args, x_0, dk)
178
178
  delta = alphak * dk # sk
179
179
  x_0 += delta[0]
180
180
  if k > m:
@@ -52,18 +52,19 @@ def gauss_newton(funcr: FuncArray,
52
52
  funcr, args, x_0 = f2m(funcr), a2m(args), p2t(x_0)
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
- res, funcs = funcr.jacobian(args), sp.Matrix([(1/2)*funcr.T*funcr])
55
+ resr, funcs = funcr.jacobian(args), sp.Matrix([(1/2)*funcr.T*funcr])
56
+ res = funcs.jacobian(args)
56
57
  while 1:
57
58
  reps = dict(zip(args, x_0))
58
59
  rk = np.array(funcr.subs(reps)).astype(DataType)
59
60
  f.append(get_value(funcs, args, x_0))
60
61
  if verbose:
61
62
  print("{}\t{}\t{}".format(x_0, f[-1], k))
62
- jk = np.array(res.subs(reps)).astype(DataType)
63
+ jk = np.array(resr.subs(reps)).astype(DataType)
63
64
  q, r = np.linalg.qr(jk)
64
65
  dk = np.linalg.inv(r).dot(-(q.T).dot(rk)).reshape(1,-1) # operate with x_0
65
66
  if np.linalg.norm(dk) > epsilon:
66
- alpha = search(funcs, args, x_0, dk)
67
+ alpha = search(funcs, res, args, x_0, dk)
67
68
  x_0 += alpha * dk[0]
68
69
  k += 1
69
70
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: optimtool
3
- Version: 2.8.0
3
+ Version: 2.8.2
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
@@ -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.0 requires Python >=3.7, but yours is {sys.version}')
7
+ raise OSError(f'optimtool-2.8.2 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
File without changes