Want Less "Noisy" Solution from fmincon

Been trying to use fmincon to optimize the mass of a column given a target load.
The results I am getting from fmincon are quite noisy, and I'm wondering if there are ways to decrease the noisy-ness of the solution.
The solution I have right now looks something like this (y-axis is mass, x-axis is load) -- see attached image.
Maybe I am not tweaking the options to fmincon correctly? I tried using more "randomized" x0 values but this seemed to make the issue worse.
Any help would be appreciated :)

6 Comments

What are the equations being optimized ?

The objective function is this:

M = @(x) pi*((2*x(1)) + ((1-(x(2)^2))*rho))

The blue and black lines, are given by these two functions which I have attached with this comment. These are given as nonlinear equality constraints for fmincon(). A load value (called Fval) is supplied for these equality constraints. The other parameters are material-related.

The bounds on the value of x for the two functions are:

  • 0.00005 <= x(1) <= 0.3
  • 0 <= x(2) <= 1
  • 5 <= x(3) <= 25 (blue line only, not directly part of obj. fn)

I was supplying a fixed initial value (x0) of: [0.01 0.3 18] ...but this caused the values at the high end of the graph to flat-line (sort of). While searching around the MATLAB Central answers I ran into a way to randomize the input using:

x0 = lb + rand(size(lb)).*(ub - lb)

Hope this helps. Any help is gladly appreciated :)

Could you show your set-up through calls to fmincon ?

Hey Walter,

Thanks for responding (sorry for not saying thanks earlier :) )

Here's the code I use inside a for-loop to call fmincon with some options:

options = optimset('Display', 'off', 'Algorithm', 'active-set', ...
    'MaxIter', 1e3, 'MaxFunEvals', 5e3, 'TolX', 1e-5);
nonlcon = @(x)fn_blueLine(x, Fval, ...
        p_hollowCore, Kbar_fullAdh, Ebar, v); 
[x, fval, ef, ~, mu] = fmincon(M, xInit, [], [], [], ...
	[], lb, ub, nonlcon, options);

I save the values of all outputs except for mu (the lagrange multiplier of the solution). The exit flag (ef) values let me know what's going on if it fails (or if it works)

Which is the input that represents load?

I initialized with

rho = rand;
Fval = rand;
p_hollowCore = rand(1,21);
Kbar_fullAdh = rand;
Ebar = rand;
v = rand;

is that acceptable, or should some of the variable be a different size or a different range?

Hi Walter,

Sorry I should have provided these values. "Fval" is the target load. It is between 1e-4 and 0.015.

Here are the values of the other variables:

rho = 0.11;
p_hollowCore = [.mat file attached]
Kbar_fullAdh = 0.03;
Ebar = 0.01;
v = 0.3;

Hope this helps. I'm trying out the first solution suggested by Alan below, hopefully before the end of today...

Sign in to comment.

 Accepted Answer

Alan Weiss
Alan Weiss on 20 Apr 2018

It seems to me that you are looking for a global optimum, but you are likely getting stuck in local optima. So I would suggest that you try two things:

  • Take as an initial value for fmincon for each load the value from the previous solution for the load. I am, of course, assuming that the value of the previous solution will be close to the value of the next solution, which is often the case.
  • Take a large number of random start points for each value of the load, as you have reported using a randomizing input. This has a chance of getting you to the appropriate Basin of Attraction of the global minimum.

Good luck,

Alan Weiss

MATLAB mathematical toolbox documentation

4 Comments

Hi Alan. Thanks for your answer! I'll try both of these suggestions...
Regarding your 2nd point: are you suggesting to solve for multiple start points at each value of the load? (to get multiple minimum points I guess, and then take the lowest of these minimums?)
Yes, that is exactly what I am suggesting. It takes more time, but you might get a better result. But I still think that my first suggestion might be even better, so you might as well try it first.
Alan Weiss
MATLAB mathematical toolbox documentation

With regard to the second part: if you have the Global Optimization Toolbox see https://www.mathworks.com/help/gads/multistart.html

bsquared
bsquared on 24 Apr 2018
Edited: bsquared on 24 Apr 2018

Sorry for the hiatus in not answering. Was trying out a bunch of things and also looking at other aspects of optimization for this particular geometry.

It's hard to pick which of the two provided answers is "most right" as you both helped me a lot! I picked this one as it was sort of the foundation of what became the right answer (or very close to it)

The method of Alan is utlized in Walter's code below, but I had to modify that code to run in my version of MATLAB (v. 2011 and 2013 on 2 different computers).

The solution I used allowed me to get a decent initial guess for the starting point of the black line such that it's really good when the range of Fvals is good. However it is still noisy (or ends up going to the highest value in my ub() range) if some parameters aren't "perfect". here's where the black line ends up being pretty good.

Given the complexity of the blue line, I will have to go with Alan's 2nd method of using severl start points at each value of Fval, so that the lowest will have to be found through many guesses using fmincon(). This will likely give a better solution than what I'm seeing here.

Thanks for both of your help :). I'll report back here if I have any other questions.

Sign in to comment.

More Answers (1)

load('pVals.mat');
rho = 0.11;
Kbar_fullAdh = 0.03;
Ebar = 0.01;
v = 0.3;
M = @(x) pi*((2*x(1)) + ((1-(x(2)^2))*rho));
lb = [0.00005, 0, 5];
ub = [0.3, 1, 25];
options = optimset('Display', 'off', 'Algorithm', 'active-set', ...
    'MaxIter', 1e3, 'MaxFunEvals', 5e3, 'TolX', 1e-5);
Fval_lb = 1e-4;
Fval_ub = 0.015;
Fval_vals = linspace(Fval_lb, Fval_ub);
n_Fval = length(Fval_vals);
blue_x = zeros(n_Fval, 3);
black_x = zeros(n_Fval, 3);
cla;
hb3 = animatedline('Color', 'b', 'DisplayName', 'blueLine(3)');
hk3 = animatedline('Color', 'k', 'DisplayName', 'blackLine(3)');
legend('show')
blueInit = lb + rand(size(lb)).*(ub - lb);
blackInit = blueInit;
for J = 1 : n_Fval
    Fval = Fval_vals(J);
    nonlcon_blue = @(x)fn_blueLine(x, Fval, ...
        p_hollowCore, Kbar_fullAdh, Ebar, v);
    nonlcon_black = @(x)fn_blackLine(x, Ebar, v, Fval);
      [this_blue_x, ~, ~, ~, ~] = fmincon(M, blueInit, [], [], [], ...
          [], lb, ub, nonlcon_blue, options);
      blue_x(J,:) = this_blue_x;
      addpoints(hb3, Fval, this_blue_x(3));
      [this_black_x, ~, ~, ~, ~] = fmincon(M, blackInit, [], [], [], ...
          [], lb, ub, nonlcon_black, options);
      black_x(J,:) = this_black_x;
      addpoints(hk3, Fval, this_black_x(3));
      blueInit = this_blue_x;
      blackInit = this_black_x;
  end

1 Comment

Wasn't able to run your script as my version of MATLAB didn't know what the animatedline command was (I'm running 2013a)

I used a similar script to yours, graph is below. Produces random inputs the first time and then uses the last result as an input to the next result. This seems to work fairly well for the black line but not as well for the blue line -- however, in both cases there is definitely a huge improvement.

The x0 values I used (i.e. randomly generated) for the above graphs are:

  • xblack= [0.1188 0.2729]
  • xblue = [0.0112 0.6733 13.5913]

The weird thing is that for some initial values of x0 for the blue line, the mass becomes negative. The solve knows this is wrong as it returns an exit flag value of -2. It's weird that this happens, but I'm not sure what to do about it

Given the still-noisy results for the blue line, I'll try out the 2nd strategy suggested by Alan. I'll find the minimum among 10 or so runs and see if this improves the result somewhat. Will report here with my findings.

Sign in to comment.

Asked:

on 20 Apr 2018

Edited:

on 24 Apr 2018

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!