is_symmetric.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "is_symmetric.h"
  9. #include "find.h"
  10. template <typename T>
  11. IGL_INLINE bool igl::is_symmetric(const Eigen::SparseMatrix<T>& A)
  12. {
  13. if(A.rows() != A.cols())
  14. {
  15. return false;
  16. }
  17. assert(A.size() != 0);
  18. Eigen::SparseMatrix<T> AT = A.transpose();
  19. Eigen::SparseMatrix<T> AmAT = A-AT;
  20. //// Eigen screws up something with LLT if you try to do
  21. //SparseMatrix<T> AmAT = A-A.transpose();
  22. //// Eigen crashes at runtime if you try to do
  23. // return (A-A.transpose()).nonZeros() == 0;
  24. return AmAT.nonZeros() == 0;
  25. }
  26. template <typename DerivedA>
  27. IGL_INLINE bool igl::is_symmetric(
  28. const Eigen::PlainObjectBase<DerivedA>& A)
  29. {
  30. if(A.rows() != A.cols())
  31. {
  32. return false;
  33. }
  34. assert(A.size() != 0);
  35. const typename Eigen::PlainObjectBase<DerivedA>& AT = A.transpose();
  36. const typename Eigen::PlainObjectBase<DerivedA>& AmAT = A-AT;
  37. //// Eigen screws up something with LLT if you try to do
  38. //SparseMatrix<T> AmAT = A-A.transpose();
  39. //// Eigen crashes at runtime if you try to do
  40. // return (A-A.transpose()).nonZeros() == 0;
  41. return AmAT.nonZeros() == 0;
  42. }
  43. template <typename AType, typename epsilonT>
  44. IGL_INLINE bool igl::is_symmetric(
  45. const Eigen::SparseMatrix<AType>& A,
  46. const epsilonT epsilon)
  47. {
  48. using namespace Eigen;
  49. using namespace igl;
  50. using namespace std;
  51. if(A.rows() != A.cols())
  52. {
  53. return false;
  54. }
  55. assert(A.size() != 0);
  56. SparseMatrix<AType> AT = A.transpose();
  57. SparseMatrix<AType> AmAT = A-AT;
  58. VectorXi AmATI,AmATJ;
  59. Matrix<AType,Dynamic,1> AmATV;
  60. find(AmAT,AmATI,AmATJ,AmATV);
  61. if(AmATI.size() == 0)
  62. {
  63. return true;
  64. }
  65. return AmATV.maxCoeff() < epsilon && AmATV.minCoeff() > -epsilon;
  66. }
  67. #ifndef IGL_HEADER_ONLY
  68. // Explicit template specialization
  69. // generated by autoexplicit.sh
  70. template bool igl::is_symmetric<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&);
  71. // generated by autoexplicit.sh
  72. template bool igl::is_symmetric<double>(Eigen::SparseMatrix<double, 0, int> const&);
  73. template bool igl::is_symmetric<double, double>(Eigen::SparseMatrix<double, 0, int> const&, double);
  74. template bool igl::is_symmetric<double, int>(Eigen::SparseMatrix<double, 0, int> const&, int);
  75. #endif