-
Notifications
You must be signed in to change notification settings - Fork 197
/
Copy pathntrust.m
213 lines (212 loc) · 5.46 KB
/
ntrust.m
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
function [x,histout,costdata] = ntrust(x0,f,tol,maxit,resolution)
%
%
% C. T. Kelley, Dec 15, 1997
%
% This code comes with no guarantee or warranty of any kind.
%
% function [x,histout,costdata] = ntrust(x0,f,tol,maxit,resolution)
%
% Dogleg trust region, Newton model, dense algorithm
%
% Input: x0 = initial iterate
% f = objective function,
% the calling sequence for f should be
% [fout,gout]=f(x) where fout=f(x) is a scalar
% and gout = grad f(x) is a COLUMN vector
% tol = termination criterion norm(grad) < tol
% maxit = maximum iterations (optional) default = 100
% resolution = estimated accuracy in functions/gradients (optional)
% default = 1.d-12
% The finite difference increment in the difference
% Hessian is set to sqrt(resolution).
%
%
% Output: x = solution
% histout = iteration history
% Each row of histout is
% [norm(grad), f, TR radius, iteration count]
% costdata = [num f, num grad, num hess]
%
% Requires: diffhess.m, dirdero.m
%
% set maxit, the resolution, and the difference increment
%
debug=0;
if nargin < 4
maxit = 100;
end
if nargin < 5
resolution = 1.d-12;
end
hdiff=sqrt(resolution);
%
maxit=100; itc=1; xc=x0; n=length(x0);
[fc,gc]=feval(f,xc);
numf=1; numg=1; numh=0;
ithist=zeros(maxit,4);
ithist(1,1)=norm(gc); ithist(1,2) = fc; ithist(1,4)=itc-1;
ithist(1,3)=0;
if debug == 1
ithist(itc,:)
end
%
% Iniitalize the TR radius, not a profound choice.
trrad=min(norm(gc),10);
%
ijob=1;
jdata=[];
while(norm(gc) > tol & itc <= maxit)
if ijob == 1
hess=diffhess(xc,f,gc,hdiff);
numf=numf+n; numg=numg+n; numh=numh+1;
else
jdata=sdata;
end
itc=itc+1;
[xp,newrad,idid,sdata,nf]=trfix(xc, f, hess, gc, fc, trrad,ijob,jdata);
numf=numf+nf;
ijob=idid;
if idid == 2
sdata=jdata;
elseif idid == 3
xpold=xp; trold=trrad; sdata=jdata;
elseif idid == 4
xp=xpold; newrad=trold; ijob=1; idid=1;
end
xc=xp; trrad=newrad;
if idid==1
[fc,gc]=feval(f,xc);
numf=numf+1; numg=numg+1;
end
ithist(itc,1)=norm(gc); ithist(itc,2) = fc;
ithist(itc,4)=itc-1; ithist(itc,3)=trrad;
if debug == 1
ithist(itc,:)
end
end
x=xc; histout=ithist(1:itc,:);
costdata=[numf, numg, numh];
function [xp, newrad,idid,sdata,nf] =...
trfix(xc, f, hc, gc, fc, oldrad,ijob,jdata)
%
%
% C. T. Kelley, Dec 15, 1997
%
% This code comes with no guarantee or warranty of any kind.
%
% function [xt, newrad, idid, sdata, nf]
% = trfix(xc, f, hc, gc, oldrad, ijob, jdata)
%
% Figure out what the new trust region radius and new point are
%
% This code is called by ntrust.m
% There is no reason for you to call this directly.
%
% Input: xc = current point
% f = objective
% hc = current Hessian
% gc = current gradient
% fc = current function value
% oldrad = current TR radius
% ijob = what to do now: 1 = fresh start
% 2 = TR radius reduction in progress
% 3 = attempt TR radius expansion
% jdata = Newton direction when ijob = 1 or 2, avoids recomputation
% nf = number of function evaluations
%
% Output: xp = new point
% newrad = new TR radius
% idid = result flag: 1 = step ok
% 2 = TR radius reduced, step not ok
% 3 = expansion attempted, save step and try
% to do better
% 4 = expansion step failed, use the last good step
% sdata = Newton direction to use in next call if idid > 1
%
%
% Find the Cauchy point
%
% bflag=1 means that the trial point is on the TR boundary and is not
% the Newton point
%
nf=0;
bflag=0;
idid=1;
trrad=oldrad;
mu=gc'*hc*gc;
mu1=gc'*gc;
dsd=-gc;
if ijob == 1
dnewt=hc\dsd;
else
dnewt=jdata;
end
sdata=dnewt;
if mu > 0
sigma = mu1/mu;
if(sigma*norm(gc)) > trrad
sigma=trrad/norm(gc);
end
cp = xc-sigma*gc;
else
%
% If steepest descent direction is a direction of negative curvature
% take a flying leap to the boundary.
%
bflag=1;
sigma=trrad/norm(gc);
cp=xc-sigma*gc;
end
%
% If CP is on the TR boundary, that's the trial point.
% If it's not, compute the Newton point and complete the dogleg.
%
if bflag==1
xt=cp;
else
%
% If we get to this point, CP is in the interior and the steepest
% descent direction is a direction of positive curvature.
%
dsd=-gc; dnewt=hc\dsd;
xn=xc+dnewt;
mu2=dsd'*dnewt;
%
% If the Newton direction goes uphill, revert to CP.
%
if mu2 <= 0
xt=cp;
%
% If the Newton point is inside, take it.
%
elseif norm(dnewt) <= trrad
xt=xn;
%
% Newton is outside and CP is inside. Find the intersection of the
% dog leg path with TR boundary.
%
else
d1=sigma*gc; d2=d1+dnewt;
aco=d2'*d2; bco=-2*d1'*d2; cco= (d1'*d1) - trrad*trrad;
xi=(-bco+sqrt((bco*bco) - 4*aco*cco))/(2*aco);
xt=cp + xi*(xn-cp);
bflag=1;
end
end
%
% Now adjust the TR radius using the trial point
%
st=xt-xc; ft=feval(f,xt); ared=ft-fc; nf=nf+1;
pred=gc'*st + .5* (st'*hc*st);
if ared/pred < .25
xt=xc;
trrad=norm(st)*.5;
idid=2;
if ijob == 3 idid = 4; end
elseif ared/pred > .75 & bflag==1
trrad=trrad*2;
idid=3;
end
newrad=trrad;
xp=xt;