// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2024 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: keir@google.com (Keir Mierle)
//         tbennun@gmail.com (Tal Ben-Nun)

#include "ceres/numeric_diff_cost_function.h"

#include <algorithm>
#include <array>
#include <cmath>
#include <memory>
#include <random>
#include <string>
#include <vector>

#include "ceres/array_utils.h"
#include "ceres/numeric_diff_test_utils.h"
#include "ceres/test_util.h"
#include "ceres/types.h"
#include "gtest/gtest.h"

namespace ceres::internal {

TEST(NumericDiffCostFunction, EasyCaseFunctorCentralDifferences) {
  auto cost_function =
      std::make_unique<NumericDiffCostFunction<EasyFunctor,
                                               CENTRAL,
                                               3,  // number of residuals
                                               5,  // size of x1
                                               5   // size of x2
                                               >>(new EasyFunctor);
  EasyFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, CENTRAL);
}

TEST(NumericDiffCostFunction, EasyCaseFunctorForwardDifferences) {
  auto cost_function =
      std::make_unique<NumericDiffCostFunction<EasyFunctor,
                                               FORWARD,
                                               3,  // number of residuals
                                               5,  // size of x1
                                               5   // size of x2
                                               >>(new EasyFunctor);
  EasyFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, FORWARD);
}

TEST(NumericDiffCostFunction, EasyCaseFunctorRidders) {
  auto cost_function =
      std::make_unique<NumericDiffCostFunction<EasyFunctor,
                                               RIDDERS,
                                               3,  // number of residuals
                                               5,  // size of x1
                                               5   // size of x2
                                               >>(new EasyFunctor);
  EasyFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, RIDDERS);
}

TEST(NumericDiffCostFunction, EasyCaseCostFunctionCentralDifferences) {
  auto cost_function =
      std::make_unique<NumericDiffCostFunction<EasyCostFunction,
                                               CENTRAL,
                                               3,  // number of residuals
                                               5,  // size of x1
                                               5   // size of x2
                                               >>(new EasyCostFunction,
                                                  TAKE_OWNERSHIP);
  EasyFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, CENTRAL);
}

TEST(NumericDiffCostFunction, EasyCaseCostFunctionForwardDifferences) {
  auto cost_function =
      std::make_unique<NumericDiffCostFunction<EasyCostFunction,
                                               FORWARD,
                                               3,  // number of residuals
                                               5,  // size of x1
                                               5   // size of x2
                                               >>(new EasyCostFunction,
                                                  TAKE_OWNERSHIP);
  EasyFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, FORWARD);
}

TEST(NumericDiffCostFunction, EasyCaseCostFunctionRidders) {
  auto cost_function =
      std::make_unique<NumericDiffCostFunction<EasyCostFunction,
                                               RIDDERS,
                                               3,  // number of residuals
                                               5,  // size of x1
                                               5   // size of x2
                                               >>(new EasyCostFunction,
                                                  TAKE_OWNERSHIP);

  EasyFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, RIDDERS);
}

TEST(NumericDiffCostFunction, TranscendentalCaseFunctorCentralDifferences) {
  auto cost_function =
      std::make_unique<NumericDiffCostFunction<TranscendentalFunctor,
                                               CENTRAL,
                                               2,  // number of residuals
                                               5,  // size of x1
                                               5   // size of x2
                                               >>(new TranscendentalFunctor);
  TranscendentalFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, CENTRAL);
}

TEST(NumericDiffCostFunction, TranscendentalCaseFunctorForwardDifferences) {
  auto cost_function =
      std::make_unique<NumericDiffCostFunction<TranscendentalFunctor,
                                               FORWARD,
                                               2,  // number of residuals
                                               5,  // size of x1
                                               5   // size of x2
                                               >>(new TranscendentalFunctor);

  TranscendentalFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, FORWARD);
}

TEST(NumericDiffCostFunction, TranscendentalCaseFunctorRidders) {
  NumericDiffOptions options;

  // Using a smaller initial step size to overcome oscillatory function
  // behavior.
  options.ridders_relative_initial_step_size = 1e-3;
  auto cost_function =
      std::make_unique<NumericDiffCostFunction<TranscendentalFunctor,
                                               RIDDERS,
                                               2,  // number of residuals
                                               5,  // size of x1
                                               5   // size of x2
                                               >>(
          new TranscendentalFunctor, TAKE_OWNERSHIP, 2, options);

  TranscendentalFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, RIDDERS);
}

TEST(NumericDiffCostFunction,
     TranscendentalCaseCostFunctionCentralDifferences) {
  auto cost_function =
      std::make_unique<NumericDiffCostFunction<TranscendentalCostFunction,
                                               CENTRAL,
                                               2,  // number of residuals
                                               5,  // size of x1
                                               5   // size of x2
                                               >>(
          new TranscendentalCostFunction, TAKE_OWNERSHIP);
  TranscendentalFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, CENTRAL);
}

TEST(NumericDiffCostFunction,
     TranscendentalCaseCostFunctionForwardDifferences) {
  auto cost_function =
      std::make_unique<NumericDiffCostFunction<TranscendentalCostFunction,
                                               FORWARD,
                                               2,  // number of residuals
                                               5,  // size of x1
                                               5   // size of x2
                                               >>(
          new TranscendentalCostFunction, TAKE_OWNERSHIP);
  TranscendentalFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, FORWARD);
}

TEST(NumericDiffCostFunction, TranscendentalCaseCostFunctionRidders) {
  NumericDiffOptions options;

  // Using a smaller initial step size to overcome oscillatory function
  // behavior.
  options.ridders_relative_initial_step_size = 1e-3;

  auto cost_function =
      std::make_unique<NumericDiffCostFunction<TranscendentalCostFunction,
                                               RIDDERS,
                                               2,  // number of residuals
                                               5,  // size of x1
                                               5   // size of x2
                                               >>(
          new TranscendentalCostFunction, TAKE_OWNERSHIP, 2, options);
  TranscendentalFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, RIDDERS);
}

template <int num_rows, int num_cols>
class SizeTestingCostFunction : public SizedCostFunction<num_rows, num_cols> {
 public:
  bool Evaluate(double const* const* parameters,
                double* residuals,
                double** jacobians) const final {
    return true;
  }
};

// As described in
// http://forum.kde.org/viewtopic.php?f=74&t=98536#p210774
// Eigen3 has restrictions on the Row/Column major storage of vectors,
// depending on their dimensions. This test ensures that the correct
// templates are instantiated for various shapes of the Jacobian
// matrix.
TEST(NumericDiffCostFunction, EigenRowMajorColMajorTest) {
  std::unique_ptr<CostFunction> cost_function = std::make_unique<
      NumericDiffCostFunction<SizeTestingCostFunction<1, 1>, CENTRAL, 1, 1>>(
      new SizeTestingCostFunction<1, 1>, ceres::TAKE_OWNERSHIP);

  cost_function = std::make_unique<
      NumericDiffCostFunction<SizeTestingCostFunction<2, 1>, CENTRAL, 2, 1>>(
      new SizeTestingCostFunction<2, 1>, ceres::TAKE_OWNERSHIP);

  cost_function = std::make_unique<
      NumericDiffCostFunction<SizeTestingCostFunction<1, 2>, CENTRAL, 1, 2>>(
      new SizeTestingCostFunction<1, 2>, ceres::TAKE_OWNERSHIP);

  cost_function = std::make_unique<
      NumericDiffCostFunction<SizeTestingCostFunction<2, 2>, CENTRAL, 2, 2>>(
      new SizeTestingCostFunction<2, 2>, ceres::TAKE_OWNERSHIP);

  cost_function = std::make_unique<
      NumericDiffCostFunction<EasyFunctor, CENTRAL, ceres::DYNAMIC, 1, 1>>(
      new EasyFunctor, TAKE_OWNERSHIP, 1);

  cost_function = std::make_unique<
      NumericDiffCostFunction<EasyFunctor, CENTRAL, ceres::DYNAMIC, 1, 1>>(
      new EasyFunctor, TAKE_OWNERSHIP, 2);

  cost_function = std::make_unique<
      NumericDiffCostFunction<EasyFunctor, CENTRAL, ceres::DYNAMIC, 1, 2>>(
      new EasyFunctor, TAKE_OWNERSHIP, 1);

  cost_function = std::make_unique<
      NumericDiffCostFunction<EasyFunctor, CENTRAL, ceres::DYNAMIC, 1, 2>>(
      new EasyFunctor, TAKE_OWNERSHIP, 2);

  cost_function = std::make_unique<
      NumericDiffCostFunction<EasyFunctor, CENTRAL, ceres::DYNAMIC, 2, 1>>(
      new EasyFunctor, TAKE_OWNERSHIP, 1);

  cost_function = std::make_unique<
      NumericDiffCostFunction<EasyFunctor, CENTRAL, ceres::DYNAMIC, 2, 1>>(
      new EasyFunctor, TAKE_OWNERSHIP, 2);
}

TEST(NumericDiffCostFunction,
     EasyCaseFunctorCentralDifferencesAndDynamicNumResiduals) {
  auto cost_function =
      std::make_unique<NumericDiffCostFunction<EasyFunctor,
                                               CENTRAL,
                                               ceres::DYNAMIC,
                                               5,  // size of x1
                                               5   // size of x2
                                               >>(
          new EasyFunctor, TAKE_OWNERSHIP, 3);
  EasyFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function, CENTRAL);
}

TEST(NumericDiffCostFunction, ExponentialFunctorRidders) {
  auto cost_function =
      std::make_unique<NumericDiffCostFunction<ExponentialFunctor,
                                               RIDDERS,
                                               1,  // number of residuals
                                               1   // size of x1
                                               >>(new ExponentialFunctor);
  ExponentialFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function);
}

TEST(NumericDiffCostFunction, ExponentialCostFunctionRidders) {
  auto cost_function =
      std::make_unique<NumericDiffCostFunction<ExponentialCostFunction,
                                               RIDDERS,
                                               1,  // number of residuals
                                               1   // size of x1
                                               >>(new ExponentialCostFunction);
  ExponentialFunctor functor;
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function);
}

TEST(NumericDiffCostFunction, RandomizedFunctorRidders) {
  std::mt19937 prng;
  NumericDiffOptions options;
  // Larger initial step size is chosen to produce robust results in the
  // presence of random noise.
  options.ridders_relative_initial_step_size = 10.0;

  auto cost_function =
      std::make_unique<NumericDiffCostFunction<RandomizedFunctor,
                                               RIDDERS,
                                               1,  // number of residuals
                                               1   // size of x1
                                               >>(
          new RandomizedFunctor(kNoiseFactor, prng),
          TAKE_OWNERSHIP,
          1,
          options);
  RandomizedFunctor functor(kNoiseFactor, prng);
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function);
}

TEST(NumericDiffCostFunction, RandomizedCostFunctionRidders) {
  std::mt19937 prng;
  NumericDiffOptions options;
  // Larger initial step size is chosen to produce robust results in the
  // presence of random noise.
  options.ridders_relative_initial_step_size = 10.0;

  auto cost_function =
      std::make_unique<NumericDiffCostFunction<RandomizedCostFunction,
                                               RIDDERS,
                                               1,  // number of residuals
                                               1   // size of x1
                                               >>(
          new RandomizedCostFunction(kNoiseFactor, prng),
          TAKE_OWNERSHIP,
          1,
          options);

  RandomizedFunctor functor(kNoiseFactor, prng);
  functor.ExpectCostFunctionEvaluationIsNearlyCorrect(*cost_function);
}

struct OnlyFillsOneOutputFunctor {
  bool operator()(const double* x, double* output) const {
    output[0] = x[0];
    return true;
  }
};

TEST(NumericDiffCostFunction, PartiallyFilledResidualShouldFailEvaluation) {
  double parameter = 1.0;
  double jacobian[2];
  double residuals[2];
  double* parameters[] = {&parameter};
  double* jacobians[] = {jacobian};

  auto cost_function = std::make_unique<
      NumericDiffCostFunction<OnlyFillsOneOutputFunctor, CENTRAL, 2, 1>>(
      new OnlyFillsOneOutputFunctor);
  InvalidateArray(2, jacobian);
  InvalidateArray(2, residuals);
  EXPECT_TRUE(cost_function->Evaluate(parameters, residuals, jacobians));
  EXPECT_FALSE(IsArrayValid(2, residuals));
  InvalidateArray(2, residuals);
  EXPECT_TRUE(cost_function->Evaluate(parameters, residuals, nullptr));
  // We are only testing residuals here, because the Jacobians are
  // computed using finite differencing from the residuals, so unless
  // we introduce a validation step after every evaluation of
  // residuals inside NumericDiffCostFunction, there is no way of
  // ensuring that the Jacobian array is invalid.
  EXPECT_FALSE(IsArrayValid(2, residuals));
}

TEST(NumericDiffCostFunction, ParameterBlockConstant) {
  constexpr int kNumResiduals = 3;
  constexpr int kX1 = 5;
  constexpr int kX2 = 5;

  auto cost_function = std::make_unique<
      NumericDiffCostFunction<EasyFunctor, CENTRAL, kNumResiduals, kX1, kX2>>(
      new EasyFunctor);

  // Prepare the parameters and residuals.
  std::array<double, kX1> x1{1e-64, 2.0, 3.0, 4.0, 5.0};
  std::array<double, kX2> x2{9.0, 9.0, 5.0, 5.0, 1.0};
  std::array<double*, 2> parameter_blocks{x1.data(), x2.data()};

  std::vector<double> residuals(kNumResiduals, -100000);

  // Evaluate the full jacobian.
  std::vector<std::vector<double>> jacobian_full_vect(2);
  jacobian_full_vect[0].resize(kNumResiduals * kX1, -100000);
  jacobian_full_vect[1].resize(kNumResiduals * kX2, -100000);
  {
    std::array<double*, 2> jacobian{jacobian_full_vect[0].data(),
                                    jacobian_full_vect[1].data()};
    ASSERT_TRUE(cost_function->Evaluate(
        parameter_blocks.data(), residuals.data(), jacobian.data()));
  }

  // Evaluate and check jacobian when first parameter block is constant.
  {
    std::vector<double> jacobian_vect(kNumResiduals * kX2, -100000);
    std::array<double*, 2> jacobian{nullptr, jacobian_vect.data()};

    ASSERT_TRUE(cost_function->Evaluate(
        parameter_blocks.data(), residuals.data(), jacobian.data()));

    for (int i = 0; i < kNumResiduals * kX2; ++i) {
      EXPECT_DOUBLE_EQ(jacobian_full_vect[1][i], jacobian_vect[i]);
    }
  }

  // Evaluate and check jacobian when second parameter block is constant.
  {
    std::vector<double> jacobian_vect(kNumResiduals * kX1, -100000);
    std::array<double*, 2> jacobian{jacobian_vect.data(), nullptr};

    ASSERT_TRUE(cost_function->Evaluate(
        parameter_blocks.data(), residuals.data(), jacobian.data()));

    for (int i = 0; i < kNumResiduals * kX1; ++i) {
      EXPECT_DOUBLE_EQ(jacobian_full_vect[0][i], jacobian_vect[i]);
    }
  }
}

struct MultiArgFunctor {
  explicit MultiArgFunctor(int a, double c) {}
  template <class T>
  bool operator()(const T* params, T* residuals) const noexcept {
    return false;
  }
};

TEST(NumericDiffCostFunction, ArgumentForwarding) {
  auto cost_function1 = std::make_unique<
      NumericDiffCostFunction<EasyFunctor, CENTRAL, 3, 5, 5>>();
  auto cost_function2 =
      std::make_unique<NumericDiffCostFunction<MultiArgFunctor, CENTRAL, 1, 1>>(
          1, 2);
}

TEST(NumericDiffCostFunction, UniquePtrCtor) {
  auto cost_function1 =
      std::make_unique<NumericDiffCostFunction<EasyFunctor, CENTRAL, 3, 5, 5>>(
          std::make_unique<EasyFunctor>());
  auto cost_function2 = std::make_unique<
      NumericDiffCostFunction<EasyFunctor, CENTRAL, 3, 5, 5>>();
}

}  // namespace ceres::internal
