@@ -12,11 +12,13 @@ const _B = MOI.Bridges
1212# A simple counter for unique operator symbols.
1313const _vno_op_counter = Ref (0 )
1414
15- # --------------------------------------------------------------------------
16- # Helpers: unwrap various MOI optimizer wrappers to reach the `Form` object,
17- # so we can call `MOI.Nonlinear.register_operator` on the underlying
18- # `MOI.Nonlinear.Model`.
19- # --------------------------------------------------------------------------
15+ """
16+ _unwrap_to_form(m)
17+
18+ Unwrap various MOI optimizer wrappers to reach the [`Form`](@ref) object,
19+ so we can call `MOI.Nonlinear.register_operator` on the underlying
20+ `MOI.Nonlinear.Model`.
21+ """
2022function _unwrap_to_form (m)
2123 if m isa Form
2224 return m
@@ -42,24 +44,29 @@ function _vno_op_symbol(base_id::Int, row::Int)
4244 return Symbol (:_diffopt_vno_ , base_id, :_ , row)
4345end
4446
45- # --------------------------------------------------------------------------
46- # Register a scalar operator for one row of the vector oracle:
47- # op_i(x...) = (oracle_f(x))[i]
48- # with gradient and Hessian (lower triangle) provided through the oracle.
49- #
50- # MOI.Nonlinear.register_operator docs:
51- # https://jump.dev/MathOptInterface.jl/stable/submodules/Nonlinear/reference/
52- #
53- # Note: For univariate functions (n=1), MOI expects:
54- # f(x) -> Float64
55- # ∇f(x) -> Float64 (the derivative, not a vector)
56- # ∇²f(x) -> Float64 (the second derivative, not a matrix)
57- #
58- # For multivariate functions (n>1), MOI expects:
59- # f(x...) -> Float64
60- # ∇f(g::Vector, x...) -> nothing (fills g with gradient)
61- # ∇²f(H::Matrix, x...) -> nothing (fills H with lower-triangular Hessian)
62- # --------------------------------------------------------------------------
47+ """
48+ _register_vno_row_operator!(nlm, op, s, row)
49+
50+ Register a scalar operator for one row of the vector oracle:
51+
52+ op_i(x...) = (oracle_f(x))[i]
53+
54+ with gradient and Hessian (lower triangle) provided through the oracle.
55+
56+ See the [MOI.Nonlinear.register_operator docs](https://jump.dev/MathOptInterface.jl/stable/submodules/Nonlinear/reference/)
57+ for details.
58+
59+ !!! note
60+ For univariate functions (`n=1`), MOI expects:
61+ - `f(x) -> Float64`
62+ - `∇f(x) -> Float64` (the derivative, not a vector)
63+ - `∇²f(x) -> Float64` (the second derivative, not a matrix)
64+
65+ For multivariate functions (`n>1`), MOI expects:
66+ - `f(x...) -> Float64`
67+ - `∇f(g::Vector, x...) -> nothing` (fills `g` with gradient)
68+ - `∇²f(H::Matrix, x...) -> nothing` (fills `H` with lower-triangular Hessian)
69+ """
6370function _register_vno_row_operator! (
6471 nlm:: MOI.Nonlinear.Model ,
6572 op:: Symbol ,
@@ -190,9 +197,14 @@ function _register_multivariate_vno_row_operator!(
190197 return
191198end
192199
193- # --------------------------------------------------------------------------
194- # The actual bridge type
195- # --------------------------------------------------------------------------
200+ """
201+ VNOToScalarNLBridge{T<:Real} <: MOI.Bridges.Constraint.AbstractBridge
202+
203+ Bridge that converts a `MOI.VectorNonlinearOracle` constraint (with a
204+ `MOI.VectorOfVariables` function) into a set of scalar `MOI.ScalarNonlinearFunction`
205+ constraints with `MOI.LessThan`, `MOI.GreaterThan`, or `MOI.EqualTo` sets,
206+ one per output row of the oracle.
207+ """
196208struct VNOToScalarNLBridge{T<: Real } <: _B.Constraint.AbstractBridge
197209 f:: MOI.VectorOfVariables
198210 s:: MOI.VectorNonlinearOracle{T}
@@ -411,8 +423,11 @@ function MOI.set(
411423 # The dual is per-input-variable (J' * λ), need to recover λ
412424 _set_duals_from_input_duals! (model, b, value)
413425 else
414- # Unexpected size, skip
415- return
426+ error (
427+ " ConstraintDualStart for VNOToScalarNLBridge expects a vector of " *
428+ " length equal to the output dimension ($m ) or input dimension ($n ), " *
429+ " but got length $(length (value)) ." ,
430+ )
416431 end
417432 return
418433end
0 commit comments