10ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Ceres Solver - A fast non-linear least squares minimizer 279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Copyright 2014 Google Inc. All rights reserved. 30ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// http://code.google.com/p/ceres-solver/ 40ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 50ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Redistribution and use in source and binary forms, with or without 60ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// modification, are permitted provided that the following conditions are met: 70ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 80ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Redistributions of source code must retain the above copyright notice, 90ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// this list of conditions and the following disclaimer. 100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Redistributions in binary form must reproduce the above copyright notice, 110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// this list of conditions and the following disclaimer in the documentation 120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// and/or other materials provided with the distribution. 130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Neither the name of Google Inc. nor the names of its contributors may be 140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// used to endorse or promote products derived from this software without 150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// specific prior written permission. 160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// POSSIBILITY OF SUCH DAMAGE. 280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// 290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Author: keir@google.com (Keir Mierle) 300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// sameeragarwal@google.com (Sameer Agarwal) 310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 3279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "ceres/internal/port.h" 330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/solver.h" 340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 3579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include <sstream> // NOLINT 360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <vector> 3779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/problem.h" 390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/problem_impl.h" 400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/program.h" 410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/solver_impl.h" 420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/stringprintf.h" 4379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "ceres/types.h" 4479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "ceres/version.h" 450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/wall_time.h" 460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace ceres { 481d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberlingnamespace { 491d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 5079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#define OPTION_OP(x, y, OP) \ 5179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (!(options.x OP y)) { \ 5279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::stringstream ss; \ 5379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez ss << "Invalid configuration. "; \ 5479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez ss << string("Solver::Options::" #x " = ") << options.x << ". "; \ 5579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez ss << "Violated constraint: "; \ 5679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez ss << string("Solver::Options::" #x " " #OP " "#y); \ 5779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = ss.str(); \ 5879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; \ 5979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 6079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 6179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#define OPTION_OP_OPTION(x, y, OP) \ 6279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (!(options.x OP options.y)) { \ 6379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez std::stringstream ss; \ 6479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez ss << "Invalid configuration. "; \ 6579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez ss << string("Solver::Options::" #x " = ") << options.x << ". "; \ 6679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez ss << string("Solver::Options::" #y " = ") << options.y << ". "; \ 6779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez ss << "Violated constraint: "; \ 6879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez ss << string("Solver::Options::" #x ); \ 6979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez ss << string(#OP " Solver::Options::" #y "."); \ 7079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = ss.str(); \ 7179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; \ 7279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 7379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 7479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#define OPTION_GE(x, y) OPTION_OP(x, y, >=); 7579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#define OPTION_GT(x, y) OPTION_OP(x, y, >); 7679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#define OPTION_LE(x, y) OPTION_OP(x, y, <=); 7779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#define OPTION_LT(x, y) OPTION_OP(x, y, <); 7879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#define OPTION_LE_OPTION(x, y) OPTION_OP_OPTION(x ,y, <=) 7979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#define OPTION_LT_OPTION(x, y) OPTION_OP_OPTION(x ,y, <) 8079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 8179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezbool CommonOptionsAreValid(const Solver::Options& options, string* error) { 8279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GE(max_num_iterations, 0); 8379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GE(max_solver_time_in_seconds, 0.0); 8479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GE(function_tolerance, 0.0); 8579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GE(gradient_tolerance, 0.0); 8679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GE(parameter_tolerance, 0.0); 8779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(num_threads, 0); 8879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(num_linear_solver_threads, 0); 8979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.check_gradients) { 9079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(gradient_check_relative_precision, 0.0); 9179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(numeric_derivative_relative_step_size, 0.0); 9279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 9379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return true; 9479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez} 9579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 9679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezbool TrustRegionOptionsAreValid(const Solver::Options& options, string* error) { 9779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(initial_trust_region_radius, 0.0); 9879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(min_trust_region_radius, 0.0); 9979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(max_trust_region_radius, 0.0); 10079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_LE_OPTION(min_trust_region_radius, max_trust_region_radius); 10179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_LE_OPTION(min_trust_region_radius, initial_trust_region_radius); 10279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_LE_OPTION(initial_trust_region_radius, max_trust_region_radius); 10379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GE(min_relative_decrease, 0.0); 10479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GE(min_lm_diagonal, 0.0); 10579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GE(max_lm_diagonal, 0.0); 10679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_LE_OPTION(min_lm_diagonal, max_lm_diagonal); 10779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GE(max_num_consecutive_invalid_steps, 0); 10879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(eta, 0.0); 10979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GE(min_linear_solver_iterations, 1); 11079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GE(max_linear_solver_iterations, 1); 11179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_LE_OPTION(min_linear_solver_iterations, max_linear_solver_iterations); 11279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 11379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.use_inner_iterations) { 11479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GE(inner_iteration_tolerance, 0.0); 11579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 11679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 11779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.use_nonmonotonic_steps) { 11879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(max_consecutive_nonmonotonic_steps, 0); 11979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 12079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 12179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.preconditioner_type == CLUSTER_JACOBI && 12279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.sparse_linear_algebra_library_type != SUITE_SPARSE) { 12379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = "CLUSTER_JACOBI requires " 12479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "Solver::Options::sparse_linear_algebra_library_type to be " 12579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "SUITE_SPARSE"; 12679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 12779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 12879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 12979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.preconditioner_type == CLUSTER_TRIDIAGONAL && 13079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.sparse_linear_algebra_library_type != SUITE_SPARSE) { 13179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = "CLUSTER_TRIDIAGONAL requires " 13279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "Solver::Options::sparse_linear_algebra_library_type to be " 13379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "SUITE_SPARSE"; 13479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 13579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 13679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 13779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#ifdef CERES_NO_LAPACK 13879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.dense_linear_algebra_library_type == LAPACK) { 13979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.linear_solver_type == DENSE_NORMAL_CHOLESKY) { 14079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = "Can't use DENSE_NORMAL_CHOLESKY with LAPACK because " 14179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "LAPACK was not enabled when Ceres was built."; 14279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 14379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 14479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 14579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.linear_solver_type == DENSE_QR) { 14679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = "Can't use DENSE_QR with LAPACK because " 14779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "LAPACK was not enabled when Ceres was built."; 14879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 14979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 15079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 15179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.linear_solver_type == DENSE_SCHUR) { 15279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = "Can't use DENSE_SCHUR with LAPACK because " 15379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "LAPACK was not enabled when Ceres was built."; 15479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 15579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 15679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 15779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#endif 15879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 15979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#ifdef CERES_NO_SUITESPARSE 16079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.sparse_linear_algebra_library_type == SUITE_SPARSE) { 16179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.linear_solver_type == SPARSE_NORMAL_CHOLESKY) { 16279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = "Can't use SPARSE_NORMAL_CHOLESKY with SUITESPARSE because " 16379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "SuiteSparse was not enabled when Ceres was built."; 16479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 16579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 16679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 16779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.linear_solver_type == SPARSE_SCHUR) { 16879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = "Can't use SPARSE_SCHUR with SUITESPARSE because " 16979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "SuiteSparse was not enabled when Ceres was built."; 17079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 17179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 17279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 17379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.preconditioner_type == CLUSTER_JACOBI) { 17479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = "CLUSTER_JACOBI preconditioner not supported. " 17579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "SuiteSparse was not enabled when Ceres was built."; 17679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 17779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 17879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 17979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.preconditioner_type == CLUSTER_TRIDIAGONAL) { 18079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = "CLUSTER_TRIDIAGONAL preconditioner not supported. " 18179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "SuiteSparse was not enabled when Ceres was built."; 18279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 18379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 18479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 18579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#endif 18679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 18779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#ifdef CERES_NO_CXSPARSE 18879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.sparse_linear_algebra_library_type == CX_SPARSE) { 18979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.linear_solver_type == SPARSE_NORMAL_CHOLESKY) { 19079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = "Can't use SPARSE_NORMAL_CHOLESKY with CX_SPARSE because " 19179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "CXSparse was not enabled when Ceres was built."; 19279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 19379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 19479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 19579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.linear_solver_type == SPARSE_SCHUR) { 19679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = "Can't use SPARSE_SCHUR with CX_SPARSE because " 19779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "CXSparse was not enabled when Ceres was built."; 19879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 19979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 20079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 20179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#endif 20279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 20379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.trust_region_strategy_type == DOGLEG) { 20479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.linear_solver_type == ITERATIVE_SCHUR || 20579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.linear_solver_type == CGNR) { 20679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = "DOGLEG only supports exact factorization based linear " 20779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "solvers. If you want to use an iterative solver please " 20879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "use LEVENBERG_MARQUARDT as the trust_region_strategy_type"; 20979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 21079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 21179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 21279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 21379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.trust_region_minimizer_iterations_to_dump.size() > 0 && 21479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.trust_region_problem_dump_format_type != CONSOLE && 21579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.trust_region_problem_dump_directory.empty()) { 21679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = "Solver::Options::trust_region_problem_dump_directory is empty."; 21779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 21879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 21979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 22079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (options.dynamic_sparsity && 22179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.linear_solver_type != SPARSE_NORMAL_CHOLESKY) { 22279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = "Dynamic sparsity is only supported with SPARSE_NORMAL_CHOLESKY."; 22379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 22479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 22579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 22679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return true; 22779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez} 22879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 22979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezbool LineSearchOptionsAreValid(const Solver::Options& options, string* error) { 23079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(max_lbfgs_rank, 0); 23179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(min_line_search_step_size, 0.0); 23279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(max_line_search_step_contraction, 0.0); 23379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_LT(max_line_search_step_contraction, 1.0); 23479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_LT_OPTION(max_line_search_step_contraction, 23579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez min_line_search_step_contraction); 23679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_LE(min_line_search_step_contraction, 1.0); 23779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(max_num_line_search_step_size_iterations, 0); 23879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(line_search_sufficient_function_decrease, 0.0); 23979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_LT_OPTION(line_search_sufficient_function_decrease, 24079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez line_search_sufficient_curvature_decrease); 24179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_LT(line_search_sufficient_curvature_decrease, 1.0); 24279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez OPTION_GT(max_line_search_step_expansion, 1.0); 24379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 24479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if ((options.line_search_direction_type == ceres::BFGS || 24579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.line_search_direction_type == ceres::LBFGS) && 24679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.line_search_type != ceres::WOLFE) { 24779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 24879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *error = 24979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez string("Invalid configuration: Solver::Options::line_search_type = ") 25079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez + string(LineSearchTypeToString(options.line_search_type)) 25179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez + string(". When using (L)BFGS, " 25279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "Solver::Options::line_search_type must be set to WOLFE."); 25379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 25479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 25579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 25679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez // Warn user if they have requested BISECTION interpolation, but constraints 25779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez // on max/min step size change during line search prevent bisection scaling 25879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez // from occurring. Warn only, as this is likely a user mistake, but one which 25979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez // does not prevent us from continuing. 26079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez LOG_IF(WARNING, 26179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez (options.line_search_interpolation_type == ceres::BISECTION && 26279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez (options.max_line_search_step_contraction > 0.5 || 26379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez options.min_line_search_step_contraction < 0.5))) 26479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez << "Line search interpolation type is BISECTION, but specified " 26579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez << "max_line_search_step_contraction: " 26679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez << options.max_line_search_step_contraction << ", and " 26779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez << "min_line_search_step_contraction: " 26879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez << options.min_line_search_step_contraction 26979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez << ", prevent bisection (0.5) scaling, continuing with solve regardless."; 27079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 27179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return true; 27279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez} 27379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 27479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#undef OPTION_OP 27579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#undef OPTION_OP_OPTION 27679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#undef OPTION_GT 27779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#undef OPTION_GE 27879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#undef OPTION_LE 27979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#undef OPTION_LT 28079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#undef OPTION_LE_OPTION 28179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#undef OPTION_LT_OPTION 28279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 2831d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberlingvoid StringifyOrdering(const vector<int>& ordering, string* report) { 2841d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling if (ordering.size() == 0) { 2851d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling internal::StringAppendF(report, "AUTOMATIC"); 2861d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling return; 2871d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } 2881d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 2891d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling for (int i = 0; i < ordering.size() - 1; ++i) { 2901d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling internal::StringAppendF(report, "%d, ", ordering[i]); 2911d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } 2921d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling internal::StringAppendF(report, "%d", ordering.back()); 2931d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling} 2941d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 29579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez} // namespace 29679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 29779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezbool Solver::Options::IsValid(string* error) const { 29879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (!CommonOptionsAreValid(*this, error)) { 29979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return false; 30079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 3010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 30279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (minimizer_type == TRUST_REGION) { 30379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return TrustRegionOptionsAreValid(*this, error); 30479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 30579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 30679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez CHECK_EQ(minimizer_type, LINE_SEARCH); 30779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return LineSearchOptionsAreValid(*this, error); 3080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 3090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 3100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongSolver::~Solver() {} 3110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 3120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongvoid Solver::Solve(const Solver::Options& options, 3130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong Problem* problem, 3140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong Solver::Summary* summary) { 3150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong double start_time_seconds = internal::WallTimeInSeconds(); 31679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez CHECK_NOTNULL(problem); 31779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez CHECK_NOTNULL(summary); 31879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 31979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez *summary = Summary(); 32079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (!options.IsValid(&summary->message)) { 32179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez LOG(ERROR) << "Terminating: " << summary->message; 32279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return; 32379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 32479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 32579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez internal::ProblemImpl* problem_impl = problem->problem_impl_.get(); 3260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong internal::SolverImpl::Solve(options, problem_impl, summary); 3270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong summary->total_time_in_seconds = 3280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong internal::WallTimeInSeconds() - start_time_seconds; 3290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 3300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 3310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongvoid Solve(const Solver::Options& options, 3320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong Problem* problem, 3330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong Solver::Summary* summary) { 3340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong Solver solver; 3350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong solver.Solve(options, problem, summary); 3360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 3370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 3380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus KongSolver::Summary::Summary() 3390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // Invalid values for most fields, to ensure that we are not 3400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong // accidentally reporting default values. 3411d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling : minimizer_type(TRUST_REGION), 34279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez termination_type(FAILURE), 34379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez message("ceres::Solve was not called."), 3440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong initial_cost(-1.0), 3450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong final_cost(-1.0), 3460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong fixed_cost(-1.0), 3470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong num_successful_steps(-1), 3480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong num_unsuccessful_steps(-1), 3491d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling num_inner_iteration_steps(-1), 3500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong preprocessor_time_in_seconds(-1.0), 3510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong minimizer_time_in_seconds(-1.0), 3520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong postprocessor_time_in_seconds(-1.0), 3530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong total_time_in_seconds(-1.0), 3541d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling linear_solver_time_in_seconds(-1.0), 3551d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling residual_evaluation_time_in_seconds(-1.0), 3561d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling jacobian_evaluation_time_in_seconds(-1.0), 3571d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling inner_iteration_time_in_seconds(-1.0), 3580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong num_parameter_blocks(-1), 3590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong num_parameters(-1), 3601d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling num_effective_parameters(-1), 3610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong num_residual_blocks(-1), 3620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong num_residuals(-1), 3630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong num_parameter_blocks_reduced(-1), 3640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong num_parameters_reduced(-1), 3651d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling num_effective_parameters_reduced(-1), 3660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong num_residual_blocks_reduced(-1), 3670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong num_residuals_reduced(-1), 3680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong num_threads_given(-1), 3690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong num_threads_used(-1), 3700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong num_linear_solver_threads_given(-1), 3710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong num_linear_solver_threads_used(-1), 3720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong linear_solver_type_given(SPARSE_NORMAL_CHOLESKY), 3730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong linear_solver_type_used(SPARSE_NORMAL_CHOLESKY), 3741d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling inner_iterations_given(false), 3751d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling inner_iterations_used(false), 3760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong preconditioner_type(IDENTITY), 37779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez visibility_clustering_type(CANONICAL_VIEWS), 3780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong trust_region_strategy_type(LEVENBERG_MARQUARDT), 379399f7d09e0c45af54b77b4ab9508d6f23759b927Scott Ettinger dense_linear_algebra_library_type(EIGEN), 380399f7d09e0c45af54b77b4ab9508d6f23759b927Scott Ettinger sparse_linear_algebra_library_type(SUITE_SPARSE), 3811d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling line_search_direction_type(LBFGS), 38279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez line_search_type(ARMIJO), 38379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez line_search_interpolation_type(BISECTION), 38479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez nonlinear_conjugate_gradient_type(FLETCHER_REEVES), 38579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez max_lbfgs_rank(-1) { 3860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} 3870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 3881d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberlingusing internal::StringAppendF; 3891d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberlingusing internal::StringPrintf; 3901d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 39179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezstring Solver::Summary::BriefReport() const { 39279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return StringPrintf("Ceres Solver Report: " 39379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "Iterations: %d, " 39479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "Initial cost: %e, " 39579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "Final cost: %e, " 39679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "Termination: %s", 39779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez num_successful_steps + num_unsuccessful_steps, 39879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez initial_cost, 39979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez final_cost, 40079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez TerminationTypeToString(termination_type)); 40179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez}; 40279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 4030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongstring Solver::Summary::FullReport() const { 4040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong string report = 4050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong "\n" 40679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "Ceres Solver v" CERES_VERSION_STRING " Solve Report\n" 40779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez "----------------------------------\n"; 40879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 40979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez StringAppendF(&report, "%45s %21s\n", "Original", "Reduced"); 41079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez StringAppendF(&report, "Parameter blocks % 25d% 25d\n", 41179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez num_parameter_blocks, num_parameter_blocks_reduced); 41279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez StringAppendF(&report, "Parameters % 25d% 25d\n", 41379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez num_parameters, num_parameters_reduced); 41479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (num_effective_parameters_reduced != num_parameters_reduced) { 41579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez StringAppendF(&report, "Effective parameters% 25d% 25d\n", 41679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez num_effective_parameters, num_effective_parameters_reduced); 4170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 41879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez StringAppendF(&report, "Residual blocks % 25d% 25d\n", 41979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez num_residual_blocks, num_residual_blocks_reduced); 42079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez StringAppendF(&report, "Residual % 25d% 25d\n", 42179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez num_residuals, num_residuals_reduced); 4220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 4231d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling if (minimizer_type == TRUST_REGION) { 4241d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling // TRUST_SEARCH HEADER 4251d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "\nMinimizer %19s\n", 4261d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling "TRUST_REGION"); 427399f7d09e0c45af54b77b4ab9508d6f23759b927Scott Ettinger 428399f7d09e0c45af54b77b4ab9508d6f23759b927Scott Ettinger if (linear_solver_type_used == DENSE_NORMAL_CHOLESKY || 429399f7d09e0c45af54b77b4ab9508d6f23759b927Scott Ettinger linear_solver_type_used == DENSE_SCHUR || 430399f7d09e0c45af54b77b4ab9508d6f23759b927Scott Ettinger linear_solver_type_used == DENSE_QR) { 431399f7d09e0c45af54b77b4ab9508d6f23759b927Scott Ettinger StringAppendF(&report, "\nDense linear algebra library %15s\n", 432399f7d09e0c45af54b77b4ab9508d6f23759b927Scott Ettinger DenseLinearAlgebraLibraryTypeToString( 433399f7d09e0c45af54b77b4ab9508d6f23759b927Scott Ettinger dense_linear_algebra_library_type)); 434399f7d09e0c45af54b77b4ab9508d6f23759b927Scott Ettinger } 435399f7d09e0c45af54b77b4ab9508d6f23759b927Scott Ettinger 4361d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling if (linear_solver_type_used == SPARSE_NORMAL_CHOLESKY || 4371d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling linear_solver_type_used == SPARSE_SCHUR || 4381d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling (linear_solver_type_used == ITERATIVE_SCHUR && 4391d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling (preconditioner_type == CLUSTER_JACOBI || 4401d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling preconditioner_type == CLUSTER_TRIDIAGONAL))) { 4411d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "\nSparse linear algebra library %15s\n", 4421d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling SparseLinearAlgebraLibraryTypeToString( 443399f7d09e0c45af54b77b4ab9508d6f23759b927Scott Ettinger sparse_linear_algebra_library_type)); 4441d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } 4450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 4461d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Trust region strategy %19s", 4471d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling TrustRegionStrategyTypeToString( 4481d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling trust_region_strategy_type)); 4491d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling if (trust_region_strategy_type == DOGLEG) { 4501d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling if (dogleg_type == TRADITIONAL_DOGLEG) { 4511d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, " (TRADITIONAL)"); 4521d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } else { 4531d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, " (SUBSPACE)"); 4541d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } 4551d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } 4561d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "\n"); 4571d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "\n"); 4581d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 4591d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "%45s %21s\n", "Given", "Used"); 4601d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Linear solver %25s%25s\n", 4611d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling LinearSolverTypeToString(linear_solver_type_given), 4621d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling LinearSolverTypeToString(linear_solver_type_used)); 4631d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 4641d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling if (linear_solver_type_given == CGNR || 4651d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling linear_solver_type_given == ITERATIVE_SCHUR) { 4661d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Preconditioner %25s%25s\n", 4671d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling PreconditionerTypeToString(preconditioner_type), 4681d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling PreconditionerTypeToString(preconditioner_type)); 4691d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } 4701d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 47179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (preconditioner_type == CLUSTER_JACOBI || 47279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez preconditioner_type == CLUSTER_TRIDIAGONAL) { 47379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez StringAppendF(&report, "Visibility clustering%24s%25s\n", 47479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez VisibilityClusteringTypeToString( 47579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez visibility_clustering_type), 47679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez VisibilityClusteringTypeToString( 47779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez visibility_clustering_type)); 47879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez } 4791d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Threads % 25d% 25d\n", 4801d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling num_threads_given, num_threads_used); 4811d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Linear solver threads % 23d% 25d\n", 4821d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling num_linear_solver_threads_given, 4831d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling num_linear_solver_threads_used); 4841d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 4851d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling if (IsSchurType(linear_solver_type_used)) { 4861d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling string given; 4871d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringifyOrdering(linear_solver_ordering_given, &given); 4881d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling string used; 4891d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringifyOrdering(linear_solver_ordering_used, &used); 4901d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, 4911d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling "Linear solver ordering %22s %24s\n", 4921d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling given.c_str(), 4931d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling used.c_str()); 4941d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } 4951d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 4961d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling if (inner_iterations_given) { 4971d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, 4981d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling "Use inner iterations %20s %20s\n", 4991d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling inner_iterations_given ? "True" : "False", 5001d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling inner_iterations_used ? "True" : "False"); 5011d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } 5021d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 5031d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling if (inner_iterations_used) { 5041d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling string given; 5051d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringifyOrdering(inner_iteration_ordering_given, &given); 5061d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling string used; 5071d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringifyOrdering(inner_iteration_ordering_used, &used); 5081d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, 5091d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling "Inner iteration ordering %20s %24s\n", 5101d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling given.c_str(), 5111d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling used.c_str()); 5121d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } 5130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } else { 5141d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling // LINE_SEARCH HEADER 5151d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "\nMinimizer %19s\n", "LINE_SEARCH"); 5160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 5170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 5181d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling string line_search_direction_string; 5191d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling if (line_search_direction_type == LBFGS) { 5201d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling line_search_direction_string = StringPrintf("LBFGS (%d)", max_lbfgs_rank); 5211d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } else if (line_search_direction_type == NONLINEAR_CONJUGATE_GRADIENT) { 5221d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling line_search_direction_string = 5231d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling NonlinearConjugateGradientTypeToString( 5241d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling nonlinear_conjugate_gradient_type); 5250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } else { 5261d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling line_search_direction_string = 5271d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling LineSearchDirectionTypeToString(line_search_direction_type); 5280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 5290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 5301d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Line search direction %19s\n", 5311d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling line_search_direction_string.c_str()); 5321d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 5331d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling const string line_search_type_string = 5341d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringPrintf("%s %s", 5351d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling LineSearchInterpolationTypeToString( 5361d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling line_search_interpolation_type), 5371d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling LineSearchTypeToString(line_search_type)); 5381d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Line search type %19s\n", 5391d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling line_search_type_string.c_str()); 5401d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "\n"); 5411d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 5421d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "%45s %21s\n", "Given", "Used"); 5431d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Threads % 25d% 25d\n", 5441d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling num_threads_given, num_threads_used); 5451d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } 5460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 5471d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "\nCost:\n"); 5481d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Initial % 30e\n", initial_cost); 54979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez if (termination_type != FAILURE && 55079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez termination_type != USER_FAILURE) { 5511d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Final % 30e\n", final_cost); 5521d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Change % 30e\n", 5531d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling initial_cost - final_cost); 5540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong } 5550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 5561d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "\nMinimizer iterations % 16d\n", 5571d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling num_successful_steps + num_unsuccessful_steps); 5581d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 5591d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling // Successful/Unsuccessful steps only matter in the case of the 5601d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling // trust region solver. Line search terminates when it encounters 5611d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling // the first unsuccessful step. 5621d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling if (minimizer_type == TRUST_REGION) { 5631d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Successful steps % 14d\n", 5641d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling num_successful_steps); 5651d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Unsuccessful steps % 14d\n", 5661d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling num_unsuccessful_steps); 5671d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } 5681d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling if (inner_iterations_used) { 5691d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Steps with inner iterations % 14d\n", 5701d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling num_inner_iteration_steps); 5711d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } 5721d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 5731d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "\nTime (in seconds):\n"); 5741d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Preprocessor %25.3f\n", 5751d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling preprocessor_time_in_seconds); 5761d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 5771d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "\n Residual evaluation %23.3f\n", 5781d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling residual_evaluation_time_in_seconds); 5791d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, " Jacobian evaluation %23.3f\n", 5801d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling jacobian_evaluation_time_in_seconds); 5811d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 5821d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling if (minimizer_type == TRUST_REGION) { 5831d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, " Linear solver %23.3f\n", 5841d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling linear_solver_time_in_seconds); 5851d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } 5861d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 5871d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling if (inner_iterations_used) { 5881d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, " Inner iterations %23.3f\n", 5891d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling inner_iteration_time_in_seconds); 5901d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling } 5911d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 5921d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Minimizer %25.3f\n\n", 5931d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling minimizer_time_in_seconds); 5941d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 5951d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Postprocessor %24.3f\n", 5961d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling postprocessor_time_in_seconds); 5971d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 5981d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling StringAppendF(&report, "Total %25.3f\n\n", 5991d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling total_time_in_seconds); 6001d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling 60179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez StringAppendF(&report, "Termination: %25s (%s)\n", 60279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez TerminationTypeToString(termination_type), message.c_str()); 6030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong return report; 6040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}; 6050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong 60679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezbool Solver::Summary::IsSolutionUsable() const { 60779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez return (termination_type == CONVERGENCE || 60879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez termination_type == NO_CONVERGENCE || 60979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez termination_type == USER_SUCCESS); 61079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez} 61179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez 6120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong} // namespace ceres 613