Variable number of Nonlinear Constraints by user-defined functions

question

#1

Hi there,

Sorry about the formatting on a previous version of the post. I am new to Julia and doing research in demand modelling. And I apologize if this is too basic. I am thinking to move my code from Rcpp to Julia to solve MPEC, mainly a optimization problem with lots of non-convex constraints (normally 100k+). I’ve heard that JuMP is a great choice due to its AD tools and efficiency. However, I encountered some difficulties here when coding my nonlinear constraint. I coded a function model_constraint whose output is a n_constraint by 1 column vector that will be the Right hand side of my nonlinear constraints. The dimension could be 20,50 and depends on the data so I cannot pin it down before hand. I know that from the other thread I could workaround the requirement that nonlinear objective functions only take scalar input by using the trick

function GMM_obj(ita...)
    ita_vec = collect(ita)
    ....
end

And while setting objective, do

JuMP.setNLobjective(mod, :Min, Expr(:call, :GMM_obj, [x[i] for i=1:n_x]…))

I tried to do similar things when the NL constraints defined by the following user-defined functions have variable length of input and output:

function model_constraint(xlist...)
    x = collect(xlist)
    ...
end

My thought was to store the vector output of the nonlinear function into a NLexpression and use a for loop to set the constraint 1 by 1 as below

JuMP.register(mod, :model_constraint, n_x, model_constraint, autodiff=true)
@expression(mod, GMM_constraint_LHS, zeros(n_constraint,1))
@NLexpression(mod, GMM_constraint_RHS, Expr(:call, :model_constraint, [x[i] for i=1:n_x]...))
 for j in 1:n_constraint
    @NLconstraints(mod, GMM_constraint_LHS[j] == GMM_constraint_RHS[j])
 end

But the line with NLexpression has error:
Unrecognized function “Expr” used in nonlinear expression.
in error at base\error.jl:21

I know the caveat for large number of input dimension or constraints but the problem here is not really about high dimension but the variable number of constraints. I have n nonlinear constraints and I cannot handcode them and have to rely on a loop to specify them if JuMP doesn’t support vector NL constraints. Is there any elegant way to do it? Thanks!


#2

No, there is currently no elegant way to handle user-defined functions with multidimensional output in JuMP. I would recommend manually using an AD tool like ReverseDiff.jl and handing the derivatives to Ipopt via MathProgBase.