# Need help with prod() or any custom function with JuMP

**URL:** <https://discourse.julialang.org/t/need-help-with-prod-or-any-custom-function-with-jump/31962>\
**Category:** Optimization (Mathematical)\
**Created:** [December 7, 2019, 10:35am UTC](https://discourse.julialang.org/t/need-help-with-prod-or-any-custom-function-with-jump/31962 "2019-12-07T10:35:35Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Xentios](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xentios/32/11729_2.png) [@Xentios](https://discourse.julialang.org/u/Xentios)\
**Post date:** [December 7, 2019, 10:35am UTC](https://discourse.julialang.org/t/need-help-with-prod-or-any-custom-function-with-jump/31962/1 "2019-12-07T10:35:35Z")

</div>

All I want is to be able to run an optimization which can use prod() or any custom function i can make.

I tried everything normal and NL objectives, constraints vs…

Ipopt optimizer does what i want but it does with float numbers, I need integer results.

```julia
using JuMP
using Printf
using SCIP

#optimizer = Juniper.Optimizer
#params = Dict{Symbol,Any}()
#params[:nl_solver] = with_optimizer(Ipopt.Optimizer,max_cpu_time=5.0,print_level=0)

#m = Model(with_optimizer(optimizer, params))
#m = Model(with_optimizer(Ipopt.Optimizer, max_cpu_time=160.0))
m = Model(with_optimizer(SCIP.Optimizer))
#m = Model(with_optimizer(AmplNLSolver, "Couenne"))

@variable(m, 0 <=groups[1:41]<=250, integer=true)

@constraint(m,[i in 1:41],sum(groups[i] for i in 1:41)==250)

@objective(m, Max,prod(groups[i] for i in 1:41))

optimize!(m)

for i in 1:41

        @printf("%d info in %f\n ", i,value(groups[i]))

end

@printf("Object cost= %f\n", objective_value(m))

```

---

<div class="post-metadata">

**Author:** ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)\
**Post date:** [December 8, 2019, 11:06am UTC](https://discourse.julialang.org/t/need-help-with-prod-or-any-custom-function-with-jump/31962/2 "2019-12-08T11:06:08Z")

</div>

You cannot use generator expression inside `prod` inside `@objective` and `@constraint` macro:

```julia
julia> using JuMP

julia> @objective(model, Max, prod(i for i in 1:2))
ERROR: LoadError: Expected sum outside generator expression; got prod
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] _parse_generator(::Expr, ::Symbol, ::Array{Any,1}, ::Array{Any,1}, ::Symbol) at /home/blegat/.julia/packages/JuMP/iGamg/src/parse_expr.jl:387
 [3] _parse_expr(::Expr, ::Symbol, ::Array{Any,1}, ::Array{Any,1}, ::Symbol) at /home/blegat/.julia/packages/JuMP/iGamg/src/parse_expr.jl:524
 [4] _parse_expr at /home/blegat/.julia/packages/JuMP/iGamg/src/parse_expr.jl:429 [inlined]
 [5] _parse_expr_toplevel(::Expr, ::Symbol) at /home/blegat/.julia/packages/JuMP/iGamg/src/parse_expr.jl:401
 [6] @objective(::LineNumberNode, ::Module, ::Any, ::Vararg{Any,N} where N) at /home/blegat/.julia/packages/JuMP/iGamg/src/macros.jl:975
in expression starting at REPL[2]:100:

```

However, you can use it outside the macro

```julia
obj = prod(groups[i] for i in eachindex(groups))
@objective(m, Max, obj)

```

and you can also simply avoid using the generator expression:

```julia
julia> @objective(model, Max, prod(groups))
ERROR: Cannot multiply a quadratic expression by a variable

```

however, as shown in the error message, it won’t work unless `length(groups) <= 2` as we only support affine and quadratic exception outside of the `@NLobjective` and `@NLconstraint` macros.  
Your problem is nonlinear and you can solve it with an NLP solver if you use `@NLobjective`.

You could also use a convex solver by doing

```julia
@variable(m, t)
@constraint(m, [t; groups] in MOI.GeometricMeanCone(length(groups) + 1))
@objective(m, Max, t)

```

as [GeometricMeanCone](https://www.juliaopt.org/MathOptInterface.jl/v0.9.7/apireference/#MathOptInterface.GeometricMeanCone) is such that `t <= prod(groups)^(1/n)`.  
Note that the elements of `groups` are additionally constrained to be nonnegative which, depending on your actual need may or may be reasonable.

---

<div class="post-metadata">

**Author:** ![Xentios](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xentios/32/11729_2.png) [@Xentios](https://discourse.julialang.org/u/Xentios)\
**Post date:** [December 8, 2019, 11:25am UTC](https://discourse.julialang.org/t/need-help-with-prod-or-any-custom-function-with-jump/31962/3 "2019-12-08T11:25:06Z")

</div>

Thank you so much for your wide explanation.

As i mention Ipopt Optimizer actually solves it but gives float results in “groups” array.

I guess i need a “MINLP = Mixed-integer nonlinear programming” solver. But i could not find a working one with Jump.

I will try convex solver.  
Thanks again for explanation.  
@blegat

---

<div class="post-metadata">

**Author:** ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)\
**Post date:** [December 8, 2019, 11:30am UTC](https://discourse.julialang.org/t/need-help-with-prod-or-any-custom-function-with-jump/31962/4 "2019-12-08T11:30:43Z")

</div>

You can try MISOCP solvers listed in [Installation Guide · JuMP](https://www.juliaopt.org/JuMP.jl/dev/installation/).  
The GeometricMeanCone will be bridged by the [GeoMeanBridge](https://www.juliaopt.org/MathOptInterface.jl/v0.9.7/apireference/#MathOptInterface.Bridges.Constraint.GeoMeanBridge) into RotatedSecondOrderCone. Then, if the solver does not support RotatedSecondOrderCone, it will be bridged into SecondOrderCone by the [RSOCBridge](https://www.juliaopt.org/MathOptInterface.jl/v0.9.7/apireference/#MathOptInterface.Bridges.Constraint.RSOCBridge).  
So you need to search for a solver supporting both integer variables and Second Order Cone (SOC) constraints, hence MISOCP solvers.

---

<div class="post-metadata">

**Author:** ![leethargo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leethargo/32/6004_2.png) [@leethargo](https://discourse.julialang.org/u/leethargo)\
**Post date:** [December 8, 2019, 2:36pm UTC](https://discourse.julialang.org/t/need-help-with-prod-or-any-custom-function-with-jump/31962/5 "2019-12-08T14:36:55Z")

</div>

Did you encounter any error with using SCIP?  
Both integer variables and SOC constraints are supported. So, with bridges, it should work for your problem.

---

<div class="post-metadata">

**Author:** ![Xentios](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xentios/32/11729_2.png) [@Xentios](https://discourse.julialang.org/u/Xentios)\
**Post date:** [December 8, 2019, 4:28pm UTC](https://discourse.julialang.org/t/need-help-with-prod-or-any-custom-function-with-jump/31962/6 "2019-12-08T16:28:03Z")

</div>

Scip gives this

```julia
> ...
> ERROR: LoadError: LoadError: Expected sum outside generator expression; got prod
> 
> Stacktrace:
> 
> [1] error(::String) at .\error.jl:33
> 
> [2] _parse_generator(::Expr, ::Symbol, ::Array{Any,1}, ::Array{Any,1}, ::Symbol) at C:\Users\Xentios\.julia\packages\JuMP\MsUSY\src\parse_expr.jl:387
> 
> [3] _parse_expr(::Expr, ::Symbol, ::Array{Any,1}, ::Array{Any,1}, ::Symbol) at C:\Users\Xentios\.julia\packages\JuMP\MsUSY\src\parse_expr.jl:524
> 
> [4] _parse_expr at C:\Users\Xentios\.julia\packages\JuMP\MsUSY\src\parse_expr.jl:429 [inlined]
> 
> [5] _parse_expr_toplevel(::Expr, ::Symbol) at C:\Users\Xentios\.julia\packages\JuMP\MsUSY\src\parse_expr.jl:401
> 
> [6] @objective(::LineNumberNode, ::Module, ::Any, ::Vararg{Any,N} where N) at C:\Users\Xentios\.julia\packages\JuMP\MsUSY\src\macros.jl:975
> 
> [7] include at .\boot.jl:328 [inlined]
> 
> [8] include_relative(::Module, ::String) at .\loading.jl:1094
> 
> [9] include(::Module, ::String) at .\Base.jl:31
> 
> [10] exec_options(::Base.JLOptions) at .\client.jl:295
> 
> [11] _start() at .\client.jl:464
> 
> in expression starting at c:\Users\Xentios\Desktop\work\Old\Julia\cop.jl:21
> 
> in expression starting at c:\Users\Xentios\Desktop\work\Old\Julia\cop.jl:21
> ...

```

Btw i did something linear so for now my problem is solved. Thank you all for your interest and help.

---

<div class="post-metadata">

**Author:** ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)\
**Post date:** [December 8, 2019, 4:29pm UTC](https://discourse.julialang.org/t/need-help-with-prod-or-any-custom-function-with-jump/31962/7 "2019-12-08T16:29:17Z")

</div>

I think @leethargo meant using SCIP with the GeometricMeanCone formulation.

---

<div class="post-metadata">

**Author:** ![leethargo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leethargo/32/6004_2.png) [@leethargo](https://discourse.julialang.org/u/leethargo)\
**Post date:** [December 9, 2019, 12:14pm UTC](https://discourse.julialang.org/t/need-help-with-prod-or-any-custom-function-with-jump/31962/8 "2019-12-09T12:14:36Z")

</div>

Yes, that error message comes from JuMP, so I don’t think that switching from SCIP to IPOPT should make any difference there.
