// 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>
//
// 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/.
#ifndef METIS_SUPPORT_H
#define METIS_SUPPORT_H

namespace Eigen {
/**
 * Get the fill-reducing ordering from the METIS package
 * 
 * If A is the original matrix and Ap is the permuted matrix, 
 * the fill-reducing permutation is defined as follows :
 * Row (column) i of A is the matperm(i) row (column) of Ap. 
 * WARNING: As computed by METIS, this corresponds to the vector iperm (instead of perm)
 */
template <typename Index>
class MetisOrdering
{
public:
  typedef PermutationMatrix<Dynamic,Dynamic,Index> PermutationType;
  typedef Matrix<Index,Dynamic,1> IndexVector; 
  
  template <typename MatrixType>
  void get_symmetrized_graph(const MatrixType& A)
  {
    Index m = A.cols(); 
    
    // Get the transpose of the input matrix 
    MatrixType At = A.transpose(); 
    // Get the number of nonzeros elements in each row/col of At+A
    Index TotNz = 0; 
    IndexVector visited(m); 
    visited.setConstant(-1); 
    for (int j = 0; j < m; j++)
    {
      // Compute the union structure of of A(j,:) and At(j,:)
      visited(j) = j; // Do not include the diagonal element
      // Get the nonzeros in row/column j of A
      for (typename MatrixType::InnerIterator it(A, j); it; ++it)
      {
        Index idx = it.index(); // Get the row index (for column major) or column index (for row major)
        if (visited(idx) != j ) 
        {
          visited(idx) = j; 
          ++TotNz; 
        }
      }
      //Get the nonzeros in row/column j of At
      for (typename MatrixType::InnerIterator it(At, j); it; ++it)
      {
        Index idx = it.index(); 
        if(visited(idx) != j)
        {
          visited(idx) = j; 
          ++TotNz; 
        }
      }
    }
    // Reserve place for A + At
    m_indexPtr.resize(m+1);
    m_innerIndices.resize(TotNz); 

    // Now compute the real adjacency list of each column/row 
    visited.setConstant(-1); 
    Index CurNz = 0; 
    for (int j = 0; j < m; j++)
    {
      m_indexPtr(j) = CurNz; 
      
      visited(j) = j; // Do not include the diagonal element
      // Add the pattern of row/column j of A to A+At
      for (typename MatrixType::InnerIterator it(A,j); it; ++it)
      {
        Index idx = it.index(); // Get the row index (for column major) or column index (for row major)
        if (visited(idx) != j ) 
        {
          visited(idx) = j; 
          m_innerIndices(CurNz) = idx; 
          CurNz++; 
        }
      }
      //Add the pattern of row/column j of At to A+At
      for (typename MatrixType::InnerIterator it(At, j); it; ++it)
      {
        Index idx = it.index(); 
        if(visited(idx) != j)
        {
          visited(idx) = j; 
          m_innerIndices(CurNz) = idx; 
          ++CurNz; 
        }
      }
    }
    m_indexPtr(m) = CurNz;    
  }
  
  template <typename MatrixType>
  void operator() (const MatrixType& A, PermutationType& matperm)
  {
     Index m = A.cols();
     IndexVector perm(m),iperm(m); 
    // First, symmetrize the matrix graph. 
     get_symmetrized_graph(A); 
     int output_error;
     
     // Call the fill-reducing routine from METIS 
     output_error = METIS_NodeND(&m, m_indexPtr.data(), m_innerIndices.data(), NULL, NULL, perm.data(), iperm.data());
     
    if(output_error != METIS_OK) 
    {
      //FIXME The ordering interface should define a class of possible errors 
     std::cerr << "ERROR WHILE CALLING THE METIS PACKAGE \n"; 
     return; 
    }
    
    // Get the fill-reducing permutation 
    //NOTE:  If Ap is the permuted matrix then perm and iperm vectors are defined as follows 
    // Row (column) i of Ap is the perm(i) row(column) of A, and row (column) i of A is the iperm(i) row(column) of Ap
    
    // To be consistent with the use of the permutation in SparseLU module, we thus keep the iperm vector 
     matperm.resize(m);
     for (int j = 0; j < m; j++)
       matperm.indices()(j) = iperm(j); 
   
  }
  
  protected:
    IndexVector m_indexPtr; // Pointer to the adjacenccy list of each row/column
    IndexVector m_innerIndices; // Adjacency list 
};

}// end namespace eigen 
#endif