// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

/*

NOTE: the _symbolic, and _numeric functions has been adapted from
      the LDL library:

LDL Copyright (c) 2005 by Timothy A. Davis.  All Rights Reserved.

LDL License:

    Your use or distribution of LDL or any modified version of
    LDL implies that you agree to this License.

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
    USA

    Permission is hereby granted to use or copy this program under the
    terms of the GNU LGPL, provided that the Copyright, this License,
    and the Availability of the original version is retained on all copies.
    User documentation of any code that uses this code or any modified
    version of this code must cite the Copyright, this License, the
    Availability note, and "Used by permission." Permission to modify
    the code and to distribute modified code is granted, provided the
    Copyright, this License, and the Availability note are retained,
    and a notice that the code was modified is included.
 */

#ifndef EIGEN_SPARSELDLT_H
#define EIGEN_SPARSELDLT_H

/** \ingroup Sparse_Module
  *
  * \class SparseLDLT
  *
  * \brief LDLT Cholesky decomposition of a sparse matrix and associated features
  *
  * \param MatrixType the type of the matrix of which we are computing the LDLT Cholesky decomposition
  *
  * \sa class LDLT, class LDLT
  */
template<typename MatrixType, int Backend = DefaultBackend>
class SparseLDLT
{
  protected:
    typedef typename MatrixType::Scalar Scalar;
    typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
    typedef SparseMatrix<Scalar> CholMatrixType;
    typedef Matrix<Scalar,MatrixType::ColsAtCompileTime,1> VectorType;

    enum {
      SupernodalFactorIsDirty      = 0x10000,
      MatrixLIsDirty               = 0x20000
    };

  public:

    /** Creates a dummy LDLT factorization object with flags \a flags. */
    SparseLDLT(int flags = 0)
      : m_flags(flags), m_status(0)
    {
      ei_assert((MatrixType::Flags&RowMajorBit)==0);
      m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
    }

    /** Creates a LDLT object and compute the respective factorization of \a matrix using
      * flags \a flags. */
    SparseLDLT(const MatrixType& matrix, int flags = 0)
      : m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0)
    {
      ei_assert((MatrixType::Flags&RowMajorBit)==0);
      m_precision = RealScalar(0.1) * Eigen::precision<RealScalar>();
      compute(matrix);
    }

    /** Sets the relative threshold value used to prune zero coefficients during the decomposition.
      *
      * Setting a value greater than zero speeds up computation, and yields to an imcomplete
      * factorization with fewer non zero coefficients. Such approximate factors are especially
      * useful to initialize an iterative solver.
      *
      * \warning if precision is greater that zero, the LDLT factorization is not guaranteed to succeed
      * even if the matrix is positive definite.
      *
      * Note that the exact meaning of this parameter might depends on the actual
      * backend. Moreover, not all backends support this feature.
      *
      * \sa precision() */
    void setPrecision(RealScalar v) { m_precision = v; }

    /** \returns the current precision.
      *
      * \sa setPrecision() */
    RealScalar precision() const { return m_precision; }

    /** Sets the flags. Possible values are:
      *  - CompleteFactorization
      *  - IncompleteFactorization
      *  - MemoryEfficient          (hint to use the memory most efficient method offered by the backend)
      *  - SupernodalMultifrontal   (implies a complete factorization if supported by the backend,
      *                              overloads the MemoryEfficient flags)
      *  - SupernodalLeftLooking    (implies a complete factorization  if supported by the backend,
      *                              overloads the MemoryEfficient flags)
      *
      * \sa flags() */
    void settags(int f) { m_flags = f; }
    /** \returns the current flags */
    int flags() const { return m_flags; }

    /** Computes/re-computes the LDLT factorization */
    void compute(const MatrixType& matrix);

    /** Perform a symbolic factorization */
    void _symbolic(const MatrixType& matrix);
    /** Perform the actual factorization using the previously
      * computed symbolic factorization */
    bool _numeric(const MatrixType& matrix);

    /** \returns the lower triangular matrix L */
    inline const CholMatrixType& matrixL(void) const { return m_matrix; }

    /** \returns the coefficients of the diagonal matrix D */
    inline VectorType vectorD(void) const { return m_diag; }

    template<typename Derived>
    bool solveInPlace(MatrixBase<Derived> &b) const;

    /** \returns true if the factorization succeeded */
    inline bool succeeded(void) const { return m_succeeded; }

  protected:
    CholMatrixType m_matrix;
    VectorType m_diag;
    VectorXi m_parent; // elimination tree
    VectorXi m_nonZerosPerCol;
//     VectorXi m_w; // workspace
    RealScalar m_precision;
    int m_flags;
    mutable int m_status;
    bool m_succeeded;
};

/** Computes / recomputes the LDLT decomposition of matrix \a a
  * using the default algorithm.
  */
template<typename MatrixType, int Backend>
void SparseLDLT<MatrixType,Backend>::compute(const MatrixType& a)
{
  _symbolic(a);
  m_succeeded = _numeric(a);
}

template<typename MatrixType, int Backend>
void SparseLDLT<MatrixType,Backend>::_symbolic(const MatrixType& a)
{
  assert(a.rows()==a.cols());
  const int size = a.rows();
  m_matrix.resize(size, size);
  m_parent.resize(size);
  m_nonZerosPerCol.resize(size);
  int * tags = ei_aligned_stack_new(int, size);

  const int* Ap = a._outerIndexPtr();
  const int* Ai = a._innerIndexPtr();
  int* Lp = m_matrix._outerIndexPtr();
  const int* P = 0;
  int* Pinv = 0;

  if (P)
  {
    /* If P is present then compute Pinv, the inverse of P */
    for (int k = 0; k < size; ++k)
      Pinv[P[k]] = k;
  }
  for (int k = 0; k < size; ++k)
  {
    /* L(k,:) pattern: all nodes reachable in etree from nz in A(0:k-1,k) */
    m_parent[k] = -1;             /* parent of k is not yet known */
    tags[k] = k;                  /* mark node k as visited */
    m_nonZerosPerCol[k] = 0;      /* count of nonzeros in column k of L */
    int kk = P ? P[k] : k;  /* kth original, or permuted, column */
    int p2 = Ap[kk+1];
    for (int p = Ap[kk]; p < p2; ++p)
    {
      /* A (i,k) is nonzero (original or permuted A) */
      int i = Pinv ? Pinv[Ai[p]] : Ai[p];
      if (i < k)
      {
        /* follow path from i to root of etree, stop at flagged node */
        for (; tags[i] != k; i = m_parent[i])
        {
          /* find parent of i if not yet determined */
          if (m_parent[i] == -1)
            m_parent[i] = k;
          ++m_nonZerosPerCol[i];        /* L (k,i) is nonzero */
          tags[i] = k;                  /* mark i as visited */
        }
      }
    }
  }
  /* construct Lp index array from m_nonZerosPerCol column counts */
  Lp[0] = 0;
  for (int k = 0; k < size; ++k)
    Lp[k+1] = Lp[k] + m_nonZerosPerCol[k];

  m_matrix.resizeNonZeros(Lp[size]);
  ei_aligned_stack_delete(int, tags, size);
}

template<typename MatrixType, int Backend>
bool SparseLDLT<MatrixType,Backend>::_numeric(const MatrixType& a)
{
  assert(a.rows()==a.cols());
  const int size = a.rows();
  assert(m_parent.size()==size);
  assert(m_nonZerosPerCol.size()==size);

  const int* Ap = a._outerIndexPtr();
  const int* Ai = a._innerIndexPtr();
  const Scalar* Ax = a._valuePtr();
  const int* Lp = m_matrix._outerIndexPtr();
  int* Li = m_matrix._innerIndexPtr();
  Scalar* Lx = m_matrix._valuePtr();
  m_diag.resize(size);

  Scalar * y = ei_aligned_stack_new(Scalar, size);
  int * pattern = ei_aligned_stack_new(int, size);
  int * tags = ei_aligned_stack_new(int, size);

  const int* P = 0;
  const int* Pinv = 0;
  bool ok = true;

  for (int k = 0; k < size; ++k)
  {
    /* compute nonzero pattern of kth row of L, in topological order */
    y[k] = 0.0;                   /* Y(0:k) is now all zero */
    int top = size;               /* stack for pattern is empty */
    tags[k] = k;                  /* mark node k as visited */
    m_nonZerosPerCol[k] = 0;      /* count of nonzeros in column k of L */
    int kk = (P) ? (P[k]) : (k);  /* kth original, or permuted, column */
    int p2 = Ap[kk+1];
    for (int p = Ap[kk]; p < p2; ++p)
    {
      int i = Pinv ? Pinv[Ai[p]] : Ai[p]; /* get A(i,k) */
      if (i <= k)
      {
        y[i] += Ax[p];            /* scatter A(i,k) into Y (sum duplicates) */
        int len;
        for (len = 0; tags[i] != k; i = m_parent[i])
        {
          pattern[len++] = i;     /* L(k,i) is nonzero */
          tags[i] = k;            /* mark i as visited */
        }
        while (len > 0)
          pattern[--top] = pattern[--len];
      }
    }
    /* compute numerical values kth row of L (a sparse triangular solve) */
    m_diag[k] = y[k];                       /* get D(k,k) and clear Y(k) */
    y[k] = 0.0;
    for (; top < size; ++top)
    {
      int i = pattern[top];      /* pattern[top:n-1] is pattern of L(:,k) */
      Scalar yi = y[i];          /* get and clear Y(i) */
      y[i] = 0.0;
      int p2 = Lp[i] + m_nonZerosPerCol[i];
      int p;
      for (p = Lp[i]; p < p2; ++p)
        y[Li[p]] -= Lx[p] * yi;
      Scalar l_ki = yi / m_diag[i];       /* the nonzero entry L(k,i) */
      m_diag[k] -= l_ki * yi;
      Li[p] = k;                          /* store L(k,i) in column form of L */
      Lx[p] = l_ki;
      ++m_nonZerosPerCol[i];              /* increment count of nonzeros in col i */
    }
    if (m_diag[k] == 0.0)
    {
      ok = false;                         /* failure, D(k,k) is zero */
      break;
    }
  }

  ei_aligned_stack_delete(Scalar, y, size);
  ei_aligned_stack_delete(int, pattern, size);
  ei_aligned_stack_delete(int, tags, size);

  return ok;  /* success, diagonal of D is all nonzero */
}

/** Computes b = L^-T L^-1 b */
template<typename MatrixType, int Backend>
template<typename Derived>
bool SparseLDLT<MatrixType, Backend>::solveInPlace(MatrixBase<Derived> &b) const
{
  const int size = m_matrix.rows();
  ei_assert(size==b.rows());
  if (!m_succeeded)
    return false;

  if (m_matrix.nonZeros()>0) // otherwise L==I
    m_matrix.template triangular<LowerTriangular|UnitDiagBit>().solveInPlace(b);
  b = b.cwise() / m_diag;
  // FIXME should be .adjoint() but it fails to compile...

  if (m_matrix.nonZeros()>0) // otherwise L==I
    m_matrix.transpose().template triangular<UpperTriangular|UnitDiagBit>().solveInPlace(b);

  return true;
}

#endif // EIGEN_SPARSELDLT_H
