init
This commit is contained in:
47
FOTF Toolbox/fminsearchbnd/demo/fminsearchbnd_demo.m
Normal file
47
FOTF Toolbox/fminsearchbnd/demo/fminsearchbnd_demo.m
Normal file
@ -0,0 +1,47 @@
|
||||
%% Optimization of a simple (Rosenbrock) function, with no constraints
|
||||
rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2;
|
||||
|
||||
% With no constraints, operation simply passes through
|
||||
% directly to fminsearch. The solution should be [1 1]
|
||||
xsol = fminsearchbnd(rosen,[3 3])
|
||||
|
||||
%% Only lower bound constraints
|
||||
xsol = fminsearchbnd(rosen,[3 3],[2 2])
|
||||
|
||||
%% Only upper bound constraints
|
||||
xsol = fminsearchbnd(rosen,[-5 -5],[],[0 0])
|
||||
|
||||
%% Dual constraints
|
||||
xsol = fminsearchbnd(rosen,[2.5 2.5],[2 2],[3 3])
|
||||
|
||||
%% Mixed constraints
|
||||
xsol = fminsearchbnd(rosen,[0 0],[2 -inf],[inf 3])
|
||||
|
||||
%% Provide your own fminsearch options
|
||||
opts = optimset('fminsearch');
|
||||
opts.Display = 'iter';
|
||||
opts.TolX = 1.e-12;
|
||||
opts.MaxFunEvals = 100;
|
||||
|
||||
n = [10,5];
|
||||
H = randn(n);
|
||||
H=H'*H;
|
||||
Quadraticfun = @(x) x*H*x';
|
||||
|
||||
% Global minimizer is at [0 0 0 0 0].
|
||||
% Set all lower bound constraints, all of which will
|
||||
% be active in this test.
|
||||
LB = [.5 .5 .5 .5 .5];
|
||||
xsol = fminsearchbnd(Quadraticfun,[1 2 3 4 5],LB,[],opts)
|
||||
|
||||
%% Exactly fix one variable, constrain some others, and set a tolerance
|
||||
opts = optimset('fminsearch');
|
||||
opts.TolFun = 1.e-12;
|
||||
|
||||
LB = [-inf 2 1 -10];
|
||||
UB = [ inf inf 1 inf];
|
||||
xsol = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB,opts)
|
||||
|
||||
%% All the standard outputs from fminsearch are still returned
|
||||
[xsol,fval,exitflag,output] = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB)
|
||||
|
299
FOTF Toolbox/fminsearchbnd/demo/html/fminsearchbnd_demo.html
Normal file
299
FOTF Toolbox/fminsearchbnd/demo/html/fminsearchbnd_demo.html
Normal file
@ -0,0 +1,299 @@
|
||||
<html xmlns:mwsh="http://www.mathworks.com/namespace/mcode/v1/syntaxhighlight.dtd">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
||||
<!--
|
||||
This HTML is auto-generated from an M-file.
|
||||
To make changes, update the M-file and republish this document.
|
||||
-->
|
||||
<title>fminsearchbnd_demo</title>
|
||||
<meta name="generator" content="MATLAB 7.0.1">
|
||||
<meta name="date" content="2006-07-24">
|
||||
<meta name="m-file" content="fminsearchbnd_demo"><style>
|
||||
body {
|
||||
background-color: white;
|
||||
margin:10px;
|
||||
}
|
||||
h1 {
|
||||
color: #990000;
|
||||
font-size: x-large;
|
||||
}
|
||||
h2 {
|
||||
color: #990000;
|
||||
font-size: medium;
|
||||
}
|
||||
p.footer {
|
||||
text-align: right;
|
||||
font-size: xx-small;
|
||||
font-weight: lighter;
|
||||
font-style: italic;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
pre.codeinput {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
span.keyword {color: #0000FF}
|
||||
span.comment {color: #228B22}
|
||||
span.string {color: #A020F0}
|
||||
span.untermstring {color: #B20000}
|
||||
span.syscmd {color: #B28C00}
|
||||
|
||||
pre.showbuttons {
|
||||
margin-left: 30px;
|
||||
border: solid black 2px;
|
||||
padding: 4px;
|
||||
background: #EBEFF3;
|
||||
}
|
||||
|
||||
pre.codeoutput {
|
||||
color: gray;
|
||||
font-style: italic;
|
||||
}
|
||||
pre.error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/* Make the text shrink to fit narrow windows, but not stretch too far in
|
||||
wide windows. On Gecko-based browsers, the shrink-to-fit doesn't work. */
|
||||
p,h1,h2,div {
|
||||
/* for MATLAB's browser */
|
||||
width: 600px;
|
||||
/* for Mozilla, but the "width" tag overrides it anyway */
|
||||
max-width: 600px;
|
||||
/* for IE */
|
||||
width:expression(document.body.clientWidth > 620 ? "600px": "auto" );
|
||||
}
|
||||
|
||||
</style></head>
|
||||
<body>
|
||||
<h2>Contents</h2>
|
||||
<div>
|
||||
<ul>
|
||||
<li><a href="#1">Optimization of a simple (Rosenbrock) function, with no constraints</a></li>
|
||||
<li><a href="#2">Only lower bound constraints</a></li>
|
||||
<li><a href="#3">Only upper bound constraints</a></li>
|
||||
<li><a href="#4">Dual constraints</a></li>
|
||||
<li><a href="#5">Mixed constraints</a></li>
|
||||
<li><a href="#6">Provide your own fminsearch options</a></li>
|
||||
<li><a href="#7">Exactly fix one variable, constrain some others, and set a tolerance</a></li>
|
||||
<li><a href="#8">All the standard outputs from fminsearch are still returned</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<h2>Optimization of a simple (Rosenbrock) function, with no constraints<a name="1"></a></h2><pre class="codeinput">rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2;
|
||||
|
||||
<span class="comment">% With no constraints, operation simply passes through</span>
|
||||
<span class="comment">% directly to fminsearch. The solution should be [1 1]</span>
|
||||
xsol = fminsearchbnd(rosen,[3 3])
|
||||
</pre><pre class="codeoutput">
|
||||
xsol =
|
||||
|
||||
0.99998 0.99995
|
||||
|
||||
</pre><h2>Only lower bound constraints<a name="2"></a></h2><pre class="codeinput">xsol = fminsearchbnd(rosen,[3 3],[2 2])
|
||||
</pre><pre class="codeoutput">
|
||||
xsol =
|
||||
|
||||
2 4
|
||||
|
||||
</pre><h2>Only upper bound constraints<a name="3"></a></h2><pre class="codeinput">xsol = fminsearchbnd(rosen,[-5 -5],[],[0 0])
|
||||
</pre><pre class="codeoutput">
|
||||
xsol =
|
||||
|
||||
-1.0447e-13 -1.4451e-08
|
||||
|
||||
</pre><h2>Dual constraints<a name="4"></a></h2><pre class="codeinput">xsol = fminsearchbnd(rosen,[2.5 2.5],[2 2],[3 3])
|
||||
</pre><pre class="codeoutput">
|
||||
xsol =
|
||||
|
||||
2 3
|
||||
|
||||
</pre><h2>Mixed constraints<a name="5"></a></h2><pre class="codeinput">xsol = fminsearchbnd(rosen,[0 0],[2 -inf],[inf 3])
|
||||
</pre><pre class="codeoutput">
|
||||
xsol =
|
||||
|
||||
2 3
|
||||
|
||||
</pre><h2>Provide your own fminsearch options<a name="6"></a></h2><pre class="codeinput">opts = optimset(<span class="string">'fminsearch'</span>);
|
||||
opts.Display = <span class="string">'iter'</span>;
|
||||
opts.TolX = 1.e-12;
|
||||
opts.MaxFunEvals = 100;
|
||||
|
||||
n = [10,5];
|
||||
H = randn(n);
|
||||
H=H'*H;
|
||||
Quadraticfun = @(x) x*H*x';
|
||||
|
||||
<span class="comment">% Global minimizer is at [0 0 0 0 0].</span>
|
||||
<span class="comment">% Set all lower bound constraints, all of which will</span>
|
||||
<span class="comment">% be active in this test.</span>
|
||||
LB = [.5 .5 .5 .5 .5];
|
||||
xsol = fminsearchbnd(Quadraticfun,[1 2 3 4 5],LB,[],opts)
|
||||
</pre><pre class="codeoutput">
|
||||
Iteration Func-count min f(x) Procedure
|
||||
0 1 173.731
|
||||
1 6 172.028 initial simplex
|
||||
2 8 162.698 expand
|
||||
3 9 162.698 reflect
|
||||
4 11 151.902 expand
|
||||
5 13 138.235 expand
|
||||
6 14 138.235 reflect
|
||||
7 16 126.604 expand
|
||||
8 17 126.604 reflect
|
||||
9 19 97.3266 expand
|
||||
10 20 97.3266 reflect
|
||||
11 21 97.3266 reflect
|
||||
12 22 97.3266 reflect
|
||||
13 24 73.7178 expand
|
||||
14 25 73.7178 reflect
|
||||
15 26 73.7178 reflect
|
||||
16 28 50.8236 expand
|
||||
17 29 50.8236 reflect
|
||||
18 31 41.6294 expand
|
||||
19 33 30.4252 expand
|
||||
20 34 30.4252 reflect
|
||||
21 36 27.782 reflect
|
||||
22 37 27.782 reflect
|
||||
23 39 27.782 contract inside
|
||||
24 41 22.6509 reflect
|
||||
25 42 22.6509 reflect
|
||||
26 43 22.6509 reflect
|
||||
27 44 22.6509 reflect
|
||||
28 45 22.6509 reflect
|
||||
29 47 21.0211 reflect
|
||||
30 48 21.0211 reflect
|
||||
31 49 21.0211 reflect
|
||||
32 51 21.0211 contract inside
|
||||
33 52 21.0211 reflect
|
||||
34 54 20.7613 contract inside
|
||||
35 55 20.7613 reflect
|
||||
36 56 20.7613 reflect
|
||||
37 57 20.7613 reflect
|
||||
38 59 20.6012 contract inside
|
||||
39 61 20.5324 contract inside
|
||||
40 63 20.4961 contract inside
|
||||
41 65 20.3886 contract inside
|
||||
42 67 20.2121 reflect
|
||||
43 69 20.0876 contract inside
|
||||
44 71 19.9164 reflect
|
||||
45 72 19.9164 reflect
|
||||
46 74 19.9164 contract inside
|
||||
47 76 19.9164 contract outside
|
||||
48 78 19.3349 expand
|
||||
49 80 19.3349 contract inside
|
||||
50 81 19.3349 reflect
|
||||
51 82 19.3349 reflect
|
||||
52 84 18.8721 expand
|
||||
53 85 18.8721 reflect
|
||||
54 87 18.6427 expand
|
||||
55 89 17.4548 expand
|
||||
56 90 17.4548 reflect
|
||||
57 92 16.0113 expand
|
||||
58 93 16.0113 reflect
|
||||
59 94 16.0113 reflect
|
||||
60 96 14.6134 expand
|
||||
61 98 12.5445 expand
|
||||
62 99 12.5445 reflect
|
||||
63 101 10.7311 expand
|
||||
|
||||
Exiting: Maximum number of function evaluations has been exceeded
|
||||
- increase MaxFunEvals option.
|
||||
Current function value: 10.731146
|
||||
|
||||
|
||||
xsol =
|
||||
|
||||
1.7022 1.0787 1.2034 0.5006 0.64666
|
||||
|
||||
</pre><h2>Exactly fix one variable, constrain some others, and set a tolerance<a name="7"></a></h2><pre class="codeinput">opts = optimset(<span class="string">'fminsearch'</span>);
|
||||
opts.TolFun = 1.e-12;
|
||||
|
||||
LB = [-inf 2 1 -10];
|
||||
UB = [ inf inf 1 inf];
|
||||
xsol = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB,opts)
|
||||
</pre><pre class="codeoutput">
|
||||
xsol =
|
||||
|
||||
-4.9034e-07 2 1 5.1394e-07
|
||||
|
||||
</pre><h2>All the standard outputs from fminsearch are still returned<a name="8"></a></h2><pre class="codeinput">[xsol,fval,exitflag,output] = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB)
|
||||
</pre><pre class="codeoutput">
|
||||
xsol =
|
||||
|
||||
3.1094e-05 2 1 -5.1706e-05
|
||||
|
||||
|
||||
fval =
|
||||
|
||||
2.2361
|
||||
|
||||
|
||||
exitflag =
|
||||
|
||||
1
|
||||
|
||||
|
||||
output =
|
||||
|
||||
iterations: 77
|
||||
funcCount: 138
|
||||
algorithm: 'Nelder-Mead simplex direct search'
|
||||
message: [1x194 char]
|
||||
|
||||
</pre><p class="footer"><br>
|
||||
Published with MATLAB® 7.0.1<br></p>
|
||||
<!--
|
||||
##### SOURCE BEGIN #####
|
||||
%% Optimization of a simple (Rosenbrock) function, with no constraints
|
||||
rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2;
|
||||
|
||||
% With no constraints, operation simply passes through
|
||||
% directly to fminsearch. The solution should be [1 1]
|
||||
xsol = fminsearchbnd(rosen,[3 3])
|
||||
|
||||
%% Only lower bound constraints
|
||||
xsol = fminsearchbnd(rosen,[3 3],[2 2])
|
||||
|
||||
%% Only upper bound constraints
|
||||
xsol = fminsearchbnd(rosen,[-5 -5],[],[0 0])
|
||||
|
||||
%% Dual constraints
|
||||
xsol = fminsearchbnd(rosen,[2.5 2.5],[2 2],[3 3])
|
||||
|
||||
%% Mixed constraints
|
||||
xsol = fminsearchbnd(rosen,[0 0],[2 -inf],[inf 3])
|
||||
|
||||
%% Provide your own fminsearch options
|
||||
opts = optimset('fminsearch');
|
||||
opts.Display = 'iter';
|
||||
opts.TolX = 1.e-12;
|
||||
opts.MaxFunEvals = 100;
|
||||
|
||||
n = [10,5];
|
||||
H = randn(n);
|
||||
H=H'*H;
|
||||
Quadraticfun = @(x) x*H*x';
|
||||
|
||||
% Global minimizer is at [0 0 0 0 0].
|
||||
% Set all lower bound constraints, all of which will
|
||||
% be active in this test.
|
||||
LB = [.5 .5 .5 .5 .5];
|
||||
xsol = fminsearchbnd(Quadraticfun,[1 2 3 4 5],LB,[],opts)
|
||||
|
||||
%% Exactly fix one variable, constrain some others, and set a tolerance
|
||||
opts = optimset('fminsearch');
|
||||
opts.TolFun = 1.e-12;
|
||||
|
||||
LB = [-inf 2 1 -10];
|
||||
UB = [ inf inf 1 inf];
|
||||
xsol = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB,opts)
|
||||
|
||||
%% All the standard outputs from fminsearch are still returned
|
||||
[xsol,fval,exitflag,output] = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB)
|
||||
|
||||
|
||||
##### SOURCE END #####
|
||||
-->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,98 @@
|
||||
{\rtf1\mac\ansicpg10000\cocoartf102
|
||||
{\fonttbl\f0\fswiss\fcharset77 Helvetica;\f1\fswiss\fcharset77 Helvetica-Bold;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\margl1440\margr1440\vieww12760\viewh17780\viewkind0
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qc
|
||||
|
||||
\f0\fs24 \cf0 \
|
||||
|
||||
\f1\b Understanding fminsearchbnd\
|
||||
\
|
||||
John D'Errico\
|
||||
woodchips@rochester.rr.com
|
||||
\f0\b0 \
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
|
||||
\cf0 \
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qj
|
||||
\cf0 \
|
||||
Fminsearchbnd is really quite simple in concept. I've implemented lower and upper bound constraints by the careful use of transformations of the variables. In turn, the optimization engine is itself fminsearch itself.\
|
||||
\
|
||||
Since fminsearch does not allow bound constraints, the trick is to insert a wrapper function around the user supplied objective function. I've done all the work, so all you, as the user, needs to do is supply a set of bounds. All the other arguments are identical to that which fminsearch would have expected. \
|
||||
\
|
||||
There are several classes of bound constraints one might consider. Simple lower bound constraints:\
|
||||
\
|
||||
LB(i) <= x(i)\
|
||||
\
|
||||
Upper bound constraints:\
|
||||
\
|
||||
x(i) <= UB(i)\
|
||||
\
|
||||
Dual constraints\
|
||||
\
|
||||
LB(i) <= x(i) <= UB(i)\
|
||||
\
|
||||
Two other classes that I allow are fully unbounded variables, and a dual constraint where the lower and upper bounds are identical. In essence, this last class of constraint fixes the variable at the given level. Of course, internally in fminsearchbnd, I just completely remove that variable from the optimization, so fminsearch never sees the variable at all.\
|
||||
\
|
||||
The bounded variables are transformed such that fminsearch itself sees a fully unconstrained problem. For example, in the case of a variable bounded on the lower end by LB(i), I use the transformation\
|
||||
\
|
||||
x(i) = LB(i) + z(i)^2\
|
||||
\
|
||||
The variable z(i) is fully unconstrained, but since the square of z(i) is always non-negative (for real z), then x(i) must necessarily be always greater than or equal to LB(i). Likewise, a pure upper bound constraint is implemented as\
|
||||
\
|
||||
x(i) = UB(i) - z(i)^2\
|
||||
\
|
||||
Clearly, x(i) in this case can never rise above UB(i). And finally, the dual bounded variable is handled by a trigonometric transformation,\
|
||||
\
|
||||
x(i) = LB(i) + (UB(i) - LB(i))*(sin(z(i))+1)/2\
|
||||
\
|
||||
In this last case, I do absolutely enforce the requirement that LB(i) <= x(i) <= UB(i), since the vagaries of floating point arithmetic might sometimes cause those bounds to be subtly exceeded.\
|
||||
\
|
||||
\
|
||||
|
||||
\f1\b Multiple solutions due to the transformations\
|
||||
|
||||
\f0\b0 \
|
||||
An artifact of the transformations used is the creation of multiple solutions to a problem that at one time may well have had a unique solution. While the presence of multiple local solutions is often a problem for an optimizer, each of these introduced solutions are fully equivalent. It matters not in the least which one is found.\
|
||||
\
|
||||
\
|
||||
|
||||
\f1\b Alternative choices for the transformations\
|
||||
|
||||
\f0\b0 \
|
||||
I have occasionally seen it suggested that one use a sin(z)^2 transformation instead of the chosen form based on sin(z). My own feeling is that either could be used to roughly equal advantage, but that the sin^2 transformation may be slightly more nonlinear, causing subtly more problems in terms of floating point arithmetic. Similarly, I've tried other one sided and two sided transformations. A two sided transformation that I found to be of interest utilized atan(z). My testing showed that it was often more slowly convergent near the bounds, taking more iterations to converge. The atan transformation was a good choice as a way to implement exclusive bounds (see below.)\
|
||||
\
|
||||
\
|
||||
|
||||
\f1\b Inclusive versus exclusive bounds\
|
||||
|
||||
\f0\b0 \
|
||||
A feature of the bound constraints that I have chosen to implement in fminsearchbnd is that they are inclusive bounds. That is, these constraints allow the boundary value itself to be achieved. Exclusive constraints would correspond to the strict inequalities, < and >. Why is this difference between inclusive and exclusive bound constraints an issue? As I said, fminsearchbnd allows its bounds to be fully achieved. So if your objective function includes an evaluation of log(x), where x is constrained to be greater than or equal to zero, then Matlab will generate a singularity.\
|
||||
\
|
||||
>> log(0)\
|
||||
Warning: Log of zero.\
|
||||
\
|
||||
ans =\
|
||||
-Inf\
|
||||
\
|
||||
An exclusive bound at zero would have prevented such an error. I've chosen not to implement them in that form however, as the necessary transformations tend to be somewhat more intractable, converging with less rapidity in practice. Also, the interface would have been more complex had I allowed the user to specify the actual boundary type for each constraint.\
|
||||
\
|
||||
All of this means that if you really need exclusive bounds, then you must offset your bound limits by a small amount.\
|
||||
\
|
||||
\
|
||||
|
||||
\f1\b Starting values, infeasible starting values, tolerances, etc.\
|
||||
|
||||
\f0\b0 \
|
||||
The transformations chosen for fminsearchbnd are all simply invertible. This allows the user supplied starting values for each variable (prior to any transformation) to be simply mapped back to a corresponding value. Infeasible starting values are simply resolved for the bound constrained problem by simply clipping to the bounded domain.\
|
||||
\
|
||||
A more difficult issue is the question of tolerances on the parameters, that is, TolX. The nonlinear transformations mean that fminsearch itself will see only the transformed parameters, not the parameters in their real domain. As I've implemented fminsearchbnd as an overlay to fminsearch itself, there is no simple way to provide explicit control over the variable tolerances without re-writing fminsearch. \
|
||||
\
|
||||
\
|
||||
|
||||
\f1\b Limitations of fminsearchbnd\
|
||||
|
||||
\f0\b0 \
|
||||
What does fminsearchbnd NOT do? You cannot provide general linear/nonlinear equality or inequality constraints, as are provided by fmincon, or lsqlin. Only simple bound constraints are allowed.\
|
||||
\
|
||||
\
|
||||
}
|
BIN
FOTF Toolbox/fminsearchbnd/doc/~$derstanding_fminsearchbnd.rtf
Normal file
BIN
FOTF Toolbox/fminsearchbnd/doc/~$derstanding_fminsearchbnd.rtf
Normal file
Binary file not shown.
304
FOTF Toolbox/fminsearchbnd/fminsearchbnd.m
Normal file
304
FOTF Toolbox/fminsearchbnd/fminsearchbnd.m
Normal file
@ -0,0 +1,304 @@
|
||||
function [x,fval,exitflag,output]=fminsearchbnd3(fun,x0,LB,UB,options,varargin)
|
||||
% FMINSEARCHBND: FMINSEARCH, but with bound constraints by transformation
|
||||
% usage: x=FMINSEARCHBND(fun,x0)
|
||||
% usage: x=FMINSEARCHBND(fun,x0,LB)
|
||||
% usage: x=FMINSEARCHBND(fun,x0,LB,UB)
|
||||
% usage: x=FMINSEARCHBND(fun,x0,LB,UB,options)
|
||||
% usage: x=FMINSEARCHBND(fun,x0,LB,UB,options,p1,p2,...)
|
||||
% usage: [x,fval,exitflag,output]=FMINSEARCHBND(fun,x0,...)
|
||||
%
|
||||
% arguments:
|
||||
% fun, x0, options - see the help for FMINSEARCH
|
||||
%
|
||||
% LB - lower bound vector or array, must be the same size as x0
|
||||
%
|
||||
% If no lower bounds exist for one of the variables, then
|
||||
% supply -inf for that variable.
|
||||
%
|
||||
% If no lower bounds at all, then LB may be left empty.
|
||||
%
|
||||
% Variables may be fixed in value by setting the corresponding
|
||||
% lower and upper bounds to exactly the same value.
|
||||
%
|
||||
% UB - upper bound vector or array, must be the same size as x0
|
||||
%
|
||||
% If no upper bounds exist for one of the variables, then
|
||||
% supply +inf for that variable.
|
||||
%
|
||||
% If no upper bounds at all, then UB may be left empty.
|
||||
%
|
||||
% Variables may be fixed in value by setting the corresponding
|
||||
% lower and upper bounds to exactly the same value.
|
||||
%
|
||||
% Notes:
|
||||
%
|
||||
% If options is supplied, then TolX will apply to the transformed
|
||||
% variables. All other FMINSEARCH parameters should be unaffected.
|
||||
%
|
||||
% Variables which are constrained by both a lower and an upper
|
||||
% bound will use a sin transformation. Those constrained by
|
||||
% only a lower or an upper bound will use a quadratic
|
||||
% transformation, and unconstrained variables will be left alone.
|
||||
%
|
||||
% Variables may be fixed by setting their respective bounds equal.
|
||||
% In this case, the problem will be reduced in size for FMINSEARCH.
|
||||
%
|
||||
% The bounds are inclusive inequalities, which admit the
|
||||
% boundary values themselves, but will not permit ANY function
|
||||
% evaluations outside the bounds. These constraints are strictly
|
||||
% followed.
|
||||
%
|
||||
% If your problem has an EXCLUSIVE (strict) constraint which will
|
||||
% not admit evaluation at the bound itself, then you must provide
|
||||
% a slightly offset bound. An example of this is a function which
|
||||
% contains the log of one of its parameters. If you constrain the
|
||||
% variable to have a lower bound of zero, then FMINSEARCHBND may
|
||||
% try to evaluate the function exactly at zero.
|
||||
%
|
||||
%
|
||||
% Example usage:
|
||||
% rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2;
|
||||
%
|
||||
% fminsearch(rosen,[3 3]) % unconstrained
|
||||
% ans =
|
||||
% 1.0000 1.0000
|
||||
%
|
||||
% fminsearchbnd(rosen,[3 3],[2 2],[]) % constrained
|
||||
% ans =
|
||||
% 2.0000 4.0000
|
||||
%
|
||||
% See test_main.m for other examples of use.
|
||||
%
|
||||
%
|
||||
% See also: fminsearch, fminspleas
|
||||
%
|
||||
%
|
||||
% Author: John D'Errico
|
||||
% E-mail: woodchips@rochester.rr.com
|
||||
% Release: 4
|
||||
% Release date: 7/23/06
|
||||
|
||||
% size checks
|
||||
xsize = size(x0);
|
||||
x0 = x0(:);
|
||||
n=length(x0);
|
||||
|
||||
if (nargin<3) || isempty(LB)
|
||||
LB = repmat(-inf,n,1);
|
||||
else
|
||||
LB = LB(:);
|
||||
end
|
||||
if (nargin<4) || isempty(UB)
|
||||
UB = repmat(inf,n,1);
|
||||
else
|
||||
UB = UB(:);
|
||||
end
|
||||
|
||||
if (n~=length(LB)) || (n~=length(UB))
|
||||
error 'x0 is incompatible in size with either LB or UB.'
|
||||
end
|
||||
|
||||
% set default options if necessary
|
||||
if (nargin<5) || isempty(options)
|
||||
options = optimset('fminsearch');
|
||||
end
|
||||
|
||||
% stuff into a struct to pass around
|
||||
params.args = varargin;
|
||||
params.LB = LB;
|
||||
params.UB = UB;
|
||||
params.fun = fun;
|
||||
params.n = n;
|
||||
params.OutputFcn = [];
|
||||
|
||||
% 0 --> unconstrained variable
|
||||
% 1 --> lower bound only
|
||||
% 2 --> upper bound only
|
||||
% 3 --> dual finite bounds
|
||||
% 4 --> fixed variable
|
||||
params.BoundClass = zeros(n,1);
|
||||
for i=1:n
|
||||
k = isfinite(LB(i)) + 2*isfinite(UB(i));
|
||||
params.BoundClass(i) = k;
|
||||
if (k==3) && (LB(i)==UB(i))
|
||||
params.BoundClass(i) = 4;
|
||||
end
|
||||
end
|
||||
|
||||
% transform starting values into their unconstrained
|
||||
% surrogates. Check for infeasible starting guesses.
|
||||
x0u = x0;
|
||||
k=1;
|
||||
for i = 1:n
|
||||
switch params.BoundClass(i)
|
||||
case 1
|
||||
% lower bound only
|
||||
if x0(i)<=LB(i)
|
||||
% infeasible starting value. Use bound.
|
||||
x0u(k) = 0;
|
||||
else
|
||||
x0u(k) = sqrt(x0(i) - LB(i));
|
||||
end
|
||||
|
||||
% increment k
|
||||
k=k+1;
|
||||
case 2
|
||||
% upper bound only
|
||||
if x0(i)>=UB(i)
|
||||
% infeasible starting value. use bound.
|
||||
x0u(k) = 0;
|
||||
else
|
||||
x0u(k) = sqrt(UB(i) - x0(i));
|
||||
end
|
||||
|
||||
% increment k
|
||||
k=k+1;
|
||||
case 3
|
||||
% lower and upper bounds
|
||||
if x0(i)<=LB(i)
|
||||
% infeasible starting value
|
||||
x0u(k) = -pi/2;
|
||||
elseif x0(i)>=UB(i)
|
||||
% infeasible starting value
|
||||
x0u(k) = pi/2;
|
||||
else
|
||||
x0u(k) = 2*(x0(i) - LB(i))/(UB(i)-LB(i)) - 1;
|
||||
% shift by 2*pi to avoid problems at zero in fminsearch
|
||||
% otherwise, the initial simplex is vanishingly small
|
||||
x0u(k) = 2*pi+asin(max(-1,min(1,x0u(k))));
|
||||
end
|
||||
|
||||
% increment k
|
||||
k=k+1;
|
||||
case 0
|
||||
% unconstrained variable. x0u(i) is set.
|
||||
x0u(k) = x0(i);
|
||||
|
||||
% increment k
|
||||
k=k+1;
|
||||
case 4
|
||||
% fixed variable. drop it before fminsearch sees it.
|
||||
% k is not incremented for this variable.
|
||||
end
|
||||
|
||||
end
|
||||
% if any of the unknowns were fixed, then we need to shorten
|
||||
% x0u now.
|
||||
if k<=n
|
||||
x0u(k:n) = [];
|
||||
end
|
||||
|
||||
% were all the variables fixed?
|
||||
if isempty(x0u)
|
||||
% All variables were fixed. quit immediately, setting the
|
||||
% appropriate parameters, then return.
|
||||
|
||||
% undo the variable transformations into the original space
|
||||
x = xtransform(x0u,params);
|
||||
|
||||
% final reshape
|
||||
x = reshape(x,xsize);
|
||||
|
||||
% stuff fval with the final value
|
||||
fval = feval(params.fun,x,params.args{:});
|
||||
|
||||
% fminsearchbnd was not called
|
||||
exitflag = 0;
|
||||
|
||||
output.iterations = 0;
|
||||
output.funcount = 1;
|
||||
output.algorithm = 'fminsearch';
|
||||
output.message = 'All variables were held fixed by the applied bounds';
|
||||
|
||||
% return with no call at all to fminsearch
|
||||
return
|
||||
end
|
||||
|
||||
% Check for an outputfcn. If there is any, then substitute my
|
||||
% own wrapper function.
|
||||
if ~isempty(options.OutputFcn)
|
||||
params.OutputFcn = options.OutputFcn;
|
||||
options.OutputFcn = @outfun_wrapper;
|
||||
end
|
||||
|
||||
% now we can call fminsearch, but with our own
|
||||
% intra-objective function.
|
||||
[xu,fval,exitflag,output] = fminsearch(@intrafun,x0u,options,params);
|
||||
|
||||
% undo the variable transformations into the original space
|
||||
x = xtransform(xu,params);
|
||||
|
||||
% final reshape
|
||||
x = reshape(x,xsize);
|
||||
|
||||
% Use a nested function as the OutputFcn wrapper
|
||||
function stop = outfun_wrapper(x,varargin);
|
||||
% we need to transform x first
|
||||
xtrans = xtransform(x,params);
|
||||
|
||||
% then call the user supplied OutputFcn
|
||||
stop = params.OutputFcn(xtrans,varargin{1:(end-1)});
|
||||
|
||||
end
|
||||
|
||||
end % mainline end
|
||||
|
||||
% ======================================
|
||||
% ========= begin subfunctions =========
|
||||
% ======================================
|
||||
function fval = intrafun(x,params)
|
||||
% transform variables, then call original function
|
||||
|
||||
% transform
|
||||
xtrans = xtransform(x,params);
|
||||
|
||||
% and call fun
|
||||
fval = feval(params.fun,xtrans,params.args{:});
|
||||
|
||||
end % sub function intrafun end
|
||||
|
||||
% ======================================
|
||||
function xtrans = xtransform(x,params)
|
||||
% converts unconstrained variables into their original domains
|
||||
|
||||
xtrans = zeros(1,params.n);
|
||||
% k allows some variables to be fixed, thus dropped from the
|
||||
% optimization.
|
||||
k=1;
|
||||
for i = 1:params.n
|
||||
switch params.BoundClass(i)
|
||||
case 1
|
||||
% lower bound only
|
||||
xtrans(i) = params.LB(i) + x(k).^2;
|
||||
|
||||
k=k+1;
|
||||
case 2
|
||||
% upper bound only
|
||||
xtrans(i) = params.UB(i) - x(k).^2;
|
||||
|
||||
k=k+1;
|
||||
case 3
|
||||
% lower and upper bounds
|
||||
xtrans(i) = (sin(x(k))+1)/2;
|
||||
xtrans(i) = xtrans(i)*(params.UB(i) - params.LB(i)) + params.LB(i);
|
||||
% just in case of any floating point problems
|
||||
xtrans(i) = max(params.LB(i),min(params.UB(i),xtrans(i)));
|
||||
|
||||
k=k+1;
|
||||
case 4
|
||||
% fixed variable, bounds are equal, set it at either bound
|
||||
xtrans(i) = params.LB(i);
|
||||
case 0
|
||||
% unconstrained variable.
|
||||
xtrans(i) = x(k);
|
||||
|
||||
k=k+1;
|
||||
end
|
||||
end
|
||||
|
||||
end % sub function xtransform end
|
||||
|
||||
|
||||
|
||||
|
||||
|
53
FOTF Toolbox/fminsearchbnd/test/test_main.m
Normal file
53
FOTF Toolbox/fminsearchbnd/test/test_main.m
Normal file
@ -0,0 +1,53 @@
|
||||
%% Optimization of a simple (Rosenbrock) function, with no constraints
|
||||
% The unconstrained solution is at [1,1]
|
||||
rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2;
|
||||
|
||||
% With no constraints, operation simply passes through
|
||||
% directly to fminsearch. The solution should be [1 1]
|
||||
xsol = fminsearchbnd(rosen,[3 3])
|
||||
|
||||
%% Full lower and upper bound constraints which will all be inactive
|
||||
xsol = fminsearchbnd(rosen,[3 3],[-1 -1],[4 4])
|
||||
|
||||
%% Only lower bound constraints
|
||||
xsol = fminsearchbnd(rosen,[3 3],[2 2])
|
||||
|
||||
%% Only upper bound constraints
|
||||
xsol = fminsearchbnd(rosen,[-5 -5],[],[0 0])
|
||||
|
||||
%% Dual constraints
|
||||
xsol = fminsearchbnd(rosen,[2.5 2.5],[2 2],[3 3])
|
||||
|
||||
%% Dual constraints, with an infeasible starting guess
|
||||
xsol = fminsearchbnd(rosen,[0 0],[2 2],[3 3])
|
||||
|
||||
%% Mixed constraints
|
||||
xsol = fminsearchbnd(rosen,[0 0],[2 -inf],[inf 3])
|
||||
|
||||
%% Provide your own fminsearch options
|
||||
opts = optimset('fminsearch');
|
||||
opts.Display = 'iter';
|
||||
opts.TolX = 1.e-12;
|
||||
|
||||
n = [10,5];
|
||||
H = randn(n);
|
||||
H=H'*H;
|
||||
Quadraticfun = @(x) x*H*x';
|
||||
|
||||
% Global minimizer is at [0 0 0 0 0].
|
||||
% Set all lower bound constraints, all of which will
|
||||
% be active in this test.
|
||||
LB = [.5 .5 .5 .5 .5];
|
||||
xsol = fminsearchbnd(Quadraticfun,[1 2 3 4 5],LB,[],opts)
|
||||
|
||||
%% Exactly fix one variable, constrain some others, and set a tolerance
|
||||
opts = optimset('fminsearch');
|
||||
opts.TolFun = 1.e-12;
|
||||
|
||||
LB = [-inf 2 1 -10];
|
||||
UB = [ inf inf 1 inf];
|
||||
xsol = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB,opts)
|
||||
|
||||
%% All the standard outputs from fminsearch are still returned
|
||||
[xsol,fval,exitflag,output] = fminsearchbnd(@(x) norm(x),[1 3 1 1],LB,UB)
|
||||
|
Reference in New Issue
Block a user