optimtool 2.8.1__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.
- {optimtool-2.8.1 → optimtool-2.8.2}/PKG-INFO +1 -1
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/__init__.py +1 -1
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/_convert.py +1 -1
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/_search.py +250 -258
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/_version.py +1 -1
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/unconstrain/gradient_descent.py +1 -1
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool.egg-info/PKG-INFO +1 -1
- {optimtool-2.8.1 → optimtool-2.8.2}/setup.py +1 -1
- {optimtool-2.8.1 → optimtool-2.8.2}/LICENSE +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/README.md +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/_drive.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/_kernel.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/_proxim.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/_typing.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/_utils.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/base.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/constrain/__init__.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/constrain/equal.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/constrain/mixequal.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/constrain/unequal.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/example/Lasso.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/example/WanYuan.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/example/__init__.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/hybrid/__init__.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/hybrid/approt.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/hybrid/fista.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/hybrid/nesterov.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/unconstrain/__init__.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/unconstrain/newton.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/unconstrain/newton_quasi.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/unconstrain/nonlinear_least_square.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool/unconstrain/trust_region.py +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool.egg-info/SOURCES.txt +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool.egg-info/dependency_links.txt +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool.egg-info/not-zip-safe +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool.egg-info/requires.txt +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/optimtool.egg-info/top_level.txt +0 -0
- {optimtool-2.8.1 → optimtool-2.8.2}/setup.cfg +0 -0
|
@@ -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.
|
|
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:
|
|
@@ -1,259 +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
|
-
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
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
:param
|
|
182
|
-
:param
|
|
183
|
-
:param
|
|
184
|
-
:param
|
|
185
|
-
:param
|
|
186
|
-
:param
|
|
187
|
-
:param
|
|
188
|
-
:param
|
|
189
|
-
:param
|
|
190
|
-
|
|
191
|
-
:
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
assert
|
|
196
|
-
assert
|
|
197
|
-
assert
|
|
198
|
-
assert
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
f1
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
:param
|
|
228
|
-
:param
|
|
229
|
-
:param
|
|
230
|
-
:param
|
|
231
|
-
:param
|
|
232
|
-
|
|
233
|
-
:
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
assert
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
while 1:
|
|
252
|
-
x = x_0 + (alpha*d)[0]
|
|
253
|
-
f1 = np.array(funcs.subs(dict(zip(args, x)))).astype(DataType)
|
|
254
|
-
Ck = C_k(funcs, args, point, eta, k)
|
|
255
|
-
if f1 <= Ck + c1 * alpha * res0.dot(d.T):
|
|
256
|
-
break
|
|
257
|
-
else:
|
|
258
|
-
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
|
|
259
251
|
return alpha
|
|
@@ -163,7 +163,7 @@ def barzilar_borwein(funcs: FuncArray,
|
|
|
163
163
|
print("{}\t{}\t{}".format(x_0, f[-1], k))
|
|
164
164
|
dk = -np.array(res.subs(reps)).astype(DataType)
|
|
165
165
|
if np.linalg.norm(dk) >= epsilon:
|
|
166
|
-
alpha = search(funcs,
|
|
166
|
+
alpha = search(funcs, args, x_0, dk, k, point, c1, beta, alpha, constant)
|
|
167
167
|
delta = alpha * dk[0]
|
|
168
168
|
x_0 = x_0 + delta
|
|
169
169
|
yk = np.array(res.subs(dict(zip(args, x_0)))).astype(DataType) + dk
|
|
@@ -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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|