How to add a constraint when using fsolve?
Show older comments
Hi, I'm currently trying to solve a system of five nonlinear equations using fsolve. However, I know that fsolve doesn't really allow you to add constraints. I need the fifth variable to be less than or equal to 24, but I don't even know where to even begin to get this problem solved. I also need all my variables to be greater than or equal to zero, but that's been a problem I've been able to solve by making my starting points around 10 instead of zero. To give greater context, these equations are all partial derivatives that are then equated to zero.

And here are the solutions:

However, the last variable (the one equal to 95.8047) can't be greater than 24. Please help! I'd really appreciate it! Thank you!
4 Comments
Alex Sha
on 14 Dec 2020
Hi, if you want x(5) less than 24, there will be no exact real number solution
Matt J
on 14 Dec 2020
@Sabrina,
Please post your code as text, rather than as images. That way, we can more conveniently copy/paste and run it.
Sabrina Chui
on 14 Dec 2020
Sabrina Chui
on 14 Dec 2020
Accepted Answer
More Answers (2)
The fifth equation involves only x(3) and can be solved immediately
x3=(2*48/0.001)^(1/3)
The 3rd and 4th equations then imply that x4=x3
x4=x3
and can be used to solve for x5,
x5=1-(-1./(x3+x4-14)*96/0.95/-0.003/x3^2)
which satisfies the constraint x5<=24.
Comparison of the first two equations implies that x1=x2=z, which reduces the problem to the single variable root finding problem
0.003*z^2 = (2*z-14)^(-1)
which can be solved with fzero() to give,
x1=x2=9.0396
3 Comments
Sabrina Chui
on 15 Dec 2020
Matt J
on 15 Dec 2020
If we subtract the 3rd equation from the 4th equation, we obtain,
0.95 * (-0.003) * (1-x(5)/96) * ( x(4)^2 -x(3)^2 ) = 0
In order for this equation to be satisfied, either x(5)=96, which you say is forbidden, or x(4)=x(3).
Sabrina Chui
on 15 Dec 2020
Walter Roberson
on 14 Dec 2020
residue = @(x)sum(fun0(x).^2)
Now use an optimizer to minimize residue using lb all 0, and ub all inf except 24 for the appropriate entry.
Caution: this approach does not guarantee that you will find a zero, and can need to be tested with multiple initial conditions, such as by using a MultiStart from Global Optimization Toolbox
12 Comments
Sabrina Chui
on 14 Dec 2020
Walter Roberson
on 15 Dec 2020
does the residue function just square fun0
No, it takes the sum() of the squares. This is a "least-squared" solution to the system. It is one of the ways of balancing the requirements of the various individual equations .
If you have two equations, A and B that should ideally both be 0, then at any point, x, that satisfies A(x) and B(x) are both exactly 0, A(x)^2 + B(x)^2 will in fact be 0 because the individual elements being squared will both be 0. Now suppose that you find an x1 such that A(x1) is 2 and B(x1) is 0, and you find another point x2 such that A(x2) is 1 and B(x2) is 1, then how do you decide whether x1 or x2 is the "better" point? In both cases, x1 and x2, the total of the individual distances is the same, 2+0 = 1+1, so does that mean that both points are equally good?
Let us consider the case of having 1000 equations, and you have two points, one of which gives 1000 for the first equation and 0 for the other equations, and the other gives 1 for all of the equations: then it becomes obvious that the solution for the first equation with the first prospective point is Probably Not Good even if the others are perfect, and that for the second prospective point, that whatever error there is is well distributed, not favoring one equation over the others. With the 1000 equation system, it becomes clear that if the equations are equally important, the solution that gives error 1 for each of them (total 1 * 1000 = 1000) is almost certainly better than the solution that gives error 1000 for the first but is exact for the others. But how to quantify that? Answer: take the sum of squares of the errors. 1000^2 + 999*0 = 1000000, vs 1^2 * 1000 = 1000 . The case in which the error was well distributed between the equations wins easily when you use sum-of-squares.
sum-of-squares effectively tries to minimize the total distance to the solution -- the solution that is least "distance" from perfect is the one that wins. Euclidean distance is sqrt() of sum-of-squares, so the location that hast least sum-of-squares has the least distance.
Walter Roberson
on 15 Dec 2020
The Global Optimization toolbox is not necessary; it is just convenient.
You should be careful not to trust that the first answer you get back from fmincon() is not necessarily going to be the best possible solution. fmincon() is a local optimizer: it uses algorithms to try to find the best solution "near" the starting point. It gets stuck in local minima.
For example if you have two "wells" beside each other then once fmincon happens to try "inside" one of the wells, it is not likely to ever try looking inside the other. When you look at a graph of the two-well system, it might seem obvious to you that it "should" have a look inside the second well, but it is not obvious to fmincon. Consider the case where you have a very large shallow bowl that has a well at some point in it, and that the second well is dug into the side of the bowl starting at a much higher elevation -- fmincon cannot somehow immediately know where that second well even is . Imagine the case where you have an extinct volcano inside a lake: the lake has a lowest point somewhere that is the "minima" outside the old volcano, but there just might happen to be an old lava tube opening inside the volcano that leads deeper... possibly much deeper.
No fixed algorithm like fmincon can reliably find the global minima of complicated systems. Algorithms that use randomness might be able to find global minima in the limiting case (run them for centuries.)
So, do not trust the first answer from fmincon... not unless it just happens to solve your equations perfectly!
Instead, you should invoke fmincon several times with different starting points... and take the best of the solutions.
Also, there are a number of shapes for which fminsearch() is better about getting into the right general area, even though it might not be the best for finding the best possible local solution.
Sabrina Chui
on 15 Dec 2020
Walter Roberson
on 15 Dec 2020
I do not have any experience with the surrogate search.
I did a bit of work with patternsearch a few years ago, but never became a convert. If I recall correctly, I ended up taking a copy of the patternsearch code and modifying it so that after an fmincon was done, that the position could be updated from the fmincon result (patternsearch permits you to run a local minimizer like fmincon every few generations, but at least at the time I was testing it, patternsearch only used the result to inform the error bounds, not to move the current point.) I did find that there were some kinds of problems where my modified version worked well, with the patternsearch component providing logic about "general areas" to search, and the fmincon updates zooming in towards solutions much more efficiently.
Sabrina Chui
on 15 Dec 2020
Walter Roberson
on 15 Dec 2020
I know that John D'Errico has different opinions on optimization than I do, based upon the kinds of functions that he has had to optimize, but for the functions that I have had to optimize, the tools I tend to use are:
- fmincon and related fixed-algorithm minimizers; these are efficient at finding local minima, but they get stuck in local minima and cannot get out of them
- fminsearch: this is significantly better at getting out of local minima than fmincon, but it is not the best at finding the precise local minima. Also, it can fail on any case where you have an asymptope descent from a central area where the minima is inside the central area, as it can end up chasing the every-decreasing outer slope, moving away from the actual solution. Which is generally a problem with minimizers.
- ga() or particleswarm(): these are heuristic algorithms that use randomness as part of the search, and do not require that the functions be continuous or have continuous derivatives. They can get over some kinds of local minima that others cannot -- but they can be quite slow. For example in one Travelling Salesman test I did, in over 100,000 iterations it was unable to notice the right pair of values to exchange to get the best possible answer. Simulated annealing also fits in this class, but I rarely use it
- tools such as MultiStart are useful for automatically trying a lot of different starting points for other algorithms. I do not tend to use them in practice, tending to instead run for loops
- I wrote my own "brute force" tool based on fmincon and fminsearch. It is not fast, but afterwards I am left feeling more confident that I did not make any "obvious" mistakes in the search
Sabrina Chui
on 15 Dec 2020
And I've just been getting just one solution, which I'm assumings is the global minimum.
You shouldn't assume that unless the least squares objective value given by the solution is zero. We know the global minimum for the least squares objective is zero because the solution in my answer achieves that. In fact, the solution in my answer is provably the unique global minimum, so unless your x(i) and mine nearly coincide, the GlobalSearch output could not be a global minimum.
However, it is weird that the solution found my fmincon, which I'm assuming would be a local minima, isn't included in the results from GlobalSearch.
GlobalSearch is just a tool for running the optimization multiple times with many different starting points. There is never any guarantee that it will find the global minimum, nor is there any guarantee that all local minima will be found.
Sabrina Chui
on 15 Dec 2020
Setting partial derivatives to zero is only a valid optimality condition for unconstrained problems. It is no longer valid once you impose bounds. So, GlobalSearch is more successful than your fun3 formulation for two reasons. First, it is guiding its search with proper optimality conditions. Second, it has mechanisms which help it avoid local minima that fmincon alone does not.
Sabrina Chui
on 15 Dec 2020
Categories
Find more on Global or Multiple Starting Point Search 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!