@@ -15,169 +15,16 @@ function _is_parameter(term::MOI.ScalarQuadraticTerm)
1515 return _is_parameter (term. variable_1) || _is_parameter (term. variable_2)
1616end
1717
18- """
19- _VectorNonlinearOracle(;
20- dimension::Int,
21- l::Vector{Float64},
22- u::Vector{Float64},
23- eval_f::Function,
24- jacobian_structure::Vector{Tuple{Int,Int}},
25- eval_jacobian::Function,
26- hessian_lagrangian_structure::Vector{Tuple{Int,Int}} = Tuple{Int,Int}[],
27- eval_hessian_lagrangian::Union{Nothing,Function} = nothing,
28- ) <: MOI.AbstractVectorSet
29-
30- The set:
31- ```math
32- S = \\ {x \\ in \\ mathbb{R}^{dimension}: l \\ le f(x) \\ le u\\ }
33- ```
34- where ``f`` is defined by the vectors `l` and `u`, and the callback oracles
35- `eval_f`, `eval_jacobian`, and `eval_hessian_lagrangian`.
36-
37- !!! warning
38- This set is experimental. We will decide by September 30, 2025, whether to
39- convert this into the public `Ipopt.VectorNonlinearOracle`, move it to
40- `MOI.VectorNonlinearOracle`, or remove it completely.
41-
42- ## f
43-
44- The `eval_f` function must have the signature
45- ```julia
46- eval_f(ret::AbstractVector, x::AbstractVector)::Nothing
47- ```
48- which fills ``f(x)`` into the dense vector `ret`.
49-
50- ## Jacobian
51-
52- The `eval_jacobian` function must have the signature
53- ```julia
54- eval_jacobian(ret::AbstractVector, x::AbstractVector)::Nothing
55- ```
56- which fills the sparse Jacobian ``\\ nabla f(x)`` into `ret`.
57-
58- The one-indexed sparsity structure must be provided in the `jacobian_structure`
59- argument.
60-
61- ## Hessian
62-
63- The `eval_hessian_lagrangian` function is optional.
64-
65- If `eval_hessian_lagrangian === nothing`, Ipopt will use a Hessian approximation
66- instead of the exact Hessian.
67-
68- If `eval_hessian_lagrangian` is a function, it must have the signature
69- ```julia
70- eval_hessian_lagrangian(
71- ret::AbstractVector,
72- x::AbstractVector,
73- μ::AbstractVector,
74- )::Nothing
75- ```
76- which fills the sparse Hessian of the Lagrangian ``\\ sum \\ mu_i \\ nabla^2 f_i(x)``
77- into `ret`.
78-
79- The one-indexed sparsity structure must be provided in the
80- `hessian_lagrangian_structure` argument.
81-
82- ## Example
83-
84- To model the set:
85- ```math
86- \\ begin{align}
87- 0 \\ le & x^2 \\ le 1
88- 0 \\ le & y^2 + z^3 - w \\ le 0
89- \\ end{align}
90- ```
91- do
92- ```jldoctest
93- julia> import Ipopt
94-
95- julia> set = Ipopt._VectorNonlinearOracle(;
96- dimension = 3,
97- l = [0.0, 0.0],
98- u = [1.0, 0.0],
99- eval_f = (ret, x) -> begin
100- ret[1] = x[2]^2
101- ret[2] = x[3]^2 + x[4]^3 - x[1]
102- return
103- end,
104- jacobian_structure = [(1, 2), (2, 1), (2, 3), (2, 4)],
105- eval_jacobian = (ret, x) -> begin
106- ret[1] = 2.0 * x[2]
107- ret[2] = -1.0
108- ret[3] = 2.0 * x[3]
109- ret[4] = 3.0 * x[4]^2
110- return
111- end,
112- hessian_lagrangian_structure = [(2, 2), (3, 3), (4, 4)],
113- eval_hessian_lagrangian = (ret, x, u) -> begin
114- ret[1] = 2.0 * u[1]
115- ret[2] = 2.0 * u[2]
116- ret[3] = 6.0 * x[4] * u[2]
117- return
118- end,
119- );
120- ```
121- """
122- struct _VectorNonlinearOracle <: MOI.AbstractVectorSet
123- input_dimension:: Int
124- output_dimension:: Int
125- l:: Vector{Float64}
126- u:: Vector{Float64}
127- eval_f:: Function
128- jacobian_structure:: Vector{Tuple{Int,Int}}
129- eval_jacobian:: Function
130- hessian_lagrangian_structure:: Vector{Tuple{Int,Int}}
131- eval_hessian_lagrangian:: Union{Nothing,Function}
132-
133- function _VectorNonlinearOracle (;
134- dimension:: Int ,
135- l:: Vector{Float64} ,
136- u:: Vector{Float64} ,
137- eval_f:: Function ,
138- jacobian_structure:: Vector{Tuple{Int,Int}} ,
139- eval_jacobian:: Function ,
140- # The hessian_lagrangian is optional.
141- hessian_lagrangian_structure:: Vector{Tuple{Int,Int}} = Tuple{Int,Int}[],
142- eval_hessian_lagrangian:: Union{Nothing,Function} = nothing ,
143- )
144- @assert length (l) == length (u)
145- return new (
146- dimension,
147- length (l),
148- l,
149- u,
150- eval_f,
151- jacobian_structure,
152- eval_jacobian,
153- hessian_lagrangian_structure,
154- eval_hessian_lagrangian,
155- )
156- end
157- end
158-
159- MOI. dimension (s:: _VectorNonlinearOracle ) = s. input_dimension
160-
161- MOI. copy (s:: _VectorNonlinearOracle ) = s
162-
163- function Base. show (io:: IO , s:: _VectorNonlinearOracle )
164- println (io, " Ipopt._VectorNonlinearOracle(;" )
165- println (io, " dimension = " , s. input_dimension, " ," )
166- println (io, " l = " , s. l, " ," )
167- println (io, " u = " , s. u, " ," )
168- println (io, " ...," )
169- print (io, " )" )
170- return
171- end
172-
17318mutable struct _VectorNonlinearOracleCache
174- set:: _VectorNonlinearOracle
19+ set:: MOI.VectorNonlinearOracle{Float64}
17520 x:: Vector{Float64}
17621 eval_f_timer:: Float64
17722 eval_jacobian_timer:: Float64
17823 eval_hessian_lagrangian_timer:: Float64
17924
180- function _VectorNonlinearOracleCache (set:: _VectorNonlinearOracle )
25+ function _VectorNonlinearOracleCache (
26+ set:: MOI.VectorNonlinearOracle{Float64} ,
27+ )
18128 return new (set, zeros (set. input_dimension), 0.0 , 0.0 , 0.0 )
18229 end
18330end
@@ -423,7 +270,7 @@ function MOI.get(model::Optimizer, attr::MOI.ListOfConstraintTypesPresent)
423270 append! (ret, MOI. get (model. qp_data, attr))
424271 _add_scalar_nonlinear_constraints (ret, model. nlp_model)
425272 if ! isempty (model. vector_nonlinear_oracle_constraints)
426- push! (ret, (MOI. VectorOfVariables, _VectorNonlinearOracle ))
273+ push! (ret, (MOI. VectorOfVariables, MOI . VectorNonlinearOracle{Float64} ))
427274 end
428275 return ret
429276end
@@ -817,43 +664,46 @@ function MOI.set(
817664 return
818665end
819666
820- # ## MOI.VectorOfVariables in _VectorNonlinearOracle
667+ # ## MOI.VectorOfVariables in MOI.VectorNonlinearOracle{Float64}
821668
822669function MOI. supports_constraint (
823670 :: Optimizer ,
824671 :: Type{MOI.VectorOfVariables} ,
825- :: Type{_VectorNonlinearOracle } ,
672+ :: Type{MOI.VectorNonlinearOracle{Float64} } ,
826673)
827674 return true
828675end
829676
830677function MOI. is_valid (
831678 model:: Optimizer ,
832- ci:: MOI.ConstraintIndex{MOI.VectorOfVariables,_VectorNonlinearOracle} ,
679+ ci:: MOI.ConstraintIndex {
680+ MOI. VectorOfVariables,
681+ MOI. VectorNonlinearOracle{Float64},
682+ },
833683)
834684 return 1 <= ci. value <= length (model. vector_nonlinear_oracle_constraints)
835685end
836686
837687function MOI. get (
838688 model:: Optimizer ,
839689 attr:: MOI.ListOfConstraintIndices{F,S} ,
840- ) where {F<: MOI.VectorOfVariables ,S<: _VectorNonlinearOracle }
690+ ) where {F<: MOI.VectorOfVariables ,S<: MOI.VectorNonlinearOracle{Float64} }
841691 n = length (model. vector_nonlinear_oracle_constraints)
842692 return MOI. ConstraintIndex {F,S} .(1 : n)
843693end
844694
845695function MOI. get (
846696 model:: Optimizer ,
847697 attr:: MOI.NumberOfConstraints{F,S} ,
848- ) where {F<: MOI.VectorOfVariables ,S<: _VectorNonlinearOracle }
698+ ) where {F<: MOI.VectorOfVariables ,S<: MOI.VectorNonlinearOracle{Float64} }
849699 return length (model. vector_nonlinear_oracle_constraints)
850700end
851701
852702function MOI. add_constraint (
853703 model:: Optimizer ,
854704 f:: F ,
855705 s:: S ,
856- ) where {F<: MOI.VectorOfVariables ,S<: _VectorNonlinearOracle }
706+ ) where {F<: MOI.VectorOfVariables ,S<: MOI.VectorNonlinearOracle{Float64} }
857707 model. inner = nothing
858708 cache = _VectorNonlinearOracleCache (s)
859709 push! (model. vector_nonlinear_oracle_constraints, (f, cache))
864714function row (
865715 model:: Optimizer ,
866716 ci:: MOI.ConstraintIndex{F,S} ,
867- ) where {F<: MOI.VectorOfVariables ,S<: _VectorNonlinearOracle }
717+ ) where {F<: MOI.VectorOfVariables ,S<: MOI.VectorNonlinearOracle{Float64} }
868718 offset = length (model. qp_data)
869719 for i in 1 : (ci. value- 1 )
870720 _, s = model. vector_nonlinear_oracle_constraints[i]
@@ -878,7 +728,7 @@ function MOI.get(
878728 model:: Optimizer ,
879729 attr:: MOI.ConstraintPrimal ,
880730 ci:: MOI.ConstraintIndex{F,S} ,
881- ) where {F<: MOI.VectorOfVariables ,S<: _VectorNonlinearOracle }
731+ ) where {F<: MOI.VectorOfVariables ,S<: MOI.VectorNonlinearOracle{Float64} }
882732 MOI. check_result_index_bounds (model, attr)
883733 MOI. throw_if_not_valid (model, ci)
884734 f, _ = model. vector_nonlinear_oracle_constraints[ci. value]
@@ -889,7 +739,7 @@ function MOI.get(
889739 model:: Optimizer ,
890740 attr:: MOI.ConstraintDual ,
891741 ci:: MOI.ConstraintIndex{F,S} ,
892- ) where {F<: MOI.VectorOfVariables ,S<: _VectorNonlinearOracle }
742+ ) where {F<: MOI.VectorOfVariables ,S<: MOI.VectorNonlinearOracle{Float64} }
893743 MOI. check_result_index_bounds (model, attr)
894744 MOI. throw_if_not_valid (model, ci)
895745 sign = - _dual_multiplier (model)
0 commit comments