1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """Cauchy Point trust region nonlinear optimization.
25
26 This file is part of the U{minfx optimisation library<https://sourceforge.net/projects/minfx>}.
27 """
28
29
30 from numpy import dot, sqrt
31
32
33 from minfx.base_classes import Min, Trust_region
34
35
36 -def cauchy_point(func=None, dfunc=None, d2func=None, args=(), x0=None, func_tol=1e-25, grad_tol=None, maxiter=1e6, delta_max=1e5, delta0=1.0, eta=0.2, full_output=0, print_flag=0, print_prefix=""):
37 """Cauchy Point trust region algorithm.
38
39 Page 69 from 'Numerical Optimization' by Jorge Nocedal and Stephen J. Wright, 1999, 2nd ed. The Cauchy point is defined by::
40
41 delta
42 pCk = - tau_k ------- dfk
43 ||dfk||
44
45 where:
46
47 - delta_k is the trust region radius,
48 - dfk is the gradient vector,
49
50 and::
51
52 / 1 if dfk . Bk . dfk <= 0
53 tau_k = <
54 \ min(||dfk||**2/(delta . dfk . Bk . dfk), 1) otherwise.
55 """
56
57 if print_flag:
58 if print_flag >= 2:
59 print(print_prefix)
60 print(print_prefix)
61 print(print_prefix + "Cauchy point minimisation")
62 print(print_prefix + "~~~~~~~~~~~~~~~~~~~~~~~~~")
63 min = Cauchy_point(func, dfunc, d2func, args, x0, func_tol, grad_tol, maxiter, delta_max, delta0, eta, full_output, print_flag, print_prefix)
64 results = min.minimise()
65 return results
66
67
69 - def __init__(self, func, dfunc, d2func, args, x0, func_tol, grad_tol, maxiter, delta_max, delta0, eta, full_output, print_flag, print_prefix):
70 """Class for Cauchy Point trust region minimisation specific functions.
71
72 Unless you know what you are doing, you should call the function 'cauchy_point' rather than using this class.
73 """
74
75
76 self.func = func
77 self.dfunc = dfunc
78 self.d2func = d2func
79 self.args = args
80 self.xk = x0
81 self.func_tol = func_tol
82 self.grad_tol = grad_tol
83 self.maxiter = maxiter
84 self.full_output = full_output
85 self.print_flag = print_flag
86 self.print_prefix = print_prefix
87 self.delta_max = delta_max
88 self.delta = delta0
89 self.eta = eta
90
91
92 self.f_count = 0
93 self.g_count = 0
94 self.h_count = 0
95
96
97 self.warning = None
98
99
100 self.setup_conv_tests()
101
102
103 self.fk, self.f_count = self.func(*(self.xk,)+self.args), self.f_count + 1
104 self.dfk, self.g_count = self.dfunc(*(self.xk,)+self.args), self.g_count + 1
105 self.d2fk, self.h_count = self.d2func(*(self.xk,)+self.args), self.h_count + 1
106
107
109 """Find the Cauchy point."""
110
111
112 curv = dot(self.dfk, dot(self.d2fk, self.dfk))
113 norm_dfk = sqrt(dot(self.dfk, self.dfk))
114
115
116 if curv <= 0.0:
117 self.tau_k = 1.0
118 else:
119 self.tau_k = min(norm_dfk ** 3 / (self.delta * curv), 1.0)
120
121 if self.print_flag >= 2:
122 print(self.print_prefix + "dfk . Bk . dfk: " + repr(curv))
123 print(self.print_prefix + "tau_k: " + repr(self.tau_k))
124
125
126 self.pk = - self.tau_k * self.delta * self.dfk / norm_dfk
127
128
129 self.xk_new = self.xk + self.pk
130 self.fk_new, self.f_count = self.func(*(self.xk_new,)+self.args), self.f_count + 1
131 self.dfk_new, self.g_count = self.dfunc(*(self.xk_new,)+self.args), self.g_count + 1
132
133
135 """Update function.
136
137 Function to update the function value, gradient vector, and Hessian matrix.
138 """
139
140 self.xk = self.xk_new * 1.0
141 self.fk = self.fk_new
142 self.dfk = self.dfk_new * 1.0
143 self.d2fk, self.h_count = self.d2func(*(self.xk,)+self.args), self.h_count + 1
144