#include "active_set.h" #include "min_quad_with_fixed.h" #include "slice.h" #include "matlab_format.h" #include #include #include template < typename AT, typename DerivedB, typename Derivedknown, typename DerivedY, typename AeqT, typename DerivedBeq, typename AieqT, typename DerivedBieq, typename Derivedlx, typename Derivedux, typename DerivedZ > IGL_INLINE igl::SolverStatus igl::active_set( const Eigen::SparseMatrix& A, const Eigen::PlainObjectBase & B, const Eigen::PlainObjectBase & known, const Eigen::PlainObjectBase & Y, const Eigen::SparseMatrix& Aeq, const Eigen::PlainObjectBase & Beq, const Eigen::SparseMatrix& Aieq, const Eigen::PlainObjectBase & Bieq, const Eigen::PlainObjectBase & lx, const Eigen::PlainObjectBase & ux, const igl::active_set_params & params, Eigen::PlainObjectBase & Z ) { using namespace igl; using namespace Eigen; using namespace std; // Linear inequality constraints are not supported yet assert(Aieq.size() == 0); assert(Bieq.size() == 0); SolverStatus ret = SOLVER_STATUS_ERROR; const int n = A.rows(); assert(n == A.cols()); // Discard const qualifiers //if(B.size() == 0) //{ // B = Eigen::PlainObjectBase::Zero(n,1); //} assert(n == B.rows()); assert(B.cols() == 1); assert(Y.cols() == 1); assert((Aeq.size() == 0 && Beq.size() == 0) || Aeq.cols() == n); assert((Aeq.size() == 0 && Beq.size() == 0) || Aeq.rows() == Beq.rows()); assert((Aeq.size() == 0 && Beq.size() == 0) || Beq.cols() == 1); assert((Aieq.size() == 0 && Bieq.size() == 0) || Aieq.cols() == n); assert((Aieq.size() == 0 && Bieq.size() == 0) || Aieq.rows() == Bieq.rows()); assert((Aieq.size() == 0 && Bieq.size() == 0) || Bieq.cols() == 1); // Discard const qualifiers //if(lx.size() == 0) //{ // lx = Eigen::PlainObjectBase::Constant( // n,1,numeric_limits::min()); //} //if(ux.size() == 0) //{ // ux = Eigen::PlainObjectBase::Constant( // n,1,numeric_limits::max()); //} assert(lx.rows() == n); assert(ux.rows() == n); assert(ux.cols() == 1); assert(lx.cols() == 1); assert((ux.array()-lx.array()).minCoeff() > 0); if(Z.size() != 0) { // Initial guess should have correct size assert(Z.rows() == n); assert(Z.cols() == 1); } assert(known.cols() == 1); // Number of knowns const int nk = known.size(); // Initialize active sets typedef bool BOOL; #define TRUE true #define FALSE false Matrix as_lx = Matrix::Constant(n,1,FALSE); Matrix as_ux = Matrix::Constant(n,1,FALSE); Matrix as_ieq(Aieq.rows(),1); // Keep track of previous Z for comparison Eigen::PlainObjectBase old_Z; old_Z = PlainObjectBase::Constant( n,1,numeric_limits::max()); int iter = 0; while(true) { // FIND BREACHES OF CONSTRAINTS int new_as_lx = 0; int new_as_ux = 0; if(Z.size() > 0) { for(int z = 0;z < n;z++) { if(Z(z) < lx(z)) { new_as_lx += (as_lx(z)?0:1); //new_as_lx++; as_lx(z) = TRUE; } if(Z(z) > ux(z)) { new_as_ux += (as_ux(z)?0:1); //new_as_ux++; as_ux(z) = TRUE; } } //cout<<"new_as_lx: "< known_i; known_i.resize(nk + as_lx_count + as_ux_count,1); Eigen::PlainObjectBase Y_i; Y_i.resize(nk + as_lx_count + as_ux_count,1); { known_i.block(0,0,known.rows(),known.cols()) = known; Y_i.block(0,0,Y.rows(),Y.cols()) = Y; int k = nk; // Then all lx for(int z = 0;z < n;z++) { if(as_lx(z)) { known_i(k) = z; Y_i(k) = lx(z); k++; } } // Finally all ux for(int z = 0;z < n;z++) { if(as_ux(z)) { known_i(k) = z; Y_i(k) = ux(z); k++; } } assert(k==Y_i.size()); assert(k==known_i.size()); } //cout< data; if(!min_quad_with_fixed_precompute(A,known_i,Aeq,params.Auu_pd,data)) { cerr<<"Error: min_quad_with_fixed precomputation failed."< Ak; // Slow slice(A,known_i,1,Ak); Eigen::PlainObjectBase Bk; slice(B,known_i,Bk); MatrixXd Lambda_known_i = -(Ak*Z + 0.5*Bk); // reverse the lambda values for lx Lambda_known_i.block(nk,0,as_lx_count,1) = (-1*Lambda_known_i.block(nk,0,as_lx_count,1)).eval(); // Remove from active set for(int l = 0;l0 && iter>=params.max_iter) { ret = SOLVER_STATUS_MAX_ITER; break; } } return ret; } #ifndef IGL_HEADER_ONLY // Explicit template specialization template igl::SolverStatus igl::active_set, Eigen::Matrix, Eigen::Matrix, double, Eigen::Matrix, double, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::SparseMatrix const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::SparseMatrix const&, Eigen::PlainObjectBase > const&, Eigen::SparseMatrix const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, Eigen::PlainObjectBase > const&, igl::active_set_params const&, Eigen::PlainObjectBase >&); #endif