#ifndef IGL_MIN_QUAD_WITH_FIXED_H #define IGL_MIN_QUAD_WITH_FIXED_H #include "igl_inline.h" #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET #include #include #include //#include // Bug in unsupported/Eigen/SparseExtra needs iostream first #include #include namespace igl { template struct min_quad_with_fixed_data; // MIN_QUAD_WITH_FIXED Minimize quadratic energy Z'*A*Z + Z'*B + C with // constraints that Z(known) = Y, optionally also subject to the constraints // Aeq*Z = Beq // // Templates: // T should be a eigen matrix primitive type like int or double // Inputs: // A n by n matrix of quadratic coefficients // B n by 1 column of linear coefficients // known list of indices to known rows in Z // Y list of fixed values corresponding to known rows in Z // Optional: // Aeq m by n list of linear equality constraint coefficients // Beq m by 1 list of linear equality constraint constant values // pd flag specifying whether A(unknown,unknown) is positive definite // Outputs: // data factorization struct with all necessary information to solve // using min_quad_with_fixed_solve // Returns true on success, false on error template IGL_INLINE bool min_quad_with_fixed_precompute( const Eigen::SparseMatrix& A, const Eigen::Matrix & known, const Eigen::SparseMatrix& Aeq, const bool pd, min_quad_with_fixed_data & data ); // Solves a system previously factored using min_quad_with_fixed_precompute // // Template: // T type of sparse matrix (e.g. double) // DerivedY type of Y (e.g. derived from VectorXd or MatrixXd) // DerivedZ type of Z (e.g. derived from VectorXd or MatrixXd) // Inputs: // data factorization struct with all necessary precomputation to solve // Outputs: // Z n by cols solution // Returns true on success, false on error template IGL_INLINE bool min_quad_with_fixed_solve( const min_quad_with_fixed_data & data, const Eigen::Matrix & B, const Eigen::PlainObjectBase & Y, const Eigen::Matrix & Beq, Eigen::PlainObjectBase & Z); } template struct igl::min_quad_with_fixed_data { // Size of original system: number of unknowns + number of knowns int n; // Whether A(unknown,unknown) is positive definite bool Auu_pd; // Whether A(unknown,unknown) is symmetric bool Auu_sym; // Indices of known variables Eigen::VectorXi known; // Indices of unknown variables Eigen::VectorXi unknown; // Indices of lagrange variables Eigen::VectorXi lagrange; // Indices of unknown variable followed by Indices of lagrange variables Eigen::VectorXi unknown_lagrange; // Matrix multiplied against Y when constructing right hand side Eigen::SparseMatrix preY; enum SolverType { LLT = 0, LDLT = 1, LU = 2, NUM_SOLVER_TYPES = 3 } solver_type; // Solvers Eigen::SimplicialLLT > llt; Eigen::SimplicialLDLT > ldlt; Eigen::SparseLU, Eigen::COLAMDOrdering > lu; // Debug Eigen::SparseMatrix NA; Eigen::Matrix NB; }; #ifdef IGL_HEADER_ONLY # include "min_quad_with_fixed.cpp" #endif #endif