I have an optimalization problem where I want to minimize the quantity -sum(p log(p))dx (entropy) with the constraints sum(p)dx == 1 and sum(p.x)dx == 0.2, where p and x are arrays and dx is a scalar. I tried to implement this using mystic this way:
from pylab import *
from mystic.symbolic import generate_constraint, generate_solvers, simplify
from mystic.solvers import diffev2
x = linspace(0, 5, 100)
dx = x[1]-x[0]
def objective(p):
return -sum(p*log(p))*dx
bounds = [(0,1)]*len(x)
equations = '''
sum(p)*dx == 1
sum(p*x)*dx == 0.2
'''
eqns = simplify(equations, variables=["p"], locals={"dx":dx, "x":x})
cf = generate_constraint(generate_solvers(eqns))
res = diffev2(objective, x0=[1/len(x)]*len(x), bounds=bounds, constraints=cf)
print(sum(res)*dx)
print(sum(res*x)*dx)
But it obviously does not work well, because it returns:
Optimization terminated successfully.
Current function value: 0.145182
Iterations: 264
Function evaluations: 26500
0.030782323656083955
0.07399192217757057
Thus constraints are violated. How should I proceed to solve my problem properly?
I'm the
mystic
author. The primary issue is that you've assumedmystic.symbolic
can understand vector notation, and it can't.This is obviously not what you want. So, if you want to work with symbolic constraints, then you have to write it out element-by-element.
This is starting to look a bit more like what you want.
You probably want a larger population than this, and as I'm seeing a lot of
inf
in the results, you probably want to go back to the constraints and add tight bounds. The latter can be accomplished by passingtight=True
to the solver, but it's slower than adding the bounds explicitly when you first define the equations. Like this:You'll then need to combine and simplify
equations
andequations_
to serve as the basis for your constraints function.As an alternative, you can use a penalty... which (once you have the simplified
eons
, builds like this:Penalties are soft constraints, and it looks like the above still has some constraints violations, but is progressing toward a good solution.
Anyway, the above should give you enough options to get past where you were stuck, and to find a solution.