min_quad_with_fixed.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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. #ifndef IGL_MIN_QUAD_WITH_FIXED_H
  9. #define IGL_MIN_QUAD_WITH_FIXED_H
  10. #include "igl_inline.h"
  11. #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
  12. #include <Eigen/Core>
  13. #include <Eigen/Dense>
  14. #include <Eigen/Sparse>
  15. #include <Eigen/SparseExtra>
  16. // Bug in unsupported/Eigen/SparseExtra needs iostream first
  17. #include <iostream>
  18. #include <unsupported/Eigen/SparseExtra>
  19. namespace igl
  20. {
  21. template <typename T>
  22. struct min_quad_with_fixed_data;
  23. // Known Bugs: rows of Aeq **must** be linearly independent. Should be using
  24. // QR decomposition otherwise:
  25. // http://www.okstate.edu/sas/v8/sashtml/ormp/chap5/sect32.htm
  26. //
  27. // MIN_QUAD_WITH_FIXED Minimize quadratic energy Z'*A*Z + Z'*B + C with
  28. // constraints that Z(known) = Y, optionally also subject to the constraints
  29. // Aeq*Z = Beq
  30. //
  31. // Templates:
  32. // T should be a eigen matrix primitive type like int or double
  33. // Inputs:
  34. // A n by n matrix of quadratic coefficients
  35. // known list of indices to known rows in Z
  36. // Y list of fixed values corresponding to known rows in Z
  37. // Aeq m by n list of linear equality constraint coefficients
  38. // pd flag specifying whether A(unknown,unknown) is positive definite
  39. // Outputs:
  40. // data factorization struct with all necessary information to solve
  41. // using min_quad_with_fixed_solve
  42. // Returns true on success, false on error
  43. //
  44. // Benchmark: For a harmonic solve on a mesh with 325K facets, matlab 2.2
  45. // secs, igl/min_quad_with_fixed.h 7.1 secs
  46. //
  47. template <typename T, typename Derivedknown>
  48. IGL_INLINE bool min_quad_with_fixed_precompute(
  49. const Eigen::SparseMatrix<T>& A,
  50. const Eigen::PlainObjectBase<Derivedknown> & known,
  51. const Eigen::SparseMatrix<T>& Aeq,
  52. const bool pd,
  53. min_quad_with_fixed_data<T> & data
  54. );
  55. // Solves a system previously factored using min_quad_with_fixed_precompute
  56. //
  57. // Template:
  58. // T type of sparse matrix (e.g. double)
  59. // DerivedY type of Y (e.g. derived from VectorXd or MatrixXd)
  60. // DerivedZ type of Z (e.g. derived from VectorXd or MatrixXd)
  61. // Inputs:
  62. // data factorization struct with all necessary precomputation to solve
  63. // B n by 1 column of linear coefficients
  64. // Y b by 1 list of constant fixed values
  65. // Beq m by 1 list of linear equality constraint constant values
  66. // Outputs:
  67. // Z n by cols solution
  68. // sol #unknowns+#lagrange by cols solution to linear system
  69. // Returns true on success, false on error
  70. template <
  71. typename T,
  72. typename DerivedB,
  73. typename DerivedY,
  74. typename DerivedBeq,
  75. typename DerivedZ,
  76. typename Derivedsol>
  77. IGL_INLINE bool min_quad_with_fixed_solve(
  78. const min_quad_with_fixed_data<T> & data,
  79. const Eigen::PlainObjectBase<DerivedB> & B,
  80. const Eigen::PlainObjectBase<DerivedY> & Y,
  81. const Eigen::PlainObjectBase<DerivedBeq> & Beq,
  82. Eigen::PlainObjectBase<DerivedZ> & Z,
  83. Eigen::PlainObjectBase<Derivedsol> & sol);
  84. // Wrapper without sol
  85. template <
  86. typename T,
  87. typename DerivedB,
  88. typename DerivedY,
  89. typename DerivedBeq,
  90. typename DerivedZ>
  91. IGL_INLINE bool min_quad_with_fixed_solve(
  92. const min_quad_with_fixed_data<T> & data,
  93. const Eigen::PlainObjectBase<DerivedB> & B,
  94. const Eigen::PlainObjectBase<DerivedY> & Y,
  95. const Eigen::PlainObjectBase<DerivedBeq> & Beq,
  96. Eigen::PlainObjectBase<DerivedZ> & Z);
  97. }
  98. template <typename T>
  99. struct igl::min_quad_with_fixed_data
  100. {
  101. // Size of original system: number of unknowns + number of knowns
  102. int n;
  103. // Whether A(unknown,unknown) is positive definite
  104. bool Auu_pd;
  105. // Whether A(unknown,unknown) is symmetric
  106. bool Auu_sym;
  107. // Indices of known variables
  108. Eigen::VectorXi known;
  109. // Indices of unknown variables
  110. Eigen::VectorXi unknown;
  111. // Indices of lagrange variables
  112. Eigen::VectorXi lagrange;
  113. // Indices of unknown variable followed by Indices of lagrange variables
  114. Eigen::VectorXi unknown_lagrange;
  115. // Matrix multiplied against Y when constructing right hand side
  116. Eigen::SparseMatrix<T> preY;
  117. enum SolverType
  118. {
  119. LLT = 0,
  120. LDLT = 1,
  121. LU = 2,
  122. QR_LLT = 3,
  123. NUM_SOLVER_TYPES = 4
  124. } solver_type;
  125. // Solvers
  126. Eigen::SimplicialLLT <Eigen::SparseMatrix<T > > llt;
  127. Eigen::SimplicialLDLT<Eigen::SparseMatrix<T > > ldlt;
  128. Eigen::SparseLU<Eigen::SparseMatrix<T, Eigen::ColMajor>, Eigen::COLAMDOrdering<int> > lu;
  129. // QR factorization
  130. // Are rows of Aeq linearly independent?
  131. bool Aeq_li;
  132. // Columns of Aeq corresponding to unknowns
  133. int neq;
  134. Eigen::SparseQR<Eigen::SparseMatrix<T>, Eigen::COLAMDOrdering<int> > AeqTQR;
  135. Eigen::SparseMatrix<T> Aeqk;
  136. Eigen::SparseMatrix<T> Aequ;
  137. Eigen::SparseMatrix<T> Auu;
  138. Eigen::SparseMatrix<T> AeqTQ1;
  139. Eigen::SparseMatrix<T> AeqTQ1T;
  140. Eigen::SparseMatrix<T> AeqTQ2;
  141. Eigen::SparseMatrix<T> AeqTQ2T;
  142. Eigen::SparseMatrix<T> AeqTR1;
  143. Eigen::SparseMatrix<T> AeqTR1T;
  144. Eigen::SparseMatrix<T> AeqTE;
  145. Eigen::SparseMatrix<T> AeqTET;
  146. // Debug
  147. Eigen::SparseMatrix<T> NA;
  148. Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> NB;
  149. };
  150. #ifdef IGL_HEADER_ONLY
  151. # include "min_quad_with_fixed.cpp"
  152. #endif
  153. #endif