I want to solve an optimisation problem using cvxpy
.
Suppose I want to use log_sum_exp
function to build a constraint like this:
m >= log(1 + exp(m+z))
The syntax of cvxpy
allows me to create a vector variable x = [z,m]
of dimension 2
and apply matrix multiplication to create a vector of expressions 0, z+m
:
import cvxpy
x = cvxpy.Variable(2)
coeff = np.array([
[0,0],
[1,1]
])
constraints = [ x[1] >= cvxpy.log_sum_exp(coeff * x)]
When coding like this, I lose some part of the logic because I want different names for different parts of my variable array. Is there some way to use the log_sum_exp
transform more explicitly, like
z = cvxpy.Variable()
m = cvxpy.Variable()
constraints = [ m >= cvxpy.log_sum_exp([0, m+z]) ]
?
I couldn't find any hints in the official docs. Thanks!
As sascha pointed out, one of the manual pages
contains the answer. In particular, I can give an example of using log_sum_exp
without matrix multiplication. Note that it is not possible to construct a correct problem within DCP (disciplined convex programming) framework using only operators exp
and log
because you will obtain concave function applied to convex one, which is considered as undefined behaviour. One should use a built-in constructor instead.
If you want to encode the constraint
F0 >= log( exp(F1) + exp(F2) + ... + exp(Fn) )
where F1
, F2
, ..., Fn
are some convex expressions, and F0
is a concave expression,
then instead of introducing slack variables, one can type
import cvxpy
... # Define variables and functions
constraints = [
...,
something >= cvxpy.log_sum_exp(
cvxpy.vstack(
F1,
F2,
...,
Fn
)
)
]
... # Solve the optimisation problem
Note that vstack
can be used both in multiple-argument style:
cvxpy.vstack(z, u)
and in list-style (but not tuples)
cvxpy.vstack([z,u])