def rosen(x):

    f = (1 - x[0])**2 + 100*(x[1] - x[0]**2)**2
    c = []

    return f, c

"""
Explanation: GA Python
Here is a simple example of using a GA in Python using PyOptSparse and my wrapper available here.
End of explanation
"""


from pyoptsparse import NSGA2

# choose optimizer and define options
optimizer = NSGA2()
optimizer.setOption('maxGen', 200)
optimizer.setOption('PopSize', 40)
optimizer.setOption('pMut_real', 0.01)
optimizer.setOption('pCross_real', 1.0)

"""
Explanation: Here is where we define the problem and choose an optimizer.  Various options exist, I've set a few, see documentation for details.
End of explanation
"""


from pyoptwrapper import optimize

x0 = [4.0, 4.0]
lb = [-5.0, -5.0]
ub = [5.0, 5.0]


xopt, fopt, info = optimize(rosen, x0, lb, ub, optimizer)
print 'results:', xopt, fopt, info

"""
Explanation: Now we can run the optimizer and parse the results.
End of explanation
"""


from pyoptsparse import SNOPT

optimizer = SNOPT()

xopt, fopt, info = optimize(rosen, x0, lb, ub, optimizer)
print 'results:', xopt, fopt, info

"""
Explanation: NSGA, like many genetic algorithms, doesn't have any speicific convergence criteria other than the maximum number of generations.  I set it at 200 in this case.  Notice that the answer is ok, but not super great.
Let's also try with SNOPT and start fairly far away (and I won't supply gradients):
End of explanation
"""


