// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2023 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 <vector>

#include "Eigen/Core"
#include "absl/log/check.h"
#include "ceres/cost_function.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,
    int kMaxResiduals = kNumResiduals, int kMaxParameters = kNumParameters>
class TinySolverCostFunctionAdapter {
 public:
  using Scalar = double;
  enum ComponentSizeType {
    NUM_PARAMETERS = kNumParameters,
    NUM_RESIDUALS = kNumResiduals,
    MAX_NUM_RESIDUALS = kMaxResiduals,
    MAX_NUM_PARAMETERS = kMaxParameters,
  };
  template <int Layout>  // Eigen::RowMajor or Eigen::ColMajor
  using JacobianMatrix = typename Eigen::Matrix<Scalar,
                                                NUM_RESIDUALS,
                                                NUM_PARAMETERS,
                                                Layout,
                                                MAX_NUM_RESIDUALS,
                                                MAX_NUM_PARAMETERS>;

  // This struct needs to have an Eigen aligned operator new as it contains
  // fixed-size Eigen types.
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW

  explicit TinySolverCostFunctionAdapter(const CostFunction& cost_function)
      : cost_function_(cost_function) {
    CHECK_EQ(cost_function_.parameter_block_sizes().size(), 1)
        << "Only CostFunctions with exactly one parameter block 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);
    }
  }

  // Evaluates the cost function.
  bool operator()(const double* parameters,
                  double* residuals,
                  double* jacobian) const {
    if (!jacobian) {
      return cost_function_.Evaluate(&parameters, residuals, nullptr);
    }

    double* jacobians[1] = {row_major_jacobian_.data()};
    if (!cost_function_.Evaluate(&parameters, 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<JacobianMatrix<Eigen::ColMajor>> 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 JacobianMatrix<Eigen::RowMajor> row_major_jacobian_;
};

}  // namespace ceres

#endif  // CERES_PUBLIC_TINY_SOLVER_COST_FUNCTION_ADAPTER_H_
