| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 | // Ceres Solver - A fast non-linear least squares minimizer// Copyright 2017 Google Inc. All rights reserved.// http://ceres-solver.org///// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are met://// * Redistributions of source code must retain the above copyright notice,//   this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above copyright notice,//   this list of conditions and the following disclaimer in the documentation//   and/or other materials provided with the distribution.// * Neither the name of Google Inc. nor the names of its contributors may be//   used to endorse or promote products derived from this software without//   specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE// POSSIBILITY OF SUCH DAMAGE.//// Author: sameeragarwal@google.com (Sameer Agarwal)#ifndef CERES_PUBLIC_TINY_SOLVER_COST_FUNCTION_ADAPTER_H_#define CERES_PUBLIC_TINY_SOLVER_COST_FUNCTION_ADAPTER_H_#include "Eigen/Core"#include "ceres/cost_function.h"#include "glog/logging.h"namespace ceres {// An adapter class that lets users of TinySolver use// ceres::CostFunction objects that have exactly one parameter block.//// The adapter allows for the number of residuals and the size of the// parameter block to be specified at compile or run-time.//// WARNING: This object is not thread-safe.//// Example usage:////  CostFunction* cost_function = ...//// Number of residuals and parameter block size known at compile time:////   TinySolverCostFunctionAdapter<kNumResiduals, kNumParameters>//   cost_function_adapter(*cost_function);//// Number of residuals known at compile time and the parameter block// size not known at compile time.////   TinySolverCostFunctionAdapter<kNumResiduals, Eigen::Dynamic>//   cost_function_adapter(*cost_function);//// Number of residuals not known at compile time and the parameter// block size known at compile time.////   TinySolverCostFunctionAdapter<Eigen::Dynamic, kParameterBlockSize>//   cost_function_adapter(*cost_function);//// Number of residuals not known at compile time and the parameter// block size not known at compile time.////   TinySolverCostFunctionAdapter cost_function_adapter(*cost_function);//template <int kNumResiduals = Eigen::Dynamic,          int kNumParameters = Eigen::Dynamic>class TinySolverCostFunctionAdapter { public:  typedef double Scalar;  enum ComponentSizeType {    NUM_PARAMETERS = kNumParameters,    NUM_RESIDUALS = kNumResiduals  };  // This struct needs to have an Eigen aligned operator new as it contains  // fixed-size Eigen types.  EIGEN_MAKE_ALIGNED_OPERATOR_NEW  TinySolverCostFunctionAdapter(const CostFunction& cost_function)      : cost_function_(cost_function) {    CHECK_EQ(cost_function_.parameter_block_sizes().size(), 1)        << "Only CostFunctions with exactly one parameter blocks are allowed.";    const int parameter_block_size = cost_function_.parameter_block_sizes()[0];    if (NUM_PARAMETERS == Eigen::Dynamic || NUM_RESIDUALS == Eigen::Dynamic) {      if (NUM_RESIDUALS != Eigen::Dynamic) {        CHECK_EQ(cost_function_.num_residuals(), NUM_RESIDUALS);      }      if (NUM_PARAMETERS != Eigen::Dynamic) {        CHECK_EQ(parameter_block_size, NUM_PARAMETERS);      }      row_major_jacobian_.resize(cost_function_.num_residuals(),                                 parameter_block_size);    }  }  bool operator()(const double* parameters,                  double* residuals,                  double* jacobian) const {    if (!jacobian) {      return cost_function_.Evaluate(¶meters, residuals, NULL);    }    double* jacobians[1] = {row_major_jacobian_.data()};    if (!cost_function_.Evaluate(¶meters, residuals, jacobians)) {      return false;    }    // The Function object used by TinySolver takes its Jacobian in a    // column-major layout, and the CostFunction objects use row-major    // Jacobian matrices. So the following bit of code does the    // conversion from row-major Jacobians to column-major Jacobians.    Eigen::Map<Eigen::Matrix<double, NUM_RESIDUALS, NUM_PARAMETERS>>        col_major_jacobian(jacobian, NumResiduals(), NumParameters());    col_major_jacobian = row_major_jacobian_;    return true;  }  int NumResiduals() const { return cost_function_.num_residuals(); }  int NumParameters() const {    return cost_function_.parameter_block_sizes()[0];  } private:  const CostFunction& cost_function_;  mutable Eigen::Matrix<double, NUM_RESIDUALS, NUM_PARAMETERS, Eigen::RowMajor>      row_major_jacobian_;};}  // namespace ceres#endif  // CERES_PUBLIC_TINY_SOLVER_COST_FUNCTION_ADAPTER_H_
 |