# Convex.jl, possible to have a product as an operation?

**URL:** <https://discourse.julialang.org/t/convex-jl-possible-to-have-a-product-as-an-operation/108101>\
**Category:** Optimization (Mathematical)\
**Tags:** question, convex-optimization\
**Created:** [December 27, 2023, 3:33pm UTC](https://discourse.julialang.org/t/convex-jl-possible-to-have-a-product-as-an-operation/108101 "2023-12-27T15:33:00Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![1m1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/1m1/32/21365_2.png) [@1m1](https://discourse.julialang.org/u/1m1)\
**Post date:** [December 27, 2023, 3:33pm UTC](https://discourse.julialang.org/t/convex-jl-possible-to-have-a-product-as-an-operation/108101/1 "2023-12-27T15:33:00Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![1m1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/1m1/32/21365_2.png) [@1m1](https://discourse.julialang.org/u/1m1)\
**Post date:** [December 27, 2023, 3:50pm UTC](https://discourse.julialang.org/t/convex-jl-possible-to-have-a-product-as-an-operation/108101/2 "2023-12-27T15:50:57Z")

</div>

prod(x::Convex.AbstractExpr) = exp(sum(log(x)))

might work

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [December 27, 2023, 4:04pm UTC](https://discourse.julialang.org/t/convex-jl-possible-to-have-a-product-as-an-operation/108101/3 "2023-12-27T16:04:28Z")

</div>

If you include a minimal runnable example to demonstrate that would help. Convex only supports the rules listed [here](https://jump.dev/Convex.jl/stable/operations/) so your product would have to be with a variable and a constant expression or as a PSD quadratic form or such.

---

<div class="post-metadata">

**Author:** ![1m1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/1m1/32/21365_2.png) [@1m1](https://discourse.julialang.org/u/1m1)\
**Post date:** [December 27, 2023, 4:35pm UTC](https://discourse.julialang.org/t/convex-jl-possible-to-have-a-product-as-an-operation/108101/4 "2023-12-27T16:35:16Z")

</div>

> <https://github.com/1m1-github/julia_arb/blob/main/convex_opt.jl>

the constraints are quadratic. the solution clearly breaks the constraint. ty for your help!

---

<div class="post-metadata">

**Author:** ![1m1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/1m1/32/21365_2.png) [@1m1](https://discourse.julialang.org/u/1m1)\
**Post date:** [December 27, 2023, 4:54pm UTC](https://discourse.julialang.org/t/convex-jl-possible-to-have-a-product-as-an-operation/108101/5 "2023-12-27T16:54:18Z")

</div>

sorry, i replied and have further cleaned up the code. if you look now, its as simple as possible (i think)

---

<div class="post-metadata">

**Author:** ![1m1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/1m1/32/21365_2.png) [@1m1](https://discourse.julialang.org/u/1m1)\
**Post date:** [December 27, 2023, 5:03pm UTC](https://discourse.julialang.org/t/convex-jl-possible-to-have-a-product-as-an-operation/108101/6 "2023-12-27T17:03:58Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [December 28, 2023, 6:56pm UTC](https://discourse.julialang.org/t/convex-jl-possible-to-have-a-product-as-an-operation/108101/7 "2023-12-28T18:56:41Z")

</div>

> 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](https://jump.dev/Convex.jl/stable/#Extended-formulations-and-the-DCP-ruleset), 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):

```julia
# 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

```

---

<div class="post-metadata">

**Author:** ![1m1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/1m1/32/21365_2.png) [@1m1](https://discourse.julialang.org/u/1m1)\
**Post date:** [December 30, 2023, 4:33pm UTC](https://discourse.julialang.org/t/convex-jl-possible-to-have-a-product-as-an-operation/108101/8 "2023-12-30T16:33:47Z")

</div>

> [@ericphanson](#):
>
> φi should be concave

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.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [December 30, 2023, 5:21pm UTC](https://discourse.julialang.org/t/convex-jl-possible-to-have-a-product-as-an-operation/108101/9 "2023-12-30T17:21:17Z")

</div>

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.
