// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2026 Google Inc. All rights reserved.
// Copyright (c) 2016, ETH Zurich and UNC Chapel Hill.
// Copyright (c) 2016-2026, The COLMAP Contributors.
// Copyright (c) 2011-2013, libmv authors.
// 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., ETH Zurich, UNC Chapel Hill, 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.
//
// SPDX-License-Identifier: BSD-3-Clause AND MIT
//
// Authors: darius.rueckert@fau.de (Darius Rueckert)
//          nikolaus@nikolaus-demmel.de (Nikolaus Demmel)
//          sameeragarwal@google.com (Sameer Agarwal)

#ifndef CERES_INTERNAL_BENCHMARK_COST_FUNCTIONS_H_
#define CERES_INTERNAL_BENCHMARK_COST_FUNCTIONS_H_

#include <algorithm>
#include <array>
#include <cmath>
#include <cstdint>
#include <memory>
#include <numeric>
#include <random>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>

#include "Eigen/Core"
#include "Eigen/Dense"
#include "Eigen/Geometry"
#include "ceres/ceres.h"
#include "ceres/constants.h"
#include "ceres/cubic_interpolation.h"
#include "ceres/rotation.h"

namespace ceres::internal {

// Owns fixed-size parameter block arrays for a benchmark cost functor and
// exposes an array of pointers suitable for CostFunction::Evaluate.
template <int... Ns>
class ParameterBlockStorage {
 public:
  static constexpr int kNumBlocks = sizeof...(Ns);

  explicit ParameterBlockStorage(const std::array<double, Ns>&... blocks)
      : blocks_(blocks...) {}

  std::array<const double*, kNumBlocks> Pointers() const {
    return PointersImpl(std::make_index_sequence<kNumBlocks>());
  }

 private:
  template <size_t... Indices>
  std::array<const double*, kNumBlocks> PointersImpl(
      std::index_sequence<Indices...>) const {
    return {std::get<Indices>(blocks_).data()...};
  }

  std::tuple<std::array<double, Ns>...> blocks_;
};

// Adapts a fixed-arity cost functor `CostFunctor(p0, p1, ..., residuals)` to
// the dynamic-arity signature `operator()(const T* const* parameters, T*
// residuals)` expected by DynamicAutoDiffCostFunction and
// DynamicNumericDiffCostFunction.
template <typename CostFunctor, int kNumParameterBlocks>
class DynamicCostFunctorAdapter {
 public:
  template <typename... Args>
  explicit DynamicCostFunctorAdapter(Args&&... args)
      : functor_(std::forward<Args>(args)...) {}

  template <typename T>
  EIGEN_STRONG_INLINE bool operator()(const T* const* parameters,
                                      T* residuals) const {
    return Apply(
        parameters, residuals, std::make_index_sequence<kNumParameterBlocks>());
  }

 private:
  template <typename T, size_t... Indices>
  EIGEN_STRONG_INLINE bool Apply(const T* const* parameters,
                                 T* residuals,
                                 std::index_sequence<Indices...>) const {
    return functor_(parameters[Indices]..., residuals);
  }

  CostFunctor functor_;
};

// Base class declaring the residual count and parameter block dimensions of a
// benchmark cost functor, along with CostFunction, Manifold, and LossFunction
// factories.
template <int kResiduals, int... Ns>
struct BenchmarkCostFunctor {
  static constexpr int kNumResiduals = kResiduals;
  static constexpr int kNumParameterBlocks = sizeof...(Ns);
  static constexpr int kTotalParameters = (Ns + ...);
  static constexpr std::array<int, kNumParameterBlocks> kBlockSizes = {Ns...};
  using ParameterBlocks = ParameterBlockStorage<Ns...>;

  template <typename CostFunctor, typename... Args>
  static std::unique_ptr<CostFunction> CreateAutoDiff(Args&&... args) {
    return std::make_unique<
        AutoDiffCostFunction<CostFunctor, kNumResiduals, Ns...>>(
        std::make_unique<CostFunctor>(std::forward<Args>(args)...));
  }

  template <typename CostFunctor, typename... Args>
  static std::unique_ptr<CostFunction> CreateAutoDiffDynamicResiduals(
      Args&&... args) {
    return std::make_unique<AutoDiffCostFunction<CostFunctor, DYNAMIC, Ns...>>(
        std::make_unique<CostFunctor>(std::forward<Args>(args)...),
        kNumResiduals);
  }

  template <typename CostFunctor, typename... Args>
  static std::unique_ptr<CostFunction> CreateDynamicAutoDiff(Args&&... args) {
    using Adapter = DynamicCostFunctorAdapter<CostFunctor, kNumParameterBlocks>;
    auto cost_function = std::make_unique<DynamicAutoDiffCostFunction<Adapter>>(
        std::make_unique<Adapter>(std::forward<Args>(args)...));
    (cost_function->AddParameterBlock(Ns), ...);
    cost_function->SetNumResiduals(kNumResiduals);
    return cost_function;
  }

  template <typename CostFunctor,
            NumericDiffMethodType kMethod,
            typename... Args>
  static std::unique_ptr<CostFunction> CreateNumericDiff(Args&&... args) {
    return std::make_unique<
        NumericDiffCostFunction<CostFunctor, kMethod, kNumResiduals, Ns...>>(
        std::make_unique<CostFunctor>(std::forward<Args>(args)...));
  }

  template <typename CostFunctor,
            NumericDiffMethodType kMethod,
            typename... Args>
  static std::unique_ptr<CostFunction> CreateDynamicNumericDiff(
      Args&&... args) {
    using Adapter = DynamicCostFunctorAdapter<CostFunctor, kNumParameterBlocks>;
    auto cost_function =
        std::make_unique<DynamicNumericDiffCostFunction<Adapter, kMethod>>(
            std::make_unique<const Adapter>(std::forward<Args>(args)...));
    (cost_function->AddParameterBlock(Ns), ...);
    cost_function->SetNumResiduals(kNumResiduals);
    return cost_function;
  }

  static std::unique_ptr<Manifold> MakeManifold(int /*block_index*/) {
    return nullptr;
  }

  static std::unique_ptr<LossFunction> MakeLossFunction() { return nullptr; }
};

inline std::array<double, 3> NormalizedVector3(double x, double y, double z) {
  std::array v{x, y, z};
  Eigen::Map<Eigen::Vector3d>(v.data()).normalize();
  return v;
}

inline std::array<double, 4> NormalizedQuaternion(double qx,
                                                  double qy,
                                                  double qz,
                                                  double qw) {
  std::array q{qx, qy, qz, qw};
  Eigen::Map<Eigen::Quaterniond>(q.data()).normalize();
  return q;
}

inline std::array<double, 7> NormalizedPose(double qx,
                                            double qy,
                                            double qz,
                                            double qw,
                                            double tx,
                                            double ty,
                                            double tz) {
  std::array pose{qx, qy, qz, qw, tx, ty, tz};
  Eigen::Map<Eigen::Quaterniond>(pose.data()).normalize();
  return pose;
}

// Converts the angle-axis rotation and translation prefix of a 9-parameter BAL
// camera `[rx, ry, rz, tx, ty, tz, ...]` into a 7-parameter pose `[qx, qy, qz,
// qw, tx, ty, tz]` with an Eigen-convention quaternion.
inline std::array<double, 7> PoseFromBALCamera(const double* bal_camera) {
  double q_wxyz[4];
  AngleAxisToQuaternion(bal_camera, q_wxyz);
  return {q_wxyz[1],
          q_wxyz[2],
          q_wxyz[3],
          q_wxyz[0],
          bal_camera[3],
          bal_camera[4],
          bal_camera[5]};
}

template <int kParameterBlockSize>
struct ConstantCostFunction : BenchmarkCostFunctor<1, kParameterBlockSize> {
  using
      typename BenchmarkCostFunctor<1, kParameterBlockSize>::ParameterBlocks;

  static ParameterBlocks MakeParameters() {
    std::array<double, kParameterBlockSize> x{};
    std::iota(x.begin(), x.end(), 0.0);
    return ParameterBlocks(x);
  }

  template <typename T>
  inline bool operator()(const T* const x, T* residuals) const {
    residuals[0] = T(5);
    return true;
  }
};

template <int kDimension>
struct LinearCostFunction : BenchmarkCostFunctor<kDimension, kDimension> {
  using typename BenchmarkCostFunctor<kDimension, kDimension>::ParameterBlocks;

  static ParameterBlocks MakeParameters() {
    std::array<double, kDimension> x{};
    std::iota(x.begin(), x.end(), 1.0);
    return ParameterBlocks(x);
  }

  template <typename T>
  inline bool operator()(const T* const x, T* residuals) const {
    for (int i = 0; i < kDimension; ++i) {
      residuals[i] = x[i] + T(i);
    }
    return true;
  }
};

// From the NIST problem collection.
struct Rat43CostFunctor : BenchmarkCostFunctor<1, 4> {
  explicit Rat43CostFunctor(const double x = 0.2, const double y = 0.3)
      : x_(x), y_(y) {}

  static ParameterBlocks MakeParameters() {
    return ParameterBlocks({1., 2., 3., 4.});
  }

  template <typename T>
  inline bool operator()(const T* parameters, T* residuals) const {
    const T& b1 = parameters[0];
    const T& b2 = parameters[1];
    const T& b3 = parameters[2];
    const T& b4 = parameters[3];
    residuals[0] = b1 * pow(1.0 + exp(b2 - b3 * x_), -1.0 / b4) - y_;
    return true;
  }

 private:
  const double x_;
  const double y_;
};

struct SnavelyReprojectionError : BenchmarkCostFunctor<2, 9, 3> {
  static constexpr int kPointBlockIndex = 1;

  explicit SnavelyReprojectionError(double observed_x = 0.2,
                                    double observed_y = 0.3)
      : observed_x(observed_x), observed_y(observed_y) {}

  static ParameterBlocks MakeParameters() {
    return ParameterBlocks({1., 2., 3., 4., 5., 6., 7., 8., 9.}, {1., 2., 3.});
  }

  static ParameterBlocks MakeParametersFromBAL(const double* bal_camera,
                                               const double* bal_point) {
    std::array<double, 9> camera{};
    std::array<double, 3> point{};
    std::copy_n(bal_camera, 9, camera.data());
    std::copy_n(bal_point, 3, point.data());
    return ParameterBlocks(camera, point);
  }

  template <typename T>
  inline bool operator()(const T* const camera,
                         const T* const point,
                         T* residuals) const {
    T ox = T(observed_x);
    T oy = T(observed_y);

    // camera[0,1,2] are the angle-axis rotation.
    T p[3];
    ceres::AngleAxisRotatePoint(camera, point, p);

    // camera[3,4,5] are the translation.
    p[0] += camera[3];
    p[1] += camera[4];
    p[2] += camera[5];

    // Compute the center of distortion. The sign change comes from
    // the camera model that Noah Snavely's Bundler assumes, whereby
    // the camera coordinate system has a negative z axis.
    const T xp = -p[0] / p[2];
    const T yp = -p[1] / p[2];

    // Apply second and fourth order radial distortion.
    const T& l1 = camera[7];
    const T& l2 = camera[8];
    const T r2 = xp * xp + yp * yp;
    const T distortion = T(1.0) + r2 * (l1 + l2 * r2);

    // Compute final projected point position.
    const T& focal = camera[6];
    const T predicted_x = focal * distortion * xp;
    const T predicted_y = focal * distortion * yp;

    // The error is the difference between the predicted and observed position.
    residuals[0] = predicted_x - ox;
    residuals[1] = predicted_y - oy;

    return true;
  }
  double observed_x;
  double observed_y;
};

// Photometric residual that computes the intensity difference for a patch
// between host and target frame. The point is parameterized with inverse
// distance relative to the host frame. The relative pose between host and
// target frame is computed from their respective absolute poses.
//
// The residual is similar to the one defined by Engel et al. [1]. Differences
// include:
//
// 1. Use of a camera model based on spherical projection, namely the enhanced
// unified camera model [2][3]. This is intended to bring some variability to
// the benchmark compared to the SnavelyReprojection that uses a
// polynomial-based distortion model.
//
// 2. To match the camera model, inverse distance parameterization is used for
// points instead of inverse depth [4].
//
// 3. For simplicity, camera intrinsics are assumed constant, and thus host
// frame points are passed as (unprojected) bearing vectors, which avoids the
// need for an 'unproject' function.
//
// 4. Some details of the residual in [1] are omitted for simplicity: The
// brightness transform parameters [a,b], the constant pre-weight w, and the
// per-pixel robust norm.
//
// [1] J. Engel, V. Koltun and D. Cremers, "Direct Sparse Odometry," in IEEE
// Transactions on Pattern Analysis and Machine Intelligence, vol. 40, no. 3,
// pp. 611-625, 1 March 2018.
//
// [2] B. Khomutenko, G. Garcia and P. Martinet, "An Enhanced Unified Camera
// Model," in IEEE Robotics and Automation Letters, vol. 1, no. 1, pp. 137-144,
// Jan. 2016.
//
// [3] V. Usenko, N. Demmel and D. Cremers, "The Double Sphere Camera Model,"
// 2018 International Conference on 3D Vision (3DV), Verona, 2018, pp. 552-560.
//
// [4] H. Matsuki, L. von Stumberg, V. Usenko, J. Stückler and D. Cremers,
// "Omnidirectional DSO: Direct Sparse Odometry With Fisheye Cameras," in IEEE
// Robotics and Automation Letters, vol. 3, no. 4, pp. 3693-3700, Oct. 2018.
template <int PATCH_SIZE_ = 8>
struct PhotometricError : BenchmarkCostFunctor<PATCH_SIZE_, 7, 7, 1> {
  static constexpr int PATCH_SIZE = PATCH_SIZE_;
  static constexpr int POSE_SIZE = 7;
  static constexpr int POINT_SIZE = 1;
  using typename BenchmarkCostFunctor<PATCH_SIZE_, 7, 7, 1>::ParameterBlocks;

  using ImageType = Eigen::Matrix<uint8_t, 128, 128, Eigen::RowMajor>;
  using Grid = Grid2D<uint8_t, 1>;
  using Interpolator = BiCubicInterpolator<Grid>;
  using Intrinsics = Eigen::Array<double, 6, 1>;

  template <typename T>
  using Patch = Eigen::Array<T, PATCH_SIZE, 1>;

  template <typename T>
  using PatchVectors = Eigen::Matrix<T, 3, PATCH_SIZE>;

  PhotometricError()
      : grid_(image_.data(), 0, image_.rows(), 0, image_.cols()),
        image_target_(grid_) {
    std::mt19937 gen(42);
    std::uniform_real_distribution<double> uniform01(0.0, 1.0);
    std::uniform_int_distribution<unsigned int> uniform0255(0, 255);

    intensities_host_ =
        Patch<double>::NullaryExpr([&]() { return uniform0255(gen); });
    bearings_host_ =
        PatchVectors<double>::NullaryExpr([&]() { return uniform01(gen); });
    bearings_host_.row(2).array() = 1.0;
    bearings_host_.colwise().normalize();

    image_ = ImageType::NullaryExpr(
        [&]() { return static_cast<uint8_t>(uniform0255(gen)); });
    intrinsics_ << 128, 128, 1, -1, 0.5, 0.5;
  }

  PhotometricError(const PhotometricError&) = delete;
  PhotometricError& operator=(const PhotometricError&) = delete;

  static ParameterBlocks MakeParameters() {
    return ParameterBlocks(
        NormalizedPose(1., 2., 3., 4., 5., 6., 7.),
        NormalizedPose(1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1),
        {1.0});
  }

  template <typename T>
  inline bool Project(Eigen::Matrix<T, 2, 1>& proj,
                      const Eigen::Matrix<T, 3, 1>& p) const {
    const double& fx = intrinsics_[0];
    const double& fy = intrinsics_[1];
    const double& cx = intrinsics_[2];
    const double& cy = intrinsics_[3];
    const double& alpha = intrinsics_[4];
    const double& beta = intrinsics_[5];

    const T rho2 = beta * (p.x() * p.x() + p.y() * p.y()) + p.z() * p.z();
    const T rho = sqrt(rho2);

    // Check if 3D point is in domain of projection function.
    // See (8) and (17) in [3].
    constexpr double NUMERIC_EPSILON = 1e-10;
    const double w =
        alpha > 0.5 ? (1.0 - alpha) / alpha : alpha / (1.0 - alpha);
    if (p.z() <= -w * rho + NUMERIC_EPSILON) {
      return false;
    }

    const T norm = alpha * rho + (1.0 - alpha) * p.z();
    const T norm_inv = 1.0 / norm;

    const T mx = p.x() * norm_inv;
    const T my = p.y() * norm_inv;

    proj[0] = fx * mx + cx;
    proj[1] = fy * my + cy;

    return true;
  }

  template <typename T>
  inline bool operator()(const T* const pose_host_ptr,
                         const T* const pose_target_ptr,
                         const T* const idist_ptr,
                         T* residuals_ptr) const {
    Eigen::Map<const Eigen::Quaternion<T>> q_w_h(pose_host_ptr);
    Eigen::Map<const Eigen::Matrix<T, 3, 1>> t_w_h(pose_host_ptr + 4);
    Eigen::Map<const Eigen::Quaternion<T>> q_w_t(pose_target_ptr);
    Eigen::Map<const Eigen::Matrix<T, 3, 1>> t_w_t(pose_target_ptr + 4);
    const T& idist = *idist_ptr;
    Eigen::Map<Patch<T>> residuals(residuals_ptr);

    // Compute relative pose from host to target frame.
    const Eigen::Quaternion<T> q_t_h = q_w_t.conjugate() * q_w_h;
    const Eigen::Matrix<T, 3, 3> R_t_h = q_t_h.toRotationMatrix();
    const Eigen::Matrix<T, 3, 1> t_t_h = q_w_t.conjugate() * (t_w_h - t_w_t);

    // Transform points from host to target frame. 3D point in target frame is
    // scaled by idist for numerical stability when idist is close to 0
    // (projection is invariant to scaling).
    PatchVectors<T> p_target_scaled =
        (R_t_h * bearings_host_).colwise() + idist * t_t_h;

    // Project points and interpolate image.
    Patch<T> intensities_target;
    for (int i = 0; i < p_target_scaled.cols(); ++i) {
      Eigen::Matrix<T, 2, 1> uv;
      if (!Project(uv, Eigen::Matrix<T, 3, 1>(p_target_scaled.col(i)))) {
        // If any point of the patch is outside the domain of the projection
        // function, the residual cannot be evaluated. For the benchmark we want
        // to avoid this case and thus return false;
        return false;
      }

      // Mind the order of u and v: Evaluate takes (row, column), but u is
      // left-to-right and v top-to-bottom image axis.
      image_target_.Evaluate(uv[1], uv[0], &intensities_target[i]);
    }

    // Residual is intensity difference between host and target frame.
    residuals = intensities_target - intensities_host_;

    return true;
  }

 private:
  ImageType image_;
  Grid grid_;
  Interpolator image_target_;
  Patch<double> intensities_host_;
  PatchVectors<double> bearings_host_;
  Intrinsics intrinsics_;
};

// Relative pose error as one might use in SE(3) pose graph optimization.
// The measurement is a relative pose T_i_j, and the parameters are absolute
// poses T_w_i and T_w_j. For the residual we use the log of the residual
// pose, in split representation SO(3) x R^3.
struct RelativePoseError : BenchmarkCostFunctor<6, 7, 7> {
  explicit RelativePoseError(
      Eigen::Quaterniond q_i_j = Eigen::Quaterniond(1, 2, 3, 4).normalized(),
      Eigen::Vector3d t_i_j = Eigen::Vector3d(1, 2, 3))
      : meas_q_i_j_(std::move(q_i_j)), meas_t_i_j_(std::move(t_i_j)) {}

  static ParameterBlocks MakeParameters() {
    return ParameterBlocks(
        NormalizedPose(1., 2., 3., 4., 5., 6., 7.),
        NormalizedPose(1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1));
  }

  template <typename T>
  inline bool operator()(const T* const pose_i_ptr,
                         const T* const pose_j_ptr,
                         T* residuals_ptr) const {
    Eigen::Map<const Eigen::Quaternion<T>> q_w_i(pose_i_ptr);
    Eigen::Map<const Eigen::Matrix<T, 3, 1>> t_w_i(pose_i_ptr + 4);
    Eigen::Map<const Eigen::Quaternion<T>> q_w_j(pose_j_ptr);
    Eigen::Map<const Eigen::Matrix<T, 3, 1>> t_w_j(pose_j_ptr + 4);
    Eigen::Map<Eigen::Matrix<T, 6, 1>> residuals(residuals_ptr);

    // Compute estimate of relative pose from i to j.
    const Eigen::Quaternion<T> est_q_j_i = q_w_j.conjugate() * q_w_i;
    const Eigen::Matrix<T, 3, 1> est_t_j_i =
        q_w_j.conjugate() * (t_w_i - t_w_j);

    // Compute residual pose.
    const Eigen::Quaternion<T> res_q = meas_q_i_j_.cast<T>() * est_q_j_i;
    const Eigen::Matrix<T, 3, 1> res_t =
        meas_q_i_j_.cast<T>() * est_t_j_i + meas_t_i_j_;

    // Convert quaternion to ceres convention (Eigen stores xyzw, Ceres wxyz).
    Eigen::Matrix<T, 4, 1> res_q_ceres;
    res_q_ceres << res_q.w(), res_q.vec();

    // Residual is log of pose. Use split representation SO(3) x R^3.
    QuaternionToAngleAxis(res_q_ceres.data(), residuals.data());
    residuals.template bottomRows<3>() = res_t;

    return true;
  }

 private:
  // Measurement of relative pose from j to i.
  Eigen::Quaterniond meas_q_i_j_;
  Eigen::Vector3d meas_t_i_j_;
};

// The brdf is based on:
// Burley, Brent, and Walt Disney Animation Studios. "Physically-based shading
// at disney." ACM SIGGRAPH. Vol. 2012. 2012.
//
// The implementation is based on:
// https://github.com/wdas/brdf/blob/master/src/brdfs/disney.brdf
struct Brdf : BenchmarkCostFunctor<3, 10, 3, 3, 3, 3, 3, 3> {
  static ParameterBlocks MakeParameters() {
    return ParameterBlocks(
        {1., 2., 3., 4., 5., 6., 7., 8., 9., 10.},
        {0.1, 0.2, 0.3},
        NormalizedVector3(-0.1, 0.5, 0.2),
        NormalizedVector3(0.5, -0.2, 0.9),
        NormalizedVector3(-0.3, 0.4, -0.3),
        NormalizedVector3(0.5, 0.7, -0.1),
        NormalizedVector3(0.2, -0.2, -0.2));
  }

  template <typename T>
  inline bool operator()(const T* const material,
                         const T* const c_ptr,
                         const T* const n_ptr,
                         const T* const v_ptr,
                         const T* const l_ptr,
                         const T* const x_ptr,
                         const T* const y_ptr,
                         T* residual) const {
    using Vec3 = Eigen::Matrix<T, 3, 1>;

    T metallic = material[0];
    T subsurface = material[1];
    T specular = material[2];
    T roughness = material[3];
    T specular_tint = material[4];
    T anisotropic = material[5];
    T sheen = material[6];
    T sheen_tint = material[7];
    T clearcoat = material[8];
    T clearcoat_gloss = material[9];

    Eigen::Map<const Vec3> c(c_ptr);
    Eigen::Map<const Vec3> n(n_ptr);
    Eigen::Map<const Vec3> v(v_ptr);
    Eigen::Map<const Vec3> l(l_ptr);
    Eigen::Map<const Vec3> x(x_ptr);
    Eigen::Map<const Vec3> y(y_ptr);

    const T n_dot_l = n.dot(l);
    const T n_dot_v = n.dot(v);

    const Vec3 l_p_v = l + v;
    const Vec3 h = l_p_v / l_p_v.norm();

    const T n_dot_h = n.dot(h);
    const T l_dot_h = l.dot(h);

    const T h_dot_x = h.dot(x);
    const T h_dot_y = h.dot(y);

    const T c_dlum = T(0.3) * c[0] + T(0.6) * c[1] + T(0.1) * c[2];

    const Vec3 c_tint = c / c_dlum;

    const Vec3 c_spec0 =
        Lerp(specular * T(0.08) *
                 Lerp(Vec3(T(1), T(1), T(1)), c_tint, specular_tint),
             c,
             metallic);
    const Vec3 c_sheen = Lerp(Vec3(T(1), T(1), T(1)), c_tint, sheen_tint);

    // Diffuse fresnel - go from 1 at normal incidence to .5 at grazing
    // and mix in diffuse retro-reflection based on roughness
    const T fl = SchlickFresnel(n_dot_l);
    const T fv = SchlickFresnel(n_dot_v);
    const T fd_90 = T(0.5) + T(2) * l_dot_h * l_dot_h * roughness;
    const T fd = Lerp(T(1), fd_90, fl) * Lerp(T(1), fd_90, fv);

    // Based on Hanrahan-Krueger brdf approximation of isotropic bssrdf
    // 1.25 scale is used to (roughly) preserve albedo
    // Fss90 used to "flatten" retroreflection based on roughness
    const T fss_90 = l_dot_h * l_dot_h * roughness;
    const T fss = Lerp(T(1), fss_90, fl) * Lerp(T(1), fss_90, fv);
    const T ss =
        T(1.25) * (fss * (T(1) / (n_dot_l + n_dot_v) - T(0.5)) + T(0.5));

    // specular
    const T eps = T(0.001);
    const T aspct = Aspect(anisotropic);
    const T ax_temp = Square(roughness) / aspct;
    const T ay_temp = Square(roughness) * aspct;
    const T ax = (ax_temp < eps ? eps : ax_temp);
    const T ay = (ay_temp < eps ? eps : ay_temp);
    const T ds = GTR2Aniso(n_dot_h, h_dot_x, h_dot_y, ax, ay);
    const T fh = SchlickFresnel(l_dot_h);
    const Vec3 fs = Lerp(c_spec0, Vec3(T(1), T(1), T(1)), fh);
    const T roughg = Square(roughness * T(0.5) + T(0.5));
    const T ggxn_dot_l = SmithG_GGX(n_dot_l, roughg);
    const T ggxn_dot_v = SmithG_GGX(n_dot_v, roughg);
    const T gs = ggxn_dot_l * ggxn_dot_v;

    // sheen
    const Vec3 f_sheen = fh * sheen * c_sheen;

    // clearcoat (ior = 1.5 -> F0 = 0.04)
    const T a = Lerp(T(0.1), T(0.001), clearcoat_gloss);
    const T dr = GTR1(n_dot_h, a);
    const T fr = Lerp(T(0.04), T(1), fh);
    const T cggxn_dot_l = SmithG_GGX(n_dot_l, T(0.25));
    const T cggxn_dot_v = SmithG_GGX(n_dot_v, T(0.25));
    const T gr = cggxn_dot_l * cggxn_dot_v;

    const Vec3 result_no_cosine =
        (T(1.0 / constants::pi) * Lerp(fd, ss, subsurface) * c + f_sheen) *
            (T(1) - metallic) +
        gs * fs * ds +
        Vec3(T(0.25), T(0.25), T(0.25)) * clearcoat * gr * fr * dr;
    const Vec3 result = n_dot_l * result_no_cosine;
    residual[0] = result(0);
    residual[1] = result(1);
    residual[2] = result(2);

    return true;
  }

  template <typename T>
  inline T SchlickFresnel(const T& u) const {
    T m = T(1) - u;
    const T m2 = m * m;
    return m2 * m2 * m;  // (1-u)^5
  }

  template <typename T>
  inline T Aspect(const T& anisotropic) const {
    return T(sqrt(T(1) - anisotropic * T(0.9)));
  }

  template <typename T>
  inline T SmithG_GGX(const T& n_dot_v, const T& alpha_g) const {
    const T a = alpha_g * alpha_g;
    const T b = n_dot_v * n_dot_v;
    return T(1) / (n_dot_v + T(sqrt(a + b - a * b)));
  }

  // Generalized-Trowbridge-Reitz (GTR) Microfacet Distribution
  // See paper, Appendix B
  template <typename T>
  inline T GTR1(const T& n_dot_h, const T& a) const {
    T result = T(0);

    if (a >= T(1)) {
      result = T(1 / constants::pi);
    } else {
      const T a2 = a * a;
      const T t = T(1) + (a2 - T(1)) * n_dot_h * n_dot_h;
      result = (a2 - T(1)) / (T(constants::pi) * T(log(a2) * t));
    }
    return result;
  }

  template <typename T>
  inline T GTR2Aniso(const T& n_dot_h,
                     const T& h_dot_x,
                     const T& h_dot_y,
                     const T& ax,
                     const T& ay) const {
    return T(1) / (T(constants::pi) * ax * ay *
                   Square(Square(h_dot_x / ax) + Square(h_dot_y / ay) +
                          n_dot_h * n_dot_h));
  }

  template <typename T>
  inline T Lerp(const T& a, const T& b, const T& u) const {
    return a + u * (b - a);
  }

  template <typename Derived1, typename Derived2>
  inline typename Derived1::PlainObject Lerp(
      const Eigen::MatrixBase<Derived1>& a,
      const Eigen::MatrixBase<Derived2>& b,
      typename Derived1::Scalar alpha) const {
    return (typename Derived1::Scalar(1) - alpha) * a + alpha * b;
  }

  template <typename T>
  inline T Square(const T& x) const {
    return x * x;
  }
};

// Functors for benchmarking CostFunctionToFunctor (static sizes) and
// DynamicCostFunctionToFunctor (dynamic sizes).
//
// CostFunctionToFunctor and DynamicCostFunctionToFunctor allow an existing
// CostFunction object (which only accepts `double` inputs and computes `double`
// residuals and Jacobians via CostFunction::Evaluate) to be used as a templated
// functor inside another cost functor. When called with `Jet<double, N>`
// arguments during automatic differentiation of the outer functor, the adapter:
//   1. Extracts the scalar (`double`) parts of the input Jets.
//   2. Calls the inner CostFunction::Evaluate to compute the inner residuals
//      and Jacobians with respect to the inner inputs.
//   3. Applies the chain rule to multiply the inner Jacobians by the derivative
//      (`.v`) parts of the input Jets to form the output residual Jets.
//
// To benchmark this composition realistically, we split a standard pinhole
// camera projection with radial distortion into two stages:
//
//   - Stage 1 (`InnerProjectionFunctor`): Projects a 3D point already in the
//     camera coordinate frame, `p_cam = [X, Y, Z]`, into 2D pixel coordinates
//     using camera `intrinsics = [focal, k1, k2]`:
//       xp = X / Z,  yp = Y / Z,  r^2 = xp^2 + yp^2
//       distortion = 1 + k1 * r^2 + k2 * r^4
//       residuals  = [focal * distortion * xp, focal * distortion * yp]
//     This inner functor is wrapped in an `AutoDiffCostFunction<..., 2, 3, 3>`,
//     representing a pre-existing CostFunction object.
//
//   - Stage 2 (`OuterProjectionFunctor`): Takes four 3D parameter blocks
//     (`rotation` angle-axis, `translation`, `intrinsics`, and a world-frame
//     `point`), transforms the world point into the camera frame:
//       p_cam = AngleAxisRotatePoint(rotation, point) + translation
//     and then invokes the inner CostFunction via either:
//       * `CostFunctionToFunctor<2, 3, 3>` (when `!kUseDynamicAdapter`), or
//       * `DynamicCostFunctionToFunctor`   (when `kUseDynamicAdapter`).
struct InnerProjectionFunctor {
  template <typename T>
  bool operator()(const T* const intrinsics,
                  const T* const point,
                  T* residuals) const {
    const T xp = point[0] / point[2];
    const T yp = point[1] / point[2];
    const T r2 = xp * xp + yp * yp;
    const T distortion = T(1.0) + r2 * (intrinsics[1] + intrinsics[2] * r2);
    residuals[0] = intrinsics[0] * distortion * xp;
    residuals[1] = intrinsics[0] * distortion * yp;
    return true;
  }
};

template <bool kUseDynamicAdapter>
struct OuterProjectionFunctor : BenchmarkCostFunctor<2, 3, 3, 3, 3> {
  using typename BenchmarkCostFunctor<2, 3, 3, 3, 3>::ParameterBlocks;

  OuterProjectionFunctor()
      : inner_(std::make_unique<
               AutoDiffCostFunction<InnerProjectionFunctor, 2, 3, 3>>(
            std::make_unique<InnerProjectionFunctor>())) {}

  static ParameterBlocks MakeParameters() {
    return ParameterBlocks({0.1, -0.2, 0.05},
                           {0.5, -0.1, 2.0},
                           {500.0, -0.01, 0.001},
                           {0.3, -0.4, 5.0});
  }

  template <typename T>
  bool operator()(const T* const rotation,
                  const T* const translation,
                  const T* const intrinsics,
                  const T* const point,
                  T* residuals) const {
    // Transform the 3D point from the world frame into the camera frame.
    T p_cam[3];
    AngleAxisRotatePoint(rotation, point, p_cam);
    p_cam[0] += translation[0];
    p_cam[1] += translation[1];
    p_cam[2] += translation[2];

    // Project the camera-frame point into 2D pixel coordinates by invoking the
    // wrapped inner CostFunction through CostFunctionToFunctor (static) or
    // DynamicCostFunctionToFunctor (dynamic).
    if constexpr (!kUseDynamicAdapter) {
      return inner_(intrinsics, p_cam, residuals);
    } else {
      const T* params[2] = {intrinsics, p_cam};
      return inner_(params, residuals);
    }
  }

  std::conditional_t<!kUseDynamicAdapter,
                     CostFunctionToFunctor<2, 3, 3>,
                     DynamicCostFunctionToFunctor>
      inner_;
};

// 1. COLMAP ReprojErrorCostFunctor<OpenCVCameraModel>: <2, 3, 7, 8>
// point3D_in_world (3), cam_from_world [qx, qy, qz, qw, tx, ty, tz] (7),
// camera_params [fx, fy, cx, cy, k1, k2, p1, p2] (8).
struct ColmapOpenCVReprojectionError : BenchmarkCostFunctor<2, 3, 7, 8> {
  static constexpr int kPointBlockIndex = 0;

  explicit ColmapOpenCVReprojectionError(double u = 650.0, double v = 350.0)
      : obs_x(u), obs_y(v) {}

  static ParameterBlocks MakeParameters() {
    return ParameterBlocks(
        {0.5, -0.3, 4.2},
        NormalizedPose(0.01, 0.02, -0.01, 0.9997, 0.1, -0.2, 0.5),
        {1000.0, 1000.0, 640.0, 360.0, -0.05, 0.01, 1e-4, -1e-4});
  }

  static ParameterBlocks MakeParametersFromBAL(const double* bal_camera,
                                               const double* bal_point) {
    // BAL cameras look down -Z with focal length bal_camera[6] and radial
    // distortion (bal_camera[7], bal_camera[8]); negate focal length so
    // projection matches COLMAP's +Z camera convention.
    std::array<double, 8> intrinsics = {-bal_camera[6],
                                        -bal_camera[6],
                                        0.0,
                                        0.0,
                                        bal_camera[7],
                                        bal_camera[8],
                                        1e-4,
                                        1e-4};
    return ParameterBlocks({bal_point[0], bal_point[1], bal_point[2]},
                           PoseFromBALCamera(bal_camera),
                           intrinsics);
  }

  static std::unique_ptr<Manifold> MakeManifold(int block_index) {
    if (block_index == 1) {
      return std::make_unique<
          ProductManifold<EigenQuaternionManifold, EuclideanManifold<3>>>();
    }
    return nullptr;
  }

  static std::unique_ptr<LossFunction> MakeLossFunction() {
    return std::make_unique<HuberLoss>(1.0);
  }

  template <typename T>
  inline bool operator()(const T* const point3D_in_world,
                         const T* const cam_from_world,
                         const T* const camera_params,
                         T* residuals) const {
    const Eigen::Map<const Eigen::Quaternion<T>> q(cam_from_world);
    const Eigen::Map<const Eigen::Matrix<T, 3, 1>> t(cam_from_world + 4);
    const Eigen::Map<const Eigen::Matrix<T, 3, 1>> p_w(point3D_in_world);
    const Eigen::Matrix<T, 3, 1> p_c = q * p_w + t;

    const T f1 = camera_params[0];
    const T f2 = camera_params[1];
    const T c1 = camera_params[2];
    const T c2 = camera_params[3];
    const T k1 = camera_params[4];
    const T k2 = camera_params[5];
    const T p1 = camera_params[6];
    const T p2 = camera_params[7];

    const T u = p_c[0] / p_c[2];
    const T v = p_c[1] / p_c[2];
    const T u2 = u * u;
    const T uv = u * v;
    const T v2 = v * v;
    const T r2 = u2 + v2;
    const T radial = k1 * r2 + k2 * r2 * r2;
    const T du = u * radial + T(2) * p1 * uv + p2 * (r2 + T(2) * u2);
    const T dv = v * radial + T(2) * p2 * uv + p1 * (r2 + T(2) * v2);

    residuals[0] = f1 * (u + du) + c1 - T(obs_x);
    residuals[1] = f2 * (v + dv) + c2 - T(obs_y);
    return true;
  }

  double obs_x;
  double obs_y;
};

// 2. COLMAP ReprojErrorCostFunctor<FullOpenCVCameraModel>: <2, 3, 7, 12>
// Rational radial + tangential distortion:
// camera_params [fx, fy, cx, cy, k1, k2, p1, p2, k3, k4, k5, k6] (12).
struct ColmapFullOpenCVReprojectionError : BenchmarkCostFunctor<2, 3, 7, 12> {
  static constexpr int kPointBlockIndex = 0;

  explicit ColmapFullOpenCVReprojectionError(double u = 650.0, double v = 350.0)
      : obs_x(u), obs_y(v) {}

  static ParameterBlocks MakeParameters() {
    return ParameterBlocks(
        {0.5, -0.3, 4.2},
        NormalizedPose(0.01, 0.02, -0.01, 0.9997, 0.1, -0.2, 0.5),
        {1000.0,
         1000.0,
         640.0,
         360.0,
         -0.05,
         0.01,
         1e-4,
         -1e-4,
         0.002,
         0.01,
         -0.005,
         0.001});
  }

  template <typename T>
  inline bool operator()(const T* const point3D_in_world,
                         const T* const cam_from_world,
                         const T* const camera_params,
                         T* residuals) const {
    const Eigen::Map<const Eigen::Quaternion<T>> q(cam_from_world);
    const Eigen::Map<const Eigen::Matrix<T, 3, 1>> t(cam_from_world + 4);
    const Eigen::Map<const Eigen::Matrix<T, 3, 1>> p_w(point3D_in_world);
    const Eigen::Matrix<T, 3, 1> p_c = q * p_w + t;

    const T f1 = camera_params[0];
    const T f2 = camera_params[1];
    const T c1 = camera_params[2];
    const T c2 = camera_params[3];
    const T k1 = camera_params[4];
    const T k2 = camera_params[5];
    const T p1 = camera_params[6];
    const T p2 = camera_params[7];
    const T k3 = camera_params[8];
    const T k4 = camera_params[9];
    const T k5 = camera_params[10];
    const T k6 = camera_params[11];

    const T u = p_c[0] / p_c[2];
    const T v = p_c[1] / p_c[2];
    const T u2 = u * u;
    const T uv = u * v;
    const T v2 = v * v;
    const T r2 = u2 + v2;
    const T r4 = r2 * r2;
    const T r6 = r4 * r2;
    const T radial = (T(1) + k1 * r2 + k2 * r4 + k3 * r6) /
                     (T(1) + k4 * r2 + k5 * r4 + k6 * r6);
    const T x = u * radial + T(2) * p1 * uv + p2 * (r2 + T(2) * u2);
    const T y = v * radial + T(2) * p2 * uv + p1 * (r2 + T(2) * v2);

    residuals[0] = f1 * x + c1 - T(obs_x);
    residuals[1] = f2 * y + c2 - T(obs_y);
    return true;
  }

  double obs_x;
  double obs_y;
};

// 3. COLMAP RigReprojErrorCostFunctor<OpenCVCameraModel>: <2, 3, 7, 7, 8>
// point3D_in_world (3), cam_from_rig (7), rig_from_world (7), camera_params
// (8).
struct ColmapRigReprojectionError : BenchmarkCostFunctor<2, 3, 7, 7, 8> {
  static constexpr int kPointBlockIndex = 0;

  explicit ColmapRigReprojectionError(double u = 650.0, double v = 350.0)
      : obs_x(u), obs_y(v) {}

  static ParameterBlocks MakeParameters() {
    return ParameterBlocks(
        {0.5, -0.3, 4.2},
        NormalizedPose(0.01, -0.01, 0.02, 0.9997, 0.05, 0.0, 0.0),
        NormalizedPose(0.02, 0.01, -0.02, 0.9995, 0.1, -0.2, 0.5),
        {1000.0, 1000.0, 640.0, 360.0, -0.05, 0.01, 1e-4, -1e-4});
  }

  template <typename T>
  inline bool operator()(const T* const point3D_in_world,
                         const T* const cam_from_rig,
                         const T* const rig_from_world,
                         const T* const camera_params,
                         T* residuals) const {
    const Eigen::Map<const Eigen::Quaternion<T>> q_cr(cam_from_rig);
    const Eigen::Map<const Eigen::Matrix<T, 3, 1>> t_cr(cam_from_rig + 4);
    const Eigen::Map<const Eigen::Quaternion<T>> q_rw(rig_from_world);
    const Eigen::Map<const Eigen::Matrix<T, 3, 1>> t_rw(rig_from_world + 4);
    const Eigen::Map<const Eigen::Matrix<T, 3, 1>> p_w(point3D_in_world);

    const Eigen::Matrix<T, 3, 1> p_c = q_cr * (q_rw * p_w + t_rw) + t_cr;

    const T f1 = camera_params[0];
    const T f2 = camera_params[1];
    const T c1 = camera_params[2];
    const T c2 = camera_params[3];
    const T k1 = camera_params[4];
    const T k2 = camera_params[5];
    const T p1 = camera_params[6];
    const T p2 = camera_params[7];

    const T u = p_c[0] / p_c[2];
    const T v = p_c[1] / p_c[2];
    const T u2 = u * u;
    const T uv = u * v;
    const T v2 = v * v;
    const T r2 = u2 + v2;
    const T radial = k1 * r2 + k2 * r2 * r2;
    const T du = u * radial + T(2) * p1 * uv + p2 * (r2 + T(2) * u2);
    const T dv = v * radial + T(2) * p2 * uv + p1 * (r2 + T(2) * v2);

    residuals[0] = f1 * (u + du) + c1 - T(obs_x);
    residuals[1] = f2 * (v + dv) + c2 - T(obs_y);
    return true;
  }

  double obs_x;
  double obs_y;
};

// 4. COLMAP SampsonErrorCostFunctor: <1, 7>
// Essential matrix E = [t]_x R(q) and signed Sampson epipolar error.
struct ColmapSampsonError : BenchmarkCostFunctor<1, 7> {
  explicit ColmapSampsonError(
      const Eigen::Vector2d& p1 = Eigen::Vector2d(0.1, -0.2),
      const Eigen::Vector2d& p2 = Eigen::Vector2d(0.15, -0.18))
      : point1_(p1), point2_(p2) {}

  static ParameterBlocks MakeParameters() {
    return ParameterBlocks(
        NormalizedPose(0.01, 0.02, -0.01, 0.9997, 0.8, 0.4, 0.4472));
  }

  template <typename T>
  inline bool operator()(const T* const cam2_from_cam1, T* residuals) const {
    const Eigen::Matrix<T, 3, 3> R =
        Eigen::Map<const Eigen::Quaternion<T>>(cam2_from_cam1)
            .toRotationMatrix();
    Eigen::Matrix<T, 3, 3> t_x;
    t_x << T(0), -cam2_from_cam1[6], cam2_from_cam1[5], cam2_from_cam1[6], T(0),
        -cam2_from_cam1[4], -cam2_from_cam1[5], cam2_from_cam1[4], T(0);
    const Eigen::Matrix<T, 3, 3> E = t_x * R;

    const Eigen::Matrix<T, 3, 1> p1(T(point1_.x()), T(point1_.y()), T(1));
    const Eigen::Matrix<T, 3, 1> p2(T(point2_.x()), T(point2_.y()), T(1));
    const Eigen::Matrix<T, 3, 1> epipolar_line1 = E * p1;
    const T num = p2.dot(epipolar_line1);
    const Eigen::Matrix<T, 4, 1> denom(p2.dot(E.col(0)),
                                       p2.dot(E.col(1)),
                                       epipolar_line1.x(),
                                       epipolar_line1.y());
    residuals[0] = num / denom.norm();
    return true;
  }

  Eigen::Vector2d point1_;
  Eigen::Vector2d point2_;
};

// 5. COLMAP ReprojErrorCostFunctor<OpenCVFisheyeCameraModel>: <2, 3, 7, 8>
// Kannala-Brandt equidistant fisheye camera model:
// point3D_in_world (3), cam_from_world (7),
// camera_params [fx, fy, cx, cy, k1, k2, k3, k4] (8).
struct ColmapFisheyeReprojectionError : BenchmarkCostFunctor<2, 3, 7, 8> {
  static constexpr int kPointBlockIndex = 0;

  explicit ColmapFisheyeReprojectionError(double u = 650.0, double v = 350.0)
      : obs_x(u), obs_y(v) {}

  static ParameterBlocks MakeParameters() {
    return ParameterBlocks(
        {0.5, -0.3, 4.2},
        NormalizedPose(0.01, 0.02, -0.01, 0.9997, 0.1, -0.2, 0.5),
        {800.0, 800.0, 640.0, 360.0, -0.02, 0.005, -0.001, 0.0002});
  }

  template <typename T>
  inline bool operator()(const T* const point3D_in_world,
                         const T* const cam_from_world,
                         const T* const camera_params,
                         T* residuals) const {
    const Eigen::Map<const Eigen::Quaternion<T>> q(cam_from_world);
    const Eigen::Map<const Eigen::Matrix<T, 3, 1>> t(cam_from_world + 4);
    const Eigen::Map<const Eigen::Matrix<T, 3, 1>> p_w(point3D_in_world);
    const Eigen::Matrix<T, 3, 1> p_c = q * p_w + t;

    const T f1 = camera_params[0];
    const T f2 = camera_params[1];
    const T c1 = camera_params[2];
    const T c2 = camera_params[3];
    const T k1 = camera_params[4];
    const T k2 = camera_params[5];
    const T k3 = camera_params[6];
    const T k4 = camera_params[7];

    const T u = p_c[0] / p_c[2];
    const T v = p_c[1] / p_c[2];
    const T r = hypot(u, v);
    T x = u;
    T y = v;
    if (r > T(1e-8)) {
      const T theta = atan(r);
      const T theta2 = theta * theta;
      const T theta4 = theta2 * theta2;
      const T theta6 = theta4 * theta2;
      const T theta8 = theta4 * theta4;
      const T thetad = theta * (T(1) + k1 * theta2 + k2 * theta4 + k3 * theta6 +
                                k4 * theta8);
      const T scale = thetad / r;
      x *= scale;
      y *= scale;
    }

    residuals[0] = f1 * x + c1 - T(obs_x);
    residuals[1] = f2 * y + c2 - T(obs_y);
    return true;
  }

  double obs_x;
  double obs_y;
};

// 6. COLMAP ReprojErrorCostFunctor<EquirectangularCameraModel>: <2, 3, 7>
// 360x180 spherical equirectangular projection using atan2 and asin.
struct ColmapSphericalReprojectionError : BenchmarkCostFunctor<2, 3, 7> {
  static constexpr int kPointBlockIndex = 0;

  explicit ColmapSphericalReprojectionError(double u = 650.0, double v = 350.0)
      : obs_x(u), obs_y(v) {}

  static ParameterBlocks MakeParameters() {
    return ParameterBlocks(
        {0.5, -0.3, 4.2},
        NormalizedPose(0.01, 0.02, -0.01, 0.9997, 0.1, -0.2, 0.5));
  }

  template <typename T>
  inline bool operator()(const T* const point3D_in_world,
                         const T* const cam_from_world,
                         T* residuals) const {
    const Eigen::Map<const Eigen::Quaternion<T>> q(cam_from_world);
    const Eigen::Map<const Eigen::Matrix<T, 3, 1>> t(cam_from_world + 4);
    const Eigen::Map<const Eigen::Matrix<T, 3, 1>> p_w(point3D_in_world);
    const Eigen::Matrix<T, 3, 1> p_c = q * p_w + t;

    const T norm = p_c.norm();
    const T lon = atan2(p_c[0], p_c[2]);
    const T lat = asin(p_c[1] / norm);

    constexpr double kWidth = 1920.0;
    constexpr double kHeight = 960.0;
    constexpr double kInvTwoPi = 1.0 / (2.0 * constants::pi);
    constexpr double kInvPi = 1.0 / constants::pi;
    residuals[0] = T(kWidth) * (T(0.5) + lon * T(kInvTwoPi)) - T(obs_x);
    residuals[1] = T(kHeight) * (T(0.5) + lat * T(kInvPi)) - T(obs_y);
    return true;
  }

  double obs_x;
  double obs_y;
};

// 7. Blender libmv Brown-Conrady ReprojectionErrorApplyIntrinsics: <2, 9, 6, 3>
// intrinsics [f, px, py, k1, k2, k3, k4, p1, p2] (9), R_t [rx, ry, rz, tx, ty,
// tz] (6), X (3).
struct LibmvBrownReprojectionError : BenchmarkCostFunctor<2, 9, 6, 3> {
  static constexpr int kPointBlockIndex = 2;

  explicit LibmvBrownReprojectionError(double u = 650.0, double v = 350.0)
      : obs_x(u), obs_y(v) {}

  static ParameterBlocks MakeParameters() {
    return ParameterBlocks(
        {1000.0, 640.0, 360.0, -0.05, 0.01, -0.002, 0.0005, 1e-4, -1e-4},
        {0.02, -0.03, 0.01, 0.1, -0.2, 0.5},
        {0.5, -0.3, 4.2});
  }

  static ParameterBlocks MakeParametersFromBAL(const double* bal_camera,
                                               const double* bal_point) {
    std::array<double, 9> intrinsics = {-bal_camera[6],
                                        0.0,
                                        0.0,
                                        bal_camera[7],
                                        bal_camera[8],
                                        0.0,
                                        0.0,
                                        1e-4,
                                        1e-4};
    std::array<double, 6> pose{};
    std::copy_n(bal_camera, 6, pose.data());
    return ParameterBlocks(
        intrinsics, pose, {bal_point[0], bal_point[1], bal_point[2]});
  }

  static std::unique_ptr<Manifold> MakeManifold(int block_index) {
    if (block_index == 0) {
      return std::make_unique<SubsetManifold>(9, std::vector<int>{1, 2, 5, 6});
    }
    return nullptr;
  }

  template <typename T>
  inline bool operator()(const T* const intrinsics,
                         const T* const R_t,
                         const T* const X,
                         T* residuals) const {
    T p[3];
    ceres::AngleAxisRotatePoint(R_t, X, p);
    p[0] += R_t[3];
    p[1] += R_t[4];
    p[2] += R_t[5];

    const T x = p[0] / p[2];
    const T y = p[1] / p[2];

    const T focal = intrinsics[0];
    const T px = intrinsics[1];
    const T py = intrinsics[2];
    const T k1 = intrinsics[3];
    const T k2 = intrinsics[4];
    const T k3 = intrinsics[5];
    const T k4 = intrinsics[6];
    const T p1 = intrinsics[7];
    const T p2 = intrinsics[8];

    const T x2 = x * x;
    const T y2 = y * y;
    const T xy2 = T(2) * x * y;
    const T r2 = x2 + y2;
    const T r_coeff = T(1) + (((k4 * r2 + k3) * r2 + k2) * r2 + k1) * r2;
    const T tx = p1 * (r2 + T(2) * x2) + p2 * xy2;
    const T ty = p2 * (r2 + T(2) * y2) + p1 * xy2;

    residuals[0] = focal * (x * r_coeff + tx) + px - T(obs_x);
    residuals[1] = focal * (y * r_coeff + ty) + py - T(obs_y);
    return true;
  }

  double obs_x;
  double obs_y;
};

// 8. Blender libmv Nuke ReprojectionErrorInvertIntrinsics: <2, 8, 6, 3>
// intrinsics [f, px, py, k1, k2, p1, p2, aspect] (8), R_t (6), X (3).
struct LibmvNukeInvertReprojectionError : BenchmarkCostFunctor<2, 8, 6, 3> {
  static constexpr int kPointBlockIndex = 2;

  explicit LibmvNukeInvertReprojectionError(double u = 650.0, double v = 350.0)
      : obs_x(u), obs_y(v) {}

  static ParameterBlocks MakeParameters() {
    return ParameterBlocks(
        {1000.0, 640.0, 360.0, -0.05, 0.01, 1e-4, -1e-4, 1.0},
        {0.02, -0.03, 0.01, 0.1, -0.2, 0.5},
        {0.5, -0.3, 4.2});
  }

  template <typename T>
  inline bool operator()(const T* const intrinsics,
                         const T* const R_t,
                         const T* const X,
                         T* residuals) const {
    const T focal = intrinsics[0];
    const T px = intrinsics[1];
    const T py = intrinsics[2];
    const T k1 = intrinsics[3];
    const T k2 = intrinsics[4];
    const T p1 = intrinsics[5];
    const T p2 = intrinsics[6];

    T p[3];
    ceres::AngleAxisRotatePoint(R_t, X, p);
    p[0] += R_t[3];
    p[1] += R_t[4];
    p[2] += R_t[5];

    const T xn = p[0] / p[2];
    const T yn = p[1] / p[2];
    const T predicted_x = focal * xn + px;
    const T predicted_y = focal * yn + py;

    constexpr double kHalfMaxImageSize = 960.0;
    const T xd = (T(obs_x) - px) / T(kHalfMaxImageSize);
    const T yd = (T(obs_y) - py) / T(kHalfMaxImageSize);
    const T xd2 = xd * xd;
    const T yd2 = yd * yd;
    const T rd2 = xd2 + yd2;
    const T rd4 = rd2 * rd2;
    const T xu = xd / (T(1) + k1 * rd2 + k2 * rd4 + p1 * yd2);
    const T yu = yd / (T(1) + k1 * rd2 + k2 * rd4 + p2 * xd2);

    const T obs_undistorted_x = xu * T(kHalfMaxImageSize) + px;
    const T obs_undistorted_y = yu * T(kHalfMaxImageSize) + py;

    residuals[0] = predicted_x - obs_undistorted_x;
    residuals[1] = predicted_y - obs_undistorted_y;
    return true;
  }

  double obs_x;
  double obs_y;
};

// 9. 3D Pose Graph SLAM Error Term (PoseGraph3dErrorTerm): <6, 3, 4, 3, 4>
struct PoseGraph3dError : BenchmarkCostFunctor<6, 3, 4, 3, 4> {
  explicit PoseGraph3dError(
      const Eigen::Vector3d& p_ab = Eigen::Vector3d(1.0, 1.0, 1.0),
      const Eigen::Quaterniond& q_ab = Eigen::Quaterniond::Identity(),
      const Eigen::Matrix<double, 6, 6>& sqrt_info =
          Eigen::Matrix<double, 6, 6>::Identity())
      : p_ab_measured_(p_ab),
        q_ab_measured_(q_ab),
        sqrt_information_(sqrt_info) {}

  static ParameterBlocks MakeParameters() {
    return ParameterBlocks(
        {1.0, 2.0, 3.0},
        NormalizedQuaternion(0.01, 0.02, -0.01, 0.9997),
        {2.1, 3.2, 4.3},
        NormalizedQuaternion(0.03, -0.01, 0.02, 0.9993));
  }

  template <typename T>
  inline bool operator()(const T* const p_a_ptr,
                         const T* const q_a_ptr,
                         const T* const p_b_ptr,
                         const T* const q_b_ptr,
                         T* residuals_ptr) const {
    const Eigen::Map<const Eigen::Matrix<T, 3, 1>> p_a(p_a_ptr);
    const Eigen::Map<const Eigen::Quaternion<T>> q_a(q_a_ptr);
    const Eigen::Map<const Eigen::Matrix<T, 3, 1>> p_b(p_b_ptr);
    const Eigen::Map<const Eigen::Quaternion<T>> q_b(q_b_ptr);

    const Eigen::Quaternion<T> q_a_inverse = q_a.conjugate();
    const Eigen::Quaternion<T> q_ab_estimated = q_a_inverse * q_b;
    const Eigen::Matrix<T, 3, 1> p_ab_estimated = q_a_inverse * (p_b - p_a);
    const Eigen::Quaternion<T> delta_q =
        q_ab_measured_.template cast<T>() * q_ab_estimated.conjugate();

    Eigen::Map<Eigen::Matrix<T, 6, 1>> residuals(residuals_ptr);
    residuals.template block<3, 1>(0, 0) =
        p_ab_estimated - p_ab_measured_.template cast<T>();
    residuals.template block<3, 1>(3, 0) = T(2.0) * delta_q.vec();
    residuals.applyOnTheLeft(sqrt_information_.template cast<T>());
    return true;
  }

  Eigen::Vector3d p_ab_measured_;
  Eigen::Quaterniond q_ab_measured_;
  Eigen::Matrix<double, 6, 6> sqrt_information_;
};

}  // namespace ceres::internal

#endif  // CERES_INTERNAL_BENCHMARK_COST_FUNCTIONS_H_
