polar_svd.cpp 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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 "polar_svd.h"
  9. #include <Eigen/SVD>
  10. #include <Eigen/Geometry>
  11. // Adapted from Olga's CGAL mentee's ARAP code
  12. template <
  13. typename DerivedA,
  14. typename DerivedR,
  15. typename DerivedT>
  16. IGL_INLINE void igl::polar_svd(
  17. const Eigen::PlainObjectBase<DerivedA> & A,
  18. Eigen::PlainObjectBase<DerivedR> & R,
  19. Eigen::PlainObjectBase<DerivedT> & T)
  20. {
  21. Eigen::PlainObjectBase<DerivedA> U;
  22. Eigen::PlainObjectBase<DerivedA> V;
  23. Eigen::Matrix<typename DerivedA::Scalar,DerivedA::RowsAtCompileTime,1> S;
  24. return igl::polar_svd(A,R,T,U,S,V);
  25. }
  26. template <
  27. typename DerivedA,
  28. typename DerivedR,
  29. typename DerivedT,
  30. typename DerivedU,
  31. typename DerivedS,
  32. typename DerivedV>
  33. IGL_INLINE void igl::polar_svd(
  34. const Eigen::PlainObjectBase<DerivedA> & A,
  35. Eigen::PlainObjectBase<DerivedR> & R,
  36. Eigen::PlainObjectBase<DerivedT> & T,
  37. Eigen::PlainObjectBase<DerivedU> & U,
  38. Eigen::PlainObjectBase<DerivedS> & S,
  39. Eigen::PlainObjectBase<DerivedV> & V)
  40. {
  41. using namespace std;
  42. Eigen::JacobiSVD<DerivedA> svd;
  43. svd.compute(A, Eigen::ComputeFullU | Eigen::ComputeFullV );
  44. U = svd.matrixU();
  45. V = svd.matrixV();
  46. S = svd.singularValues();
  47. // TODO: Check for sign and switch here.
  48. R = U*V.transpose();
  49. const auto & SV = S.asDiagonal() * V.adjoint();
  50. // Check for reflection
  51. if(R.determinant() < 0)
  52. {
  53. V.col(V.cols()-1) *= -1.;
  54. R = U*V.transpose();
  55. }
  56. T = V*SV;
  57. }
  58. #ifndef IGL_HEADER_ONLY
  59. // Explicit template instanciation
  60. template void igl::polar_svd<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> >&);
  61. template void igl::polar_svd<Eigen::Matrix<double, 2, 2, 0, 2, 2>, Eigen::Matrix<double, 2, 2, 0, 2, 2>, Eigen::Matrix<double, 2, 2, 0, 2, 2> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 2, 0, 2, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 2, 0, 2, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 2, 0, 2, 2> >&);
  62. template void igl::polar_svd<Eigen::Matrix<double, 3, 3, 0, 3, 3>, Eigen::Matrix<double, 3, 3, 0, 3, 3>, Eigen::Matrix<double, 3, 3, 0, 3, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 3, 0, 3, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 3, 0, 3, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 3, 0, 3, 3> >&);
  63. template void igl::polar_svd<Eigen::Matrix<float, 2, 2, 0, 2, 2>, Eigen::Matrix<float, 2, 2, 0, 2, 2>, Eigen::Matrix<float, 2, 2, 0, 2, 2> >(Eigen::PlainObjectBase<Eigen::Matrix<float, 2, 2, 0, 2, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 2, 2, 0, 2, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, 2, 2, 0, 2, 2> >&);
  64. #endif