std::vector<Sparsity> LrDpleInternal::getSparsity(const std::map<std::string, std::vector<Sparsity> >& st, const std::vector< std::vector<int> > &Hs_) { // Chop-up the arguments std::vector<Sparsity> As, Vs, Cs, Hs; if (st.count("a")) As = st.at("a"); if (st.count("v")) Vs = st.at("v"); if (st.count("c")) Cs = st.at("c"); if (st.count("h")) Hs = st.at("h"); bool with_H = !Hs.empty(); int K = As.size(); Sparsity A; if (K==1) { A = As[0]; } else { Sparsity AL = diagcat(vector_slice(As, range(As.size()-1))); Sparsity AL2 = horzcat(AL, Sparsity(AL.size1(), As[0].size2())); Sparsity AT = horzcat(Sparsity(As[0].size1(), AL.size2()), As.back()); A = vertcat(AT, AL2); } Sparsity V = diagcat(Vs.back(), diagcat(vector_slice(Vs, range(Vs.size()-1)))); Sparsity C; if (!Cs.empty()) { C = diagcat(Cs.back(), diagcat(vector_slice(Cs, range(Cs.size()-1)))); } Sparsity H; std::vector<int> Hs_agg; std::vector<int> Hi(1, 0); if (Hs_.size()>0 && with_H) { H = diagcat(Hs.back(), diagcat(vector_slice(Hs, range(Hs.size()-1)))); casadi_assert(K==Hs_.size()); for (int k=0;k<K;++k) { Hs_agg.insert(Hs_agg.end(), Hs_[k].begin(), Hs_[k].end()); int sum=0; for (int i=0;i<Hs_[k].size();++i) { sum+= Hs_[k][i]; } Hi.push_back(Hi.back()+sum); } } Sparsity res = LrDleInternal::getSparsity(make_map("a", A, "v", V, "c", C, "h", H), Hs_agg); if (with_H) { return diagsplit(res, Hi); } else { return diagsplit(res, As[0].size2()); } }
Sparsity horzcat(const std::vector<Sparsity> & sp) { if(sp.empty()){ return Sparsity(); } else { Sparsity ret = sp[0]; for(int i=1; i<sp.size(); ++i) { ret.appendColumns(sp[i]); } return ret; } }
Sparsity Conic::get_sparsity_out(int i) { switch (static_cast<ConicOutput>(i)) { case CONIC_COST: return Sparsity::scalar(); case CONIC_X: case CONIC_LAM_X: return Sparsity::dense(nx_, 1); case CONIC_LAM_A: return Sparsity::dense(na_, 1); case CONIC_NUM_OUT: break; } return Sparsity(); }
// Constructor Conic::Conic(const std::string& name, const std::map<std::string, Sparsity> &st) : FunctionInternal(name) { for (auto i=st.begin(); i!=st.end(); ++i) { if (i->first=="a") { A_ = i->second; } else if (i->first=="h") { H_ = i->second; } else { casadi_error("Unrecognized field in QP structure: " << i->first); } } // We need either A or H casadi_assert_message(!A_.is_null() || !H_.is_null(), "Cannot determine dimension"); // Generate A or H if (A_.is_null()) { A_ = Sparsity(0, H_.size2()); } else if (H_.is_null()) { H_ = Sparsity(A_.size2(), A_.size2()); } else { // Consistency check casadi_assert_message(A_.size2()==H_.size2(), "Got incompatible dimensions. min x'Hx + G'x s.t. LBA <= Ax <= UBA :" << std::endl << "H: " << H_.dim() << " - A: " << A_.dim() << std::endl << "We need: H_.size2()==A_.size2()" << std::endl); } casadi_assert_message(H_.is_symmetric(), "Got incompatible dimensions. min x'Hx + G'x" << std::endl << "H: " << H_.dim() << "We need H square & symmetric" << std::endl); nx_ = A_.size2(); na_ = A_.size1(); }
void QpToQcqp::init() { // Initialize the base classes QpSolverInternal::init(); Dict options; if (hasSetOption(optionsname())) options = getOption(optionsname()); options = OptionsFunctionality::addOptionRecipe(options, "qp"); // Create an QcqpSolver instance solver_ = QcqpSolver("qcqpsolver", getOption(solvername()), make_map("h", input(QP_SOLVER_H).sparsity(), "p", Sparsity(n_, 0), "a", input(QP_SOLVER_A).sparsity()), options); }
DM CSparseCholeskyInterface::linsol_cholesky(void* mem, bool tr) const { auto m = static_cast<CsparseCholMemory*>(mem); casadi_assert(m->L); cs *L = m->L->L; int nz = L->nzmax; std::vector< int > colind(L->m+1); std::copy(L->p, L->p+L->m+1, colind.begin()); std::vector< int > row(nz); std::copy(L->i, L->i+nz, row.begin()); std::vector< double > data(nz); std::copy(L->x, L->x+nz, data.begin()); DM ret(Sparsity(L->n, L->m, colind, row), data, false); return tr ? ret.T() : ret; }
DMatrix CSparseCholeskyInternal::getFactorization(bool transpose) const { casadi_assert(L_); cs *L = L_->L; int nz = L->nzmax; int m = L->m; // number of cols int n = L->n; // number of rows std::vector< int > colind(m+1); std::copy(L->p, L->p+m+1, colind.begin()); std::vector< int > row(nz); std::copy(L->i, L->i+nz, row.begin()); std::vector< double > data(nz); std::copy(L->x, L->x+nz, data.begin()); DMatrix ret(Sparsity(n, m, colind, row), data, false); return transpose? ret.T() : ret; }
std::vector<Sparsity> horzsplit(const Sparsity& sp, const std::vector<int>& offset){ // Consistency check casadi_assert(offset.size()>=1); casadi_assert(offset.front()==0); casadi_assert_message(offset.back()==sp.size2(),"horzsplit(Sparsity,std::vector<int>): Last elements of offset (" << offset.back() << ") must equal the number of columns (" << sp.size2() << ")"); casadi_assert(isMonotone(offset)); // Number of outputs int n = offset.size()-1; // Get the sparsity of the input const vector<int>& colind_x = sp.colind(); const vector<int>& row_x = sp.row(); // Allocate result std::vector<Sparsity> ret; ret.reserve(n); // Sparsity pattern as CCS vectors vector<int> colind, row; int ncol, nrow = sp.size1(); // Get the sparsity patterns of the outputs for(int i=0; i<n; ++i){ int first_col = offset[i]; int last_col = offset[i+1]; ncol = last_col - first_col; // Construct the sparsity pattern colind.resize(ncol+1); copy(colind_x.begin()+first_col, colind_x.begin()+last_col+1, colind.begin()); for(vector<int>::iterator it=colind.begin()+1; it!=colind.end(); ++it) *it -= colind[0]; colind[0] = 0; row.resize(colind.back()); copy(row_x.begin()+colind_x[first_col],row_x.begin()+colind_x[last_col],row.begin()); // Append to the list ret.push_back(Sparsity(nrow,ncol,colind,row)); } // Return (RVO) return ret; }
Sparsity Conic::get_sparsity_in(int i) { switch (static_cast<ConicInput>(i)) { case CONIC_X0: case CONIC_G: case CONIC_LBX: case CONIC_UBX: case CONIC_LAM_X0: return get_sparsity_out(CONIC_X); case CONIC_LBA: case CONIC_UBA: case CONIC_LAM_A0: return get_sparsity_out(CONIC_LAM_A); case CONIC_A: return A_; case CONIC_H: return H_; case CONIC_NUM_IN: break; } return Sparsity(); }
Sparsity blkdiag(const std::vector< Sparsity > &v) { int n = 0; int m = 0; std::vector<int> colind(1,0); std::vector<int> row; int nz = 0; for (int i=0;i<v.size();++i) { const std::vector<int> &colind_ = v[i].colind(); const std::vector<int> &row_ = v[i].row(); for (int k=1;k<colind_.size();++k) { colind.push_back(colind_[k]+nz); } for (int k=0;k<row_.size();++k) { row.push_back(row_[k]+m); } n+= v[i].size2(); m+= v[i].size1(); nz+= v[i].size(); } return Sparsity(m,n,colind,row); }
void SdqpToSdp::init() { // Initialize the base classes SdqpSolverInternal::init(); cholesky_ = LinearSolver("cholesky", "csparsecholesky", st_[SDQP_STRUCT_H]); MX g_socp = MX::sym("x", cholesky_.getFactorizationSparsity(true)); MX h_socp = MX::sym("h", n_); MX f_socp = sqrt(inner_prod(h_socp, h_socp)); MX en_socp = 0.5/f_socp; MX f_sdqp = MX::sym("f", input(SDQP_SOLVER_F).sparsity()); MX g_sdqp = MX::sym("g", input(SDQP_SOLVER_G).sparsity()); std::vector<MX> fi(n_+1); MX znp = MX(n_+1, n_+1); for (int k=0;k<n_;++k) { MX gk = vertcat(g_socp(ALL, k), MX(1, 1)); MX fk = -blockcat(znp, gk, gk.T(), MX(1, 1)); // TODO(Joel): replace with ALL fi.push_back(diagcat(f_sdqp(ALL, Slice(f_sdqp.size1()*k, f_sdqp.size1()*(k+1))), fk)); } MX fin = en_socp*DMatrix::eye(n_+2); fin(n_, n_+1) = en_socp; fin(n_+1, n_) = en_socp; fi.push_back(diagcat(DMatrix(f_sdqp.size1(), f_sdqp.size1()), -fin)); MX h0 = vertcat(h_socp, DMatrix(1, 1)); MX g = blockcat(f_socp*DMatrix::eye(n_+1), h0, h0.T(), f_socp); g = diagcat(g_sdqp, g); Dict opts; opts["input_scheme"] = IOScheme("g_socp", "h_socp", "f_sdqp", "g_sdqp"); opts["output_scheme"] = IOScheme("f", "g"); mapping_ = MXFunction("mapping", make_vector(g_socp, h_socp, f_sdqp, g_sdqp), make_vector(horzcat(fi), g), opts); Dict options; if (hasSetOption(optionsname())) options = getOption(optionsname()); // Create an SdpSolver instance solver_ = SdpSolver("sdpsolver", getOption(solvername()), make_map("g", mapping_.output("g").sparsity(), "f", mapping_.output("f").sparsity(), "a", horzcat(input(SDQP_SOLVER_A).sparsity(), Sparsity(nc_, 1))), options); solver_.input(SDP_SOLVER_C).at(n_)=1; // Output arguments obuf_.resize(SDQP_SOLVER_NUM_OUT); output(SDQP_SOLVER_X) = DMatrix::zeros(n_, 1); std::vector<int> r = range(input(SDQP_SOLVER_G).size1()); output(SDQP_SOLVER_P) = solver_.output(SDP_SOLVER_P).isempty() ? DMatrix() : solver_.output(SDP_SOLVER_P)(r, r); output(SDQP_SOLVER_DUAL) = solver_.output(SDP_SOLVER_DUAL).isempty() ? DMatrix() : solver_.output(SDP_SOLVER_DUAL)(r, r); output(SDQP_SOLVER_COST) = 0.0; output(SDQP_SOLVER_DUAL_COST) = 0.0; output(SDQP_SOLVER_LAM_X) = DMatrix::zeros(n_, 1); output(SDQP_SOLVER_LAM_A) = DMatrix::zeros(nc_, 1); }
void SparseStorage<DataType>::clear() { sparsity_ = Sparsity(0, 0); nonzeros().clear(); }
SparseStorage<DataType>::SparseStorage() : sparsity_(Sparsity(0, 0)) { }
namespace CasADi{ /** \ingroup expression_tools @{ */ /** \brief concatenate vertically * * horzcat(horzsplit(x,...)) = x */ MX horzcat(const std::vector<MX>& x); /** \brief split vertically, retaining groups of cols * \param output_offset List of all start cols for each group * the last col group will run to the end. * * horzcat(horzsplit(x,...)) = x */ std::vector<MX> horzsplit(const MX& x, const std::vector<int>& output_offset); /** \brief split vertically, retaining fixed-sized groups of cols * \param incr Size of each group of cols * * horzcat(horzsplit(x,...)) = x */ std::vector<MX> horzsplit(const MX& x, int incr=1); /** \brief concatenate horizontally * * vertcat(vertsplit(x,...)) = x */ MX vertcat(const std::vector<MX>& comp); /** \brief split horizontally, retaining groups of rows * \param output_offset List of all start rows for each group * the last row group will run to the end. * * vertcat(vertsplit(x,...)) = x */ std::vector<MX> vertsplit(const MX& x, const std::vector<int>& output_offset); /** \brief split horizontally, retaining fixed-sized groups of rows * \param incr Size of each group of rows * * vertcat(vertsplit(x,...)) = x */ std::vector<MX> vertsplit(const MX& x, int incr=1); /** \brief Construct a matrix from a list of list of blocks. * * blockcat(blocksplit(x,...,...)) = x */ MX blockcat(const std::vector< std::vector<MX > > &v); /** \brief chop up into blocks * \brief vert_offset Defines the boundaries of the block cols * \brief horz_offset Defines the boundaries of the block rows * * blockcat(blocksplit(x,...,...)) = x */ std::vector< std::vector<MX > > blocksplit(const MX& x, const std::vector<int>& vert_offset, const std::vector<int>& horz_offset); /** \brief chop up into blocks * \brief vert_incr Defines the increment for block boundaries in col dimension * \brief horz_incr Defines the increment for block boundaries in row dimension * * blockcat(blocksplit(x,...,...)) = x */ std::vector< std::vector<MX > > blocksplit(const MX& x, int vert_incr = 1, int horz_incr = 1); #ifndef SWIG /** \brief Construct a matrix from a list of list of blocks.*/ MX blockcat(const MX &A,const MX &B,const MX &C,const MX &D); #endif // SWIG /** \brief Concatenate vertically while vectorizing all arguments */ MX veccat(const std::vector<MX>& comp); /** \brief concatenate vertically while vecing all arguments with vecNZ */ MX vecNZcat(const std::vector<MX>& comp); #ifndef SWIG /** \brief concatenate vertically, two matrices */ MX horzcat(const MX& a, const MX& b); /** \brief concatenate horizontally, two matrices */ MX vertcat(const MX& a, const MX& b); #endif // SWIG /** \brief Frobenius norm */ MX norm_F(const MX &x); /** \brief 2-norm */ MX norm_2(const MX &x); /** \brief 1-norm */ MX norm_1(const MX &x); /** \brief Infinity-norm */ MX norm_inf(const MX &x); /** \brief Transpose an expression */ MX transpose(const MX &x); /** \brief Take the matrix product of 2 MX objects * * With optional sp_z you can specify the sparsity of the result * A typical use case might be where the product is only constructed to * inspect the trace of it. sp_z diagonal will be more efficient then. * */ MX mul(const MX &x, const MX &y, const Sparsity& sp_z=Sparsity()); /** \brief Take the matrix product of n MX objects */ MX mul(const std::vector< MX > &x); /** \brief Take the inner product of two vectors Equals \code trans(x)*y \endcode with x and y vectors */ MX inner_prod(const MX &x, const MX &y); /** \brief Take the outer product of two vectors Equals \code x*trans(y) \endcode with x and y vectors */ MX outer_prod(const MX &x, const MX &y); /** \brief Branching on MX nodes Ternary operator, "cond ? if_true : if_false" */ MX if_else(const MX &cond, const MX &if_true, const MX &if_false); #ifndef SWIG //! \brief Returns a reshaped version of the MX MX reshape(const MX &x, int nrow, int ncol); #endif // SWIG //! \brief Returns a reshaped version of the MX, dimensions as a vector MX reshape(const MX &x, std::pair<int,int> rc); //! \brief Reshape the MX MX reshape(const MX &x, const Sparsity& sp); /** \brief Returns a vectorized version of the MX Same as reshape(x, x.numel(),1) a c b d turns into a b c d */ MX vec(const MX &x); /** \brief Returns a vectorized version of the MX, prseverving only nonzeros */ MX vecNZ(const MX &x); /** \brief Unite two matrices no overlapping sparsity */ MX unite(const MX& A, const MX& B); /** \brief Simplify an expression */ void simplify(MX& ex); /** \brief Matrix trace */ MX trace(const MX& A); /** \brief Repeat matrix A n times vertically and m times horizontally */ MX repmat(const MX &A, int n, int m); /** \brief create a clipped view into a matrix Create a sparse matrix from a dense matrix A, with sparsity pattern sp **/ //MX clip(const MX& A, const Sparsity& sp); #ifndef SWIGOCTAVE /** \brief Make the matrix dense if not already */ MX dense(const MX& x); #endif // SWIGOCTAVE /** \brief Create a parent MX on which all given MX's will depend. In some sense, this function is the inverse of \param deps Must all be symbolic matrices. */ MX createParent(std::vector<MX> &deps); /** \brief Create a parent MX on which a bunch of MX's (sizes given as argument) will depend */ MX createParent(const std::vector<MX> &deps, std::vector<MX>& SWIG_OUTPUT(children)); /** \brief Create a parent MX on which a bunch of MX's (sizes given as argument) will depend */ MX createParent(const std::vector<Sparsity> &deps, std::vector<MX>& SWIG_OUTPUT(children)); /** Count number of nodes */ int countNodes(const MX& A); /** \brief Get the diagonal of a matrix or construct a diagonal When the input is square, the diagonal elements are returned. If the input is vector-like, a diagonal matrix is constructed with it. */ MX diag(const MX& x); /** \brief Construct a matrix with given blocks on the diagonal */ MX blkdiag(const std::vector<MX> &A); #ifndef SWIG /** \brief Construct a matrix with given blocks on the diagonal */ MX blkdiag(const MX &A, const MX& B); #endif // SWIG /** \brief Return a col-wise summation of elements */ MX sumCols(const MX &x); /** \brief Return a row-wise summation of elements */ MX sumRows(const MX &x); /// Return summation of all elements MX sumAll(const MX &x); /** \brief Evaluate a polynomial with coefficeints p in x */ MX polyval(const MX& p, const MX& x); /** \brief Get a string representation for a binary MX, using custom arguments */ std::string getOperatorRepresentation(const MX& x, const std::vector<std::string>& args); /** \brief Substitute variable v with expression vdef in an expression ex */ MX substitute(const MX &ex, const MX& v, const MX& vdef); /** \brief Substitute variable var with expression expr in multiple expressions */ std::vector<MX> substitute(const std::vector<MX> &ex, const std::vector<MX> &v, const std::vector<MX> &vdef); /** \brief Substitute variable v with expression vdef in an expression ex, preserving nodes */ MX graph_substitute(const MX &ex, const std::vector<MX> &v, const std::vector<MX> &vdef); /** \brief Substitute variable var with expression expr in multiple expressions, preserving nodes */ std::vector<MX> graph_substitute(const std::vector<MX> &ex, const std::vector<MX> &v, const std::vector<MX> &vdef); /** \brief Inplace substitution * Substitute variables v out of the expressions vdef sequentially */ #ifndef SWIG void substituteInPlace(const std::vector<MX>& v, std::vector<MX>& vdef, bool reverse=false); #else // SWIG void substituteInPlace(const std::vector<MX>& v, std::vector<MX>& INOUT, bool reverse=false); #endif // SWIG /** \brief Inplace substitution with piggyback expressions * Substitute variables v out of the expressions vdef sequentially, as well as out of a number of other expressions piggyback */ #ifndef SWIG void substituteInPlace(const std::vector<MX>& v, std::vector<MX>& vdef, std::vector<MX>& ex, bool reverse=false); #else // SWIG void substituteInPlace(const std::vector<MX>& v, std::vector<MX>& INOUT, std::vector<MX>& INOUT, bool reverse=false); #endif // SWIG /** \brief Extract shared subexpressions from an set of expressions */ void extractShared(std::vector<MX>& ex, std::vector<MX>& v, std::vector<MX>& vdef, const std::string& v_prefix="v_", const std::string& v_suffix=""); /** \brief Print compact, introducing new variables for shared subexpressions */ void printCompact(const MX& ex, std::ostream &stream=std::cout); //@{ /** \brief Calculate jacobian via source code transformation Uses CasADi::MXFunction::jac */ MX jacobian(const MX &ex, const MX &arg); MX gradient(const MX &ex, const MX &arg); MX tangent(const MX &ex, const MX &arg); //@} /** \brief Computes the nullspace of a matrix A * * Finds Z m-by-(m-n) such that AZ = 0 * with A n-by-m with m > n * * Assumes A is full rank * * Inspired by Numerical Methods in Scientific Computing by Ake Bjorck */ MX nullspace(const MX& A); /** \brief Matrix determinant (experimental) */ MX det(const MX& A); /** \brief Matrix inverse (experimental) */ MX inv(const MX& A); /** \brief Get all symbols contained in the supplied expression * Get all symbols on which the supplied expression depends * \see MXFunction::getFree() */ std::vector<MX> getSymbols(const MX& e); /** \brief Get all symbols contained in the supplied expression * Get all symbols on which the supplied expression depends * \see MXFunction::getFree() */ std::vector<MX> getSymbols(const std::vector<MX>& e); /** \brief Check if expression depends on any of the arguments The arguments must be symbolic */ bool dependsOn(const MX& ex, const std::vector<MX> &arg); /** \brief Expand MX graph to SXFunction call * * Expand the given expression e, optionally * supplying expressions contained in it at which expansion should stop. * */ MX matrix_expand(const MX& e, const std::vector<MX> &boundary = std::vector<MX>()); /** \brief Expand MX graph to SXFunction call * * Expand the given expression e, optionally * supplying expressions contained in it at which expansion should stop. * */ std::vector<MX> matrix_expand(const std::vector<MX>& e, const std::vector<MX> &boundary = std::vector<MX>()); /** \brief Kronecker tensor product * * Creates a block matrix in which each element (i,j) is a_ij*b */ MX kron(const MX& a, const MX& b); /** \brief Solve a system of equations: A*x = b */ MX solve(const MX& A, const MX& b, linearSolverCreator lsolver = SymbolicQR::creator, const Dictionary& dict = Dictionary()); /** \brief Computes the Moore-Penrose pseudo-inverse * * If the matrix A is fat (size1>size2), mul(A,pinv(A)) is unity. * If the matrix A is slender (size2<size1), mul(pinv(A),A) is unity. * */ MX pinv(const MX& A, linearSolverCreator lsolver, const Dictionary& dict = Dictionary()); /// \cond INTERNAL #ifndef WITHOUT_PRE_1_9_X /** \brief [DEPRECATED] */ //@{ inline MX msym(const std::string& name, int nrow=1, int ncol=1){ return MX::sym(name,nrow,ncol); } inline MX msym(const std::string& name, const std::pair<int,int> & rc){ return MX::sym(name,rc);} inline std::vector<MX> msym(const std::string& name, const Sparsity& sp, int p){ return MX::sym(name,sp,p);} inline std::vector<MX> msym(const std::string& name, int nrow, int ncol, int p){ return MX::sym(name,nrow,ncol,p);} inline std::vector<std::vector<MX> > msym(const std::string& name, const Sparsity& sp, int p, int r){ return MX::sym(name,sp,p,r);} inline std::vector<std::vector<MX> > msym(const std::string& name, int nrow, int ncol, int p, int r){ return MX::sym(name,nrow,ncol,p,r);} inline MX msym(const std::string& name, const Sparsity& sp){ return MX::sym(name,sp);} inline MX msym(const Matrix<double>& x){ return MX(x);} inline bool isVector(const MX& ex){ return ex.isVector();} inline bool isDense(const MX& ex){ return ex.isDense();} inline void makeDense(MX& x){ return x.densify();} inline MX densify(const MX& x){ MX ret(x); ret.densify(); return ret;} inline bool isSymbolic(const MX& ex){ return ex.isSymbolic();} inline bool isSymbolicSparse(const MX& ex){ return ex.isSymbolicSparse();} inline bool isIdentity(const MX& ex){ return ex.isIdentity();} inline bool isZero(const MX& ex){ return ex.isZero();} inline bool isOne(const MX& ex){ return ex.isOne();} inline bool isMinusOne(const MX& ex){ return ex.isMinusOne();} inline bool isTranspose(const MX& ex){ return ex.isTranspose();} inline bool isRegular(const MX& ex){ return ex.isRegular();} inline MX trans(const MX &x){ return transpose(x);} //@} #endif /// \endcond /** @} */ } // namespace CasADi
A : DenseMatrix 4 x 3 B : SparseMatrix 4 x 3 , 5 structural non-zeros k = A.find() A[k] will contain the elements of A that are non-zero in B */ std::vector<int> find(bool ind1=SWIG_IND1) const; #ifndef SWIG /// Get the location of all nonzero elements (inplace version) void find(std::vector<int>& loc, bool ind1=false) const; #endif // SWIG /** \brief Perform a unidirectional coloring: A greedy distance-2 coloring algorithm (Algorithm 3.1 in A. H. GEBREMEDHIN, F. MANNE, A. POTHEN) */ Sparsity unidirectionalColoring(const Sparsity& AT=Sparsity(), int cutoff = std::numeric_limits<int>::max()) const; /** \brief Perform a star coloring of a symmetric matrix: A greedy distance-2 coloring algorithm Algorithm 4.1 in What Color Is Your Jacobian? Graph Coloring for Computing Derivatives A. H. GEBREMEDHIN, F. MANNE, A. POTHEN SIAM Rev., 47(4), 629–705 (2006) Ordering options: None (0), largest first (1) */ Sparsity starColoring(int ordering = 1, int cutoff = std::numeric_limits<int>::max()) const; /** \brief Perform a star coloring of a symmetric matrix: A new greedy distance-2 coloring algorithm
void Sqpmethod::init() { // Call the init method of the base class NlpSolverInternal::init(); // Read options max_iter_ = getOption("max_iter"); max_iter_ls_ = getOption("max_iter_ls"); c1_ = getOption("c1"); beta_ = getOption("beta"); merit_memsize_ = getOption("merit_memory"); lbfgs_memory_ = getOption("lbfgs_memory"); tol_pr_ = getOption("tol_pr"); tol_du_ = getOption("tol_du"); regularize_ = getOption("regularize"); exact_hessian_ = getOption("hessian_approximation")=="exact"; min_step_size_ = getOption("min_step_size"); // Get/generate required functions gradF(); jacG(); if (exact_hessian_) { hessLag(); } // Allocate a QP solver Sparsity H_sparsity = exact_hessian_ ? hessLag().output().sparsity() : Sparsity::dense(nx_, nx_); H_sparsity = H_sparsity + Sparsity::diag(nx_); Sparsity A_sparsity = jacG().isNull() ? Sparsity(0, nx_) : jacG().output().sparsity(); // QP solver options Dict qp_solver_options; if (hasSetOption("qp_solver_options")) { qp_solver_options = getOption("qp_solver_options"); } // Allocate a QP solver qp_solver_ = QpSolver("qp_solver", getOption("qp_solver"), make_map("h", H_sparsity, "a", A_sparsity), qp_solver_options); // Lagrange multipliers of the NLP mu_.resize(ng_); mu_x_.resize(nx_); // Lagrange gradient in the next iterate gLag_.resize(nx_); gLag_old_.resize(nx_); // Current linearization point x_.resize(nx_); x_cand_.resize(nx_); x_old_.resize(nx_); // Constraint function value gk_.resize(ng_); gk_cand_.resize(ng_); // Hessian approximation Bk_ = DMatrix::zeros(H_sparsity); // Jacobian Jk_ = DMatrix::zeros(A_sparsity); // Bounds of the QP qp_LBA_.resize(ng_); qp_UBA_.resize(ng_); qp_LBX_.resize(nx_); qp_UBX_.resize(nx_); // QP solution dx_.resize(nx_); qp_DUAL_X_.resize(nx_); qp_DUAL_A_.resize(ng_); // Gradient of the objective gf_.resize(nx_); // Create Hessian update function if (!exact_hessian_) { // Create expressions corresponding to Bk, x, x_old, gLag and gLag_old SX Bk = SX::sym("Bk", H_sparsity); SX x = SX::sym("x", input(NLP_SOLVER_X0).sparsity()); SX x_old = SX::sym("x", x.sparsity()); SX gLag = SX::sym("gLag", x.sparsity()); SX gLag_old = SX::sym("gLag_old", x.sparsity()); SX sk = x - x_old; SX yk = gLag - gLag_old; SX qk = mul(Bk, sk); // Calculating theta SX skBksk = inner_prod(sk, qk); SX omega = if_else(inner_prod(yk, sk) < 0.2 * inner_prod(sk, qk), 0.8 * skBksk / (skBksk - inner_prod(sk, yk)), 1); yk = omega * yk + (1 - omega) * qk; SX theta = 1. / inner_prod(sk, yk); SX phi = 1. / inner_prod(qk, sk); SX Bk_new = Bk + theta * mul(yk, yk.T()) - phi * mul(qk, qk.T()); // Inputs of the BFGS update function vector<SX> bfgs_in(BFGS_NUM_IN); bfgs_in[BFGS_BK] = Bk; bfgs_in[BFGS_X] = x; bfgs_in[BFGS_X_OLD] = x_old; bfgs_in[BFGS_GLAG] = gLag; bfgs_in[BFGS_GLAG_OLD] = gLag_old; bfgs_ = SXFunction("bfgs", bfgs_in, make_vector(Bk_new)); // Initial Hessian approximation B_init_ = DMatrix::eye(nx_); } // Header if (static_cast<bool>(getOption("print_header"))) { userOut() << "-------------------------------------------" << endl << "This is casadi::SQPMethod." << endl; if (exact_hessian_) { userOut() << "Using exact Hessian" << endl; } else { userOut() << "Using limited memory BFGS Hessian approximation" << endl; } userOut() << endl << "Number of variables: " << setw(9) << nx_ << endl << "Number of constraints: " << setw(9) << ng_ << endl << "Number of nonzeros in constraint Jacobian: " << setw(9) << A_sparsity.nnz() << endl << "Number of nonzeros in Lagrangian Hessian: " << setw(9) << H_sparsity.nnz() << endl << endl; } }
Project::Project(const MX& x, const Sparsity& sp) { setDependencies(x); setSparsity(Sparsity(sp)); }