// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2013 Alec Jacobson // // 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/. #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; } assert(A.size() != 0); 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; } assert(A.size() != 0); return (A-A.transpose()).eval().nonZeros() == 0; } template IGL_INLINE bool igl::is_symmetric( const Eigen::SparseMatrix& A, const epsilonT epsilon) { using namespace Eigen; using namespace std; if(A.rows() != A.cols()) { return false; } assert(A.size() != 0); SparseMatrix AT = A.transpose(); SparseMatrix AmAT = A-AT; VectorXi AmATI,AmATJ; Matrix AmATV; find(AmAT,AmATI,AmATJ,AmATV); if(AmATI.size() == 0) { return true; } return AmATV.maxCoeff() < epsilon && AmATV.minCoeff() > -epsilon; } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation // 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