| 220 | } |
| 221 | |
| 222 | void PythonModel::compute_hessian_vector_product(const double* x, const double* vector, double objective_multiplier, |
| 223 | const Vector<double>& multipliers, double* result) const { |
| 224 | if (this->user_model.lagrangian_hessian_operator.has_value()) { |
| 225 | objective_multiplier *= this->optimization_sense; |
| 226 | // if the model has a different sign convention for the Lagrangian than Uno, flip the signs of the multipliers |
| 227 | if (this->user_model.lagrangian_sign_convention == UNO_MULTIPLIER_POSITIVE) { |
| 228 | const_cast<Vector<double>&>(multipliers).scale(-1.); |
| 229 | } |
| 230 | const auto x_py = to_const_array(x, this->number_variables); |
| 231 | const auto multipliers_py = to_const_array(multipliers.data(), this->number_constraints); |
| 232 | const auto vector_py = to_const_array(vector, this->number_variables); |
| 233 | auto result_py = to_array(result, this->number_variables); |
| 234 | |
| 235 | // evaluate Hessian-vector product |
| 236 | try { |
| 237 | (*this->user_model.lagrangian_hessian_operator)(x_py, true, objective_multiplier, multipliers_py, vector_py, result_py); |
| 238 | } |
| 239 | catch (const std::exception&) { |
| 240 | throw HessianEvaluationError(); |
| 241 | } |
| 242 | // flip the signs of the multipliers back |
| 243 | if (this->user_model.lagrangian_sign_convention == UNO_MULTIPLIER_POSITIVE) { |
| 244 | const_cast<Vector<double>&>(multipliers).scale(-1.); |
| 245 | } |
| 246 | } |
| 247 | else { |
| 248 | throw std::runtime_error("compute_hessian_vector_product not implemented"); |
| 249 | } |
| 250 | } |
| 251 | |
| 252 | const std::vector<double>& PythonModel::get_variables_lower_bounds() const { |
| 253 | return this->user_model.variables_lower_bounds; |
nothing calls this directly
no test coverage detected