Home | History | Annotate | Download | only in ceres
      1 // Ceres Solver - A fast non-linear least squares minimizer
      2 // Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
      3 // http://code.google.com/p/ceres-solver/
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are met:
      7 //
      8 // * Redistributions of source code must retain the above copyright notice,
      9 //   this list of conditions and the following disclaimer.
     10 // * Redistributions in binary form must reproduce the above copyright notice,
     11 //   this list of conditions and the following disclaimer in the documentation
     12 //   and/or other materials provided with the distribution.
     13 // * Neither the name of Google Inc. nor the names of its contributors may be
     14 //   used to endorse or promote products derived from this software without
     15 //   specific prior written permission.
     16 //
     17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     27 // POSSIBILITY OF SUCH DAMAGE.
     28 //
     29 // Author: keir (at) google.com (Keir Mierle)
     30 
     31 #include "ceres/solver_impl.h"
     32 
     33 #include <cstdio>
     34 #include <iostream>  // NOLINT
     35 #include <numeric>
     36 #include "ceres/coordinate_descent_minimizer.h"
     37 #include "ceres/evaluator.h"
     38 #include "ceres/gradient_checking_cost_function.h"
     39 #include "ceres/iteration_callback.h"
     40 #include "ceres/levenberg_marquardt_strategy.h"
     41 #include "ceres/linear_solver.h"
     42 #include "ceres/map_util.h"
     43 #include "ceres/minimizer.h"
     44 #include "ceres/ordered_groups.h"
     45 #include "ceres/parameter_block.h"
     46 #include "ceres/parameter_block_ordering.h"
     47 #include "ceres/problem.h"
     48 #include "ceres/problem_impl.h"
     49 #include "ceres/program.h"
     50 #include "ceres/residual_block.h"
     51 #include "ceres/stringprintf.h"
     52 #include "ceres/trust_region_minimizer.h"
     53 #include "ceres/wall_time.h"
     54 
     55 namespace ceres {
     56 namespace internal {
     57 namespace {
     58 
     59 // Callback for updating the user's parameter blocks. Updates are only
     60 // done if the step is successful.
     61 class StateUpdatingCallback : public IterationCallback {
     62  public:
     63   StateUpdatingCallback(Program* program, double* parameters)
     64       : program_(program), parameters_(parameters) {}
     65 
     66   CallbackReturnType operator()(const IterationSummary& summary) {
     67     if (summary.step_is_successful) {
     68       program_->StateVectorToParameterBlocks(parameters_);
     69       program_->CopyParameterBlockStateToUserState();
     70     }
     71     return SOLVER_CONTINUE;
     72   }
     73 
     74  private:
     75   Program* program_;
     76   double* parameters_;
     77 };
     78 
     79 // Callback for logging the state of the minimizer to STDERR or STDOUT
     80 // depending on the user's preferences and logging level.
     81 class LoggingCallback : public IterationCallback {
     82  public:
     83   explicit LoggingCallback(bool log_to_stdout)
     84       : log_to_stdout_(log_to_stdout) {}
     85 
     86   ~LoggingCallback() {}
     87 
     88   CallbackReturnType operator()(const IterationSummary& summary) {
     89     const char* kReportRowFormat =
     90         "% 4d: f:% 8e d:% 3.2e g:% 3.2e h:% 3.2e "
     91         "rho:% 3.2e mu:% 3.2e li:% 3d it:% 3.2e tt:% 3.2e";
     92     string output = StringPrintf(kReportRowFormat,
     93                                  summary.iteration,
     94                                  summary.cost,
     95                                  summary.cost_change,
     96                                  summary.gradient_max_norm,
     97                                  summary.step_norm,
     98                                  summary.relative_decrease,
     99                                  summary.trust_region_radius,
    100                                  summary.linear_solver_iterations,
    101                                  summary.iteration_time_in_seconds,
    102                                  summary.cumulative_time_in_seconds);
    103     if (log_to_stdout_) {
    104       cout << output << endl;
    105     } else {
    106       VLOG(1) << output;
    107     }
    108     return SOLVER_CONTINUE;
    109   }
    110 
    111  private:
    112   const bool log_to_stdout_;
    113 };
    114 
    115 // Basic callback to record the execution of the solver to a file for
    116 // offline analysis.
    117 class FileLoggingCallback : public IterationCallback {
    118  public:
    119   explicit FileLoggingCallback(const string& filename)
    120       : fptr_(NULL) {
    121     fptr_ = fopen(filename.c_str(), "w");
    122     CHECK_NOTNULL(fptr_);
    123   }
    124 
    125   virtual ~FileLoggingCallback() {
    126     if (fptr_ != NULL) {
    127       fclose(fptr_);
    128     }
    129   }
    130 
    131   virtual CallbackReturnType operator()(const IterationSummary& summary) {
    132     fprintf(fptr_,
    133             "%4d %e %e\n",
    134             summary.iteration,
    135             summary.cost,
    136             summary.cumulative_time_in_seconds);
    137     return SOLVER_CONTINUE;
    138   }
    139  private:
    140     FILE* fptr_;
    141 };
    142 
    143 }  // namespace
    144 
    145 void SolverImpl::Minimize(const Solver::Options& options,
    146                           Program* program,
    147                           CoordinateDescentMinimizer* inner_iteration_minimizer,
    148                           Evaluator* evaluator,
    149                           LinearSolver* linear_solver,
    150                           double* parameters,
    151                           Solver::Summary* summary) {
    152   Minimizer::Options minimizer_options(options);
    153 
    154   // TODO(sameeragarwal): Add support for logging the configuration
    155   // and more detailed stats.
    156   scoped_ptr<IterationCallback> file_logging_callback;
    157   if (!options.solver_log.empty()) {
    158     file_logging_callback.reset(new FileLoggingCallback(options.solver_log));
    159     minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
    160                                        file_logging_callback.get());
    161   }
    162 
    163   LoggingCallback logging_callback(options.minimizer_progress_to_stdout);
    164   if (options.logging_type != SILENT) {
    165     minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
    166                                        &logging_callback);
    167   }
    168 
    169   StateUpdatingCallback updating_callback(program, parameters);
    170   if (options.update_state_every_iteration) {
    171     // This must get pushed to the front of the callbacks so that it is run
    172     // before any of the user callbacks.
    173     minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
    174                                        &updating_callback);
    175   }
    176 
    177   minimizer_options.evaluator = evaluator;
    178   scoped_ptr<SparseMatrix> jacobian(evaluator->CreateJacobian());
    179   minimizer_options.jacobian = jacobian.get();
    180   minimizer_options.inner_iteration_minimizer = inner_iteration_minimizer;
    181 
    182   TrustRegionStrategy::Options trust_region_strategy_options;
    183   trust_region_strategy_options.linear_solver = linear_solver;
    184   trust_region_strategy_options.initial_radius =
    185       options.initial_trust_region_radius;
    186   trust_region_strategy_options.max_radius = options.max_trust_region_radius;
    187   trust_region_strategy_options.lm_min_diagonal = options.lm_min_diagonal;
    188   trust_region_strategy_options.lm_max_diagonal = options.lm_max_diagonal;
    189   trust_region_strategy_options.trust_region_strategy_type =
    190       options.trust_region_strategy_type;
    191   trust_region_strategy_options.dogleg_type = options.dogleg_type;
    192   scoped_ptr<TrustRegionStrategy> strategy(
    193       TrustRegionStrategy::Create(trust_region_strategy_options));
    194   minimizer_options.trust_region_strategy = strategy.get();
    195 
    196   TrustRegionMinimizer minimizer;
    197   double minimizer_start_time = WallTimeInSeconds();
    198   minimizer.Minimize(minimizer_options, parameters, summary);
    199   summary->minimizer_time_in_seconds =
    200       WallTimeInSeconds() - minimizer_start_time;
    201 }
    202 
    203 void SolverImpl::Solve(const Solver::Options& original_options,
    204                        ProblemImpl* original_problem_impl,
    205                        Solver::Summary* summary) {
    206   double solver_start_time = WallTimeInSeconds();
    207 
    208   Program* original_program = original_problem_impl->mutable_program();
    209   ProblemImpl* problem_impl = original_problem_impl;
    210 
    211   // Reset the summary object to its default values.
    212   *CHECK_NOTNULL(summary) = Solver::Summary();
    213 
    214   summary->num_parameter_blocks = problem_impl->NumParameterBlocks();
    215   summary->num_parameters = problem_impl->NumParameters();
    216   summary->num_residual_blocks = problem_impl->NumResidualBlocks();
    217   summary->num_residuals = problem_impl->NumResiduals();
    218 
    219   // Empty programs are usually a user error.
    220   if (summary->num_parameter_blocks == 0) {
    221     summary->error = "Problem contains no parameter blocks.";
    222     LOG(ERROR) << summary->error;
    223     return;
    224   }
    225 
    226   if (summary->num_residual_blocks == 0) {
    227     summary->error = "Problem contains no residual blocks.";
    228     LOG(ERROR) << summary->error;
    229     return;
    230   }
    231 
    232   Solver::Options options(original_options);
    233   options.linear_solver_ordering = NULL;
    234   options.inner_iteration_ordering = NULL;
    235 
    236 #ifndef CERES_USE_OPENMP
    237   if (options.num_threads > 1) {
    238     LOG(WARNING)
    239         << "OpenMP support is not compiled into this binary; "
    240         << "only options.num_threads=1 is supported. Switching "
    241         << "to single threaded mode.";
    242     options.num_threads = 1;
    243   }
    244   if (options.num_linear_solver_threads > 1) {
    245     LOG(WARNING)
    246         << "OpenMP support is not compiled into this binary; "
    247         << "only options.num_linear_solver_threads=1 is supported. Switching "
    248         << "to single threaded mode.";
    249     options.num_linear_solver_threads = 1;
    250   }
    251 #endif
    252 
    253   summary->num_threads_given = original_options.num_threads;
    254   summary->num_threads_used = options.num_threads;
    255 
    256   if (options.lsqp_iterations_to_dump.size() > 0) {
    257     LOG(WARNING) << "Dumping linear least squares problems to disk is"
    258         " currently broken. Ignoring Solver::Options::lsqp_iterations_to_dump";
    259   }
    260 
    261   // Evaluate the initial cost, residual vector and the jacobian
    262   // matrix if requested by the user. The initial cost needs to be
    263   // computed on the original unpreprocessed problem, as it is used to
    264   // determine the value of the "fixed" part of the objective function
    265   // after the problem has undergone reduction.
    266   if (!Evaluator::Evaluate(original_program,
    267                            options.num_threads,
    268                            &(summary->initial_cost),
    269                            options.return_initial_residuals
    270                            ? &summary->initial_residuals
    271                            : NULL,
    272                            options.return_initial_gradient
    273                            ? &summary->initial_gradient
    274                            : NULL,
    275                            options.return_initial_jacobian
    276                            ? &summary->initial_jacobian
    277                            : NULL)) {
    278     summary->termination_type = NUMERICAL_FAILURE;
    279     summary->error = "Unable to evaluate the initial cost.";
    280     LOG(ERROR) << summary->error;
    281     return;
    282   }
    283 
    284   original_program->SetParameterBlockStatePtrsToUserStatePtrs();
    285 
    286   // If the user requests gradient checking, construct a new
    287   // ProblemImpl by wrapping the CostFunctions of problem_impl inside
    288   // GradientCheckingCostFunction and replacing problem_impl with
    289   // gradient_checking_problem_impl.
    290   scoped_ptr<ProblemImpl> gradient_checking_problem_impl;
    291   if (options.check_gradients) {
    292     VLOG(1) << "Checking Gradients";
    293     gradient_checking_problem_impl.reset(
    294         CreateGradientCheckingProblemImpl(
    295             problem_impl,
    296             options.numeric_derivative_relative_step_size,
    297             options.gradient_check_relative_precision));
    298 
    299     // From here on, problem_impl will point to the gradient checking
    300     // version.
    301     problem_impl = gradient_checking_problem_impl.get();
    302   }
    303 
    304   if (original_options.linear_solver_ordering != NULL) {
    305     if (!IsOrderingValid(original_options, problem_impl, &summary->error)) {
    306       LOG(ERROR) << summary->error;
    307       return;
    308     }
    309     options.linear_solver_ordering =
    310         new ParameterBlockOrdering(*original_options.linear_solver_ordering);
    311   } else {
    312     options.linear_solver_ordering = new ParameterBlockOrdering;
    313     const ProblemImpl::ParameterMap& parameter_map =
    314         problem_impl->parameter_map();
    315     for (ProblemImpl::ParameterMap::const_iterator it = parameter_map.begin();
    316          it != parameter_map.end();
    317          ++it) {
    318       options.linear_solver_ordering->AddElementToGroup(it->first, 0);
    319     }
    320   }
    321 
    322   // Create the three objects needed to minimize: the transformed program, the
    323   // evaluator, and the linear solver.
    324   scoped_ptr<Program> reduced_program(CreateReducedProgram(&options,
    325                                                            problem_impl,
    326                                                            &summary->fixed_cost,
    327                                                            &summary->error));
    328   if (reduced_program == NULL) {
    329     return;
    330   }
    331 
    332   summary->num_parameter_blocks_reduced = reduced_program->NumParameterBlocks();
    333   summary->num_parameters_reduced = reduced_program->NumParameters();
    334   summary->num_residual_blocks_reduced = reduced_program->NumResidualBlocks();
    335   summary->num_residuals_reduced = reduced_program->NumResiduals();
    336 
    337   if (summary->num_parameter_blocks_reduced == 0) {
    338     summary->preprocessor_time_in_seconds =
    339         WallTimeInSeconds() - solver_start_time;
    340 
    341     LOG(INFO) << "Terminating: FUNCTION_TOLERANCE reached. "
    342               << "No non-constant parameter blocks found.";
    343 
    344     // FUNCTION_TOLERANCE is the right convergence here, as we know
    345     // that the objective function is constant and cannot be changed
    346     // any further.
    347     summary->termination_type = FUNCTION_TOLERANCE;
    348 
    349     double post_process_start_time = WallTimeInSeconds();
    350     // Evaluate the final cost, residual vector and the jacobian
    351     // matrix if requested by the user.
    352     if (!Evaluator::Evaluate(original_program,
    353                              options.num_threads,
    354                              &summary->final_cost,
    355                              options.return_final_residuals
    356                              ? &summary->final_residuals
    357                              : NULL,
    358                              options.return_final_gradient
    359                              ? &summary->final_gradient
    360                              : NULL,
    361                              options.return_final_jacobian
    362                              ? &summary->final_jacobian
    363                              : NULL)) {
    364       summary->termination_type = NUMERICAL_FAILURE;
    365       summary->error = "Unable to evaluate the final cost.";
    366       LOG(ERROR) << summary->error;
    367       return;
    368     }
    369 
    370     // Ensure the program state is set to the user parameters on the way out.
    371     original_program->SetParameterBlockStatePtrsToUserStatePtrs();
    372 
    373     summary->postprocessor_time_in_seconds =
    374         WallTimeInSeconds() - post_process_start_time;
    375     return;
    376   }
    377 
    378   scoped_ptr<LinearSolver>
    379       linear_solver(CreateLinearSolver(&options, &summary->error));
    380   if (linear_solver == NULL) {
    381     return;
    382   }
    383 
    384   summary->linear_solver_type_given = original_options.linear_solver_type;
    385   summary->linear_solver_type_used = options.linear_solver_type;
    386 
    387   summary->preconditioner_type = options.preconditioner_type;
    388 
    389   summary->num_linear_solver_threads_given =
    390       original_options.num_linear_solver_threads;
    391   summary->num_linear_solver_threads_used = options.num_linear_solver_threads;
    392 
    393   summary->sparse_linear_algebra_library =
    394       options.sparse_linear_algebra_library;
    395 
    396   summary->trust_region_strategy_type = options.trust_region_strategy_type;
    397   summary->dogleg_type = options.dogleg_type;
    398 
    399   // Only Schur types require the lexicographic reordering.
    400   if (IsSchurType(options.linear_solver_type)) {
    401     const int num_eliminate_blocks =
    402         options.linear_solver_ordering
    403         ->group_to_elements().begin()
    404         ->second.size();
    405     if (!LexicographicallyOrderResidualBlocks(num_eliminate_blocks,
    406                                               reduced_program.get(),
    407                                               &summary->error)) {
    408       return;
    409     }
    410   }
    411 
    412   scoped_ptr<Evaluator> evaluator(CreateEvaluator(options,
    413                                                   problem_impl->parameter_map(),
    414                                                   reduced_program.get(),
    415                                                   &summary->error));
    416   if (evaluator == NULL) {
    417     return;
    418   }
    419 
    420   scoped_ptr<CoordinateDescentMinimizer> inner_iteration_minimizer;
    421   if (options.use_inner_iterations) {
    422     if (reduced_program->parameter_blocks().size() < 2) {
    423       LOG(WARNING) << "Reduced problem only contains one parameter block."
    424                    << "Disabling inner iterations.";
    425     } else {
    426       inner_iteration_minimizer.reset(
    427           CreateInnerIterationMinimizer(original_options,
    428                                         *reduced_program,
    429                                         problem_impl->parameter_map(),
    430                                         &summary->error));
    431       if (inner_iteration_minimizer == NULL) {
    432         LOG(ERROR) << summary->error;
    433         return;
    434       }
    435     }
    436   }
    437 
    438   // The optimizer works on contiguous parameter vectors; allocate some.
    439   Vector parameters(reduced_program->NumParameters());
    440 
    441   // Collect the discontiguous parameters into a contiguous state vector.
    442   reduced_program->ParameterBlocksToStateVector(parameters.data());
    443 
    444   Vector original_parameters = parameters;
    445 
    446   double minimizer_start_time = WallTimeInSeconds();
    447   summary->preprocessor_time_in_seconds =
    448       minimizer_start_time - solver_start_time;
    449 
    450   // Run the optimization.
    451   Minimize(options,
    452            reduced_program.get(),
    453            inner_iteration_minimizer.get(),
    454            evaluator.get(),
    455            linear_solver.get(),
    456            parameters.data(),
    457            summary);
    458 
    459   // If the user aborted mid-optimization or the optimization
    460   // terminated because of a numerical failure, then return without
    461   // updating user state.
    462   if (summary->termination_type == USER_ABORT ||
    463       summary->termination_type == NUMERICAL_FAILURE) {
    464     return;
    465   }
    466 
    467   double post_process_start_time = WallTimeInSeconds();
    468 
    469   // Push the contiguous optimized parameters back to the user's parameters.
    470   reduced_program->StateVectorToParameterBlocks(parameters.data());
    471   reduced_program->CopyParameterBlockStateToUserState();
    472 
    473   // Evaluate the final cost, residual vector and the jacobian
    474   // matrix if requested by the user.
    475   if (!Evaluator::Evaluate(original_program,
    476                            options.num_threads,
    477                            &summary->final_cost,
    478                            options.return_final_residuals
    479                            ? &summary->final_residuals
    480                            : NULL,
    481                            options.return_final_gradient
    482                            ? &summary->final_gradient
    483                            : NULL,
    484                            options.return_final_jacobian
    485                            ? &summary->final_jacobian
    486                            : NULL)) {
    487     // This failure requires careful handling.
    488     //
    489     // At this point, we have modified the user's state, but the
    490     // evaluation failed and we inform him of NUMERICAL_FAILURE. Ceres
    491     // guarantees that user's state is not modified if the solver
    492     // returns with NUMERICAL_FAILURE. Thus, we need to restore the
    493     // user's state to their original values.
    494 
    495     reduced_program->StateVectorToParameterBlocks(original_parameters.data());
    496     reduced_program->CopyParameterBlockStateToUserState();
    497 
    498     summary->termination_type = NUMERICAL_FAILURE;
    499     summary->error = "Unable to evaluate the final cost.";
    500     LOG(ERROR) << summary->error;
    501     return;
    502   }
    503 
    504   // Ensure the program state is set to the user parameters on the way out.
    505   original_program->SetParameterBlockStatePtrsToUserStatePtrs();
    506 
    507   // Stick a fork in it, we're done.
    508   summary->postprocessor_time_in_seconds =
    509       WallTimeInSeconds() - post_process_start_time;
    510 }
    511 
    512 bool SolverImpl::IsOrderingValid(const Solver::Options& options,
    513                                  const ProblemImpl* problem_impl,
    514                                  string* error) {
    515   if (options.linear_solver_ordering->NumElements() !=
    516       problem_impl->NumParameterBlocks()) {
    517       *error = "Number of parameter blocks in user supplied ordering "
    518           "does not match the number of parameter blocks in the problem";
    519     return false;
    520   }
    521 
    522   const Program& program = problem_impl->program();
    523   const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
    524   for (vector<ParameterBlock*>::const_iterator it = parameter_blocks.begin();
    525        it != parameter_blocks.end();
    526        ++it) {
    527     if (!options.linear_solver_ordering
    528         ->IsMember(const_cast<double*>((*it)->user_state()))) {
    529       *error = "Problem contains a parameter block that is not in "
    530           "the user specified ordering.";
    531       return false;
    532     }
    533   }
    534 
    535   if (IsSchurType(options.linear_solver_type) &&
    536       options.linear_solver_ordering->NumGroups() > 1) {
    537     const vector<ResidualBlock*>& residual_blocks = program.residual_blocks();
    538     const set<double*>& e_blocks  =
    539         options.linear_solver_ordering->group_to_elements().begin()->second;
    540     if (!IsParameterBlockSetIndependent(e_blocks, residual_blocks)) {
    541       *error = "The user requested the use of a Schur type solver. "
    542           "But the first elimination group in the ordering is not an "
    543           "independent set.";
    544       return false;
    545     }
    546   }
    547   return true;
    548 }
    549 
    550 bool SolverImpl::IsParameterBlockSetIndependent(const set<double*>& parameter_block_ptrs,
    551                                                 const vector<ResidualBlock*>& residual_blocks) {
    552   // Loop over each residual block and ensure that no two parameter
    553   // blocks in the same residual block are part of
    554   // parameter_block_ptrs as that would violate the assumption that it
    555   // is an independent set in the Hessian matrix.
    556   for (vector<ResidualBlock*>::const_iterator it = residual_blocks.begin();
    557        it != residual_blocks.end();
    558        ++it) {
    559     ParameterBlock* const* parameter_blocks = (*it)->parameter_blocks();
    560     const int num_parameter_blocks = (*it)->NumParameterBlocks();
    561     int count = 0;
    562     for (int i = 0; i < num_parameter_blocks; ++i) {
    563       count += parameter_block_ptrs.count(
    564           parameter_blocks[i]->mutable_user_state());
    565     }
    566     if (count > 1) {
    567       return false;
    568     }
    569   }
    570   return true;
    571 }
    572 
    573 
    574 // Strips varying parameters and residuals, maintaining order, and updating
    575 // num_eliminate_blocks.
    576 bool SolverImpl::RemoveFixedBlocksFromProgram(Program* program,
    577                                               ParameterBlockOrdering* ordering,
    578                                               double* fixed_cost,
    579                                               string* error) {
    580   vector<ParameterBlock*>* parameter_blocks =
    581       program->mutable_parameter_blocks();
    582 
    583   scoped_array<double> residual_block_evaluate_scratch;
    584   if (fixed_cost != NULL) {
    585     residual_block_evaluate_scratch.reset(
    586         new double[program->MaxScratchDoublesNeededForEvaluate()]);
    587     *fixed_cost = 0.0;
    588   }
    589 
    590   // Mark all the parameters as unused. Abuse the index member of the parameter
    591   // blocks for the marking.
    592   for (int i = 0; i < parameter_blocks->size(); ++i) {
    593     (*parameter_blocks)[i]->set_index(-1);
    594   }
    595 
    596   // Filter out residual that have all-constant parameters, and mark all the
    597   // parameter blocks that appear in residuals.
    598   {
    599     vector<ResidualBlock*>* residual_blocks =
    600         program->mutable_residual_blocks();
    601     int j = 0;
    602     for (int i = 0; i < residual_blocks->size(); ++i) {
    603       ResidualBlock* residual_block = (*residual_blocks)[i];
    604       int num_parameter_blocks = residual_block->NumParameterBlocks();
    605 
    606       // Determine if the residual block is fixed, and also mark varying
    607       // parameters that appear in the residual block.
    608       bool all_constant = true;
    609       for (int k = 0; k < num_parameter_blocks; k++) {
    610         ParameterBlock* parameter_block = residual_block->parameter_blocks()[k];
    611         if (!parameter_block->IsConstant()) {
    612           all_constant = false;
    613           parameter_block->set_index(1);
    614         }
    615       }
    616 
    617       if (!all_constant) {
    618         (*residual_blocks)[j++] = (*residual_blocks)[i];
    619       } else if (fixed_cost != NULL) {
    620         // The residual is constant and will be removed, so its cost is
    621         // added to the variable fixed_cost.
    622         double cost = 0.0;
    623         if (!residual_block->Evaluate(
    624               &cost, NULL, NULL, residual_block_evaluate_scratch.get())) {
    625           *error = StringPrintf("Evaluation of the residual %d failed during "
    626                                 "removal of fixed residual blocks.", i);
    627           return false;
    628         }
    629         *fixed_cost += cost;
    630       }
    631     }
    632     residual_blocks->resize(j);
    633   }
    634 
    635   // Filter out unused or fixed parameter blocks, and update
    636   // the ordering.
    637   {
    638     vector<ParameterBlock*>* parameter_blocks =
    639         program->mutable_parameter_blocks();
    640     int j = 0;
    641     for (int i = 0; i < parameter_blocks->size(); ++i) {
    642       ParameterBlock* parameter_block = (*parameter_blocks)[i];
    643       if (parameter_block->index() == 1) {
    644         (*parameter_blocks)[j++] = parameter_block;
    645       } else {
    646         ordering->Remove(parameter_block->mutable_user_state());
    647       }
    648     }
    649     parameter_blocks->resize(j);
    650   }
    651 
    652   CHECK(((program->NumResidualBlocks() == 0) &&
    653          (program->NumParameterBlocks() == 0)) ||
    654         ((program->NumResidualBlocks() != 0) &&
    655          (program->NumParameterBlocks() != 0)))
    656       << "Congratulations, you found a bug in Ceres. Please report it.";
    657   return true;
    658 }
    659 
    660 Program* SolverImpl::CreateReducedProgram(Solver::Options* options,
    661                                           ProblemImpl* problem_impl,
    662                                           double* fixed_cost,
    663                                           string* error) {
    664   CHECK_NOTNULL(options->linear_solver_ordering);
    665   Program* original_program = problem_impl->mutable_program();
    666   scoped_ptr<Program> transformed_program(new Program(*original_program));
    667   ParameterBlockOrdering* linear_solver_ordering =
    668       options->linear_solver_ordering;
    669 
    670   const int min_group_id =
    671       linear_solver_ordering->group_to_elements().begin()->first;
    672   const int original_num_groups = linear_solver_ordering->NumGroups();
    673 
    674   if (!RemoveFixedBlocksFromProgram(transformed_program.get(),
    675                                     linear_solver_ordering,
    676                                     fixed_cost,
    677                                     error)) {
    678     return NULL;
    679   }
    680 
    681   if (transformed_program->NumParameterBlocks() == 0) {
    682     if (transformed_program->NumResidualBlocks() > 0) {
    683       *error = "Zero parameter blocks but non-zero residual blocks"
    684           " in the reduced program. Congratulations, you found a "
    685           "Ceres bug! Please report this error to the developers.";
    686       return NULL;
    687     }
    688 
    689     LOG(WARNING) << "No varying parameter blocks to optimize; "
    690                  << "bailing early.";
    691     return transformed_program.release();
    692   }
    693 
    694   // If the user supplied an linear_solver_ordering with just one
    695   // group, it is equivalent to the user supplying NULL as
    696   // ordering. Ceres is completely free to choose the parameter block
    697   // ordering as it sees fit. For Schur type solvers, this means that
    698   // the user wishes for Ceres to identify the e_blocks, which we do
    699   // by computing a maximal independent set.
    700   if (original_num_groups == 1 && IsSchurType(options->linear_solver_type)) {
    701     vector<ParameterBlock*> schur_ordering;
    702     const int num_eliminate_blocks = ComputeSchurOrdering(*transformed_program,
    703                                                           &schur_ordering);
    704     CHECK_EQ(schur_ordering.size(), transformed_program->NumParameterBlocks())
    705         << "Congratulations, you found a Ceres bug! Please report this error "
    706         << "to the developers.";
    707 
    708     for (int i = 0; i < schur_ordering.size(); ++i) {
    709       linear_solver_ordering->AddElementToGroup(
    710           schur_ordering[i]->mutable_user_state(),
    711           (i < num_eliminate_blocks) ? 0 : 1);
    712     }
    713   }
    714 
    715   if (!ApplyUserOrdering(problem_impl->parameter_map(),
    716                          linear_solver_ordering,
    717                          transformed_program.get(),
    718                          error)) {
    719     return NULL;
    720   }
    721 
    722   // If the user requested the use of a Schur type solver, and
    723   // supplied a non-NULL linear_solver_ordering object with more than
    724   // one elimination group, then it can happen that after all the
    725   // parameter blocks which are fixed or unused have been removed from
    726   // the program and the ordering, there are no more parameter blocks
    727   // in the first elimination group.
    728   //
    729   // In such a case, the use of a Schur type solver is not possible,
    730   // as they assume there is at least one e_block. Thus, we
    731   // automatically switch to one of the other solvers, depending on
    732   // the user's indicated preferences.
    733   if (IsSchurType(options->linear_solver_type) &&
    734       original_num_groups > 1 &&
    735       linear_solver_ordering->GroupSize(min_group_id) == 0) {
    736     string msg = "No e_blocks remaining. Switching from ";
    737     if (options->linear_solver_type == SPARSE_SCHUR) {
    738       options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
    739       msg += "SPARSE_SCHUR to SPARSE_NORMAL_CHOLESKY.";
    740     } else if (options->linear_solver_type == DENSE_SCHUR) {
    741       // TODO(sameeragarwal): This is probably not a great choice.
    742       // Ideally, we should have a DENSE_NORMAL_CHOLESKY, that can
    743       // take a BlockSparseMatrix as input.
    744       options->linear_solver_type = DENSE_QR;
    745       msg += "DENSE_SCHUR to DENSE_QR.";
    746     } else if (options->linear_solver_type == ITERATIVE_SCHUR) {
    747       msg += StringPrintf("ITERATIVE_SCHUR with %s preconditioner "
    748                           "to CGNR with JACOBI preconditioner.",
    749                           PreconditionerTypeToString(
    750                               options->preconditioner_type));
    751       options->linear_solver_type = CGNR;
    752       if (options->preconditioner_type != IDENTITY) {
    753         // CGNR currently only supports the JACOBI preconditioner.
    754         options->preconditioner_type = JACOBI;
    755       }
    756     }
    757 
    758     LOG(WARNING) << msg;
    759   }
    760 
    761   // Since the transformed program is the "active" program, and it is mutated,
    762   // update the parameter offsets and indices.
    763   transformed_program->SetParameterOffsetsAndIndex();
    764   return transformed_program.release();
    765 }
    766 
    767 LinearSolver* SolverImpl::CreateLinearSolver(Solver::Options* options,
    768                                              string* error) {
    769   CHECK_NOTNULL(options);
    770   CHECK_NOTNULL(options->linear_solver_ordering);
    771   CHECK_NOTNULL(error);
    772 
    773   if (options->trust_region_strategy_type == DOGLEG) {
    774     if (options->linear_solver_type == ITERATIVE_SCHUR ||
    775         options->linear_solver_type == CGNR) {
    776       *error = "DOGLEG only supports exact factorization based linear "
    777                "solvers. If you want to use an iterative solver please "
    778                "use LEVENBERG_MARQUARDT as the trust_region_strategy_type";
    779       return NULL;
    780     }
    781   }
    782 
    783 #ifdef CERES_NO_SUITESPARSE
    784   if (options->linear_solver_type == SPARSE_NORMAL_CHOLESKY &&
    785       options->sparse_linear_algebra_library == SUITE_SPARSE) {
    786     *error = "Can't use SPARSE_NORMAL_CHOLESKY with SUITESPARSE because "
    787              "SuiteSparse was not enabled when Ceres was built.";
    788     return NULL;
    789   }
    790 
    791   if (options->preconditioner_type == SCHUR_JACOBI) {
    792     *error =  "SCHUR_JACOBI preconditioner not suppored. Please build Ceres "
    793         "with SuiteSparse support.";
    794     return NULL;
    795   }
    796 
    797   if (options->preconditioner_type == CLUSTER_JACOBI) {
    798     *error =  "CLUSTER_JACOBI preconditioner not suppored. Please build Ceres "
    799         "with SuiteSparse support.";
    800     return NULL;
    801   }
    802 
    803   if (options->preconditioner_type == CLUSTER_TRIDIAGONAL) {
    804     *error =  "CLUSTER_TRIDIAGONAL preconditioner not suppored. Please build "
    805         "Ceres with SuiteSparse support.";
    806     return NULL;
    807   }
    808 #endif
    809 
    810 #ifdef CERES_NO_CXSPARSE
    811   if (options->linear_solver_type == SPARSE_NORMAL_CHOLESKY &&
    812       options->sparse_linear_algebra_library == CX_SPARSE) {
    813     *error = "Can't use SPARSE_NORMAL_CHOLESKY with CXSPARSE because "
    814              "CXSparse was not enabled when Ceres was built.";
    815     return NULL;
    816   }
    817 #endif
    818 
    819 #if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE)
    820   if (options->linear_solver_type == SPARSE_SCHUR) {
    821     *error = "Can't use SPARSE_SCHUR because neither SuiteSparse nor"
    822         "CXSparse was enabled when Ceres was compiled.";
    823     return NULL;
    824   }
    825 #endif
    826 
    827   if (options->linear_solver_max_num_iterations <= 0) {
    828     *error = "Solver::Options::linear_solver_max_num_iterations is 0.";
    829     return NULL;
    830   }
    831   if (options->linear_solver_min_num_iterations <= 0) {
    832     *error = "Solver::Options::linear_solver_min_num_iterations is 0.";
    833     return NULL;
    834   }
    835   if (options->linear_solver_min_num_iterations >
    836       options->linear_solver_max_num_iterations) {
    837     *error = "Solver::Options::linear_solver_min_num_iterations > "
    838         "Solver::Options::linear_solver_max_num_iterations.";
    839     return NULL;
    840   }
    841 
    842   LinearSolver::Options linear_solver_options;
    843   linear_solver_options.min_num_iterations =
    844         options->linear_solver_min_num_iterations;
    845   linear_solver_options.max_num_iterations =
    846       options->linear_solver_max_num_iterations;
    847   linear_solver_options.type = options->linear_solver_type;
    848   linear_solver_options.preconditioner_type = options->preconditioner_type;
    849   linear_solver_options.sparse_linear_algebra_library =
    850       options->sparse_linear_algebra_library;
    851 
    852   linear_solver_options.num_threads = options->num_linear_solver_threads;
    853   // The matrix used for storing the dense Schur complement has a
    854   // single lock guarding the whole matrix. Running the
    855   // SchurComplementSolver with multiple threads leads to maximum
    856   // contention and slowdown. If the problem is large enough to
    857   // benefit from a multithreaded schur eliminator, you should be
    858   // using a SPARSE_SCHUR solver anyways.
    859   if ((linear_solver_options.num_threads > 1) &&
    860       (linear_solver_options.type == DENSE_SCHUR)) {
    861     LOG(WARNING) << "Warning: Solver::Options::num_linear_solver_threads = "
    862                  << options->num_linear_solver_threads
    863                  << " with DENSE_SCHUR will result in poor performance; "
    864                  << "switching to single-threaded.";
    865     linear_solver_options.num_threads = 1;
    866   }
    867   options->num_linear_solver_threads = linear_solver_options.num_threads;
    868 
    869   linear_solver_options.use_block_amd = options->use_block_amd;
    870   const map<int, set<double*> >& groups =
    871       options->linear_solver_ordering->group_to_elements();
    872   for (map<int, set<double*> >::const_iterator it = groups.begin();
    873        it != groups.end();
    874        ++it) {
    875     linear_solver_options.elimination_groups.push_back(it->second.size());
    876   }
    877   // Schur type solvers, expect at least two elimination groups. If
    878   // there is only one elimination group, then CreateReducedProgram
    879   // guarantees that this group only contains e_blocks. Thus we add a
    880   // dummy elimination group with zero blocks in it.
    881   if (IsSchurType(linear_solver_options.type) &&
    882       linear_solver_options.elimination_groups.size() == 1) {
    883     linear_solver_options.elimination_groups.push_back(0);
    884   }
    885 
    886   return LinearSolver::Create(linear_solver_options);
    887 }
    888 
    889 bool SolverImpl::ApplyUserOrdering(const ProblemImpl::ParameterMap& parameter_map,
    890                                    const ParameterBlockOrdering* ordering,
    891                                    Program* program,
    892                                    string* error) {
    893   if (ordering->NumElements() != program->NumParameterBlocks()) {
    894     *error = StringPrintf("User specified ordering does not have the same "
    895                           "number of parameters as the problem. The problem"
    896                           "has %d blocks while the ordering has %d blocks.",
    897                           program->NumParameterBlocks(),
    898                           ordering->NumElements());
    899     return false;
    900   }
    901 
    902   vector<ParameterBlock*>* parameter_blocks =
    903       program->mutable_parameter_blocks();
    904   parameter_blocks->clear();
    905 
    906   const map<int, set<double*> >& groups =
    907       ordering->group_to_elements();
    908 
    909   for (map<int, set<double*> >::const_iterator group_it = groups.begin();
    910        group_it != groups.end();
    911        ++group_it) {
    912     const set<double*>& group = group_it->second;
    913     for (set<double*>::const_iterator parameter_block_ptr_it = group.begin();
    914          parameter_block_ptr_it != group.end();
    915          ++parameter_block_ptr_it) {
    916       ProblemImpl::ParameterMap::const_iterator parameter_block_it =
    917           parameter_map.find(*parameter_block_ptr_it);
    918       if (parameter_block_it == parameter_map.end()) {
    919         *error = StringPrintf("User specified ordering contains a pointer "
    920                               "to a double that is not a parameter block in the "
    921                               "problem. The invalid double is in group: %d",
    922                               group_it->first);
    923         return false;
    924       }
    925       parameter_blocks->push_back(parameter_block_it->second);
    926     }
    927   }
    928   return true;
    929 }
    930 
    931 // Find the minimum index of any parameter block to the given residual.
    932 // Parameter blocks that have indices greater than num_eliminate_blocks are
    933 // considered to have an index equal to num_eliminate_blocks.
    934 int MinParameterBlock(const ResidualBlock* residual_block,
    935                       int num_eliminate_blocks) {
    936   int min_parameter_block_position = num_eliminate_blocks;
    937   for (int i = 0; i < residual_block->NumParameterBlocks(); ++i) {
    938     ParameterBlock* parameter_block = residual_block->parameter_blocks()[i];
    939     if (!parameter_block->IsConstant()) {
    940       CHECK_NE(parameter_block->index(), -1)
    941           << "Did you forget to call Program::SetParameterOffsetsAndIndex()? "
    942           << "This is a Ceres bug; please contact the developers!";
    943       min_parameter_block_position = std::min(parameter_block->index(),
    944                                               min_parameter_block_position);
    945     }
    946   }
    947   return min_parameter_block_position;
    948 }
    949 
    950 // Reorder the residuals for program, if necessary, so that the residuals
    951 // involving each E block occur together. This is a necessary condition for the
    952 // Schur eliminator, which works on these "row blocks" in the jacobian.
    953 bool SolverImpl::LexicographicallyOrderResidualBlocks(const int num_eliminate_blocks,
    954                                                       Program* program,
    955                                                       string* error) {
    956   CHECK_GE(num_eliminate_blocks, 1)
    957       << "Congratulations, you found a Ceres bug! Please report this error "
    958       << "to the developers.";
    959 
    960   // Create a histogram of the number of residuals for each E block. There is an
    961   // extra bucket at the end to catch all non-eliminated F blocks.
    962   vector<int> residual_blocks_per_e_block(num_eliminate_blocks + 1);
    963   vector<ResidualBlock*>* residual_blocks = program->mutable_residual_blocks();
    964   vector<int> min_position_per_residual(residual_blocks->size());
    965   for (int i = 0; i < residual_blocks->size(); ++i) {
    966     ResidualBlock* residual_block = (*residual_blocks)[i];
    967     int position = MinParameterBlock(residual_block, num_eliminate_blocks);
    968     min_position_per_residual[i] = position;
    969     DCHECK_LE(position, num_eliminate_blocks);
    970     residual_blocks_per_e_block[position]++;
    971   }
    972 
    973   // Run a cumulative sum on the histogram, to obtain offsets to the start of
    974   // each histogram bucket (where each bucket is for the residuals for that
    975   // E-block).
    976   vector<int> offsets(num_eliminate_blocks + 1);
    977   std::partial_sum(residual_blocks_per_e_block.begin(),
    978                    residual_blocks_per_e_block.end(),
    979                    offsets.begin());
    980   CHECK_EQ(offsets.back(), residual_blocks->size())
    981       << "Congratulations, you found a Ceres bug! Please report this error "
    982       << "to the developers.";
    983 
    984   CHECK(find(residual_blocks_per_e_block.begin(),
    985              residual_blocks_per_e_block.end() - 1, 0) !=
    986         residual_blocks_per_e_block.end())
    987       << "Congratulations, you found a Ceres bug! Please report this error "
    988       << "to the developers.";
    989 
    990   // Fill in each bucket with the residual blocks for its corresponding E block.
    991   // Each bucket is individually filled from the back of the bucket to the front
    992   // of the bucket. The filling order among the buckets is dictated by the
    993   // residual blocks. This loop uses the offsets as counters; subtracting one
    994   // from each offset as a residual block is placed in the bucket. When the
    995   // filling is finished, the offset pointerts should have shifted down one
    996   // entry (this is verified below).
    997   vector<ResidualBlock*> reordered_residual_blocks(
    998       (*residual_blocks).size(), static_cast<ResidualBlock*>(NULL));
    999   for (int i = 0; i < residual_blocks->size(); ++i) {
   1000     int bucket = min_position_per_residual[i];
   1001 
   1002     // Decrement the cursor, which should now point at the next empty position.
   1003     offsets[bucket]--;
   1004 
   1005     // Sanity.
   1006     CHECK(reordered_residual_blocks[offsets[bucket]] == NULL)
   1007         << "Congratulations, you found a Ceres bug! Please report this error "
   1008         << "to the developers.";
   1009 
   1010     reordered_residual_blocks[offsets[bucket]] = (*residual_blocks)[i];
   1011   }
   1012 
   1013   // Sanity check #1: The difference in bucket offsets should match the
   1014   // histogram sizes.
   1015   for (int i = 0; i < num_eliminate_blocks; ++i) {
   1016     CHECK_EQ(residual_blocks_per_e_block[i], offsets[i + 1] - offsets[i])
   1017         << "Congratulations, you found a Ceres bug! Please report this error "
   1018         << "to the developers.";
   1019   }
   1020   // Sanity check #2: No NULL's left behind.
   1021   for (int i = 0; i < reordered_residual_blocks.size(); ++i) {
   1022     CHECK(reordered_residual_blocks[i] != NULL)
   1023         << "Congratulations, you found a Ceres bug! Please report this error "
   1024         << "to the developers.";
   1025   }
   1026 
   1027   // Now that the residuals are collected by E block, swap them in place.
   1028   swap(*program->mutable_residual_blocks(), reordered_residual_blocks);
   1029   return true;
   1030 }
   1031 
   1032 Evaluator* SolverImpl::CreateEvaluator(const Solver::Options& options,
   1033                                        const ProblemImpl::ParameterMap& parameter_map,
   1034                                        Program* program,
   1035                                        string* error) {
   1036   Evaluator::Options evaluator_options;
   1037   evaluator_options.linear_solver_type = options.linear_solver_type;
   1038   evaluator_options.num_eliminate_blocks =
   1039       (options.linear_solver_ordering->NumGroups() > 0 &&
   1040        IsSchurType(options.linear_solver_type))
   1041       ? (options.linear_solver_ordering
   1042          ->group_to_elements().begin()
   1043          ->second.size())
   1044       : 0;
   1045   evaluator_options.num_threads = options.num_threads;
   1046   return Evaluator::Create(evaluator_options, program, error);
   1047 }
   1048 
   1049 CoordinateDescentMinimizer* SolverImpl::CreateInnerIterationMinimizer(
   1050     const Solver::Options& options,
   1051     const Program& program,
   1052     const ProblemImpl::ParameterMap& parameter_map,
   1053     string* error) {
   1054   scoped_ptr<CoordinateDescentMinimizer> inner_iteration_minimizer(
   1055       new CoordinateDescentMinimizer);
   1056   scoped_ptr<ParameterBlockOrdering> inner_iteration_ordering;
   1057   ParameterBlockOrdering* ordering_ptr  = NULL;
   1058 
   1059   if (options.inner_iteration_ordering == NULL) {
   1060     // Find a recursive decomposition of the Hessian matrix as a set
   1061     // of independent sets of decreasing size and invert it. This
   1062     // seems to work better in practice, i.e., Cameras before
   1063     // points.
   1064     inner_iteration_ordering.reset(new ParameterBlockOrdering);
   1065     ComputeRecursiveIndependentSetOrdering(program,
   1066                                            inner_iteration_ordering.get());
   1067     inner_iteration_ordering->Reverse();
   1068     ordering_ptr = inner_iteration_ordering.get();
   1069   } else {
   1070     const map<int, set<double*> >& group_to_elements =
   1071         options.inner_iteration_ordering->group_to_elements();
   1072 
   1073     // Iterate over each group and verify that it is an independent
   1074     // set.
   1075     map<int, set<double*> >::const_iterator it = group_to_elements.begin();
   1076     for ( ;it != group_to_elements.end(); ++it) {
   1077       if (!IsParameterBlockSetIndependent(it->second,
   1078                                           program.residual_blocks())) {
   1079         *error =
   1080             StringPrintf("The user-provided "
   1081                          "parameter_blocks_for_inner_iterations does not "
   1082                          "form an independent set. Group Id: %d", it->first);
   1083         return NULL;
   1084       }
   1085     }
   1086     ordering_ptr = options.inner_iteration_ordering;
   1087   }
   1088 
   1089   if (!inner_iteration_minimizer->Init(program,
   1090                                        parameter_map,
   1091                                        *ordering_ptr,
   1092                                        error)) {
   1093     return NULL;
   1094   }
   1095 
   1096   return inner_iteration_minimizer.release();
   1097 }
   1098 
   1099 }  // namespace internal
   1100 }  // namespace ceres
   1101