 
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2012  Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.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/>.

#ifndef EIGEN_ORDERING_H
#define EIGEN_ORDERING_H

#include "Amd.h"
namespace Eigen {
  
#include "Eigen_Colamd.h"

namespace internal {
    
    /**
    * Get the symmetric pattern A^T+A from the input matrix A. 
    * FIXME: The values should not be considered here
    */
    template<typename MatrixType> 
    void ordering_helper_at_plus_a(const MatrixType& mat, MatrixType& symmat)
    {
      MatrixType C;
      C = mat.transpose(); // NOTE: Could be  costly
      for (int i = 0; i < C.rows(); i++) 
      {
          for (typename MatrixType::InnerIterator it(C, i); it; ++it)
            it.valueRef() = 0.0;
      }
      symmat = C + mat; 
    }
    
}

/** 
 * Get the approximate minimum degree ordering
 * If the matrix is not structurally symmetric, an ordering of A^T+A is computed
 * \tparam  Index The type of indices of the matrix 
 */
template <typename Index>
class AMDOrdering
{
  public:
    typedef PermutationMatrix<Dynamic, Dynamic, Index> PermutationType;
    
    /** Compute the permutation vector from a sparse matrix
     * This routine is much faster if the input matrix is column-major     
     */
    template <typename MatrixType>
    void operator()(const MatrixType& mat, PermutationType& perm)
    {
      // Compute the symmetric pattern
      SparseMatrix<typename MatrixType::Scalar, ColMajor, Index> symm;
      internal::ordering_helper_at_plus_a(mat,symm); 
    
      // Call the AMD routine 
      //m_mat.prune(keep_diag());
      internal::minimum_degree_ordering(symm, perm);
    }
    
    /** Compute the permutation with a selfadjoint matrix */
    template <typename SrcType, unsigned int SrcUpLo> 
    void operator()(const SparseSelfAdjointView<SrcType, SrcUpLo>& mat, PermutationType& perm)
    { 
      SparseMatrix<typename SrcType::Scalar, ColMajor, Index> C = mat;
      
      // Call the AMD routine 
      // m_mat.prune(keep_diag()); //Remove the diagonal elements 
      internal::minimum_degree_ordering(C, perm);
    }
};

/** 
 * Get the natural ordering
 * 
 *NOTE Returns an empty permutation matrix
 * \tparam  Index The type of indices of the matrix 
 */
template <typename Index>
class NaturalOrdering
{
  public:
    typedef PermutationMatrix<Dynamic, Dynamic, Index> PermutationType;
    
    /** Compute the permutation vector from a column-major sparse matrix */
    template <typename MatrixType>
    void operator()(const MatrixType& mat, PermutationType& perm)
    {
      perm.resize(0); 
    }
    
};

/** 
 * Get the column approximate minimum degree ordering 
 * The matrix should be in column-major format
 */
template<typename Index>
class COLAMDOrdering; 
#include "Eigen_Colamd.h"

template<typename Index>
class COLAMDOrdering
{
  public:
    typedef PermutationMatrix<Dynamic, Dynamic, Index> PermutationType; 
    typedef Matrix<Index, Dynamic, 1> IndexVector; 
    /** Compute the permutation vector form a sparse matrix */
    template <typename MatrixType>
    void operator() (const MatrixType& mat, PermutationType& perm)
    {
        int m = mat.rows();
        int n = mat.cols();
        int nnz = mat.nonZeros();
        // Get the recommended value of Alen to be used by colamd
        int Alen = internal::colamd_recommended(nnz, m, n); 
        // Set the default parameters
        double knobs [COLAMD_KNOBS]; 
        int stats [COLAMD_STATS];
        internal::colamd_set_defaults(knobs);
        
        int info;
        IndexVector p(n+1), A(Alen); 
        for(int i=0; i <= n; i++) p(i) = mat.outerIndexPtr()[i];
        for(int i=0; i < nnz; i++) A(i) = mat.innerIndexPtr()[i];
        // Call Colamd routine to compute the ordering 
        info = internal::colamd(m, n, Alen, A.data(), p.data(), knobs, stats); 
        eigen_assert( info && "COLAMD failed " );
        
        perm.resize(n);
        for (int i = 0; i < n; i++) perm.indices()(p(i)) = i;
        
    }
 
};

} // end namespace Eigen
#endif