Nonconvex.jl
                                
                                
                                
                                    Nonconvex.jl copied to clipboard
                            
                            
                            
                        Throw a better error when passing a vector as initial solution with a DictModel
@ccoffrin and I are interested in evaluating Nonconvex.jl to test out some different solvers and AD systems. However, we're stymied by conversions from JuMP to Nonconvex:
julia> using JuMP
julia> import Nonconvex
julia> Nonconvex.@load Ipopt
[ Info: Attempting to load the package NonconvexIpopt.
[ Info: Loading succesful.
julia> model = JuMP.Model();
julia> @variable(model, x >= 0)
x
julia> ncvx_model = DictModel(model)
DictModel(NonconvexCore.Objective{NonconvexCore.var"#168#171"{Vector{Symbol}, SparseArrays.SparseVector{Float64, Int64}}, Base.RefValue{Float64}, Set{Symbol}}(NonconvexCore.var"#168#171"{Vector{Symbol}, SparseArrays.SparseVector{Float64, Int64}}([:x], 1-element SparseArrays.SparseVector{Float64, Int64} with 0 stored entries), Base.RefValue{Float64}(1.0), Set{Symbol}()), NonconvexCore.VectorOfFunctions{Vector{NonconvexCore.EqConstraint}}(NonconvexCore.EqConstraint[]), NonconvexCore.VectorOfFunctions{Vector{NonconvexCore.IneqConstraint}}(NonconvexCore.IneqConstraint[]), NonconvexCore.VectorOfFunctions{Vector{NonconvexCore.SDConstraint}}(NonconvexCore.SDConstraint[]), OrderedDict{Any, Any}(:x => 0.0), OrderedDict{Any, Any}(:x => Inf), OrderedDict{Any, Any}(:x => 1.0), OrderedDict{Any, Any}(:x => false))
julia> optimize(ncvx_model, IpoptAlg(), [0.0]; options = IpoptOptions())
This is Ipopt version 3.14.4, running with linear solver MUMPS 5.4.1.
Number of nonzeros in equality constraint Jacobian...:        0
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:        0
ERROR: MethodError: no method matching flatten(::Vector{Float64}, ::Vector{Symbol})
Closest candidates are:
  flatten(::Vector{var"#s46"} where var"#s46"<:Real) at /Users/oscar/.julia/packages/NonconvexCore/YjDSM/src/models/flatten.jl:52
  flatten(::AbstractVector{T} where T) at /Users/oscar/.julia/packages/NonconvexCore/YjDSM/src/models/flatten.jl:54
  flatten(::AbstractArray) at /Users/oscar/.julia/packages/NonconvexCore/YjDSM/src/models/flatten.jl:65
  ...
Stacktrace:
  [1] macro expansion
    @ ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:0 [inlined]
  [2] _pullback(::Zygote.Context, ::typeof(NonconvexCore.flatten), ::Vector{Float64}, ::Vector{Symbol})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:9
  [3] _pullback
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/models/jump.jl:211 [inlined]
  [4] _pullback(ctx::Zygote.Context, f::NonconvexCore.var"#168#171"{Vector{Symbol}, SparseArrays.SparseVector{Float64, Int64}}, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:0
  [5] _apply(::Function, ::Vararg{Any, N} where N)
    @ Core ./boot.jl:804
  [6] adjoint
    @ ~/.julia/packages/Zygote/cCyLF/src/lib/lib.jl:200 [inlined]
  [7] _pullback
    @ ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:65 [inlined]
  [8] _pullback
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/functions/functions.jl:170 [inlined]
  [9] _pullback(::Zygote.Context, ::NonconvexCore.var"##_#8", ::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::NonconvexCore.Objective{NonconvexCore.var"#168#171"{Vector{Symbol}, SparseArrays.SparseVector{Float64, Int64}}, Base.RefValue{Float64}, Set{Symbol}}, ::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:0
 [10] _apply(::Function, ::Vararg{Any, N} where N)
    @ Core ./boot.jl:804
 [11] adjoint
    @ ~/.julia/packages/Zygote/cCyLF/src/lib/lib.jl:200 [inlined]
 [12] _pullback
    @ ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:65 [inlined]
 [13] _pullback
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/functions/functions.jl:170 [inlined]
 [14] _pullback(ctx::Zygote.Context, f::NonconvexCore.Objective{NonconvexCore.var"#168#171"{Vector{Symbol}, SparseArrays.SparseVector{Float64, Int64}}, Base.RefValue{Float64}, Set{Symbol}}, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:0
 [15] _pullback
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/models/vec_model.jl:90 [inlined]
 [16] _pullback(ctx::Zygote.Context, f::NonconvexCore.var"#133#140"{DictModel, NonconvexCore.Unflatten{Vector{Float64}, typeof(identity)}}, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:0
 [17] _apply
    @ ./boot.jl:804 [inlined]
 [18] adjoint
    @ ~/.julia/packages/Zygote/cCyLF/src/lib/lib.jl:200 [inlined]
 [19] _pullback
    @ ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:65 [inlined]
 [20] _pullback
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/functions/functions.jl:170 [inlined]
 [21] _pullback(::Zygote.Context, ::NonconvexCore.var"##_#8", ::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::NonconvexCore.Objective{NonconvexCore.var"#133#140"{DictModel, NonconvexCore.Unflatten{Vector{Float64}, typeof(identity)}}, Base.RefValue{Float64}, Set{Symbol}}, ::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:0
 [22] _apply(::Function, ::Vararg{Any, N} where N)
    @ Core ./boot.jl:804
 [23] adjoint
    @ ~/.julia/packages/Zygote/cCyLF/src/lib/lib.jl:200 [inlined]
 [24] _pullback
    @ ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:65 [inlined]
 [25] _pullback
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/functions/functions.jl:170 [inlined]
 [26] _pullback
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/functions/counting_function.jl:9 [inlined]
 [27] _pullback(ctx::Zygote.Context, f::NonconvexCore.CountingFunction{NonconvexCore.Objective{NonconvexCore.var"#133#140"{DictModel, NonconvexCore.Unflatten{Vector{Float64}, typeof(identity)}}, Base.RefValue{Float64}, Set{Symbol}}}, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface2.jl:0
 [28] _pullback(f::Function, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface.jl:34
 [29] pullback(f::Function, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface.jl:40
 [30] gradient(f::Function, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/cCyLF/src/compiler/interface.jl:75
 [31] (::NonconvexIpopt.var"#eval_grad_f#13"{NonconvexCore.CountingFunction{NonconvexCore.Objective{NonconvexCore.var"#133#140"{DictModel, NonconvexCore.Unflatten{Vector{Float64}, typeof(identity)}}, Base.RefValue{Float64}, Set{Symbol}}}})(x::Vector{Float64}, grad_f::Vector{Float64})
    @ NonconvexIpopt ~/.julia/packages/NonconvexIpopt/4F7iF/src/ipopt.jl:135
 [32] _Eval_Grad_F_CB(n::Int32, x_ptr::Ptr{Float64}, #unused#::Int32, grad_f::Ptr{Float64}, user_data::Ptr{Nothing})
    @ Ipopt ~/.julia/packages/Ipopt/gZvYd/src/C_wrapper.jl:49
 [33] IpoptSolve(prob::Ipopt.IpoptProblem)
    @ Ipopt ~/.julia/packages/Ipopt/gZvYd/src/C_wrapper.jl:431
 [34] optimize!(workspace::NonconvexIpopt.IpoptWorkspace{NonconvexCore.VecModel{Vector{Float64}}, Ipopt.IpoptProblem, Vector{Float64}, IpoptOptions{NamedTuple{(:hessian_approximation, :jac_c_constant, :jac_d_constant), Tuple{String, String, String}}}, Base.RefValue{Int64}})
    @ NonconvexIpopt ~/.julia/packages/NonconvexIpopt/4F7iF/src/ipopt.jl:52
 [35] #optimize#131
    @ ~/.julia/packages/NonconvexCore/YjDSM/src/models/vec_model.jl:74 [inlined]
 [36] optimize(::DictModel, ::IpoptAlg, ::Vector{Float64}; kwargs::Base.Iterators.Pairs{Symbol, IpoptOptions{NamedTuple{(:hessian_approximation, :jac_c_constant, :jac_d_constant), Tuple{String, String, String}}}, Tuple{Symbol}, NamedTuple{(:options,), Tuple{IpoptOptions{NamedTuple{(:hessian_approximation, :jac_c_constant, :jac_d_constant), Tuple{String, String, String}}}}}})
    @ NonconvexCore ~/.julia/packages/NonconvexCore/YjDSM/src/common.jl:233
 [37] top-level scope
    @ REPL[35]:1
(ncvx) pkg> st
      Status `/private/tmp/ncvx/Project.toml`
  [b6b21f68] Ipopt v0.9.1
  [4076af6c] JuMP v0.22.3
  [01bcebdf] Nonconvex v1.0.2
  [bf347577] NonconvexIpopt v0.1.3
  [c36e90e8] PowerModels v0.19.1
                                    
                                    
                                    
                                
This should work:
using JuMP
import Nonconvex
Nonconvex.@load Ipopt
model = JuMP.Model();
@variable(model, x >= 0)
ncvx_model = DictModel(model)
optimize(ncvx_model, IpoptAlg(), Dict(:x => 0.0); options = IpoptOptions())
Note that the initial solution of a DictModel is a dictionary. You can get the default initial solution by calling init = NonconvexCore.getinit(ncvx_model)
Closing this issue. Please open more issues if you feel the need to.
Ah. I guess I got confused with the Zygote error since it didn't throw a method error passing the initial point as a vector.
It would be nice to throw a better error here.
Also I suggest adding some documentation of the existence of getinit.  I did not find it in the documentation that is here, https://julianonconvex.github.io/Nonconvex.jl/stable/