Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef METIS_SUPPORT_H
00010 #define METIS_SUPPORT_H
00011
00012 namespace Eigen {
00021 template <typename Index>
00022 class MetisOrdering
00023 {
00024 public:
00025 typedef PermutationMatrix<Dynamic,Dynamic,Index> PermutationType;
00026 typedef Matrix<Index,Dynamic,1> IndexVector;
00027
00028 template <typename MatrixType>
00029 void get_symmetrized_graph(const MatrixType& A)
00030 {
00031 Index m = A.cols();
00032 eigen_assert((A.rows() == A.cols()) && "ONLY FOR SQUARED MATRICES");
00033
00034 MatrixType At = A.transpose();
00035
00036 Index TotNz = 0;
00037 IndexVector visited(m);
00038 visited.setConstant(-1);
00039 for (int j = 0; j < m; j++)
00040 {
00041
00042 visited(j) = j;
00043
00044 for (typename MatrixType::InnerIterator it(A, j); it; ++it)
00045 {
00046 Index idx = it.index();
00047 if (visited(idx) != j )
00048 {
00049 visited(idx) = j;
00050 ++TotNz;
00051 }
00052 }
00053
00054 for (typename MatrixType::InnerIterator it(At, j); it; ++it)
00055 {
00056 Index idx = it.index();
00057 if(visited(idx) != j)
00058 {
00059 visited(idx) = j;
00060 ++TotNz;
00061 }
00062 }
00063 }
00064
00065 m_indexPtr.resize(m+1);
00066 m_innerIndices.resize(TotNz);
00067
00068
00069 visited.setConstant(-1);
00070 Index CurNz = 0;
00071 for (int j = 0; j < m; j++)
00072 {
00073 m_indexPtr(j) = CurNz;
00074
00075 visited(j) = j;
00076
00077 for (typename MatrixType::InnerIterator it(A,j); it; ++it)
00078 {
00079 Index idx = it.index();
00080 if (visited(idx) != j )
00081 {
00082 visited(idx) = j;
00083 m_innerIndices(CurNz) = idx;
00084 CurNz++;
00085 }
00086 }
00087
00088 for (typename MatrixType::InnerIterator it(At, j); it; ++it)
00089 {
00090 Index idx = it.index();
00091 if(visited(idx) != j)
00092 {
00093 visited(idx) = j;
00094 m_innerIndices(CurNz) = idx;
00095 ++CurNz;
00096 }
00097 }
00098 }
00099 m_indexPtr(m) = CurNz;
00100 }
00101
00102 template <typename MatrixType>
00103 void operator() (const MatrixType& A, PermutationType& matperm)
00104 {
00105 Index m = A.cols();
00106 IndexVector perm(m),iperm(m);
00107
00108 get_symmetrized_graph(A);
00109 int output_error;
00110
00111
00112 output_error = METIS_NodeND(&m, m_indexPtr.data(), m_innerIndices.data(), NULL, NULL, perm.data(), iperm.data());
00113
00114 if(output_error != METIS_OK)
00115 {
00116
00117 std::cerr << "ERROR WHILE CALLING THE METIS PACKAGE \n";
00118 return;
00119 }
00120
00121
00122
00123
00124
00125 matperm.resize(m);
00126 for (int j = 0; j < m; j++)
00127 matperm.indices()(iperm(j)) = j;
00128
00129 }
00130
00131 protected:
00132 IndexVector m_indexPtr;
00133 IndexVector m_innerIndices;
00134 };
00135
00136 }
00137 #endif