My constraints have a product. It is a convex set. I cannot find an operation to simply have the product of the components of a vector (or matrix/tensor in general).
Is that not possible?
prod(x::Convex.AbstractExpr) = exp(sum(log(x)))
might work
If you include a minimal runnable example to demonstrate that would help. Convex only supports the rules listed here so your product would have to be with a variable and a constant expression or as a PSD quadratic form or such.
the constraints are quadratic. the solution clearly breaks the constraint. ty for your help!
sorry, i replied and have further cleaned up the code. if you look now, its as simple as possible (i think)
non DCP warnings are printed. I thot the constraints are still considered tho. In my case, the solution clearly violates the constraints. Are non-DCP constraints just ignored?
Are non-DCP constraints just ignored?
No, but in some ways it is worse than that, they are reformulated in ways that are invalid. I have tried to explain it here, let me know if that makes sense to you.
Regarding the problem, from the paper they say the \varphi_i should be concave and increasing, but here prod
is not.
If I choose sum(log(x))
(dropping the exp
) we do have a concave, increasing function, and the result does respect the constraints (up to some numerical tolerance):
# https://arxiv.org/pdf/2204.05238.pdf
# page 5, (2)
using Convex, SCS
### PARAMETERS
n = 4 # num tokens, j=1..n
m = 6 # num CFMMs, i=1..m
# ni = 2
A = [
[
1 0
0 1
0 0
0 0
],
[
1 0
0 0
0 1
0 0
],
[
1 0
0 0
0 0
0 1
],
[
0 0
1 0
0 1
0 0
],
[
0 0
1 0
0 0
0 1
],
[
0 0
0 0
1 0
0 1
],
]
R = [[1,1], [1,1], [1,1], [1,1], [1,1], [1,1]]
γ = [30/10000 for i in 1:m]
### VARIABLES
Δ = [Variable(2, Positive()) for i in 1:m]
Λ = [Variable(2, Positive()) for i in 1:m]
### CONSTRAINTS
ϕ(x::Convex.AbstractExpr) = sum(log(x))
ϕ(x) = sum(log.(x))
# the following constraints are quadratic
# the solution below is breaking these constraints
constr = [ϕ(R[i] + γ[i]*Δ[i] - Λ[i]) >= ϕ(R[i]) for i in 1:m]
Ψ = sum(i -> A[i] * (Λ[i] - Δ[i]), 1:m)
# constr = [constr..., Ψ>=0]
### OBJECTIVE
# utility to maximize
U = sum(Ψ)
### SOLVE
problem = maximize(U, constr)
solve!(problem, SCS.Optimizer)
problem.status ## OPTIMAL::TerminationStatusCode = 1
problem.optval ## ~ 12
### CHECK
# is our constraint is broken for the optimal value?
i=1
tol=1e-4
evaluate(ϕ(R[i] + γ[i]*Δ[i] - Λ[i])) + tol >= evaluate(ϕ(R[i])) # true
in my case, φ is actually sqrt of prod, which makes is concave; however, the set of the constraint φ(x+d)<=φ(x) is equivalent with or without the sqrt, which allows us to write the constraint quadratically.
Ah right. For conic solvers, the non-quadratic formulation is actually better. In Convex, you can use the geomean
primitive. It only supports two variables, but if you want you can try the master branch of Convex.jl which has a geomean supporting more.