I suppose I should clarify that x is a vector of values, about 100 of them. The final solution for each of the 100 values must not lie in the range -30 to 0, but some can be in the lower range (-100 to -30) and others can be in the upper range (0 to 100) in the final solution vector. The problem is an electromagnetic method of moments simulation, I wrote my own MoM codes. I am trying to optimize a bunch of impedances to get a specific scattered field. The impedances cannot be in the range -j30 ohms to 0 ohms. Hope this helps..
How to exclude range of values in fmincon
17 views (last 30 days)
Show older comments
I am running a fmincon optimization. The variable x has the following constraints:
0<x<100 and -100<x<-30
essentially the variable x cannot take a value within the range -30 to 0 and also outside of the range of +/- 100. If need be I can forego the second constraints and only exlude the values -30 to 0. Thanks in advance.
2 Comments
Answers (2)
Dana
on 17 Aug 2020
One option would be to do a variable transformation in your objective function. So for example, instead of making x your optimizing variable, use y, which we define as:
y = x if 0<x<100, and y = x+30 if -100<x<-30.
Note that, for allowable values of x, y ranges from -70 to +100, so you'd want to make those the constraints for y in fmincon. You can then invert this transformation at the beginning of your objective function by
x = y if 0<y<100, and x=y-30 if -70<y<0.
John D'Errico
on 17 Aug 2020
+1 to Dana, with a gentle caveat. Dana has offered what MAY be a good idea.
That is, fmincon CANNOT handle a disjoint set, thus where x must lie in one of two sub-domains. The simple and common solution is to solve the problem twice. That is, solve it over the domain where x is constrained to lie within the bounds [-100,-30], and then solve the second problem where x must lie in the upper interval, so [0,100].
Take the better solution of the two in terms of objective function value, which now gives you an overall solution.
Dana's solution offers a way to join the two sub-domains into one contiguous domain. And that is a good thing, in a sense. Now fmincon can move across the joint more easily.
However, it may create a problem where at the joint, the function will probably be non-differentiable. A non-differentiable objective is not the end of the world for fmincon, but it can be a problem. If the objective is discontinuous across that break, that may be more significant. Much will depend on the shape of the surface in that region, and what happens across the break.
Honestly, for the simple problem with two simple sub-domains in one variable, if you want some confidence that fmincon would solve the problem, I would follow the classic approach - just solve the problem twice, once with x bounded to live in each discontinuous segment.
3 Comments
John D'Errico
on 17 Aug 2020
Edited: John D'Errico
on 17 Aug 2020
So, you have 100 values, where each must lie in one range or the other? This is a 100 variable problem? Real life is never as easy as it looks from afar. :(
That means the dual problem approach will not work, since then you would need to solve 2^100 possible combinations of optimizations - clearly an impossible task.
I would probably recommend that you use GA, and not FMINCON. There are two ways you could approach the problem with GA. (GA comes from the global optimization toolbox.)
- Use Dana's solution, combining the disjoint intervals into one. When then use GA? Because GA is much more robust to problems, less likely to get stuck. It can handle a problem with breaks in there.
- Use GA, but now with an extra 100 binary integer variables. Each variable x_i would have an associated binary variable b_i, that can take on two values, say 1 and 2. When b_i is 1, this will put x_i into the lower interval. When b_j is 2, that puts the corresponding variable into the upper bracket.
Thus, option 2 would have 200 unknowns. Call it y. Inside your objective function, you might write:
b = y(1:100);
x = y(101:200);
brackets = [-100 -30; 0 100];
x = brackets(b,1) + x.*(brackets(b,2) - brackets(b,1));
The constraints on the optimization vector would then be
lb = [ones(1,100),zeros(1,100)];
ub = [2*ones(1,100),ones(1,100)];
intcon = 1:100;
so the binary variables are the first 100 ariables, which will be forced to be integers from the set [1,2]. The second block of 100 variables (y) would be continuous, and can fall anywhere in the interval [0,1].
When the optimization converges, you can then easily recover the actual values x from the corresponding pairs.
The virtue of this approach is it may be more robust, less likely to get stuck. The disadvantage is it is now a 200 variable optimization, so MATLAB will be searching a larger space, but perhaps doing a better job of the search.
Either approach may work, but in any case, I would strongly advise use of GA, not fmincon. Could fmincon still work? Possibly, but now you are looking at a LOT of potential discontinuities. I might not have a lot of confidence in the result. In the event that you do not have the global optimization toolbox (you should get it!) I might try multi-start ideas, thus starting fmincon many times with various randomly chosen start points, taking the best result overall. I have little confidence this will work well for your problem though, because fmincon can too easily get stuck if there are discontinuities at those breaks.
See Also
Categories
Find more on Surrogate Optimization in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!