polar_dec.cpp 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include "polar_dec.h"
  2. #include "polar_svd.h"
  3. #ifdef _WIN32
  4. #else
  5. # include <fenv.h>
  6. #endif
  7. #include <cmath>
  8. #include <Eigen/Eigenvalues>
  9. #include <iostream>
  10. // From Olga's CGAL mentee's ARAP code
  11. template <
  12. typename DerivedA,
  13. typename DerivedR,
  14. typename DerivedT,
  15. typename DerivedU,
  16. typename DerivedS,
  17. typename DerivedV>
  18. IGL_INLINE void igl::polar_dec(
  19. const Eigen::PlainObjectBase<DerivedA> & A,
  20. Eigen::PlainObjectBase<DerivedR> & R,
  21. Eigen::PlainObjectBase<DerivedT> & T,
  22. Eigen::PlainObjectBase<DerivedU> & U,
  23. Eigen::PlainObjectBase<DerivedS> & S,
  24. Eigen::PlainObjectBase<DerivedV> & V)
  25. {
  26. using namespace std;
  27. typedef typename DerivedA::Scalar Scalar;
  28. const Scalar th = std::sqrt(Eigen::NumTraits<Scalar>::dummy_precision());
  29. Eigen::SelfAdjointEigenSolver<DerivedA> eig;
  30. feclearexcept(FE_UNDERFLOW);
  31. eig.computeDirect(A.transpose()*A);
  32. if(fetestexcept(FE_UNDERFLOW) || eig.eigenvalues()(0)/eig.eigenvalues()(2)<th)
  33. {
  34. cout<<"resorting to svd 1..."<<endl;
  35. return polar_svd(A,R,T,U,S,V);
  36. }
  37. S = eig.eigenvalues().cwiseSqrt();
  38. T = eig.eigenvectors() * S.asDiagonal() * eig.eigenvectors().transpose();
  39. U = A * eig.eigenvectors();
  40. V = eig.eigenvectors();
  41. R = U * S.asDiagonal().inverse() * V.transpose();
  42. S = S.reverse().eval();
  43. V = V.rowwise().reverse().eval();
  44. U = U.rowwise().reverse().eval() * S.asDiagonal().inverse();
  45. if(std::fabs(R.squaredNorm()-3.) > th)
  46. {
  47. cout<<"resorting to svd 2..."<<endl;
  48. return polar_svd(A,R,T,U,S,V);
  49. }
  50. }
  51. template <
  52. typename DerivedA,
  53. typename DerivedR,
  54. typename DerivedT>
  55. IGL_INLINE void igl::polar_dec(
  56. const Eigen::PlainObjectBase<DerivedA> & A,
  57. Eigen::PlainObjectBase<DerivedR> & R,
  58. Eigen::PlainObjectBase<DerivedT> & T)
  59. {
  60. Eigen::PlainObjectBase<DerivedA> U;
  61. Eigen::PlainObjectBase<DerivedA> V;
  62. Eigen::Matrix<typename DerivedA::Scalar,DerivedA::RowsAtCompileTime,1> S;
  63. return igl::polar_dec(A,R,T,U,S,V);
  64. }
  65. #ifndef IGL_HEADER_ONLY
  66. // Explicit template instanciation
  67. template void igl::polar_dec<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  68. #endif