From 92040c2951c5fe8e70cc529e2e8efccc7b768b9f Mon Sep 17 00:00:00 2001
From: tbittar <thomas.bittar@rte-france.com>
Date: Tue, 21 May 2024 09:53:30 +0200
Subject: [PATCH] Add lambdas to math logs (#821)

Closes #816
---
 src/cpp/benders/benders_core/BendersBase.cpp  | 20 ++++++++++++++-----
 .../benders_core/BendersMathLogger.cpp        | 17 ++++++++++++++--
 .../benders_core/include/BendersBase.h        |  2 +-
 .../include/BendersStructsDatas.h             |  2 ++
 src/cpp/benders/outer_loop/OuterLoop.cpp      |  4 +++-
 5 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/src/cpp/benders/benders_core/BendersBase.cpp b/src/cpp/benders/benders_core/BendersBase.cpp
index 3cfe5af80..1f1147d92 100644
--- a/src/cpp/benders/benders_core/BendersBase.cpp
+++ b/src/cpp/benders/benders_core/BendersBase.cpp
@@ -1020,15 +1020,25 @@ double BendersBase::ExternalLoopLambdaMin() const {
   return outer_loop_biLevel_.LambdaMin();
 }
 
-void BendersBase::init_data(double external_loop_lambda) {
+void BendersBase::init_data(double external_loop_lambda,
+                            double external_loop_lambda_min,
+                            double external_loop_lambda_max) {
   benders_timer.restart();
-  auto benders_num_run = _data.outer_loop_current_iteration_data.benders_num_run;
-  auto outer_loop_bilevel_best_ub = _data.outer_loop_current_iteration_data.outer_loop_bilevel_best_ub;
+  auto benders_num_run =
+      _data.outer_loop_current_iteration_data.benders_num_run;
+  auto outer_loop_bilevel_best_ub =
+      _data.outer_loop_current_iteration_data.outer_loop_bilevel_best_ub;
   init_data();
   _data.outer_loop_current_iteration_data.outer_loop_criterion.clear();
   _data.outer_loop_current_iteration_data.benders_num_run = benders_num_run;
-  _data.outer_loop_current_iteration_data.outer_loop_bilevel_best_ub = outer_loop_bilevel_best_ub;
-  _data.outer_loop_current_iteration_data.external_loop_lambda = external_loop_lambda;
+  _data.outer_loop_current_iteration_data.outer_loop_bilevel_best_ub =
+      outer_loop_bilevel_best_ub;
+  _data.outer_loop_current_iteration_data.external_loop_lambda =
+      external_loop_lambda;
+  _data.outer_loop_current_iteration_data.external_loop_lambda_min =
+      external_loop_lambda_min;
+  _data.outer_loop_current_iteration_data.external_loop_lambda_max =
+      external_loop_lambda_max;
 }
 
 bool BendersBase::ExternalLoopFoundFeasible() const {
diff --git a/src/cpp/benders/benders_core/BendersMathLogger.cpp b/src/cpp/benders/benders_core/BendersMathLogger.cpp
index 3022a42cc..359af3220 100644
--- a/src/cpp/benders/benders_core/BendersMathLogger.cpp
+++ b/src/cpp/benders/benders_core/BendersMathLogger.cpp
@@ -53,6 +53,9 @@ std::vector<std::string> HeadersManagerExternalLoop::HeadersList() {
   headers_list.push_back("Max Criterion");
   headers_list.push_back("Area Max Criterion");
   headers_list.push_back("Bilevel best ub");
+  headers_list.push_back("Lambda");
+  headers_list.push_back("Lambda min");
+  headers_list.push_back("Lambda max");
   auto base_headers = HeadersManager::HeadersList();
   std::move(base_headers.begin(), base_headers.end(),
             std::back_inserter(headers_list));
@@ -167,8 +170,18 @@ void PrintExternalLoopData(LogDestination& log_destination,
                   << data.outer_loop_current_iteration_data.max_criterion;
   log_destination << data.outer_loop_current_iteration_data.max_criterion_area;
 
-  log_destination << std::scientific << std::setprecision(10)
-                  << data.outer_loop_current_iteration_data.outer_loop_bilevel_best_ub;
+  log_destination
+      << std::scientific << std::setprecision(10)
+      << data.outer_loop_current_iteration_data.outer_loop_bilevel_best_ub;
+  log_destination
+      << std::scientific << std::setprecision(10)
+      << data.outer_loop_current_iteration_data.external_loop_lambda;
+  log_destination
+      << std::scientific << std::setprecision(10)
+      << data.outer_loop_current_iteration_data.external_loop_lambda_min;
+  log_destination
+      << std::scientific << std::setprecision(10)
+      << data.outer_loop_current_iteration_data.external_loop_lambda_max;
   PrintBendersData(log_destination, data, type, method);
 }
 void MathLoggerBaseExternalLoop::Print(const CurrentIterationData& data) {
diff --git a/src/cpp/benders/benders_core/include/BendersBase.h b/src/cpp/benders/benders_core/include/BendersBase.h
index 705a622c7..67ea04c9f 100644
--- a/src/cpp/benders/benders_core/include/BendersBase.h
+++ b/src/cpp/benders/benders_core/include/BendersBase.h
@@ -89,7 +89,7 @@ class BendersBase {
   OuterLoopCurrentIterationData GetOuterLoopData() const;
   std::vector<double> GetOuterLoopCriterionAtBestBenders() const;
   virtual void init_data();
-  void init_data(double external_loop_lambda);
+  void init_data(double external_loop_lambda, double external_loop_lambda_min, double external_loop_lambda_max);
 
   double ExternalLoopLambdaMax() const;
   double ExternalLoopLambdaMin() const;
diff --git a/src/cpp/benders/benders_core/include/BendersStructsDatas.h b/src/cpp/benders/benders_core/include/BendersStructsDatas.h
index 9329a19ca..bbdc27211 100644
--- a/src/cpp/benders/benders_core/include/BendersStructsDatas.h
+++ b/src/cpp/benders/benders_core/include/BendersStructsDatas.h
@@ -12,6 +12,8 @@ struct OuterLoopCurrentIterationData{
   double max_criterion_best_it = 0.;
   double outer_loop_bilevel_best_ub = +1e20;
   double external_loop_lambda = 0.;
+  double external_loop_lambda_min = 0.;
+  double external_loop_lambda_max = 0.;
   std::string max_criterion_area;
   std::string max_criterion_area_best_it;
 };
diff --git a/src/cpp/benders/outer_loop/OuterLoop.cpp b/src/cpp/benders/outer_loop/OuterLoop.cpp
index 49642fee2..d03a8ace1 100644
--- a/src/cpp/benders/outer_loop/OuterLoop.cpp
+++ b/src/cpp/benders/outer_loop/OuterLoop.cpp
@@ -25,7 +25,9 @@ void OuterLoop::Run() {
   bool stop_update_master = false;
   while (!stop_update_master) {
     PrintLog();
-    benders_->init_data(master_updater_->Rhs());
+    benders_->init_data(master_updater_->Rhs(),
+                        benders_->ExternalLoopLambdaMin(),
+                        benders_->ExternalLoopLambdaMax());
     benders_->launch();
     if(!benders_->isExceptionRaised()) {
       benders_->RunExternalLoopBilevelChecks();