#include "is_symmetric.h" #include "find.h" template IGL_INLINE bool igl::is_symmetric(const Eigen::SparseMatrix& A) { if(A.rows() != A.cols()) { return false; } Eigen::SparseMatrix AT = A.transpose(); Eigen::SparseMatrix AmAT = A-AT; //// Eigen screws up something with LLT if you try to do //SparseMatrix AmAT = A-A.transpose(); //// Eigen crashes at runtime if you try to do // return (A-A.transpose()).nonZeros() == 0; return AmAT.nonZeros() == 0; } template IGL_INLINE bool igl::is_symmetric( const Eigen::PlainObjectBase& A) { if(A.rows() != A.cols()) { return false; } const typename Eigen::PlainObjectBase& AT = A.transpose(); const typename Eigen::PlainObjectBase& AmAT = A-AT; //// Eigen screws up something with LLT if you try to do //SparseMatrix AmAT = A-A.transpose(); //// Eigen crashes at runtime if you try to do // return (A-A.transpose()).nonZeros() == 0; return AmAT.nonZeros() == 0; } template IGL_INLINE bool igl::is_symmetric( const Eigen::SparseMatrix& A, const epsilonT epsilon) { using namespace Eigen; using namespace igl; if(A.rows() != A.cols()) { return false; } SparseMatrix AT = A.transpose(); SparseMatrix AmAT = A-AT; VectorXi AmATI,AmATJ; Matrix AmATV; find(AmAT,AmATI,AmATJ,AmATV); return AmATV.maxCoeff() < epsilon && AmATV.minCoeff() > -epsilon; } #ifndef IGL_HEADER_ONLY // Explicit template specialization // generated by autoexplicit.sh template bool igl::is_symmetric >(Eigen::PlainObjectBase > const&); // generated by autoexplicit.sh template bool igl::is_symmetric(Eigen::SparseMatrix const&); template bool igl::is_symmetric(Eigen::SparseMatrix const&, double); template bool igl::is_symmetric(Eigen::SparseMatrix const&, int); #endif