-
Notifications
You must be signed in to change notification settings - Fork 196
/
mds.m
148 lines (148 loc) · 3.56 KB
/
mds.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
function [x,lhist,histout]=mds(x0,f,tol,maxit,budget)
%
% Multidirectional search
%
% C. T. Kelley, July 17, 1998
%
%
% This code comes with no guarantee or warranty of any kind.
%
% function [x,lhist,histout] = mds(x0,f,tol,maxit,budget)
%
% inputs:
% vertices of initial simplex = x0 (n x n+1 matrix)
% The code will order the vertices for you and no benefit is
% accrued if you do it yourself.
%
% objective function = f
%
% termination tolerance = tol
% maximum number of iterations = maxit (default = 100)
% As of today, dist = | best value - worst value | < tol
% or when maxit iterations have been taken
% budget = max f evals (default=50*number of variables)
% The iteration will terminate after the iteration that
% exhausts the budget
%
%
% outputs:
% final simplex = x (n x n+1) matrix
% lhist = number of iterations before termination
% iteration histor = histout itout x 4
% histout = iteration history, updated after each nonlinear iteration
% = lhist x 4 array, the rows are
% [fcount, fval, norm(grad), dist, diam]
% fcount = cumulative function evals
% fval = current best function value
% dist = difference between worst and best values
% diam = max oriented length
%
% initialize counters
%
lhist=0; fcount=0;
%
% set debug=1 to print out iteration stats
%
debug=0;
%
% Set the MDS parameters
%
de=2; dc=.5;
%
% cache control paramters
%
global cache_size cache cache_ptr cache_fvals
[n,m]=size(x0);
cache_size=4*n; cache=zeros(n,cache_size); cache_ptr=0;
cache_fvals=zeros(cache_size,1);
%
if nargin < 4 maxit=100; end
if nargin < 5 budget=100*n; end
%
% Order the vertices for the first time
%
x=x0;
histout=[];
itout=0; orth=0; fv=zeros(n+1,1);
xtmp=zeros(n,n+1); z=zeros(n,n); delf=zeros(n,1);
for j=1:n+1; fv(j)=geval(f,x(:,j));
end; fcount=fcount+n+1;
[fs,is]=sort(fv); xtmp=x(:,is); x=xtmp; fv=fs;
itc=0; dist=fv(n+1)-fv(1);
diam=zeros(n,1);
for j=2:n+1
v(:,j-1)=-x(:,1)+x(:,j);
diam(j-1)=norm(v(:,j-1));
end
lhist=lhist+1;
thist=[fcount, fv(1), dist, max(diam)]; histout=[histout',thist']';
%
% main MDS loop
%
while(itc < maxit & dist > tol & fcount <= budget)
happy=0;
%
% reflect
%
for j=2:n+1 xr(:,j)=x(:,1) - v(:,j-1);
[fr(j),ctr] = geval(f,xr(:,j));
fcount=fcount+ctr;
end
%fcount=fcount+n;
fvr=min(fr(2:n+1));
if fv(1) > fvr
happy=1;
%
% expand
%
for j=2:n+1 xe(:,j)=x(:,1) - de*v(:,j-1); fe(j) = feval(f,xe(:,j)); end
fcount=fcount+n; fve=min(fe(2:n+1));
if fvr > fve
for j=2:n+1 x(:,j)=xe(:,j); fv(j)=fe(j); end
else
for j=2:n+1 x(:,j)=xr(:,j); fv(j)=fr(j); end
end
end
%
% contract
%
if happy==0
for j=2:n+1 x(:,j)=x(:,1) + dc*v(:,j-1);
[fv(j),ctr] = geval(f,x(:,j)); fcount=fcount+ctr;
end
% fcount=fcount+n;
end
%
% sort the new vertices
%
[fs,is]=sort(fv); xtmp=x(:,is); x=xtmp; fv=fs;
%
% compute the diameter of the new simplex and the iteration data
%
for j=2:n+1
v(:,j-1)=-x(:,1)+x(:,j);
diam(j-1)=norm(v(:,j-1));
end
dist=fv(n+1)-fv(1);
lhist=lhist+1;
thist=[fcount, fv(1), dist, max(diam)]; histout=[histout',thist']';
end
%
%
%
function [fs,ctr]=geval(fh,xh)
global cache_size cache cache_ptr cache_fvals
for i=1:cache_size
nz(i)=norm(xh-cache(:,i));
end
[vz,iz]=min(nz);
if vz == 0 & cache_ptr ~=0
fs=cache_fvals(iz);
ctr=0;
else
fs=feval(fh,xh);
ctr=1;
cache_ptr=mod(cache_ptr,cache_size)+1;
cache(:,cache_ptr)=xh;
cache_fvals(cache_ptr)=fs;
end