1

I am trying to supply constraints to a a function minimisation that I have hitherto been performing successfully with an unconstrained algorithm available via scipy (scipy.optimize.fmin_l_bfgs_b()).

Reading up (see, e.g, Python constrained non-linear optimization), I discovered a minimisation packed called mystic that seems to be what I need. My situation is as follows. I have a function of 3N variables (representing xyz position coordinates of N nodes), and I want to supply a list of constraints such that z/x = const. for each node. This makes for a total of N constraints. How do I do define/supply these constraints most efficiently for mystic()? Can the same constraint object be used with scipy.optimize.slsqp() as well? Since my constraints are linear, this should be a viable option too.

I tried the following, but it crashed my computer:

import mystic.symbolic as ms
ieqns = ''
for p in range(N):
    ieqns += 'x'+str(p+2) +'/x'+str(p) +" <= 2"

cf = ms.generate_constraint(ms.generate_solvers(ms.simplify(ieqns)))
pf = ms.generate_penalty(ms.generate_conditions(ieqns), k=1e12)
ap21
  • 2,372
  • 3
  • 16
  • 32
  • For `N=3` I get `'x2/x0 <= 2x3/x1 <= 2x4/x2 <= 2'`. Do you need a linebreak here? Also, this might indeed be suitable for a linear programming solver, as you can rewrite all your constraints to `z = c * x` (but we don't know your objective function...). – Cleb Nov 13 '18 at 07:34
  • @Cleb, Indeed, I realised that my objective function, though complicated, is quadratic in `x`. Hence, something like `SLSQP` should be ideal for what I am searching (see https://stackoverflow.com/questions/52001922/linearconstraint-in-scipy-optimize for a guide to defining constraints with `scipy.minimize()`). However, for future reference, I would still like to know how to define a vector of constraints for `mystic`. Is adding a `\n` enough? – ap21 Nov 13 '18 at 17:29
  • @ap21: The answer is yes, adding the `\n` is enough. Also what `simplify` does is isolate a single variable on the left-hand side... that can take some time, so generally, if it's as easy as your constraints equations are, I just would rewrite them by hand. – Mike McKerns Nov 14 '18 at 13:27

1 Answers1

1

I'm the mystic author. I believe what you are looking to do is something like this:

>>> import mystic.symbolic as ms
>>> ieqns = ''
>>> for p in range(10):
...   ieqns += 'x{0} <= 2*x{1}\n'.format(p+2,p)
... 
>>> cf = ms.generate_constraint(ms.generate_solvers(ieqns))
>>>
>>> # test that it applies the constraints
>>> cf([1.,3.,5.,7.,9.,11.,13.,15.,17.,19.,21.,23.,25.])
[1.0, 3.0, 2.0, 6.0, 4.0, 11.0, 8.0, 15.0, 16.0, 19.0, 21.0, 23.0, 25.0]

Then we can minimize while applying the constraints (however, in the following case the constraints are basically irrelevant):

>>> # get an objective
>>> import mystic.models as mm
>>> rosen = mm.dejong.Rosenbrock(12).function
>>> 
>>> # get an optimizer
>>> import mystic.solvers as my
>>> result = my.diffev2(rosen, x0=bounds, bounds=bounds, constrints=cf, npop=40, disp=False, full_output=True, gtol=100)
>>>
>>> # get the solution 
>>> result[0]
array([0.99997179, 1.00005506, 1.00012367, 0.99998539, 0.99984306,
       0.99981495, 0.999951  , 0.99996505, 0.99971107, 0.99925239,
       0.99846259, 0.99692293])
>>> # and the final 'cost'
>>> result[1]
2.2385442425350018e-05
>>> 
Mike McKerns
  • 33,715
  • 8
  • 119
  • 139
  • Thanks! But tell me, shouldn't suppyling a vector `x` to the constraints give back a vector of Boolean values? What are the numbers it is returning? – ap21 Nov 14 '18 at 21:57
  • A different question: I have an explicit gradient of my cost function as well. I couldn't find any default algorithm in `mystic` that makes use of an explicit gradient. Is there some algorithm that can use a gradient? – ap21 Nov 14 '18 at 22:03
  • 1
    @ap21: No, a `mystic.constraint` is a "mapping", so it has the form `x' = c(x)` -- you could think of it as a nonlinear transform. On the other hand, a `mystic.penalty` returns a penalty value that is added to the cost... so has the form `y = k*p(x)`, which is additive to the `cost`. With respect to your second question, the most recent `mystic` release doesn't have a gradient solver... however, I have built a gradient solver, and standalone functions that calculate the gradient from points the solar evaluates. These will be included in the next release, and should be in GitHub this month. – Mike McKerns Nov 15 '18 at 00:58