// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>
// Copyright (C) 2012 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>
//
// The algorithm of this class initially comes from MINPACK whose original authors are:
// Copyright Jorge More - Argonne National Laboratory
// Copyright Burt Garbow - Argonne National Laboratory
// Copyright Ken Hillstrom - Argonne National Laboratory
//
// This Source Code Form is subject to the terms of the Minpack license
// (a BSD-like license) described in the campaigned CopyrightMINPACK.txt file.
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// SPDX-License-Identifier: MPL-2.0 AND LicenseRef-MINPACK

#ifndef EIGEN_LEVENBERGMARQUARDT_H
#define EIGEN_LEVENBERGMARQUARDT_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {
namespace LevenbergMarquardtSpace {
enum Status {
  NotStarted = -2,
  Running = -1,
  ImproperInputParameters = 0,
  RelativeReductionTooSmall = 1,
  RelativeErrorTooSmall = 2,
  RelativeErrorAndReductionTooSmall = 3,
  CosinusTooSmall = 4,
  TooManyFunctionEvaluation = 5,
  FtolTooSmall = 6,
  XtolTooSmall = 7,
  GtolTooSmall = 8,
  UserAsked = 9
};
}

template <typename Scalar_, int NX = Dynamic, int NY = Dynamic>
struct DenseFunctor {
  typedef Scalar_ Scalar;
  enum { InputsAtCompileTime = NX, ValuesAtCompileTime = NY };
  typedef Matrix<Scalar, InputsAtCompileTime, 1> InputType;
  typedef Matrix<Scalar, ValuesAtCompileTime, 1> ValueType;
  typedef Matrix<Scalar, ValuesAtCompileTime, InputsAtCompileTime> JacobianType;
  typedef ColPivHouseholderQR<JacobianType> QRSolver;
  const int m_inputs, m_values;

  DenseFunctor() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {}
  DenseFunctor(int inputs, int values) : m_inputs(inputs), m_values(values) {}

  int inputs() const { return m_inputs; }
  int values() const { return m_values; }

  // int operator()(const InputType &x, ValueType& fvec) { }
  //  should be defined in derived classes

  // int df(const InputType &x, JacobianType& fjac) { }
  //  should be defined in derived classes
};

template <typename Scalar_, typename Index_>
struct SparseFunctor {
  typedef Scalar_ Scalar;
  typedef Index_ Index;
  typedef Matrix<Scalar, Dynamic, 1> InputType;
  typedef Matrix<Scalar, Dynamic, 1> ValueType;
  typedef SparseMatrix<Scalar, ColMajor, Index> JacobianType;
  typedef SparseQR<JacobianType, COLAMDOrdering<int> > QRSolver;
  enum { InputsAtCompileTime = Dynamic, ValuesAtCompileTime = Dynamic };

  SparseFunctor(int inputs, int values) : m_inputs(inputs), m_values(values) {}

  int inputs() const { return m_inputs; }
  int values() const { return m_values; }

  const int m_inputs, m_values;
  // int operator()(const InputType &x, ValueType& fvec) { }
  //  to be defined in the functor

  // int df(const InputType &x, JacobianType& fjac) { }
  //  to be defined in the functor if no automatic differentiation
};
namespace internal {
template <typename QRSolver, typename VectorType>
void lmpar2(const QRSolver &qr, const VectorType &diag, const VectorType &qtb, typename VectorType::Scalar m_delta,
            typename VectorType::Scalar &par, VectorType &x);
}
/**
 * \ingroup NonLinearOptimization_Module
 * \brief Performs non linear optimization over a non-linear function,
 * using a variant of the Levenberg Marquardt algorithm.
 *
 * Check wikipedia for more information.
 * http://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm
 */
template <typename FunctorType_>
class LevenbergMarquardt : internal::no_assignment_operator {
 public:
  typedef FunctorType_ FunctorType;
  typedef typename FunctorType::QRSolver QRSolver;
  typedef typename FunctorType::JacobianType JacobianType;
  typedef typename JacobianType::Scalar Scalar;
  typedef typename JacobianType::RealScalar RealScalar;
  typedef typename QRSolver::StorageIndex PermIndex;
  typedef Matrix<Scalar, Dynamic, 1> FVectorType;
  typedef PermutationMatrix<Dynamic, Dynamic, int> PermutationType;

 public:
  LevenbergMarquardt(FunctorType &functor)
      : m_functor(functor),
        m_nfev(0),
        m_njev(0),
        m_fnorm(0.0),
        m_gnorm(0),
        m_isInitialized(false),
        m_info(InvalidInput) {
    resetParameters();
    m_useExternalScaling = false;
  }

  LevenbergMarquardtSpace::Status minimize(FVectorType &x);
  LevenbergMarquardtSpace::Status minimizeInit(FVectorType &x);
  LevenbergMarquardtSpace::Status minimizeOneStep(FVectorType &x);
  LevenbergMarquardtSpace::Status lmder1(FVectorType &x, const Scalar tol = std::sqrt(NumTraits<Scalar>::epsilon()));
  static LevenbergMarquardtSpace::Status lmdif1(FunctorType &functor, FVectorType &x, Index *nfev,
                                                const Scalar tol = std::sqrt(NumTraits<Scalar>::epsilon()));

  /** Sets the default parameters */
  void resetParameters() {
    using std::sqrt;

    m_factor = 100.;
    m_maxfev = 400;
    m_ftol = sqrt(NumTraits<RealScalar>::epsilon());
    m_xtol = sqrt(NumTraits<RealScalar>::epsilon());
    m_gtol = 0.;
    m_epsfcn = 0.;
  }

  /** Sets the tolerance for the norm of the solution vector*/
  void setXtol(RealScalar xtol) { m_xtol = xtol; }

  /** Sets the tolerance for the norm of the vector function*/
  void setFtol(RealScalar ftol) { m_ftol = ftol; }

  /** Sets the tolerance for the norm of the gradient of the error vector*/
  void setGtol(RealScalar gtol) { m_gtol = gtol; }

  /** Sets the step bound for the diagonal shift */
  void setFactor(RealScalar factor) { m_factor = factor; }

  /** Sets the error precision  */
  void setEpsilon(RealScalar epsfcn) { m_epsfcn = epsfcn; }

  /** Sets the maximum number of function evaluation */
  void setMaxfev(Index maxfev) { m_maxfev = maxfev; }

  /** Use an external Scaling. If set to true, pass a nonzero diagonal to diag() */
  void setExternalScaling(bool value) { m_useExternalScaling = value; }

  /** \returns the tolerance for the norm of the solution vector */
  RealScalar xtol() const { return m_xtol; }

  /** \returns the tolerance for the norm of the vector function */
  RealScalar ftol() const { return m_ftol; }

  /** \returns the tolerance for the norm of the gradient of the error vector */
  RealScalar gtol() const { return m_gtol; }

  /** \returns the step bound for the diagonal shift */
  RealScalar factor() const { return m_factor; }

  /** \returns the error precision */
  RealScalar epsilon() const { return m_epsfcn; }

  /** \returns the maximum number of function evaluation */
  Index maxfev() const { return m_maxfev; }

  /** \returns a reference to the diagonal of the jacobian */
  FVectorType &diag() { return m_diag; }

  /** \returns the number of iterations performed */
  Index iterations() const { return m_iter; }

  /** \returns the number of functions evaluation */
  Index nfev() const { return m_nfev; }

  /** \returns the number of jacobian evaluation */
  Index njev() const { return m_njev; }

  /** \returns the norm of current vector function */
  RealScalar fnorm() const { return m_fnorm; }

  /** \returns the norm of the gradient of the error */
  RealScalar gnorm() const { return m_gnorm; }

  /** \returns the LevenbergMarquardt parameter */
  RealScalar lm_param(void) const { return m_par; }

  /** \returns a reference to the  current vector function
   */
  FVectorType &fvec() { return m_fvec; }

  /** \returns a reference to the matrix where the current Jacobian matrix is stored
   */
  JacobianType &jacobian() { return m_fjac; }

  /** \returns a reference to the triangular matrix R from the QR of the jacobian matrix.
   * \sa jacobian()
   */
  JacobianType &matrixR() { return m_rfactor; }

  /** the permutation used in the QR factorization
   */
  PermutationType permutation() const { return m_permutation; }

  /**
   * \brief Reports whether the minimization was successful
   * \returns \c Success if the minimization was successful,
   *         \c NumericalIssue if a numerical problem arises during the
   *          minimization process, for example during the QR factorization
   *         \c NoConvergence if the minimization did not converge after
   *          the maximum number of function evaluation allowed
   *          \c InvalidInput if the input matrix is invalid
   */
  ComputationInfo info() const { return m_info; }

 private:
  JacobianType m_fjac;
  JacobianType m_rfactor;  // The triangular matrix R from the QR of the jacobian matrix m_fjac
  FunctorType &m_functor;
  FVectorType m_fvec, m_qtf, m_diag;
  Index n;
  Index m;
  Index m_nfev;
  Index m_njev;
  RealScalar m_fnorm;   // Norm of the current vector function
  RealScalar m_gnorm;   // Norm of the gradient of the error
  RealScalar m_factor;  //
  Index m_maxfev;       // Maximum number of function evaluation
  RealScalar m_ftol;    // Tolerance in the norm of the vector function
  RealScalar m_xtol;    //
  RealScalar m_gtol;    // tolerance of the norm of the error gradient
  RealScalar m_epsfcn;  //
  Index m_iter;         // Number of iterations performed
  RealScalar m_delta;
  bool m_useExternalScaling;
  PermutationType m_permutation;
  FVectorType m_wa1, m_wa2, m_wa3, m_wa4;  // Temporary vectors
  RealScalar m_par;
  bool m_isInitialized;  // Check whether the minimization step has been called
  ComputationInfo m_info;
};

template <typename FunctorType>
LevenbergMarquardtSpace::Status LevenbergMarquardt<FunctorType>::minimize(FVectorType &x) {
  LevenbergMarquardtSpace::Status status = minimizeInit(x);
  if (status == LevenbergMarquardtSpace::ImproperInputParameters) {
    m_isInitialized = true;
    return status;
  }
  do {
    status = minimizeOneStep(x);
  } while (status == LevenbergMarquardtSpace::Running);
  m_isInitialized = true;
  return status;
}

template <typename FunctorType>
LevenbergMarquardtSpace::Status LevenbergMarquardt<FunctorType>::minimizeInit(FVectorType &x) {
  n = x.size();
  m = m_functor.values();

  m_wa1.resize(n);
  m_wa2.resize(n);
  m_wa3.resize(n);
  m_wa4.resize(m);
  m_fvec.resize(m);
  // FIXME: Sparse case: allocate space for the Jacobian.
  m_fjac.resize(m, n);
  if (!m_useExternalScaling) m_diag.resize(n);
  eigen_assert((!m_useExternalScaling || m_diag.size() == n) &&
               "When m_useExternalScaling is set, the caller must provide a valid 'm_diag'");
  m_qtf.resize(n);

  /* Function Body */
  m_nfev = 0;
  m_njev = 0;

  /*     check the input parameters for errors. */
  if (n <= 0 || m < n || m_ftol < 0. || m_xtol < 0. || m_gtol < 0. || m_maxfev <= 0 || m_factor <= 0.) {
    m_info = InvalidInput;
    return LevenbergMarquardtSpace::ImproperInputParameters;
  }

  if (m_useExternalScaling)
    for (Index j = 0; j < n; ++j)
      if (m_diag[j] <= 0.) {
        m_info = InvalidInput;
        return LevenbergMarquardtSpace::ImproperInputParameters;
      }

  /*     evaluate the function at the starting point */
  /*     and calculate its norm. */
  m_nfev = 1;
  if (m_functor(x, m_fvec) < 0) return LevenbergMarquardtSpace::UserAsked;
  m_fnorm = m_fvec.stableNorm();

  /*     initialize levenberg-marquardt parameter and iteration counter. */
  m_par = 0.;
  m_iter = 1;

  return LevenbergMarquardtSpace::NotStarted;
}

template <typename FunctorType>
LevenbergMarquardtSpace::Status LevenbergMarquardt<FunctorType>::lmder1(FVectorType &x, const Scalar tol) {
  n = x.size();
  m = m_functor.values();

  /* check the input parameters for errors. */
  if (n <= 0 || m < n || tol < 0.) return LevenbergMarquardtSpace::ImproperInputParameters;

  resetParameters();
  m_ftol = tol;
  m_xtol = tol;
  m_maxfev = 100 * (n + 1);

  return minimize(x);
}

template <typename FunctorType>
LevenbergMarquardtSpace::Status LevenbergMarquardt<FunctorType>::lmdif1(FunctorType &functor, FVectorType &x,
                                                                        Index *nfev, const Scalar tol) {
  Index n = x.size();
  Index m = functor.values();

  /* check the input parameters for errors. */
  if (n <= 0 || m < n || tol < 0.) return LevenbergMarquardtSpace::ImproperInputParameters;

  NumericalDiff<FunctorType> numDiff(functor);
  // embedded LevenbergMarquardt
  LevenbergMarquardt<NumericalDiff<FunctorType> > lm(numDiff);
  lm.setFtol(tol);
  lm.setXtol(tol);
  lm.setMaxfev(200 * (n + 1));

  LevenbergMarquardtSpace::Status info = LevenbergMarquardtSpace::Status(lm.minimize(x));
  if (nfev) *nfev = lm.nfev();
  return info;
}

}  // end namespace Eigen

#endif  // EIGEN_LEVENBERGMARQUARDT_H
