Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inf fp get when keyword debug is True #9

Open
TsingQAQ opened this issue Apr 21, 2017 · 2 comments
Open

Inf fp get when keyword debug is True #9

TsingQAQ opened this issue Apr 21, 2017 · 2 comments

Comments

@TsingQAQ
Copy link

TsingQAQ commented Apr 21, 2017

Hi tisimst and others,

I've tried to use pyswarm to solve an engineering optimal problem but get Inf fp return when the debug keyworld in PSO is set to be true.

Here's a simple structure of my code:
To be short, it is a 8 variable optimal problem with two inequal constraints

But when I run this with PSO builtin debug mode, the fopt of each generation will always be inf:

Best after iteration 1: [-0.11882721 -0.02219953 -0.11879306 -0.11291183 0.19934821 0.24063626
0.1900103 0.07119408] inf

I'm really puzzled by this, one potential risk in my code is that some times drag in the Drag_Coefficient function or the lift in the Lift_Constraints function may get a bad return(a list with no answer) from other function, in that case will return a default value (like drag=1 in this case, since the predicted object value of drag is around 0.08, far less than 1, which also means that if I get a bad return from other function, I think that this sort of parameter is not good enough to be a candidate of the minimum, so just set a relative large value to eliminate it) , which may influnce the minimal searching. But I still don't know why it's Inf instead of a finite number.

Some hints? Really thanks.

Attach my codes for reference:

def Drag_Coefficient(x):
    try:       
        drag = CST_Shape(Weight_Lower=[x[0], x[1], x[2], x[3]], Weight_Upper=[x[4], x[5], x[6], x[7]],
                     TE_width=0).Cd([0], 0.1, 100000)[0]
    except IndexError:
        drag = 1
    print(drag)
    return drag


def Thickness_Constraint(x):
    Thickness = CST_Shape(Weight_Lower=[x[0], x[1], x[2], x[3]], Weight_Upper=[x[4], x[5], x[6], x[7]],
                          TE_width=0).Thickness(0.25)
    return Thickness - 0.10


def Lift_Constraint(x):
    try:
        lift = CST_Shape(Weight_Lower=[x[0], x[1], x[2], x[3]], Weight_Upper=[x[4], x[5], x[6], x[7]],
                         TE_width=0).Cl([0], 0.1, 100000)[0]
    except IndexError:
        return -1
    return lift - 0.05


lb = [-0.15, -0.15, -0.15, -0.2, 0.15, 0.1, 0.05, 0.05]
ub = [-0.1, 0, 0, 0, 0.2, 0.3, 0.2, 0.15]

xopt, fopt = pso(Drag_Coefficient, lb, ub, ieqcons=[Thickness_Constraint, Lift_Constraint], debug=True, air_plot=True, phig=1, phip=1)

`

@tisimst
Copy link
Owner

tisimst commented Apr 21, 2017

Your code in and of itself looks just fine, but naturally, I can't test it myself without having access also to CST_Shape. The internal code of pso is relatively simple with minimal calculations, so I'm inclined to think there's an uncaught bad output from CST_Shape in your code.

The only thing I can really recommend is that you add a little more of your own verbosity to each of the functions to narrow down where the error is surfacing from. When I have several functions like this that I need to keep track of, I find it helpful to prefix my printed string with a tag, like the command name or some other unique identifier, so I know where the message comes from, like this:

print('[Drag_Coef] drag = {:}'.format(drag))

You may need to have a couple of extra lines of code to break up what you are doing, too. In other words, instead of

drag = CST_Shape(...).Cd(...)[0]

refactor it using more intermediate variables and add print statements between them, like

tmp = CST_Shape(...)
print('[Drag_Coef] tmp = {:}'.format(tmp))
Cd = tmp.Cd(...)
print('[Drag_Coef] Cd = {:}'.format(Cd))
drag = Cd[0]
print('[Drag_Coef] drag = {:}'.format(drag))

It can feel tedious, but it works.

I have no reason to believe you are getting bad input values from the optimizer, but it wouldn't hurt to print those out, too, just in case.

If, after all this, you've found everything working correctly in your code, then we can dig deeper into pso to try and isolate what is causing the bad output. Which version of pyswarm are you using?

By the way, why do you pass the kwarg air_plot to pso?

@TsingQAQ
Copy link
Author

TsingQAQ commented Apr 22, 2017

Hi @tisimst ,

thanks for your suggestion, I may get where Inf comes.

To be short:
When none of the initial candidate locates in the feasible domain, an Inf fp will get [This is only my case]

Here's what I do:
Just as you sueggest, I've printed the Cd, Cl, and Thickness every time the function call to check if there're some unexpect return(e.g Inf), but after some generation it semms that all are well, reasonable float numbers get from here no Inf at all, but I've aware that none of these return fits one of the constraints: Thickness.
When I relax this constraint, the opt will be a number and all seems will.

So if this is the case,
here's some suggestions/problem I thought which could(if solved) make pyswarm better:

  1. Some times user may set a very strict constraints(thus will lead a very small size of feasible domains though the domains consisted of the paramter is relatively quite large than that) and will get a Inf fopt return in debug mode, this maybe true in mathematics but not so readable for users, in this case some print may be a good hint like:
    Whtch out ! In this step none of the candidates fits the requirements.
  2. Equal constraints: Just like the equal constraints #8 I post, another solution you suggest to handle equal constraints is to give two inequal constraints, but if we treat it this way, we may get Inf return most of the time,so still, this is a problem need to be solved.
  3. Since many times an optimal question is based on an exist data which need to be optimized. If I get an initial(baseline) data, it may be a good start to make it one of the start swarms, in that case at least one candidates fit the requirments, this may be quite useful in some cases the constraints are very difficult to meet like the upper one.

Ps.
Reply to your question :

  1. I'm use the pyswarm from github here, the latest version(it seems this code have not been updates for years)
  2. about air_plot, I'm trying to make the solve process visible(not like debug but a graph shows the trend curve when Optimize), so I've tried to add a dynamic plot function in pyswarm, which will dynamically update plot after each step, like this:

test

I think this is a very useful tool and will help pyswarm a lot if the code could integrate this, just use matplotlib and do not need any other unofficial dependency, though I'm not good at programming so just add some ugly codes to make it run. Get some hints from here. Currently my air_plot only works with plot fp and steps, but information from partial_output are also good candidates to plot.

Question:
if I want the pyswarm to tend to search away from the best known minimum, should I use a large or smaller value of phig and phip?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants