27 #ifndef CASADI_SPARSITY_HPP
28 #define CASADI_SPARSITY_HPP
30 #include "shared_object.hpp"
31 #include "printable.hpp"
32 #include "casadi_common.hpp"
33 #include "sparsity_interface.hpp"
34 #include "generic_type.hpp"
38 #include <unordered_map>
39 #ifdef CASADI_WITH_THREAD
40 #ifdef CASADI_WITH_THREAD_MINGW
41 #include <mingw.mutex.h>
49 class SparsityInternal;
50 class SerializingStream;
51 class DeserializingStream;
61 const casadi_int*
row;
199 public SWIG_IF_ELSE(SparsityInterfaceCommon, SparsityInterface<Sparsity>),
200 public SWIG_IF_ELSE(PrintableCommon, Printable<Sparsity>) {
248 explicit Sparsity(casadi_int dummy=0);
303 Sparsity(casadi_int nrow, casadi_int ncol);
379 Sparsity(casadi_int nrow, casadi_int ncol,
380 const std::vector<casadi_int>& colind,
const std::vector<casadi_int>& row,
381 bool order_rows=
false);
386 explicit Sparsity(
const std::pair<casadi_int, casadi_int>& rc);
390 Sparsity(casadi_int nrow, casadi_int ncol,
const casadi_int* colind,
const casadi_int* row,
391 bool order_rows=
false);
455 {
return dense_scalar ? dense(1, 1) :
Sparsity(1, 1); }
520 static Sparsity dense(casadi_int nrow, casadi_int ncol=1);
522 return dense(rc.first, rc.second);
563 static Sparsity unit(casadi_int n, casadi_int el);
612 static Sparsity upper(casadi_int n);
664 static Sparsity lower(casadi_int n);
724 static Sparsity diag(casadi_int nrow, casadi_int ncol);
726 return diag(rc.first, rc.second);
797 static Sparsity band(casadi_int n, casadi_int p);
849 static Sparsity banded(casadi_int n, casadi_int p);
899 static Sparsity rowcol(
const std::vector<casadi_int>& row,
900 const std::vector<casadi_int>& col,
901 casadi_int nrow, casadi_int ncol);
992 static Sparsity triplet(casadi_int nrow, casadi_int ncol,
993 const std::vector<casadi_int>& row,
const std::vector<casadi_int>& col,
994 std::vector<casadi_int>& SWIG_OUTPUT(mapping),
bool invert_mapping);
995 static Sparsity triplet(casadi_int nrow, casadi_int ncol,
const std::vector<casadi_int>& row,
996 const std::vector<casadi_int>& col);
1057 static Sparsity nonzeros(casadi_int nrow, casadi_int ncol,
const std::vector<casadi_int>& nz,
1058 bool ind1=SWIG_IND1);
1119 static Sparsity compressed(
const std::vector<casadi_int>& v,
bool order_rows=
false);
1121 static Sparsity compressed(
const casadi_int* v,
bool order_rows=
false);
1200 static Sparsity permutation(
const std::vector<casadi_int>& p,
bool invert=
false);
1256 const std::vector<casadi_int> permutation_vector(
bool invert=
false)
const;
1315 Sparsity get_diag(std::vector<casadi_int>& SWIG_OUTPUT(mapping))
const;
1366 std::vector<casadi_int> compress(
bool canonical=
true)
const;
1430 bool is_equal(const Sparsity& y) const;
1432 bool is_equal(casadi_int nrow, casadi_int ncol,
const std::vector<casadi_int>& colind,
1433 const std::vector<casadi_int>& row)
const;
1435 bool is_equal(casadi_int nrow, casadi_int ncol,
1436 const casadi_int* colind,
const casadi_int* row)
const;
1486 bool is_stacked(
const Sparsity& y, casadi_int n)
const;
1495 operator const casadi_int*()
const;
1500 operator const std::vector<casadi_int>&()
const;
1540 casadi_int size1()
const;
1543 casadi_int
rows()
const {
return size1();}
1546 casadi_int size2()
const;
1582 casadi_int numel()
const;
1619 double density()
const;
1666 bool is_empty(
bool both=
false)
const;
1676 casadi_int nnz()
const;
1732 casadi_int nnz_upper(
bool strictly=
false)
const;
1741 casadi_int nnz_lower(
bool strictly=
false)
const;
1748 casadi_int nnz_diag()
const;
1790 casadi_int bw_upper()
const;
1832 casadi_int bw_lower()
const;
1867 std::pair<casadi_int, casadi_int> size()
const;
1875 casadi_int size(casadi_int axis)
const;
1998 void to_file(
const std::string&
filename,
const std::string& format_hint=
"")
const;
2008 static Sparsity from_file(
const std::string&
filename,
const std::string& format_hint=
"");
2014 void serialize(std::ostream &stream)
const;
2060 std::string serialize()
const;
2065 static Sparsity deserialize(std::istream& stream);
2072 static Sparsity deserialize(
const std::string& s);
2090 const casadi_int* row()
const;
2095 const casadi_int* colind()
const;
2156 std::vector<casadi_int> get_row()
const;
2167 std::vector<casadi_int> get_colind()
const;
2212 casadi_int colind(casadi_int cc)
const;
2221 casadi_int row(casadi_int el)
const;
2231 std::vector<casadi_int> get_col()
const;
2289 void resize(casadi_int nrow, casadi_int ncol);
2351 casadi_int add_nz(casadi_int rr, casadi_int cc);
2397 casadi_int get_nz(casadi_int rr, casadi_int cc)
const;
2430 bool has_nz(casadi_int rr, casadi_int cc)
const;
2465 std::vector<casadi_int> get_nz(
const std::vector<casadi_int>& rr,
2466 const std::vector<casadi_int>& cc)
const;
2514 void get_nz(std::vector<casadi_int>& SWIG_INOUT(indices))
const;
2553 std::vector<casadi_int> get_lower()
const;
2560 std::vector<casadi_int> get_upper()
const;
2594 void get_ccs(std::vector<casadi_int>& SWIG_OUTPUT(colind),
2595 std::vector<casadi_int>& SWIG_OUTPUT(row))
const;
2633 void get_crs(std::vector<casadi_int>& SWIG_OUTPUT(rowind),
2634 std::vector<casadi_int>& SWIG_OUTPUT(col))
const;
2670 void get_triplet(std::vector<casadi_int>& SWIG_OUTPUT(row),
2671 std::vector<casadi_int>& SWIG_OUTPUT(col))
const;
2745 Sparsity sub(
const std::vector<casadi_int>& rr,
2746 const std::vector<casadi_int>& cc,
2747 std::vector<casadi_int>& SWIG_OUTPUT(mapping),
bool ind1=
false)
const;
2816 std::vector<casadi_int>& SWIG_OUTPUT(mapping),
bool ind1=
false)
const;
2914 Sparsity transpose(std::vector<casadi_int>& SWIG_OUTPUT(mapping),
2915 bool invert_mapping=
false)
const;
2955 bool is_transpose(
const Sparsity& y)
const;
2998 bool is_reshape(
const Sparsity& y)
const;
3046 bool is_compactible(std::vector<casadi_int>& SWIG_OUTPUT(row),
3047 std::vector<casadi_int>& SWIG_OUTPUT(col))
const;
3123 std::vector<unsigned char>& mapping)
const;
3186 Sparsity unite(
const Sparsity& y, std::vector<unsigned char>& mapping)
const;
3236 std::vector<unsigned char>& mapping)
const;
3289 bool is_subset(
const Sparsity& rhs)
const;
3421 static Sparsity horzcat(
const std::vector<Sparsity> & sp);
3422 static Sparsity vertcat(
const std::vector<Sparsity> & sp);
3423 static Sparsity blockcat(
const std::vector< std::vector< Sparsity > > &v);
3424 static Sparsity diagcat(
const std::vector< Sparsity > &v);
3425 static std::vector<Sparsity>
3426 horzsplit(
const Sparsity& x,
const std::vector<casadi_int>& offset);
3427 static std::vector<Sparsity>
3428 vertsplit(
const Sparsity& x,
const std::vector<casadi_int>& offset);
3429 static std::vector<Sparsity>
3431 const std::vector<casadi_int>& offset1,
3432 const std::vector<casadi_int>& offset2);
3434 const std::string& blas =
"reference");
3436 const std::string& =
"reference") {
return z;}
3437 static Sparsity reshape(
const Sparsity& x, casadi_int nrow, casadi_int ncol);
3440 static casadi_int sprank(
const Sparsity& x);
3538 void enlarge(casadi_int nrow, casadi_int ncol,
3539 const std::vector<casadi_int>& rr,
3540 const std::vector<casadi_int>& cc,
bool ind1=
false);
3581 void enlargeRows(casadi_int nrow,
const std::vector<casadi_int>& rr,
bool ind1=
false);
3619 void enlargeColumns(casadi_int ncol,
const std::vector<casadi_int>& cc,
bool ind1=
false);
3655 Sparsity makeDense(std::vector<casadi_int>& SWIG_OUTPUT(mapping))
const;
3711 std::vector<casadi_int> erase(
const std::vector<casadi_int>& rr,
3712 const std::vector<casadi_int>& cc,
bool ind1=
false);
3777 std::vector<casadi_int> erase(
const std::vector<casadi_int>& rr,
bool ind1=
false);
3882 void appendColumns(
const Sparsity& sp);
3919 bool is_scalar(
bool scalar_and_dense=
false)
const;
3962 bool is_dense()
const;
3998 bool is_row()
const;
4032 bool is_column()
const;
4074 bool is_vector()
const;
4117 bool is_diag()
const;
4149 bool is_square()
const;
4186 bool is_symmetric()
const;
4230 bool is_triu(
bool strictly =
false)
const;
4272 bool is_tril(
bool strictly =
false)
const;
4323 bool is_singular()
const;
4422 bool is_selection(
bool allow_empty=
false)
const;
4481 bool is_orthonormal(
bool allow_empty=
false)
const;
4524 bool is_orthonormal_rows(
bool allow_empty=
false)
const;
4537 bool is_orthonormal_columns(
bool allow_empty=
false)
const;
4576 bool rowsSequential(
bool strictly=
true)
const;
4617 void removeDuplicates(std::vector<casadi_int>& SWIG_INOUT(mapping));
4620 typedef std::unordered_multimap<std::size_t, WeakRef>
CachingMap;
4625 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
4627 static std::mutex cachingmap_mtx;
4631 static const Sparsity& getScalar();
4634 static const Sparsity& getScalarSparse();
4684 std::vector<casadi_int> etree(
bool ata=
false)
const;
4757 Sparsity ldl(std::vector<casadi_int>& SWIG_OUTPUT(p),
bool amd=
true)
const;
4818 std::vector<casadi_int>& SWIG_OUTPUT(prinv),
4819 std::vector<casadi_int>& SWIG_OUTPUT(pc),
bool amd=
true)
const;
4866 casadi_int dfs(casadi_int j, casadi_int top, std::vector<casadi_int>& SWIG_INOUT1(xi),
4867 std::vector<casadi_int>& SWIG_INOUT2(pstack),
4868 const std::vector<casadi_int>& pinv, std::vector<bool>& SWIG_INOUT3(marked))
const;
4963 casadi_int scc(std::vector<casadi_int>& SWIG_OUTPUT(index),
4964 std::vector<casadi_int>& SWIG_OUTPUT(offset))
const;
5059 casadi_int btf(std::vector<casadi_int>& SWIG_OUTPUT(rowperm),
5060 std::vector<casadi_int>& SWIG_OUTPUT(colperm),
5061 std::vector<casadi_int>& SWIG_OUTPUT(rowblock),
5062 std::vector<casadi_int>& SWIG_OUTPUT(colblock),
5063 std::vector<casadi_int>& SWIG_OUTPUT(coarse_rowblock),
5064 std::vector<casadi_int>& SWIG_OUTPUT(coarse_colblock))
const;
5117 std::vector<casadi_int> amd()
const;
5173 std::vector<casadi_int>
find(
bool ind1=SWIG_IND1)
const;
5177 void find(std::vector<casadi_int>& loc,
bool ind1=
false)
const;
5275 casadi_int cutoff = std::numeric_limits<casadi_int>::max())
const;
5360 Sparsity star_coloring_new(std::vector<casadi_int>& SWIG_OUTPUT(which_color),
5426 Sparsity star_coloring(casadi_int ordering = 1,
5427 casadi_int cutoff = std::numeric_limits<casadi_int>::max())
const;
5473 Sparsity star_coloring2(casadi_int ordering = 1,
5474 casadi_int cutoff = std::numeric_limits<casadi_int>::max())
const;
5509 std::vector<casadi_int> largest_first()
const;
5606 Sparsity pmult(
const std::vector<casadi_int>& p,
5607 bool permute_rows=
true,
bool permute_columns=
true,
5658 std::string dim(
bool with_nz=
false)
const;
5714 std::string postfix_dim()
const;
5755 std::string repr_el(casadi_int k)
const;
5832 void spy_matlab(
const std::string& mfile)
const;
5921 void export_code(
const std::string& lang, std::ostream &stream=
casadi::uout(),
5964 std::size_t hash()
const;
6039 bool with_x_diag=
true,
bool with_lam_g_diag=
true);
6047 template<
typename T>
6055 template<
typename T>
6063 template<
typename T>
6066 static std::string file_format(
const std::string&
filename,
6067 const std::string& format_hint,
const std::set<std::string>& file_formats);
6072 void assign_cached(casadi_int nrow, casadi_int ncol,
const std::vector<casadi_int>& colind,
6073 const std::vector<casadi_int>& row,
bool order_rows=
false);
6076 void assign_cached(casadi_int nrow, casadi_int ncol,
6077 const casadi_int* colind,
const casadi_int* row,
bool order_rows=
false);
6085 CASADI_EXPORT std::size_t
hash_sparsity(casadi_int nrow, casadi_int ncol,
6086 const std::vector<casadi_int>& colind,
6087 const std::vector<casadi_int>& row);
6089 CASADI_EXPORT std::size_t
hash_sparsity(casadi_int nrow, casadi_int ncol,
6090 const casadi_int* colind,
6091 const casadi_int* row);
6095 template<
typename DataType>
6098 const casadi_int sz =
nnz();
6099 const casadi_int sz1 =
size1();
6100 const casadi_int sz2 =
size2();
6103 const casadi_int val_sz = val_sp.
nnz();
6104 const casadi_int val_sz1 = val_sp.
size1();
6105 const casadi_int val_sz2 = val_sp.
size2();
6106 const casadi_int val_nel = val_sz1*val_sz2;
6109 if (val_sp==*
this) {
6110 std::copy(val_data, val_data+sz, data);
6117 }
else if (val_nel==1) {
6118 std::fill(data, data+sz, val_sz==0 ? DataType(0) : val_data[0]);
6119 }
else if (sz2==val_sz2 && sz1==val_sz1) {
6122 const casadi_int* c =
row();
6123 const casadi_int* rind =
colind();
6124 const casadi_int* v_c = val_sp.
row();
6125 const casadi_int* v_rind = val_sp.
colind();
6128 for (casadi_int i=0; i<sz2; ++i) {
6131 casadi_int v_el = v_rind[i];
6134 casadi_int v_el_end = v_rind[i+1];
6137 casadi_int v_j = v_el<v_el_end ? v_c[v_el] : sz1;
6140 for (casadi_int el=rind[i]; el!=rind[i+1]; ++el) {
6148 v_j = v_el<v_el_end ? v_c[v_el] : sz1;
6153 data[el] = val_data[v_el++];
6154 v_j = v_el<v_el_end ? v_c[v_el] : sz1;
6160 }
else if (sz1==val_sz2 && sz2==val_sz1 && sz2 == 1) {
6162 const casadi_int* v_cind = val_sp.
colind();
6163 const casadi_int* r =
row();
6164 for (casadi_int el=0; el<sz; ++el) {
6165 casadi_int rr=r[el];
6166 data[el] = v_cind[rr]==v_cind[rr+1] ? 0 : val_data[v_cind[rr]];
6168 }
else if (sz1==val_sz2 && sz2==val_sz1 && sz1 == 1) {
6170 for (casadi_int el=0; el<sz; ++el) data[el] = 0;
6171 const casadi_int* cind =
colind();
6172 const casadi_int* v_r = val_sp.
row();
6173 for (casadi_int el=0; el<val_sz; ++el) {
6174 casadi_int rr=v_r[el];
6175 if (cind[rr]!=cind[rr+1]) {
6176 data[cind[rr]] = val_data[el];
6181 casadi_error(
"Sparsity::set<DataType>: shape mismatch. lhs is "
6182 +
dim() +
", while rhs is " + val_sp.
dim() +
".");
6186 template<
typename DataType>
6189 const casadi_int sz =
nnz();
6190 const casadi_int sz1 =
size1();
6191 const casadi_int sz2 =
size2();
6192 const casadi_int nel = sz1*sz2;
6195 const casadi_int val_sz = val_sp.
nnz();
6196 const casadi_int val_sz1 = val_sp.
size1();
6197 const casadi_int val_sz2 = val_sp.
size2();
6198 const casadi_int val_nel = val_sz1*val_sz2;
6201 if (val_sp==*
this) {
6202 for (casadi_int k=0; k<sz; ++k) {
6203 data[k] += val_data[k];
6211 }
else if (val_nel==1) {
6213 for (casadi_int k=0; k<sz; ++k) {
6214 data[k] += val_data[0];
6219 if (nel==0 && val_nel==0)
return;
6222 casadi_assert(sz2==val_sz2 && sz1==val_sz1,
6223 "Sparsity::add<DataType>: shape mismatch. lhs is "
6224 +
dim() +
", while rhs is " + val_sp.
dim() +
".");
6227 const casadi_int* c =
row();
6228 const casadi_int* rind =
colind();
6229 const casadi_int* v_c = val_sp.
row();
6230 const casadi_int* v_rind = val_sp.
colind();
6233 for (casadi_int i=0; i<sz2; ++i) {
6236 casadi_int v_el = v_rind[i];
6239 casadi_int v_el_end = v_rind[i+1];
6242 casadi_int v_j = v_el<v_el_end ? v_c[v_el] : sz1;
6245 for (casadi_int el=rind[i]; el!=rind[i+1]; ++el) {
6253 v_j = v_el<v_el_end ? v_c[v_el] : sz1;
6258 data[el] += val_data[v_el++];
6259 v_j = v_el<v_el_end ? v_c[v_el] : sz1;
6266 template<
typename DataType>
6269 const casadi_int sz =
nnz();
6270 const casadi_int sz1 =
size1();
6271 const casadi_int sz2 =
size2();
6272 const casadi_int nel = sz1*sz2;
6275 const casadi_int val_sz = val_sp.
nnz();
6276 const casadi_int val_sz1 = val_sp.
size1();
6277 const casadi_int val_sz2 = val_sp.
size2();
6278 const casadi_int val_nel = val_sz1*val_sz2;
6281 if (val_sp==*
this) {
6282 for (casadi_int k=0; k<sz; ++k) {
6283 data[k] |= val_data[k];
6291 }
else if (val_nel==1) {
6293 for (casadi_int k=0; k<sz; ++k) {
6294 data[k] |= val_data[0];
6299 if (nel==0 && val_nel==0)
return;
6302 casadi_assert(sz2==val_sz2 && sz1==val_sz1,
6303 "Sparsity::add<DataType>: shape mismatch. lhs is "
6304 +
dim() +
", while rhs is " + val_sp.
dim() +
".");
6307 const casadi_int* c =
row();
6308 const casadi_int* rind =
colind();
6309 const casadi_int* v_c = val_sp.
row();
6310 const casadi_int* v_rind = val_sp.
colind();
6313 for (casadi_int i=0; i<sz2; ++i) {
6316 casadi_int v_el = v_rind[i];
6319 casadi_int v_el_end = v_rind[i+1];
6322 casadi_int v_j = v_el<v_el_end ? v_c[v_el] : sz1;
6325 for (casadi_int el=rind[i]; el!=rind[i+1]; ++el) {
6333 v_j = v_el<v_el_end ? v_c[v_el] : sz1;
6338 data[el] |= val_data[v_el++];
6339 v_j = v_el<v_el_end ? v_c[v_el] : sz1;
6350 typedef std::map<std::string, Sparsity>
SpDict;
Helper class for Serialization.
Helper class for Serialization.
GenericShared implements a reference counting framework similar for efficient and.
casadi_int columns() const
Number of columns, Octave-style alias of size2.
void bor(T *data, const T *val_data, const Sparsity &val_sp) const
Bitwise or of the nonzero entries of one sparsity pattern and the nonzero.
static std::string type_name()
Readable name of the public class.
std::unordered_multimap< std::size_t, WeakRef > CachingMap
casadi_int size1() const
Number of rows.
static std::set< std::string > file_formats
static Sparsity dense(const std::pair< casadi_int, casadi_int > &rc)
Create a dense rectangular sparsity pattern.
static Sparsity diag(casadi_int nrow)
Create a diagonal sparsity pattern.
static Sparsity diag(const std::pair< casadi_int, casadi_int > &rc)
Create a diagonal sparsity pattern.
void add(T *data, const T *val_data, const Sparsity &val_sp) const
Add the nonzero entries of one sparsity pattern to the nonzero entries.
std::string dim(bool with_nz=false) const
Dimensions as a string "nrow x ncol", optionally with the number of nonzeros.
void set(T *data, const T *val_data, const Sparsity &val_sp) const
Assign the nonzero entries of one sparsity pattern to the nonzero.
static Sparsity mac(const Sparsity &x, const Sparsity &y, const Sparsity &z, const std::string &="reference")
Accessed by SparsityInterface.
casadi_int rows() const
Number of rows, Octave-style alias of size1.
casadi_int nnz() const
Number of structural nonzeros.
casadi_int size2() const
Number of columns.
const casadi_int * row() const
Get a reference to row-vector,.
static Sparsity scalar(bool dense_scalar=true)
Create a 1-by-1 sparsity pattern.
bool is_empty(bool both=false) const
Check whether the pattern has a zero dimension.
bool operator!=(const Sparsity &y) const
Check whether two sparsity patterns differ (negation of is_equal)
const casadi_int * colind() const
Get a reference to the colindex of all column element (see class description)
bool operator==(const Sparsity &y) const
Check whether two sparsity patterns are identical.
SparsityInterface< Sparsity > B
Base class.
bool is_equal(double x, double y, casadi_int depth=0)
std::vector< casadi_int > invert_permutation(const std::vector< casadi_int > &a)
inverse a permutation vector
unsigned long long bvec_t
Dict combine(const Dict &first, const Dict &second, bool recurse)
Combine two dicts. First has priority.
std::vector< casadi_int > find(const std::vector< T > &v)
find nonzeros
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
std::size_t hash_sparsity(casadi_int nrow, casadi_int ncol, const std::vector< casadi_int > &colind, const std::vector< casadi_int > &row)
Hash a sparsity pattern.
std::map< std::string, Sparsity > SpDict
MX kron_contract(const MX &m, const MX &x, bool inner)
Kronecker contraction, the adjoint of kron.
bool is_permutation(const std::vector< casadi_int > &order)
Does the list represent a permutation?
std::string filename(const std::string &path)
Compact representation of a sparsity pattern.
const casadi_int * colind