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.