comparison Code/Descriptors/Matlab/MPEG7/FromWeb/VoiceSauce/fminsearchbnd.m @ 4:92ca03a8fa99 tip

Update to ICASSP 2013 benchmark
author Dawn Black
date Wed, 13 Feb 2013 11:02:39 +0000
parents
children
comparison
equal deleted inserted replaced
3:e1cfa7765647 4:92ca03a8fa99
1 function [x,fval,exitflag,output]=fminsearchbnd(fun,x0,LB,UB,options,varargin)
2 % FMINSEARCHBND: FMINSEARCH, but with bound constraints by transformation
3 % usage: x=FMINSEARCHBND(fun,x0)
4 % usage: x=FMINSEARCHBND(fun,x0,LB)
5 % usage: x=FMINSEARCHBND(fun,x0,LB,UB)
6 % usage: x=FMINSEARCHBND(fun,x0,LB,UB,options)
7 % usage: x=FMINSEARCHBND(fun,x0,LB,UB,options,p1,p2,...)
8 % usage: [x,fval,exitflag,output]=FMINSEARCHBND(fun,x0,...)
9 %
10 % arguments:
11 % fun, x0, options - see the help for FMINSEARCH
12 %
13 % LB - lower bound vector or array, must be the same size as x0
14 %
15 % If no lower bounds exist for one of the variables, then
16 % supply -inf for that variable.
17 %
18 % If no lower bounds at all, then LB may be left empty.
19 %
20 % Variables may be fixed in value by setting the corresponding
21 % lower and upper bounds to exactly the same value.
22 %
23 % UB - upper bound vector or array, must be the same size as x0
24 %
25 % If no upper bounds exist for one of the variables, then
26 % supply +inf for that variable.
27 %
28 % If no upper bounds at all, then UB may be left empty.
29 %
30 % Variables may be fixed in value by setting the corresponding
31 % lower and upper bounds to exactly the same value.
32 %
33 % Notes:
34 %
35 % If options is supplied, then TolX will apply to the transformed
36 % variables. All other FMINSEARCH parameters should be unaffected.
37 %
38 % Variables which are constrained by both a lower and an upper
39 % bound will use a sin transformation. Those constrained by
40 % only a lower or an upper bound will use a quadratic
41 % transformation, and unconstrained variables will be left alone.
42 %
43 % Variables may be fixed by setting their respective bounds equal.
44 % In this case, the problem will be reduced in size for FMINSEARCH.
45 %
46 % The bounds are inclusive inequalities, which admit the
47 % boundary values themselves, but will not permit ANY function
48 % evaluations outside the bounds. These constraints are strictly
49 % followed.
50 %
51 % If your problem has an EXCLUSIVE (strict) constraint which will
52 % not admit evaluation at the bound itself, then you must provide
53 % a slightly offset bound. An example of this is a function which
54 % contains the log of one of its parameters. If you constrain the
55 % variable to have a lower bound of zero, then FMINSEARCHBND may
56 % try to evaluate the function exactly at zero.
57 %
58 %
59 % Example usage:
60 % rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2;
61 %
62 % fminsearch(rosen,[3 3]) % unconstrained
63 % ans =
64 % 1.0000 1.0000
65 %
66 % fminsearchbnd(rosen,[3 3],[2 2],[]) % constrained
67 % ans =
68 % 2.0000 4.0000
69 %
70 % See test_main.m for other examples of use.
71 %
72 %
73 % See also: fminsearch, fminspleas
74 %
75 %
76 % Author: John D'Errico
77 % E-mail: woodchips@rochester.rr.com
78 % Release: 4
79 % Release date: 7/23/06
80
81 % size checks
82 xsize = size(x0);
83 x0 = x0(:);
84 n=length(x0);
85
86 if (nargin<3) || isempty(LB)
87 LB = repmat(-inf,n,1);
88 else
89 LB = LB(:);
90 end
91 if (nargin<4) || isempty(UB)
92 UB = repmat(inf,n,1);
93 else
94 UB = UB(:);
95 end
96
97 if (n~=length(LB)) || (n~=length(UB))
98 error 'x0 is incompatible in size with either LB or UB.'
99 end
100
101 % set default options if necessary
102 if (nargin<5) || isempty(options)
103 options = optimset('fminsearch');
104 end
105
106 % stuff into a struct to pass around
107 params.args = varargin;
108 params.LB = LB;
109 params.UB = UB;
110 params.fun = fun;
111 params.n = n;
112 params.OutputFcn = [];
113
114 % 0 --> unconstrained variable
115 % 1 --> lower bound only
116 % 2 --> upper bound only
117 % 3 --> dual finite bounds
118 % 4 --> fixed variable
119 params.BoundClass = zeros(n,1);
120 for i=1:n
121 k = isfinite(LB(i)) + 2*isfinite(UB(i));
122 params.BoundClass(i) = k;
123 if (k==3) && (LB(i)==UB(i))
124 params.BoundClass(i) = 4;
125 end
126 end
127
128 % transform starting values into their unconstrained
129 % surrogates. Check for infeasible starting guesses.
130 x0u = x0;
131 k=1;
132 for i = 1:n
133 switch params.BoundClass(i)
134 case 1
135 % lower bound only
136 if x0(i)<=LB(i)
137 % infeasible starting value. Use bound.
138 x0u(k) = 0;
139 else
140 x0u(k) = sqrt(x0(i) - LB(i));
141 end
142
143 % increment k
144 k=k+1;
145 case 2
146 % upper bound only
147 if x0(i)>=UB(i)
148 % infeasible starting value. use bound.
149 x0u(k) = 0;
150 else
151 x0u(k) = sqrt(UB(i) - x0(i));
152 end
153
154 % increment k
155 k=k+1;
156 case 3
157 % lower and upper bounds
158 if x0(i)<=LB(i)
159 % infeasible starting value
160 x0u(k) = -pi/2;
161 elseif x0(i)>=UB(i)
162 % infeasible starting value
163 x0u(k) = pi/2;
164 else
165 x0u(k) = 2*(x0(i) - LB(i))/(UB(i)-LB(i)) - 1;
166 % shift by 2*pi to avoid problems at zero in fminsearch
167 % otherwise, the initial simplex is vanishingly small
168 x0u(k) = 2*pi+asin(max(-1,min(1,x0u(k))));
169 end
170
171 % increment k
172 k=k+1;
173 case 0
174 % unconstrained variable. x0u(i) is set.
175 x0u(k) = x0(i);
176
177 % increment k
178 k=k+1;
179 case 4
180 % fixed variable. drop it before fminsearch sees it.
181 % k is not incremented for this variable.
182 end
183
184 end
185 % if any of the unknowns were fixed, then we need to shorten
186 % x0u now.
187 if k<=n
188 x0u(k:n) = [];
189 end
190
191 % were all the variables fixed?
192 if isempty(x0u)
193 % All variables were fixed. quit immediately, setting the
194 % appropriate parameters, then return.
195
196 % undo the variable transformations into the original space
197 x = xtransform(x0u,params);
198
199 % final reshape
200 x = reshape(x,xsize);
201
202 % stuff fval with the final value
203 fval = feval(params.fun,x,params.args{:});
204
205 % fminsearchbnd was not called
206 exitflag = 0;
207
208 output.iterations = 0;
209 output.funcount = 1;
210 output.algorithm = 'fminsearch';
211 output.message = 'All variables were held fixed by the applied bounds';
212
213 % return with no call at all to fminsearch
214 return
215 end
216
217 % Check for an outputfcn. If there is any, then substitute my
218 % own wrapper function.
219 if ~isempty(options.OutputFcn)
220 params.OutputFcn = options.OutputFcn;
221 options.OutputFcn = @outfun_wrapper;
222 end
223
224 % now we can call fminsearch, but with our own
225 % intra-objective function.
226 [xu,fval,exitflag,output] = fminsearch(@intrafun,x0u,options,params);
227
228 % undo the variable transformations into the original space
229 x = xtransform(xu,params);
230
231 % final reshape
232 x = reshape(x,xsize);
233
234 % Use a nested function as the OutputFcn wrapper
235 function stop = outfun_wrapper(x,varargin);
236 % we need to transform x first
237 xtrans = xtransform(x,params);
238
239 % then call the user supplied OutputFcn
240 stop = params.OutputFcn(xtrans,varargin{1:(end-1)});
241
242 end
243
244 end % mainline end
245
246 % ======================================
247 % ========= begin subfunctions =========
248 % ======================================
249 function fval = intrafun(x,params)
250 % transform variables, then call original function
251
252 % transform
253 xtrans = xtransform(x,params);
254
255 % and call fun
256 fval = feval(params.fun,xtrans,params.args{:});
257
258 end % sub function intrafun end
259
260 % ======================================
261 function xtrans = xtransform(x,params)
262 % converts unconstrained variables into their original domains
263
264 xtrans = zeros(1,params.n);
265 % k allows some variables to be fixed, thus dropped from the
266 % optimization.
267 k=1;
268 for i = 1:params.n
269 switch params.BoundClass(i)
270 case 1
271 % lower bound only
272 xtrans(i) = params.LB(i) + x(k).^2;
273
274 k=k+1;
275 case 2
276 % upper bound only
277 xtrans(i) = params.UB(i) - x(k).^2;
278
279 k=k+1;
280 case 3
281 % lower and upper bounds
282 xtrans(i) = (sin(x(k))+1)/2;
283 xtrans(i) = xtrans(i)*(params.UB(i) - params.LB(i)) + params.LB(i);
284 % just in case of any floating point problems
285 xtrans(i) = max(params.LB(i),min(params.UB(i),xtrans(i)));
286
287 k=k+1;
288 case 4
289 % fixed variable, bounds are equal, set it at either bound
290 xtrans(i) = params.LB(i);
291 case 0
292 % unconstrained variable.
293 xtrans(i) = x(k);
294
295 k=k+1;
296 end
297 end
298
299 end % sub function xtransform end
300
301
302
303
304