10ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Ceres Solver - A fast non-linear least squares minimizer
20ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Copyright 2010, 2011, 2012 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//
310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// This is the implementation of the public Problem API. The pointer to
320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// implementation (PIMPL) idiom makes it possible for Ceres internal code to
330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// refer to the private data members without needing to exposing it to the
340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// world. An alternative to PIMPL is to have a factory which returns instances
350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// of a virtual base class; while that approach would work, it requires clients
360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// to always put a Problem object into a scoped pointer; this needlessly muddies
370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// client code for little benefit. Therefore, the PIMPL comprise was chosen.
380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#ifndef CERES_PUBLIC_PROBLEM_IMPL_H_
400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#define CERES_PUBLIC_PROBLEM_IMPL_H_
410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <map>
430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include <vector>
440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/internal/macros.h"
460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/internal/port.h"
470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/internal/scoped_ptr.h"
480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/problem.h"
490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/types.h"
500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace ceres {
520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongclass CostFunction;
540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongclass LossFunction;
550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongclass LocalParameterization;
561d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberlingstruct CRSMatrix;
570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace internal {
590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongclass Program;
610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongclass ResidualBlock;
620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongclass ProblemImpl {
640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong public:
650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  typedef map<double*, ParameterBlock*> ParameterMap;
660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ProblemImpl();
680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  explicit ProblemImpl(const Problem::Options& options);
690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ~ProblemImpl();
710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // See the public problem.h file for description of these methods.
730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   LossFunction* loss_function,
750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   const vector<double*>& parameter_blocks);
760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   LossFunction* loss_function,
780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x0);
790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   LossFunction* loss_function,
810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x0, double* x1);
820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   LossFunction* loss_function,
840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x0, double* x1, double* x2);
850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   LossFunction* loss_function,
870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x0, double* x1, double* x2,
880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x3);
890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   LossFunction* loss_function,
910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x0, double* x1, double* x2,
920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x3, double* x4);
930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   LossFunction* loss_function,
950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x0, double* x1, double* x2,
960ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x3, double* x4, double* x5);
970ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   LossFunction* loss_function,
990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x0, double* x1, double* x2,
1000ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x3, double* x4, double* x5,
1010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x6);
1020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
1030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   LossFunction* loss_function,
1040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x0, double* x1, double* x2,
1050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x3, double* x4, double* x5,
1060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x6, double* x7);
1070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
1080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   LossFunction* loss_function,
1090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x0, double* x1, double* x2,
1100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x3, double* x4, double* x5,
1110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x6, double* x7, double* x8);
1120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ResidualBlockId AddResidualBlock(CostFunction* cost_function,
1130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   LossFunction* loss_function,
1140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x0, double* x1, double* x2,
1150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x3, double* x4, double* x5,
1160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x6, double* x7, double* x8,
1170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                   double* x9);
1180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  void AddParameterBlock(double* values, int size);
1190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  void AddParameterBlock(double* values,
1200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                         int size,
1210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                         LocalParameterization* local_parameterization);
1221d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1231d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  void RemoveResidualBlock(ResidualBlock* residual_block);
1241d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  void RemoveParameterBlock(double* values);
1251d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  void SetParameterBlockConstant(double* values);
1270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  void SetParameterBlockVariable(double* values);
1280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  void SetParameterization(double* values,
1290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                           LocalParameterization* local_parameterization);
1301d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1311d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool Evaluate(const Problem::EvaluateOptions& options,
1321d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                double* cost,
1331d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                vector<double>* residuals,
1341d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                vector<double>* gradient,
1351d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                CRSMatrix* jacobian);
1361d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  int NumParameterBlocks() const;
1380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  int NumParameters() const;
1390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  int NumResidualBlocks() const;
1400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  int NumResiduals() const;
1410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1421d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  int ParameterBlockSize(const double* parameter_block) const;
1431d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  int ParameterBlockLocalSize(const double* parameter_block) const;
1441d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  void GetParameterBlocks(vector<double*>* parameter_blocks) const;
1451d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  const Program& program() const { return *program_; }
1470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  Program* mutable_program() { return program_.get(); }
1480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  const ParameterMap& parameter_map() const { return parameter_block_map_; }
1500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong private:
1521d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  ParameterBlock* InternalAddParameterBlock(double* values, int size);
1531d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1541d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  bool InternalEvaluate(Program* program,
1551d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                        double* cost,
1561d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                        vector<double>* residuals,
1571d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                        vector<double>* gradient,
1581d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                        CRSMatrix* jacobian);
1591d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1601d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  // Delete the arguments in question. These differ from the Remove* functions
1611d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  // in that they do not clean up references to the block to delete; they
1621d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  // merely delete them.
1631d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  template<typename Block>
1641d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  void DeleteBlockInVector(vector<Block*>* mutable_blocks,
1651d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling                           Block* block_to_remove);
1661d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  void DeleteBlock(ResidualBlock* residual_block);
1671d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  void DeleteBlock(ParameterBlock* parameter_block);
1681d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  const Problem::Options options_;
1700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // The mapping from user pointers to parameter blocks.
1720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  map<double*, ParameterBlock*> parameter_block_map_;
1730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1741d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  // The actual parameter and residual blocks.
1750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  internal::scoped_ptr<internal::Program> program_;
1761d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1771d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  // When removing residual and parameter blocks, cost/loss functions and
1781d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  // parameterizations have ambiguous ownership. Instead of scanning the entire
1791d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  // problem to see if the cost/loss/parameterization is shared with other
1801d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  // residual or parameter blocks, buffer them until destruction.
1811d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  //
1821d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  // TODO(keir): See if it makes sense to use sets instead.
1831d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  vector<CostFunction*> cost_functions_to_delete_;
1841d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  vector<LossFunction*> loss_functions_to_delete_;
1851d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling  vector<LocalParameterization*> local_parameterizations_to_delete_;
1861d2624a10e2c559f8ba9ef89eaa30832c0a83a96Sascha Haeberling
1870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  CERES_DISALLOW_COPY_AND_ASSIGN(ProblemImpl);
1880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong};
1890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}  // namespace internal
1910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}  // namespace ceres
1920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#endif  // CERES_PUBLIC_PROBLEM_IMPL_H_
194