// 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_NUMERIC_DIFF_FIRST_ORDER_FUNCTION_H_
#define CERES_PUBLIC_NUMERIC_DIFF_FIRST_ORDER_FUNCTION_H_

#include <algorithm>
#include <memory>
#include <type_traits>
#include <utility>

#include "absl/container/fixed_array.h"
#include "absl/log/check.h"
#include "ceres/first_order_function.h"
#include "ceres/internal/eigen.h"
#include "ceres/internal/numeric_diff.h"
#include "ceres/internal/parameter_dims.h"
#include "ceres/internal/variadic_evaluate.h"
#include "ceres/numeric_diff_options.h"
#include "ceres/types.h"

namespace ceres {

// Creates FirstOrderFunctions as needed by the GradientProblem
// framework, with gradients computed via numeric differentiation. For
// more information on numeric differentiation, see the Wikipedia
// article at https://en.wikipedia.org/wiki/Numerical_differentiation
//
// To get a numerically differentiated cost function, you must define
// a class with an operator() (a functor) that computes the cost.
//
// The function must write the computed value in the last argument
// (the only non-const one) and return true to indicate success.
//
// For example, consider a scalar error e = x'y - a, where both x and y are
// two-dimensional column vector parameters, the prime sign indicates
// transposition, and a is a constant.
//
// To write a numerically-differentiable cost function for the above model,
// first define the object
//
//  class QuadraticCostFunctor {
//   public:
//    explicit QuadraticCostFunctor(double a) : a_(a) {}
//    bool operator()(const double* const xy, double* cost) const {
//      constexpr int kInputVectorLength = 2;
//      const double* const x = xy;
//      const double* const y = xy + kInputVectorLength;
//      *cost = x[0] * y[0] + x[1] * y[1] - a_;
//      return true;
//    }
//
//   private:
//    double a_;
//  };
//
//
// Note that in the declaration of operator() the input parameters xy
// come first, and are passed as const pointers to array of
// doubles. The output cost is the last parameter.
//
// Then given this class definition, the numerically differentiated
// first order function with central differences used for computing the
// derivative can be constructed as follows.
//
//   std::unique_ptr<FirstOrderFunction> function
//       = std::make_unique<
//           NumericDiffFirstOrderFunction<QuadraticCostFunctor, CENTRAL, 4>>(
//               std::make_unique<QuadraticCostFunctor>(1.0));     ^     ^
//                                                                 |     |
//                                 Finite Differencing Scheme -----+     |
//                                 Dimension of xy ----------------------+
//
//
// In the instantiation above, the template parameters following
// "QuadraticCostFunctor", "CENTRAL, 4", describe the finite
// differencing scheme as "central differencing" and the functor as
// computing its cost from a 4 dimensional input.
//
// If the size of the parameter vector is not known at compile time, then an
// alternate construction syntax can be used:
//
//   std::unique_ptr<FirstOrderFunction> function
//       = std::make_unique<NumericDiffFirstOrderFunction<QuadraticCostFunctor,
//                                                        CENTRAL>>(
//           std::make_unique<QuadraticCostFunctor>(1.0), 4);
//
// Note that instead of passing 4 as a template argument, it is now passed as
// the second argument to the constructor.
template <typename FirstOrderFunctor,
          NumericDiffMethodType kMethod,
          int kNumParameters = DYNAMIC>
class NumericDiffFirstOrderFunction final : public FirstOrderFunction {
 public:
  NumericDiffFirstOrderFunction(const NumericDiffFirstOrderFunction&) = delete;
  NumericDiffFirstOrderFunction& operator=(
      const NumericDiffFirstOrderFunction&) = delete;
  NumericDiffFirstOrderFunction(
      NumericDiffFirstOrderFunction&& other) noexcept = default;
  NumericDiffFirstOrderFunction& operator=(
      NumericDiffFirstOrderFunction&& other) noexcept = default;

  // Constructor for the case where the parameter size is known at compile time.
  explicit NumericDiffFirstOrderFunction(
      std::unique_ptr<FirstOrderFunctor> functor,
      const NumericDiffOptions& options = NumericDiffOptions())
      : NumericDiffFirstOrderFunction(
            std::move(functor), TAKE_OWNERSHIP, kNumParameters, options) {
    static_assert(kNumParameters != DYNAMIC,
                  "When kNumParameters is DYNAMIC, the number of parameters "
                  "must be provided as a constructor argument.");
  }

  template <class... Args,
            typename = std::enable_if_t<
                (kNumParameters != DYNAMIC) &&
                std::is_constructible_v<FirstOrderFunctor, Args&&...>>>
  explicit NumericDiffFirstOrderFunction(Args&&... args)
      : NumericDiffFirstOrderFunction(
            std::make_unique<FirstOrderFunctor>(std::forward<Args>(args)...)) {}

  explicit NumericDiffFirstOrderFunction(FirstOrderFunctor* functor,
                                         Ownership ownership = TAKE_OWNERSHIP)
      : NumericDiffFirstOrderFunction(
            std::unique_ptr<FirstOrderFunctor>(functor),
            kNumParameters,
            ownership) {
    static_assert(kNumParameters != DYNAMIC,
                  "When kNumParameters is DYNAMIC, the number of parameters "
                  "must be provided as a constructor argument.");
  }

  // Constructor for the case where the parameter size is specified at run time.
  explicit NumericDiffFirstOrderFunction(
      std::unique_ptr<FirstOrderFunctor> functor,
      int num_parameters,
      Ownership ownership = TAKE_OWNERSHIP,
      const NumericDiffOptions& options = NumericDiffOptions())
      : NumericDiffFirstOrderFunction(
            std::move(functor), ownership, num_parameters, options) {
    if constexpr (kNumParameters != DYNAMIC) {
      DCHECK_EQ(num_parameters, kNumParameters);
    }
  }

  ~NumericDiffFirstOrderFunction() override {
    if (ownership_ == DO_NOT_TAKE_OWNERSHIP) {
      functor_.release();
    }
  }

  bool Evaluate(const double* const parameters,
                double* cost,
                double* gradient) const override {
    // Get the function value (cost) at the point to evaluate.
    if (!(*functor_)(parameters, cost)) {
      return false;
    }

    if (gradient == nullptr) {
      return true;
    }

    // Create a copy of the parameters which will get mutated.
    absl::FixedArray<double> parameters_copy(num_parameters_);
    std::copy_n(parameters, num_parameters_, parameters_copy.data());
    double* parameters_ptr = parameters_copy.data();
    constexpr int kNumResiduals = 1;
    if constexpr (kNumParameters == DYNAMIC) {
      internal::FirstOrderFunctorAdapter<FirstOrderFunctor> fofa(*functor_);
      return internal::NumericDiff<
          internal::FirstOrderFunctorAdapter<FirstOrderFunctor>,
          kMethod,
          kNumResiduals,
          internal::DynamicParameterDims,
          0,
          DYNAMIC>::EvaluateJacobianForParameterBlock(&fofa,
                                                      cost,
                                                      options_,
                                                      kNumResiduals,
                                                      0,
                                                      num_parameters_,
                                                      &parameters_ptr,
                                                      gradient);
    } else {
      using ParameterDims = internal::StaticParameterDims<kNumParameters>;
      return internal::EvaluateJacobianForParameterBlocks<kMethod,
                                                          kNumResiduals,
                                                          ParameterDims>(
          functor_.get(),
          cost,
          options_,
          kNumResiduals,
          &parameters_ptr,
          &gradient);
    }
  }

  int NumParameters() const override { return num_parameters_; }

  const FirstOrderFunctor& functor() const { return *functor_; }

 private:
  explicit NumericDiffFirstOrderFunction(
      std::unique_ptr<FirstOrderFunctor> functor,
      Ownership ownership,
      int num_parameters,
      const NumericDiffOptions& options)
      : functor_(std::move(functor)),
        num_parameters_(num_parameters),
        ownership_(ownership),
        options_(options) {
    if constexpr (kNumParameters == DYNAMIC) {
      DCHECK_GT(num_parameters, 0);
    } else {
      DCHECK_EQ(num_parameters, kNumParameters);
    }
  }

  std::unique_ptr<FirstOrderFunctor> functor_;
  int num_parameters_;
  Ownership ownership_;
  NumericDiffOptions options_;
};

}  // namespace ceres

#endif  // CERES_PUBLIC_NUMERIC_DIFF_FIRST_ORDER_FUNCTION_H_
