| 96 | GradientProblemSolver::~GradientProblemSolver() = default; |
| 97 | |
| 98 | void GradientProblemSolver::Solve(const GradientProblemSolver::Options& options, |
| 99 | const GradientProblem& problem, |
| 100 | double* parameters_ptr, |
| 101 | GradientProblemSolver::Summary* summary) { |
| 102 | using internal::CallStatistics; |
| 103 | using internal::GradientProblemEvaluator; |
| 104 | using internal::GradientProblemSolverStateUpdatingCallback; |
| 105 | using internal::LoggingCallback; |
| 106 | using internal::Minimizer; |
| 107 | using internal::SetSummaryFinalCost; |
| 108 | using internal::WallTimeInSeconds; |
| 109 | |
| 110 | double start_time = WallTimeInSeconds(); |
| 111 | |
| 112 | CHECK(summary != nullptr); |
| 113 | *summary = Summary(); |
| 114 | // clang-format off |
| 115 | summary->num_parameters = problem.NumParameters(); |
| 116 | summary->num_tangent_parameters = problem.NumTangentParameters(); |
| 117 | summary->line_search_direction_type = options.line_search_direction_type; // NOLINT |
| 118 | summary->line_search_interpolation_type = options.line_search_interpolation_type; // NOLINT |
| 119 | summary->line_search_type = options.line_search_type; |
| 120 | summary->max_lbfgs_rank = options.max_lbfgs_rank; |
| 121 | summary->nonlinear_conjugate_gradient_type = options.nonlinear_conjugate_gradient_type; // NOLINT |
| 122 | // clang-format on |
| 123 | |
| 124 | // Check validity |
| 125 | if (!options.IsValid(&summary->message)) { |
| 126 | LOG(ERROR) << "Terminating: " << summary->message; |
| 127 | return; |
| 128 | } |
| 129 | |
| 130 | VectorRef parameters(parameters_ptr, problem.NumParameters()); |
| 131 | Vector solution(problem.NumParameters()); |
| 132 | solution = parameters; |
| 133 | |
| 134 | // TODO(sameeragarwal): This is a bit convoluted, we should be able |
| 135 | // to convert to minimizer options directly, but this will do for |
| 136 | // now. |
| 137 | Minimizer::Options minimizer_options = |
| 138 | Minimizer::Options(GradientProblemSolverOptionsToSolverOptions(options)); |
| 139 | minimizer_options.evaluator = |
| 140 | std::make_unique<GradientProblemEvaluator>(problem); |
| 141 | |
| 142 | std::unique_ptr<IterationCallback> logging_callback; |
| 143 | if (options.logging_type != SILENT) { |
| 144 | logging_callback = std::make_unique<LoggingCallback>( |
| 145 | LINE_SEARCH, options.minimizer_progress_to_stdout); |
| 146 | minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(), |
| 147 | logging_callback.get()); |
| 148 | } |
| 149 | |
| 150 | std::unique_ptr<IterationCallback> state_updating_callback; |
| 151 | if (options.update_state_every_iteration) { |
| 152 | state_updating_callback = |
| 153 | std::make_unique<GradientProblemSolverStateUpdatingCallback>( |
| 154 | problem.NumParameters(), solution.data(), parameters_ptr); |
| 155 | minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(), |
no test coverage detected