Commit bcc43a24 authored by Janis Born's avatar Janis Born
Browse files

add stdout output options and some documentation

parent af2a4e32
Pipeline #5264 failed with stages
in 6 minutes and 31 seconds
......@@ -13,8 +13,8 @@ int LBFGSSolver::solve(COMISO::NProblemInterface* _problem)
auto data_x = std::vector<double>(n); // current solution
auto data_newx = std::vector<double>(n); // next solution
auto data_g = std::vector<double>(n); // next gradient
auto data_newg = std::vector<double>(n); // current gradient
auto data_g = std::vector<double>(n); // current gradient
auto data_newg = std::vector<double>(n); // next gradient
auto data_d = std::vector<double>(n); // update direction
auto x = Eigen::Map<Eigen::VectorXd>(data_x.data(), n);
......@@ -46,7 +46,9 @@ int LBFGSSolver::solve(COMISO::NProblemInterface* _problem)
for (int iteration = 0; iteration < options.maxIterations; ++iteration) {
auto g_sqrnorm = g.squaredNorm();
if (g_sqrnorm < options.convergenceThreshold) {
printf("Gradient norm threshold reached. Terminating.\n");
if (options.logMessages) {
printf("Gradient norm threshold reached. Terminating.\n");
}
break;
}
......@@ -72,7 +74,9 @@ int LBFGSSolver::solve(COMISO::NProblemInterface* _problem)
// enforce descent
double descent = d.dot(g);
if (descent < 0.01 * options.convergenceThreshold) {
std::cout << "Update direction points away from gradient! Falling back to gradient descent." << std::endl;
if (options.logMessages) {
std::cout << "Update direction points away from gradient! Falling back to gradient descent." << std::endl;
}
d = g;
y_hist.clear();
s_hist.clear();
......@@ -90,6 +94,10 @@ int LBFGSSolver::solve(COMISO::NProblemInterface* _problem)
newf = _problem->eval_f(data_newx.data()); ++num_f_evaluations;
++line_search_evaluations;
if (line_search_evaluations >= options.maxLineSearchIterations) {
if (options.logMessages) {
std::cout << "Warning: Line search could not find a decrease after " << options.maxLineSearchIterations << " iterations." << std::endl;
}
newx = x;
break;
}
}
......@@ -121,7 +129,9 @@ int LBFGSSolver::solve(COMISO::NProblemInterface* _problem)
if (delta_f / f < options.acceptableDecreaseThreshold) {
++acceptable_iterations;
if (acceptable_iterations >= options.maxAcceptableIterations) {
printf("Acceptable threshold reached. Terminating.\n");
if (options.logMessages) {
printf("Acceptable threshold reached. Terminating.\n");
}
break;
}
}
......@@ -129,13 +139,15 @@ int LBFGSSolver::solve(COMISO::NProblemInterface* _problem)
acceptable_iterations = 0;
}
if (iteration % 10 == 0) {
std::printf("+-------+--------------+--------------+--------------+--------------+------+--------------+--------------+--------+\n");
std::printf("| iter | f | |g| | rate | |s| | LSI | g . d | delta f | accept |\n");
std::printf("+-------+--------------+--------------+--------------+--------------+------+--------------+--------------+--------+\n");
if (options.logProgress) {
if (iteration % 10 == 0) {
std::printf("+-------+--------------+--------------+--------------+--------------+------+--------------+--------------+--------+\n");
std::printf("| iter | f | |g| | rate | |s| | LSI | g . d | delta f | accept |\n");
std::printf("+-------+--------------+--------------+--------------+--------------+------+--------------+--------------+--------+\n");
}
std::printf("| %5d | %12g | %12g | %12g | %12g | %4d | %12g | %12g | %6d |\n", iteration+1, f, g_sqrnorm, rate, last_step_size, line_search_evaluations+1, descent, delta_f, acceptable_iterations);
std::cout << std::flush;
}
std::printf("| %5d | %12g | %12g | %12g | %12g | %4d | %12g | %12g | %6d |\n", iteration+1, f, g_sqrnorm, rate, last_step_size, line_search_evaluations+1, descent, delta_f, acceptable_iterations);
std::cout << std::flush;
if (line_search_evaluations == 0) {
rate *= options.lineSearchGrowthFactor;
......@@ -145,13 +157,17 @@ int LBFGSSolver::solve(COMISO::NProblemInterface* _problem)
iteration_callback(iteration, data_x.data());
}
}
std::printf("+-------+--------------+--------------+--------------+--------------+------+--------------+--------------+--------+\n");
if (options.logProgress) {
std::printf("+-------+--------------+--------------+--------------+--------------+------+--------------+--------------+--------+\n");
}
double final_f = _problem->eval_f(data_x.data()); ++num_f_evaluations;
std::cout << "Objective decreased from " << initial_f << " to " << final_f << " (" << (final_f / initial_f) * 100 << " % of initial value)" << std::endl;
std::cout << "Number of unknown variables: " << n << std::endl;
std::cout << "Number of objective evaluations: " << num_f_evaluations << std::endl;
std::cout << "Number of objective gradient evaluations: " << num_g_evaluations << std::endl;
if (options.logMessages) {
std::cout << "Objective decreased from " << initial_f << " to " << final_f << " (" << (final_f / initial_f) * 100 << " % of initial value)" << std::endl;
std::cout << "Number of unknown variables: " << n << std::endl;
std::cout << "Number of objective evaluations: " << num_f_evaluations << std::endl;
std::cout << "Number of objective gradient evaluations: " << num_g_evaluations << std::endl;
}
_problem->store_result(data_x.data());
return 1; // success
......
......@@ -13,14 +13,16 @@ class COMISODLLEXPORT LBFGSSolver
public:
struct Options
{
int maxIterations = 10000;
int historySize = 20;
int maxLineSearchIterations = 32;
int maxAcceptableIterations = 8; // after this many "acceptable" iterations, search is terminated
double lineSearchShrinkFactor = 0.6;
double lineSearchGrowthFactor = 1.2;
double convergenceThreshold = 1e-9;
double convergenceThreshold = 1e-9; // when the squared norm of the gradient falls below this threshold, search is terminated
int maxAcceptableIterations = 8; // after this many "acceptable" iterations, search is terminated
double acceptableDecreaseThreshold = 1e-6; // a relative decrease below this value is considered "acceptable"
int maxIterations = 10000; // after this number of iterations, search is terminated
int maxLineSearchIterations = 64; // maximum number of retries to achieve a descent in the backtracking line search
double lineSearchShrinkFactor = 0.6; // rate used to shrink the step size in the backtracking line search
double lineSearchGrowthFactor = 1.2; // rate used to adaptively grow the step size when the line search succeeds immediately
bool logProgress = true; // print table with current solver progress to stdout
bool logMessages = true; // print status messages (warnings, errors, reports) to stdout
};
int solve(NProblemInterface* _problem);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment