Skip to content

Commit 8d5b746

Browse files
author
Benjamin Chrétien
committed
Fix lambda in result structure
1 parent 2797498 commit 8d5b746

1 file changed

Lines changed: 47 additions & 8 deletions

File tree

src/tnlp.hxx

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,46 @@ namespace roboptim
8383
{}
8484
#endif //!ROBOPTIM_CORE_IPOPT_PLUGIN_CHECK_GRADIENT
8585

86+
template <typename T>
87+
void fillMultipliers (Function::vector_t& multipliers,
88+
const Function::value_type* z_L,
89+
const Function::value_type* z_U,
90+
const Function::value_type* lambda,
91+
Function::size_type n,
92+
Function::size_type m,
93+
const Solver<T>& solver)
94+
{
95+
const Eigen::Map<const Function::argument_t> map_zL (z_L, n);
96+
const Eigen::Map<const Function::argument_t> map_zU (z_U, n);
97+
const Eigen::Map<const Function::argument_t> map_lambda (lambda, m);
98+
99+
multipliers.resize (n + m + 1);
100+
multipliers.setZero ();
101+
102+
// First, argument bounds multipliers
103+
Function::size_type i = 0;
104+
typedef IpoptSolver::problem_t::intervals_t::const_iterator citer_t;
105+
for (citer_t it = solver.problem ().argumentBounds ().begin ();
106+
it != solver.problem ().argumentBounds ().end (); ++it)
107+
{
108+
// Active lower bound
109+
// Note: we expect λ < 0 if active lower bound constraint, and λ > 0 if
110+
// active upper bound constraint
111+
if ((*it).first != -Function::infinity () && map_zL[i] > map_zU[i])
112+
multipliers[i] = -map_zL[i];
113+
// Active upper bound
114+
else if ((*it).second != Function::infinity () && map_zU[i] >= map_zL[i])
115+
multipliers[i] = map_zU[i];
116+
117+
i++;
118+
}
119+
120+
// Then constraint multipliers
121+
multipliers.segment (n, m) = map_lambda;
122+
123+
// Finally, for 1D objective function: 1
124+
multipliers[n+m] = 1.;
125+
}
86126

87127
void
88128
jacobianFromGradients
@@ -541,12 +581,11 @@ namespace roboptim
541581
return false;
542582
}
543583

544-
#define FILL_RESULT() \
545-
array_to_vector (res.x, x); \
546-
res.constraints.resize (m); \
547-
array_to_vector (res.constraints, g); \
548-
res.lambda.resize (m); \
549-
array_to_vector (res.lambda, lambda); \
584+
#define FILL_RESULT() \
585+
res.x = Eigen::Map<const Function::argument_t> (x, n); \
586+
res.constraints = Eigen::Map<const Function::vector_t> (g, m); \
587+
res.lambda = Eigen::Map<const Function::vector_t> (lambda, m); \
588+
fillMultipliers (res.lambda, z_L, z_U, lambda, n, m, solver_); \
550589
res.value (0) = obj_value
551590

552591
#define SWITCH_ERROR(NAME, ERROR) \
@@ -599,8 +638,8 @@ namespace roboptim
599638
void
600639
Tnlp<T>::finalize_solution
601640
(SolverReturn status,
602-
Index n, const Number* x, const Number*,
603-
const Number*, Index m, const Number* g,
641+
Index n, const Number* x, const Number* z_L,
642+
const Number* z_U, Index m, const Number* g,
604643
const Number* lambda, Number obj_value,
605644
const IpoptData*,
606645
IpoptCalculatedQuantities*)

0 commit comments

Comments
 (0)