1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 """Testing functions.
27
28 This file is part of the U{minfx optimisation library<https://sourceforge.net/projects/minfx>}.
29 """
30
31
32 from math import cos, pi, sin, sqrt
33 from numpy import array, float64
34
35
36 from more_thuente import more_thuente
37
38
40 print("\n\n\n\n\n\n\n\n\n\n\n\n\t\t<<< Test Functions >>>\n\n\n")
41 print("\nSelect the function to test:")
42 while True:
43 input = raw_input('> ')
44 valid_functions = ['1', '2', '3', '4', '5', '6']
45 if input in valid_functions:
46 func = int(input)
47 break
48 else:
49 print("Choose a function number between 1 and 6.")
50
51 print("\nSelect a0:")
52 while True:
53 input = raw_input('> ')
54 valid_vals = ['1e-3', '1e-1', '1e1', '1e3']
55 if input in valid_vals:
56 a0 = float(input)
57 break
58 else:
59 print("Choose a0 as one of ['1e-3', '1e-1', '1e1', '1e3'].")
60
61 print("Testing line minimiser using test function " + repr(func))
62 if func == 1:
63 f, df = func1, dfunc1
64 mu, eta = 0.001, 0.1
65 elif func == 2:
66 f, df = func2, dfunc2
67 mu, eta = 0.1, 0.1
68 elif func == 3:
69 f, df = func3, dfunc3
70 mu, eta = 0.1, 0.1
71 elif func == 4:
72 f, df = func456, dfunc456
73 beta1, beta2 = 0.001, 0.001
74 mu, eta = 0.001, 0.001
75 elif func == 5:
76 f, df = func456, dfunc456
77 beta1, beta2 = 0.01, 0.001
78 mu, eta = 0.001, 0.001
79 elif func == 6:
80 f, df = func456, dfunc456
81 beta1, beta2 = 0.001, 0.01
82 mu, eta = 0.001, 0.001
83
84 xk = array([0.0], float64)
85 pk = array([1.0], float64)
86 if func >= 4:
87 args = (beta1, beta2)
88 else:
89 args = ()
90 f0 = f(*(xk,)+args)
91 g0 = df(*(xk,)+args)
92 a = more_thuente(f, df, args, xk, pk, f0, g0, a_init=a0, mu=mu, eta=eta, print_flag=1)
93 print("The minimum is at " + repr(a))
94
95
96 -def func1(alpha, beta=2.0):
97 """Test function 1.
98
99 From More, J. J., and Thuente, D. J. 1994, Line search algorithms with guaranteed sufficient decrease. ACM Trans. Math. Softw. 20, 286-307.
100
101 The function is::
102
103 alpha
104 phi(alpha) = - ---------------
105 alpha**2 + beta
106 """
107
108 return - alpha[0]/(alpha[0]**2 + beta)
109
110
112 """Derivative of test function 1.
113
114 From More, J. J., and Thuente, D. J. 1994, Line search algorithms with guaranteed sufficient decrease. ACM Trans. Math. Softw. 20, 286-307.
115
116 The gradient is::
117
118 2*alpha**2 1
119 phi'(alpha) = -------------------- - ---------------
120 (alpha**2 + beta)**2 alpha**2 + beta
121 """
122
123 temp = array([0.0], float64)
124 if alpha[0] > 1e90:
125 return temp
126 else:
127 a = 2.0*(alpha[0]**2)/((alpha[0]**2 + beta)**2)
128 b = 1.0/(alpha[0]**2 + beta)
129 temp[0] = a - b
130 return temp
131
132
133 -def func2(alpha, beta=0.004):
134 """Test function 2.
135
136 From More, J. J., and Thuente, D. J. 1994, Line search algorithms with guaranteed sufficient decrease. ACM Trans. Math. Softw. 20, 286-307.
137
138 The function is::
139
140 phi(alpha) = (alpha + beta)**5 - 2(alpha + beta)**4
141 """
142
143 return (alpha[0] + beta)**5 - 2.0*((alpha[0] + beta)**4)
144
145
146 -def dfunc2(alpha, beta=0.004):
147 """Derivative of test function 2.
148
149 From More, J. J., and Thuente, D. J. 1994, Line search algorithms with guaranteed sufficient decrease. ACM Trans. Math. Softw. 20, 286-307.
150
151 The gradient is::
152
153 phi'(alpha) = 5(alpha + beta)**4 - 8(alpha + beta)**3
154 """
155
156 temp = array([0.0], float64)
157 temp[0] = 5.0*((alpha[0] + beta)**4) - 8.0*((alpha[0] + beta)**3)
158 return temp
159
160
161 -def func3(alpha, beta=0.01, l=39.0):
162 """Test function 3.
163
164 From More, J. J., and Thuente, D. J. 1994, Line search algorithms with guaranteed sufficient decrease. ACM Trans. Math. Softw. 20, 286-307.
165
166 The function is::
167
168 2(1 - beta) / l*pi \
169 phi(alpha) = phi0(alpha) + ----------- . sin | ---- . alpha |
170 l*pi \ 2 /
171
172 where::
173
174 / 1 - alpha, if alpha <= 1 - beta,
175 |
176 | alpha - 1, if alpha >= 1 + beta,
177 phi0(alpha) = <
178 | 1 1
179 | ------(alpha - 1)**2 + - beta, if alpha in [1 - beta, 1 + beta].
180 \ 2*beta 2
181 """
182
183
184 if alpha[0] <= 1.0 - beta:
185 phi0 = 1.0 - alpha[0]
186 elif alpha[0] >= 1.0 + beta:
187 phi0 = alpha[0] - 1.0
188 else:
189 phi0 = 0.5/beta * (alpha[0] - 1.0)**2 + 0.5*beta
190
191 return phi0 + 2.0*(1.0 - beta)/(l*pi) * sin(0.5 * l * pi * alpha[0])
192
193
194 -def dfunc3(alpha, beta=0.01, l=39.0):
195 """Derivative of test function 3.
196
197 From More, J. J., and Thuente, D. J. 1994, Line search algorithms with guaranteed sufficient decrease. ACM Trans. Math. Softw. 20, 286-307.
198
199 The gradient is::
200 / l*pi \
201 phi(alpha) = phi0'(alpha) + (1 - beta) . cos | ---- . alpha |
202 \ 2 /
203
204 where::
205
206 / -1, if alpha <= 1 - beta,
207 |
208 | 1, if alpha >= 1 + beta,
209 phi0'(alpha) = <
210 | alpha - 1
211 | ---------, if alpha in [1 - beta, 1 + beta].
212 \ beta
213 """
214
215
216 if alpha[0] <= 1.0 - beta:
217 phi0_prime = -1.0
218 elif alpha[0] >= 1.0 + beta:
219 phi0_prime = 1.0
220 else:
221 phi0_prime = (alpha[0] - 1.0)/beta
222
223 temp = array([0.0], float64)
224 temp[0] = phi0_prime + (1.0 - beta) * cos(0.5 * l * pi * alpha[0])
225 return temp
226
227
229 """Test functions 4, 5, and 6.
230
231 From More, J. J., and Thuente, D. J. 1994, Line search algorithms with guaranteed sufficient decrease. ACM Trans. Math. Softw. 20, 286-307.
232
233 The function is::
234
235 phi(alpha) = gamma(beta1) * sqrt((1 - alpha)**2 + beta2**2)
236 + gamma(beta2) * sqrt(alpha**2 + beta1**2)
237
238 where::
239
240 gamma(beta) = sqrt(1 + beta**2) - beta
241 """
242
243 g1 = sqrt(1.0 + beta1**2) - beta1
244 g2 = sqrt(1.0 + beta2**2) - beta2
245 return g1 * sqrt((1.0 - alpha[0])**2 + beta2**2) + g2 * sqrt(alpha[0]**2 + beta1**2)
246
247
249 """Test functions 4, 5, and 6.
250
251 From More, J. J., and Thuente, D. J. 1994, Line search algorithms with guaranteed sufficient decrease. ACM Trans. Math. Softw. 20, 286-307.
252
253 The function is::
254
255 (1 - alpha)
256 phi'(alpha) = - gamma(beta1) * -------------------------------
257 sqrt((1 - alpha)**2 + beta2**2)
258
259 a
260 + gamma(beta2) * -------------------------
261 sqrt(alpha**2 + beta1**2)
262
263 where::
264
265 gamma(beta) = sqrt(1 + beta**2) - beta
266 """
267
268 temp = array([0.0], float64)
269 g1 = sqrt(1.0 + beta1**2) - beta1
270 g2 = sqrt(1.0 + beta2**2) - beta2
271 a = -g1 * (1.0 - alpha[0]) / sqrt((1.0 - alpha[0])**2 + beta2**2)
272 b = g2 * alpha[0] / sqrt(alpha[0]**2 + beta1**2)
273 temp[0] = a + b
274 return temp
275
276
277 if __name__ == '__main__':
278 run()
279