Skip to content

Commit b9649d7

Browse files
fix comments and rm output dual set
1 parent 0cd9293 commit b9649d7

2 files changed

Lines changed: 15 additions & 24 deletions

File tree

src/NonLinearProgram/vno_bridge.jl

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -405,30 +405,22 @@ function MOI.set(
405405
b::VNOToScalarNLBridge{T},
406406
value::AbstractVector,
407407
) where {T}
408-
# For VectorOfVariables in VectorNonlinearOracle, the ConstraintDual from solvers
409-
# like Ipopt has length = input_dimension (variables), not output_dimension.
410-
# This is because it represents the dual contribution per variable: J' * λ
411-
# where J is the Jacobian and λ is the vector of constraint duals.
412-
#
413-
# For our bridged scalar constraints, we need the dual per output (λ).
414-
# We can recover λ from the Jacobian: λ = (J * J')^{-1} * J * dual_per_var
408+
# The dual for the VNO constraint is λ (length n = input_dimension), one
409+
# multiplier per variable. The bridged scalar constraints have duals μ
410+
# (length m = output_dimension). The Lagrangian gradient identity
411+
# `λ = J(x)' * μ` determines the relationship, so we always solve
412+
# J(x)' * μ = λ regardless of whether m == n.
415413

416-
m = b.s.output_dimension
417414
n = b.s.input_dimension
418415

419-
if length(value) == m
420-
# Direct mapping: value[i] is dual for output i
421-
_set_duals_from_output_duals!(model, b, value)
422-
elseif length(value) == n
423-
# The dual is per-input-variable (J' * λ), need to recover λ
424-
_set_duals_from_input_duals!(model, b, value)
425-
else
416+
if length(value) != n
426417
error(
427418
"ConstraintDualStart for VNOToScalarNLBridge expects a vector of " *
428-
"length equal to the output dimension ($m) or input dimension ($n), " *
419+
"length equal to the input dimension ($n), " *
429420
"but got length $(length(value)).",
430421
)
431422
end
423+
_set_duals_from_input_duals!(model, b, value)
432424
return
433425
end
434426

@@ -456,14 +448,13 @@ function _set_duals_from_input_duals!(
456448
J[r, c] = vals[k]
457449
end
458450

459-
# Compute λ from dual_per_var = J' * λ
460-
# λ = (J * J')^{-1} * J * dual_per_var
461-
# For numerical stability, use least squares: λ = J' \ dual_per_var
462-
# which solves min ||J' * λ - dual_per_var||
463-
λ = J' \ dual_per_var
451+
# Solve J(x)' * μ = dual_per_var (= λ) for the output duals μ.
452+
# J' is (n×m), so this is an n-equation system in m unknowns.
453+
# Julia's \ uses the minimum-norm / least-squares solution as appropriate.
454+
μ = J' \ dual_per_var
464455

465-
# Now set the scalar constraint duals
466-
_set_duals_from_output_duals!(model, b, λ)
456+
# Set the scalar constraint dual starts to μ.
457+
_set_duals_from_output_duals!(model, b, μ)
467458
return
468459
end
469460

test/vno_bridge.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -695,8 +695,8 @@ function test_VectorNonlinearOracle_dual_start_size_error()
695695
bridge,
696696
[1.0, 2.0, 3.0],
697697
)
698-
@test occursin("output dimension", err.value.msg)
699698
@test occursin("input dimension", err.value.msg)
699+
@test !occursin("output dimension", err.value.msg)
700700
@test occursin("3", err.value.msg)
701701
end
702702

0 commit comments

Comments
 (0)