List of all members | Public Types | Public Member Functions | Static Public Member Functions
casadi::Sparsity Class Reference

General sparsity class. More...

#include <sparsity.hpp>

Detailed Description

The storage format is a compressed column storage (CCS) format.
In this format, the structural non-zero elements are stored in column-major order, starting from the upper left corner of the matrix and ending in the lower right corner.

In addition to the dimension (size1(), size2()), (i.e. the number of rows and the number of columns respectively), there are also two vectors of integers:

  1. "colind" [length size2()+1], which contains the index to the first non-zero element on or after the corresponding column. All the non-zero elements of a particular column i are thus the elements with index el that fulfills: colind[i] <= el < colind[i+1].
  2. "row" [same length as the number of non-zero elements, nnz()] The rows for each of the structural non-zeros.

Note that with this format, it is cheap to loop over all the non-zero elements of a particular column, at constant time per element, but expensive to jump to access a location (i, j).

If the matrix is dense, i.e. length(row) == size1()*size2(), the format reduces to standard dense column major format, which allows access to an arbitrary element in constant time.

Since the object is reference counted (it inherits from SharedObject), several matrices are allowed to share the same sparsity pattern.

The implementations of methods marked as such in this class has been taken from the CSparse package and modified to fit CasADi data structures and separation of sparsity pattern calculation and numerical evaluation. These functions are Copyright(c) Timothy A. Davis, 2006-2009 and licensed as a derivative work under the GNU LGPL

Every DM, SX and MX carries a pattern, obtained with sparsity(), and a symbolic or numeric matrix can be created from one, e.g. SX.sym("x", sp) or DM(sp, 1). Entries outside the pattern are structural zeros: they are never stored and never computed with. The row indices within a column are strictly increasing.

Patterns are immutable and cached: constructing a pattern that already exists returns a reference to the cached object, so equal patterns are cheap to compare. The in-place methods (resize, enlarge, erase, append, add_nz, ...) rebind the object to a new pattern rather than modify the shared one. Use is_equal or the == operator to compare patterns; object identity is not meaningful in the target languages.

A default-constructed Sparsity is a null object (is_null() is true): it carries no pattern and most methods raise an error on it. It is used as "no pattern" sentinel, e.g. as the result of a coloring that exceeds its cutoff. Empty patterns are allowed: a 0-by-n or n-by-0 pattern has no nonzeros, is dense, and is_empty() is true for it.

   >>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
   >>> DM(sp, 1)
   DM(
   [[1, 00, 00, 1],
    [00, 00, 1, 00],
    [1, 00, 00, 00]])
   >>> sp
   Sparsity(3x4,4nz)
   >>> sp.size1(), sp.size2(), sp.nnz(), sp.numel()
   (3, 4, 4, 12)
   >>> sp.colind(), sp.row()
   ([0, 2, 2, 3, 4], [0, 2, 1, 0])
   >>> sp == Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
   True
   >>> SX.sym("x", sp)
   SX(
   [[x_0, 00, 00, x_3],
    [00, 00, x_2, 00],
    [x_1, 00, 00, 00]])
   >>> Sparsity.dense(0, 3), Sparsity().is_null()
   (Sparsity(0x3), True)

   >> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
   >> DM(sp, 1)
   [[1, 00, 00, 1],
    [00, 00, 1, 00],
    [1, 00, 00, 00]]
   >> sp
   3x4,4nz
   >> fprintf('%d %d %d %d\n', sp.size1(), sp.size2(), sp.nnz(), sp.numel())
   3 4 4 12
   >> sp.colind(), sp.row()
   0 2 2 3 4
   0 2 1 0
   >> sp == Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
   1
   >> SX.sym('x', sp)
   [[x_0, 00, 00, x_3],
    [00, 00, x_2, 00],
    [x_1, 00, 00, 00]]
   >> Sparsity.dense(0, 3), Sparsity().is_null()
   0x3
   1

   julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
   julia> ca.DM(sp, 1)
   DM(
   [[1, 00, 00, 1],
    [00, 00, 1, 00],
    [1, 00, 00, 00]])
   julia> sp
   Sparsity(3x4,4nz)
   julia> ca.size1(sp), ca.size2(sp), ca.nnz(sp), ca.numel(sp)
   (3, 4, 4, 12)
   julia> ca.colind(sp), ca.row(sp)
   ([0, 2, 2, 3, 4], [0, 2, 1, 0])
   julia> ca.is_equal(sp, ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]))
   true
   julia> ca.SX.sym("x", sp)
   SX(
   [[x_0, 00, 00, x_3],
    [00, 00, x_2, 00],
    [x_1, 00, 00, 00]])
   julia> ca.Sparsity.dense(0, 3), ca.is_null(ca.Sparsity())
   (0x3, true)

See also
Matrix
Author
Joel Andersson
Date
2010-2015

Extra doc: https://github.com/casadi/casadi/wiki/L_b9

Definition at line 197 of file sparsity.hpp.

Inheritance diagram for casadi::Sparsity:
Inheritance graph
[legend]

Public Types

using internal_base_type = SharedObjectInternal
 
using base_type = SharedObject
 

Public Member Functions

 Sparsity (casadi_int dummy=0)
 Default constructor: a null object that holds no pattern. More...
 
 Sparsity (casadi_int nrow, casadi_int ncol)
 Pattern of the given shape with all structural zeros. More...
 
 Sparsity (casadi_int nrow, casadi_int ncol, const std::vector< casadi_int > &colind, const std::vector< casadi_int > &row, bool order_rows=false)
 Construct from compressed column storage vectors. More...
 
 Sparsity (const std::pair< casadi_int, casadi_int > &rc)
 Pattern with all structural zeros, shape given as a pair (nrow, ncol) More...
 
const std::vector< casadi_int > permutation_vector (bool invert=false) const
 Recover the permutation vector p from the pattern of a permutation matrix. More...
 
Sparsity get_diag (std::vector< casadi_int > &mapping) const
 Pattern of the diagonal of a matrix, or of the diagonal matrix built from a vector. More...
 
std::vector< casadi_int > compress (bool canonical=true) const
 Compact single-vector representation of the pattern. More...
 
bool operator!= (const Sparsity &y) const
 Check whether two sparsity patterns differ (negation of is_equal) More...
 
bool is_stacked (const Sparsity &y, casadi_int n) const
 Check whether the pattern is n copies of y placed side by side. More...
 
Dict info () const
 The pattern as a dictionary with entries nrow, ncol, colind and row. More...
 
void to_file (const std::string &filename, const std::string &format_hint="") const
 Write the pattern to a file. More...
 
std::string serialize () const
 Serialize the pattern to a string. More...
 
void serialize (SerializingStream &s) const
 Serialize an object. More...
 
std::vector< casadi_int > get_row () const
 Row index of every nonzero, in nonzero (column-major) order. More...
 
std::vector< casadi_int > get_colind () const
 Column offsets of the compressed column storage. More...
 
casadi_int colind (casadi_int cc) const
 Index of the first nonzero of column cc. More...
 
casadi_int row (casadi_int el) const
 Row index of nonzero el. More...
 
std::vector< casadi_int > get_col () const
 Column index of every nonzero, in nonzero (column-major) order. More...
 
void resize (casadi_int nrow, casadi_int ncol)
 Change the shape in place, keeping the nonzeros that still fit. More...
 
casadi_int add_nz (casadi_int rr, casadi_int cc)
 Nonzero index of entry (rr, cc), inserting the entry into the pattern if needed. More...
 
casadi_int get_nz (casadi_int rr, casadi_int cc) const
 Nonzero index of entry (rr, cc), or -1 if it is a structural zero. More...
 
bool has_nz (casadi_int rr, casadi_int cc) const
 Check whether entry (rr, cc) is a structural nonzero. More...
 
std::vector< casadi_int > get_nz (const std::vector< casadi_int > &rr, const std::vector< casadi_int > &cc) const
 Nonzero indices of the block of entries with rows rr and columns cc. More...
 
void get_nz (std::vector< casadi_int > &indices) const
 Map flat (column-major) element indices to nonzero indices. More...
 
std::vector< casadi_int > get_lower () const
 Nonzero indices of the entries in the lower triangular part (row >= col) More...
 
std::vector< casadi_int > get_upper () const
 Nonzero indices of the entries in the upper triangular part (row <= col) More...
 
void get_ccs (std::vector< casadi_int > &colind, std::vector< casadi_int > &row) const
 The pattern in compressed column storage: the colind and row vectors. More...
 
void get_crs (std::vector< casadi_int > &rowind, std::vector< casadi_int > &col) const
 The pattern in compressed row storage: the rowind and col vectors. More...
 
void get_triplet (std::vector< casadi_int > &row, std::vector< casadi_int > &col) const
 The pattern in sparse triplet format: the row and column of every nonzero. More...
 
Sparsity sub (const std::vector< casadi_int > &rr, const std::vector< casadi_int > &cc, std::vector< casadi_int > &mapping, bool ind1=false) const
 Pattern of the submatrix with rows rr and columns cc. More...
 
Sparsity sub (const std::vector< casadi_int > &rr, const Sparsity &sp, std::vector< casadi_int > &mapping, bool ind1=false) const
 Pattern of a set of elements, arranged according to a given pattern. More...
 
Sparsity T () const
 Transposed pattern. More...
 
Sparsity transpose (std::vector< casadi_int > &mapping, bool invert_mapping=false) const
 Transposed pattern together with the reordering of the nonzeros. More...
 
bool is_transpose (const Sparsity &y) const
 Check whether y is the transpose of this pattern. More...
 
bool is_reshape (const Sparsity &y) const
 Check whether y is a reshape of this pattern. More...
 
bool is_compactible (std::vector< casadi_int > &row, std::vector< casadi_int > &col) const
 Check if the nonzero pattern is the Cartesian product of a row and a column subset. More...
 
bool is_subset (const Sparsity &rhs) const
 Check whether every nonzero of this pattern is also a nonzero of rhs. More...
 
Sparsity sparsity_cast_mod (const Sparsity &X, const Sparsity &Y) const
 Propagate a subset of a pattern through a sparsity cast. More...
 
Sparsity pattern_inverse () const
 Complement of the pattern: structural zeros become nonzeros and vice versa. More...
 
void enlarge (casadi_int nrow, casadi_int ncol, const std::vector< casadi_int > &rr, const std::vector< casadi_int > &cc, bool ind1=false)
 Enlarge the pattern in place by inserting empty rows and columns. More...
 
void enlargeRows (casadi_int nrow, const std::vector< casadi_int > &rr, bool ind1=false)
 Enlarge the pattern in place by inserting empty rows. More...
 
void enlargeColumns (casadi_int ncol, const std::vector< casadi_int > &cc, bool ind1=false)
 Enlarge the pattern in place by inserting empty columns. More...
 
Sparsity makeDense (std::vector< casadi_int > &mapping) const
 Dense pattern of the same shape, with the flat index of every nonzero. More...
 
std::vector< casadi_int > erase (const std::vector< casadi_int > &rr, const std::vector< casadi_int > &cc, bool ind1=false)
 Turn the entries with rows rr and columns cc into structural zeros, in place. More...
 
std::vector< casadi_int > erase (const std::vector< casadi_int > &rr, bool ind1=false)
 Turn the entries with flat (column-major) indices rr into structural zeros. More...
 
void append (const Sparsity &sp)
 Append a pattern below this one, in place (vertical concatenation) More...
 
void appendColumns (const Sparsity &sp)
 Append a pattern to the right of this one, in place (horizontal concatenation) More...
 
bool is_scalar (bool scalar_and_dense=false) const
 Check whether the pattern is 1-by-1. More...
 
bool is_dense () const
 Check whether every entry is a structural nonzero, i.e. nnz() == numel() More...
 
bool is_row () const
 Check whether the pattern is a row vector, i.e. size1() == 1. More...
 
bool is_column () const
 Check whether the pattern is a column vector, i.e. size2() == 1. More...
 
bool is_vector () const
 Check whether the pattern is a row or a column vector. More...
 
bool is_diag () const
 Check whether the pattern is square with exactly the full diagonal as nonzeros. More...
 
bool is_square () const
 Check whether the number of rows equals the number of columns. More...
 
bool is_symmetric () const
 Check whether the pattern equals its transpose. More...
 
bool is_triu (bool strictly=false) const
 Check whether all nonzeros are on or above the diagonal (row <= col) More...
 
bool is_tril (bool strictly=false) const
 Check whether all nonzeros are on or below the diagonal (row >= col) More...
 
bool is_singular () const
 Check whether a square pattern is structurally singular. More...
 
bool is_permutation () const
 Check whether the pattern is that of a permutation matrix. More...
 
bool is_selection (bool allow_empty=false) const
 Check whether the pattern is that of a selection matrix. More...
 
bool is_orthonormal (bool allow_empty=false) const
 Check whether every row and every column has at most one nonzero. More...
 
bool is_orthonormal_rows (bool allow_empty=false) const
 Check whether the rows are orthonormal: one nonzero per row, at most one per column. More...
 
bool is_orthonormal_columns (bool allow_empty=false) const
 Check whether the columns are orthonormal (see is_orthonormal_rows) More...
 
bool rowsSequential (bool strictly=true) const
 Check whether the row indices are increasing within every column. More...
 
void removeDuplicates (std::vector< casadi_int > &mapping)
 Remove duplicate entries, in place. More...
 
std::vector< casadi_int > etree (bool ata=false) const
 Elimination tree of the pattern. More...
 
Sparsity ldl (std::vector< casadi_int > &p, bool amd=true) const
 Symbolic LDL factorization of a symmetric pattern. More...
 
void qr_sparse (Sparsity &V, Sparsity &R, std::vector< casadi_int > &prinv, std::vector< casadi_int > &pc, bool amd=true) const
 Symbolic QR factorization. More...
 
casadi_int dfs (casadi_int j, casadi_int top, std::vector< casadi_int > &SWIG_INOUT1(xi), std::vector< casadi_int > &SWIG_INOUT2(pstack), const std::vector< casadi_int > &pinv, std::vector< bool > &SWIG_INOUT3(marked)) const
 Depth-first search on the adjacency graph of the sparsity. More...
 
casadi_int scc (std::vector< casadi_int > &index, std::vector< casadi_int > &offset) const
 Strongly connected components of the directed graph of a square pattern. More...
 
casadi_int btf (std::vector< casadi_int > &rowperm, std::vector< casadi_int > &colperm, std::vector< casadi_int > &rowblock, std::vector< casadi_int > &colblock, std::vector< casadi_int > &coarse_rowblock, std::vector< casadi_int > &coarse_colblock) const
 Block triangular form (BTF) through the Dulmage-Mendelsohn decomposition. More...
 
std::vector< casadi_int > amd () const
 Approximate minimum degree (AMD) ordering of a symmetric pattern. More...
 
std::vector< casadi_int > find (bool ind1=SWIG_IND1) const
 Flat (column-major) element index of every nonzero. More...
 
Sparsity uni_coloring (const Sparsity &AT=Sparsity(), casadi_int cutoff=std::numeric_limits< casadi_int >::max()) const
 Unidirectional (column) coloring for compressed Jacobian evaluation. More...
 
Sparsity star_coloring_new (std::vector< casadi_int > &which_color, const Dict &opts=Dict()) const
 Star coloring of a symmetric pattern, with the color that recovers each nonzero. More...
 
Sparsity star_coloring (casadi_int ordering=1, casadi_int cutoff=std::numeric_limits< casadi_int >::max()) const
 Star coloring of a symmetric pattern (greedy distance-2 coloring) More...
 
Sparsity star_coloring2 (casadi_int ordering=1, casadi_int cutoff=std::numeric_limits< casadi_int >::max()) const
 Star coloring of a symmetric pattern with the newer algorithm. More...
 
std::vector< casadi_int > largest_first () const
 Column indices ordered by decreasing number of nonzeros. More...
 
Sparsity pmult (const std::vector< casadi_int > &p, bool permute_rows=true, bool permute_columns=true, bool invert_permutation=false) const
 Permute the rows and/or columns of the pattern. More...
 
std::string dim (bool with_nz=false) const
 Dimensions as a string "nrow x ncol", optionally with the number of nonzeros. More...
 
std::string postfix_dim () const
 Dimension string to append to a name, as used when printing symbolic primitives. More...
 
std::string repr_el (casadi_int k) const
 Describe the position of nonzero k as a string. More...
 
void spy (std::ostream &stream=casadi::uout()) const
 Print a textual picture of the pattern. More...
 
void spy_matlab (const std::string &mfile) const
 Write a MATLAB/Octave script that builds the pattern as a sparse matrix and calls spy. More...
 
void export_code (const std::string &lang, std::ostream &stream=casadi::uout(), const Dict &options=Dict()) const
 Write code that reconstructs the pattern in another language. More...
 
std::size_t hash () const
 Hash of the pattern (dimensions, colind and row) More...
 
std::string class_name () const
 Get class name. More...
 
void disp (std::ostream &stream, bool more=false) const
 Print a description of the object. More...
 
std::string get_str (bool more=false) const
 Get string representation. More...
 
std::string debug_repr () const
 
bool is_null () const
 Is a null pointer? More...
 
casadi_int __hash__ () const
 Returns a number that is unique for a given Node. More...
 
bool is_equal (const Sparsity &y) const
 Check whether two sparsity patterns are identical. More...
 
bool is_equal (casadi_int nrow, casadi_int ncol, const std::vector< casadi_int > &colind, const std::vector< casadi_int > &row) const
 Check whether two sparsity patterns are identical. More...
 
bool operator== (const Sparsity &y) const
 Check whether two sparsity patterns are identical. More...
 
Size and element counting
casadi_int size1 () const
 Number of rows. More...
 
casadi_int rows () const
 Number of rows, Octave-style alias of size1. More...
 
casadi_int size2 () const
 Number of columns. More...
 
casadi_int columns () const
 Number of columns, Octave-style alias of size2. More...
 
casadi_int numel () const
 Total number of entries, structural zeros included, i.e. size1()*size2() More...
 
double density () const
 Percentage of nonzeros: 100*nnz()/numel() More...
 
bool is_empty (bool both=false) const
 Check whether the pattern has a zero dimension. More...
 
casadi_int nnz () const
 Number of structural nonzeros. More...
 
casadi_int nnz_upper (bool strictly=false) const
 Number of nonzeros in the upper triangular part, i.e. entries (i, j) with i <= j. More...
 
casadi_int nnz_lower (bool strictly=false) const
 Number of nonzeros in the lower triangular part, i.e. entries (i, j) with i >= j. More...
 
casadi_int nnz_diag () const
 Number of nonzeros on the main diagonal, i.e. entries (i, i) More...
 
casadi_int bw_upper () const
 Upper half-bandwidth: the largest j - i over all nonzeros (i, j) with j > i. More...
 
casadi_int bw_lower () const
 Lower half-bandwidth: the largest i - j over all nonzeros (i, j) with i > j. More...
 
std::pair< casadi_int, casadi_int > size () const
 Shape as a pair (number of rows, number of columns) More...
 
casadi_int size (casadi_int axis) const
 Size along one dimension. More...
 
Sparsity combine (const Sparsity &y, bool f0x_is_zero, bool function0_is_zero) const
 Combine two patterns of the same shape, as the result of a binary operation. More...
 
Sparsity unite (const Sparsity &y) const
 Union of two sparsity patterns of the same shape (also available as the + operator) More...
 
Sparsity operator+ (const Sparsity &b) const
 Union of two sparsity patterns of the same shape (also available as the + operator) More...
 
Sparsity intersect (const Sparsity &y) const
 Intersection of two sparsity patterns of the same shape (also the * operator) More...
 
Sparsity operator* (const Sparsity &b) const
 Intersection of two sparsity patterns of the same shape (also the * operator) More...
 

Static Public Member Functions

static Sparsity upper (casadi_int n)
 Create an upper triangular square sparsity pattern. More...
 
static Sparsity lower (casadi_int n)
 Create a lower triangular square sparsity pattern. More...
 
static Sparsity band (casadi_int n, casadi_int p)
 Create a single band in a square sparsity pattern. More...
 
static Sparsity banded (casadi_int n, casadi_int p)
 Create a banded square sparsity pattern. More...
 
static Sparsity rowcol (const std::vector< casadi_int > &row, const std::vector< casadi_int > &col, casadi_int nrow, casadi_int ncol)
 Create the pattern of a block: all entries (i, j) with i in row and j in col. More...
 
static Sparsity nonzeros (casadi_int nrow, casadi_int ncol, const std::vector< casadi_int > &nz, bool ind1=SWIG_IND1)
 Create a sparsity pattern from the flat (column-major) index of every nonzero. More...
 
static Sparsity permutation (const std::vector< casadi_int > &p, bool invert=false)
 Construct the pattern of a permutation matrix P from a permutation vector p. More...
 
static Sparsity from_file (const std::string &filename, const std::string &format_hint="")
 Read a pattern from a file written by to_file (Matrix Market pattern format) More...
 
static Sparsity deserialize (std::istream &stream)
 Build a Sparsity from a serialized stream. More...
 
static Sparsity deserialize (const std::string &s)
 Build a Sparsity from a string produced by serialize() More...
 
static Sparsity deserialize (DeserializingStream &s)
 Deserialize. More...
 
static std::string type_name ()
 Readable name of the public class. More...
 
static bool test_cast (const SharedObjectInternal *ptr)
 Check if a particular cast is allowed. More...
 
static Sparsity kkt (const Sparsity &H, const Sparsity &J, bool with_x_diag=true, bool with_lam_g_diag=true)
 Pattern of a KKT system [H + I1, J'; J, I2]. More...
 
static Sparsity scalar (bool dense_scalar=true)
 Create a 1-by-1 sparsity pattern. More...
 
static Sparsity dense (casadi_int nrow, casadi_int ncol=1)
 Create a dense rectangular sparsity pattern. More...
 
static Sparsity dense (const std::pair< casadi_int, casadi_int > &rc)
 Create a dense rectangular sparsity pattern. More...
 
static Sparsity unit (casadi_int n, casadi_int el)
 Create the pattern of a unit vector: a column of length n with one nonzero. More...
 
static Sparsity diag (casadi_int nrow)
 Create a diagonal sparsity pattern. More...
 
static Sparsity diag (casadi_int nrow, casadi_int ncol)
 Create a diagonal sparsity pattern. More...
 
static Sparsity diag (const std::pair< casadi_int, casadi_int > &rc)
 Create a diagonal sparsity pattern. More...
 
static Sparsity triplet (casadi_int nrow, casadi_int ncol, const std::vector< casadi_int > &row, const std::vector< casadi_int > &col, std::vector< casadi_int > &mapping, bool invert_mapping)
 Create a sparsity pattern from the (row, col) index of every nonzero. More...
 
static Sparsity triplet (casadi_int nrow, casadi_int ncol, const std::vector< casadi_int > &row, const std::vector< casadi_int > &col)
 Create a sparsity pattern from the (row, col) index of every nonzero. More...
 
static Sparsity compressed (const std::vector< casadi_int > &v, bool order_rows=false)
 Create from the compact single-vector representation of a pattern. More...
 

Member Typedef Documentation

◆ base_type

Definition at line 103 of file shared_object.hpp.

◆ internal_base_type

using casadi::SharedObject::internal_base_type = SharedObjectInternal
inherited

Definition at line 102 of file shared_object.hpp.

Constructor & Destructor Documentation

◆ Sparsity() [1/4]

casadi::Sparsity::Sparsity ( casadi_int  dummy = 0)
explicit

is_null() is true for the result and most other methods raise an error on it. A null Sparsity is the "no pattern" sentinel used by e.g. uni_coloring (as default for AT) and returned by the colorings when the cutoff is exceeded.

Parameters
dummyMust be 0 (any other value raises an error)

>>> sp = Sparsity()
>>> sp.is_null(), sp
(True, Sparsity(NULL))
>>> try: sp.nnz()
... except Exception as e: print("error")
error

>> sp = Sparsity();
>> sp.is_null(), sp
1
NULL
>> try, sp.nnz(); catch e, disp('error'); end
error

julia> sp = ca.Sparsity();
julia> ca.is_null(sp), sp
(true, NULL)
julia> try
           ca.nnz(sp)
       catch e
           println("error")
       end
error

Extra doc: https://github.com/casadi/casadi/wiki/L_2nj

◆ Sparsity() [2/4]

casadi::Sparsity::Sparsity ( casadi_int  nrow,
casadi_int  ncol 
)
Parameters
nrowNumber of rows, nonnegative
ncolNumber of columns, nonnegative

>>> sp = Sparsity(2, 3)
>>> sp, sp.nnz(), sp.is_dense()
(Sparsity(2x3,0nz), 0, False)
>>> Sparsity(0, 0), Sparsity(0, 0).is_dense()
(Sparsity(0x0), True)
>>> DM(Sparsity(2, 2), 1)
DM(
[[00, 00],
 [00, 00]])

>> sp = Sparsity(2, 3);
>> sp, sp.nnz(), sp.is_dense()
2x3,0nz
0
0
>> Sparsity(0, 0), Sparsity(0, 0).is_dense()
0x0
1
>> DM(Sparsity(2, 2), 1)
[[00, 00],
 [00, 00]]

julia> sp = ca.Sparsity(2, 3)
Sparsity(2x3,0nz)
julia> ca.nnz(sp), ca.is_dense(sp)
(0, false)
julia> ca.Sparsity(0, 0), ca.is_dense(ca.Sparsity(0, 0))
(0x0, true)
julia> ca.DM(ca.Sparsity(2, 2), 1)
DM(
[[00, 00],
 [00, 00]])

See also
dense, is_empty

Extra doc: https://github.com/casadi/casadi/wiki/L_ba

◆ Sparsity() [3/4]

casadi::Sparsity::Sparsity ( casadi_int  nrow,
casadi_int  ncol,
const std::vector< casadi_int > &  colind,
const std::vector< casadi_int > &  row,
bool  order_rows = false 
)
Parameters
nrowNumber of rows
ncolNumber of columns
colindColumn offsets, length ncol+1, colind[0] == 0, nondecreasing
rowRow index of each nonzero, length colind[ncol], each in [0, nrow), strictly increasing within a column
order_rowsIf true, row indices that are not sorted within a column are sorted (duplicates merged) instead of raising an error

An invalid colind or an out-of-range row index raises an error. A pattern with colind[ncol] == nrow*ncol is the dense pattern.

>>> sp = Sparsity(3, 2, [0, 2, 3], [0, 2, 1])
>>> DM(sp, 1)
DM(
[[1, 00],
 [00, 1],
 [1, 00]])
>>> Sparsity(2, 2, [0, 2, 4], [0, 1, 0, 1]).is_dense()
True
>>> try: Sparsity(3, 2, [0, 2, 3], [2, 0, 1])
... except Exception as e: print("not sorted")
not sorted
>>> Sparsity(3, 2, [0, 2, 3], [2, 0, 1], True).row()
[0, 2, 1]

>> sp = Sparsity(3, 2, [0, 2, 3], [0, 2, 1]);
>> DM(sp, 1)
[[1, 00],
 [00, 1],
 [1, 00]]
>> Sparsity(2, 2, [0, 2, 4], [0, 1, 0, 1]).is_dense()
1
>> try, Sparsity(3, 2, [0, 2, 3], [2, 0, 1]); catch e, disp('not sorted'); end
not sorted
>> Sparsity(3, 2, [0, 2, 3], [2, 0, 1], true).row()
0 2 1

julia> sp = ca.Sparsity(3, 2, [0, 2, 3], [0, 2, 1]);
julia> ca.DM(sp, 1)
DM(
[[1, 00],
 [00, 1],
 [1, 00]])
julia> ca.is_dense(ca.Sparsity(2, 2, [0, 2, 4], [0, 1, 0, 1]))
true
julia> try
           ca.Sparsity(3, 2, [0, 2, 3], [2, 0, 1])
       catch e
           println("not sorted")
       end
not sorted
julia> ca.row(ca.Sparsity(3, 2, [0, 2, 3], [2, 0, 1], true))
3-element Vector{Int64}:
 0
 2
 1

See also
compressed, triplet, get_ccs

Extra doc: https://github.com/casadi/casadi/wiki/L_2nk

◆ Sparsity() [4/4]

casadi::Sparsity::Sparsity ( const std::pair< casadi_int, casadi_int > &  rc)
explicit

Member Function Documentation

◆ __hash__()

casadi_int casadi::GenericShared< SharedObject , SharedObjectInternal >::__hash__
inherited

If the Object does not point to any node, "0" is returned.

Extra doc: https://github.com/casadi/casadi/wiki/L_av

Definition at line 123 of file generic_shared_impl.hpp.

◆ add_nz()

casadi_int casadi::Sparsity::add_nz ( casadi_int  rr,
casadi_int  cc 
)

Returns the position of the entry among the nonzeros. If the entry is a structural zero, the object is rebound to a pattern that includes it (nonzero indices after it shift by one). Negative indices count from the end. An index out of bounds raises an error.

>>> sp = Sparsity(3, 3)
>>> sp.add_nz(1, 1), sp.add_nz(0, 0), sp.add_nz(1, 1), sp
(0, 0, 1, Sparsity(3x3,2nz))
>>> DM(sp, 1)
DM(
[[1, 00, 00],
 [00, 1, 00],
 [00, 00, 00]])
>>> try: sp.add_nz(3, 0)
... except Exception as e: print("out of bounds")
out of bounds

>> sp = Sparsity(3, 3);
>> [sp.add_nz(1, 1), sp.add_nz(0, 0), sp.add_nz(1, 1)], sp
0 0 1
3x3,2nz
>> DM(sp, 1)
[[1, 00, 00],
 [00, 1, 00],
 [00, 00, 00]]
>> try, sp.add_nz(3, 0); catch e, disp('out of bounds'); end
out of bounds

julia> sp = ca.Sparsity(3, 3);
julia> ca.add_nz(sp, 1, 1), ca.add_nz(sp, 0, 0), ca.add_nz(sp, 1, 1)
(0, 0, 1)
julia> ca.DM(sp, 1)
DM(
[[1, 00, 00],
 [00, 1, 00],
 [00, 00, 00]])
julia> try
           ca.add_nz(sp, 3, 0)
       catch e
           println("out of bounds")
       end
out of bounds

See also
get_nz, has_nz

Extra doc: https://github.com/casadi/casadi/wiki/L_ce

◆ amd()

std::vector<casadi_int> casadi::Sparsity::amd ( ) const

Fill-reducing ordering p to apply to a symmetric linear system before factorization: factorize A[p, p] instead of A. The pattern must be symmetric, otherwise an error is raised; for an unsymmetric A, order the pattern of A^T*A (as qr_sparse does). Used by ldl and qr_sparse when their amd argument is true.

The implementation is a modified version of cs_amd in CSparse Copyright(c) Timothy A. Davis, 2006-2009 Licensed as a derivative work under the GNU LGPL

>>> Sparsity.banded(4, 1).amd(), Sparsity.dense(3, 3).amd(), Sparsity(0, 0).amd()
([3, 2, 0, 1], [0, 1, 2], [])
>>> try: Sparsity.upper(3).amd()
... except Exception as e: print("not symmetric")
not symmetric

>> Sparsity.banded(4, 1).amd(), Sparsity.dense(3, 3).amd()
3 2 0 1
0 1 2
>> isempty(Sparsity(0, 0).amd())
1
>> try, Sparsity.upper(3).amd(); catch e, disp('not symmetric'); end
not symmetric

julia> ca.amd(ca.Sparsity.banded(4, 1)), ca.amd(ca.Sparsity.dense(3, 3))
([3, 2, 0, 1], [0, 1, 2])
julia> ca.amd(ca.Sparsity(0, 0))
Int64[]
julia> try
           ca.amd(ca.Sparsity.upper(3))
       catch e
           println("not symmetric")
       end
not symmetric

See also
ldl, qr_sparse, etree, is_symmetric

Extra doc: https://github.com/casadi/casadi/wiki/L_d8

◆ append()

void casadi::Sparsity::append ( const Sparsity &  sp)

The number of columns must match, otherwise an error is raised; a 0-by-0 pattern on either side is ignored. Equivalent to rebinding to vertcat(self, sp); only cheap when both are column vectors.

>>> sp = Sparsity.dense(2, 2); sp.append(Sparsity.diag(2)); print(DM(sp, 1))
[[1, 1], 
 [1, 1], 
 [1, 00], 
 [00, 1]]
>>> sp = Sparsity(0, 0); sp.append(Sparsity.diag(2)); print(sp)
2x2,2nz
>>> try: Sparsity.dense(2, 2).append(Sparsity.dense(2, 3))
... except Exception as e: print("column mismatch")
column mismatch

>> sp = Sparsity.dense(2, 2); sp.append(Sparsity.diag(2)); disp(DM(sp, 1))
[[1, 1],
 [1, 1],
 [1, 00],
 [00, 1]]
>> sp = Sparsity(0, 0); sp.append(Sparsity.diag(2)); disp(sp)
2x2,2nz
>> try, sp.append(Sparsity.dense(2, 3)); catch e, disp('column mismatch'); end
column mismatch

julia> sp = ca.Sparsity.dense(2, 2); ca.append(sp, ca.Sparsity.diag(2)); ca.DM(sp, 1)
DM(
[[1, 1],
 [1, 1],
 [1, 00],
 [00, 1]])
julia> sp = ca.Sparsity(0, 0); ca.append(sp, ca.Sparsity.diag(2)); print(sp)
2x2,2nz
julia> try
           ca.append(ca.Sparsity.dense(2, 2), ca.Sparsity.dense(2, 3))
       catch e
           println("column mismatch")
       end
column mismatch

See also
appendColumns, vertcat

Extra doc: https://github.com/casadi/casadi/wiki/L_2o6

◆ appendColumns()

void casadi::Sparsity::appendColumns ( const Sparsity &  sp)

The number of rows must match, otherwise an error is raised; a 0-by-0 pattern on either side is ignored. Equivalent to rebinding to horzcat(self, sp).

>>> sp = Sparsity.dense(2, 2); sp.appendColumns(Sparsity.diag(2)); print(DM(sp, 1))
[[1, 1, 1, 00], 
 [1, 1, 00, 1]]
>>> try: Sparsity.dense(2, 2).appendColumns(Sparsity.dense(3, 2))
... except Exception as e: print("row mismatch")
row mismatch

>> sp = Sparsity.dense(2, 2); sp.appendColumns(Sparsity.diag(2)); disp(DM(sp, 1))
[[1, 1, 1, 00],
 [1, 1, 00, 1]]
>> try, sp.appendColumns(Sparsity.dense(3, 2)); catch e, disp('row mismatch'); end
row mismatch

julia> sp = ca.Sparsity.dense(2, 2); ca.appendColumns(sp, ca.Sparsity.diag(2)); ca.DM(sp, 1)
DM(
[[1, 1, 1, 00],
 [1, 1, 00, 1]])
julia> try
           ca.appendColumns(ca.Sparsity.dense(2, 2), ca.Sparsity.dense(3, 2))
       catch e
           println("row mismatch")
       end
row mismatch

See also
append, horzcat

Extra doc: https://github.com/casadi/casadi/wiki/L_2o7

◆ band()

static Sparsity casadi::Sparsity::band ( casadi_int  n,
casadi_int  p 
)
static

The nonzeros are the entries (i+p, i): band(n, 0) equals diag(n), band(n, 1) is the first subdiagonal and band(n, -1) the first superdiagonal.

Parameters
nSize of the square pattern
pOffset of the band from the diagonal, positive below the diagonal and negative above it; |p| must be smaller than n, otherwise an error is raised

>>> DM(Sparsity.band(4, 1), 1)
DM(
[[00, 00, 00, 00],
 [1, 00, 00, 00],
 [00, 1, 00, 00],
 [00, 00, 1, 00]])
>>> DM(Sparsity.band(4, -2), 1)
DM(
[[00, 00, 1, 00],
 [00, 00, 00, 1],
 [00, 00, 00, 00],
 [00, 00, 00, 00]])
>>> Sparsity.band(4, 0) == Sparsity.diag(4)
True

>> DM(Sparsity.band(4, 1), 1)
[[00, 00, 00, 00],
 [1, 00, 00, 00],
 [00, 1, 00, 00],
 [00, 00, 1, 00]]
>> DM(Sparsity.band(4, -2), 1)
[[00, 00, 1, 00],
 [00, 00, 00, 1],
 [00, 00, 00, 00],
 [00, 00, 00, 00]]
>> Sparsity.band(4, 0) == Sparsity.diag(4)
1

julia> ca.DM(ca.Sparsity.band(4, 1), 1)
DM(
[[00, 00, 00, 00],
 [1, 00, 00, 00],
 [00, 1, 00, 00],
 [00, 00, 1, 00]])
julia> ca.DM(ca.Sparsity.band(4, -2), 1)
DM(
[[00, 00, 1, 00],
 [00, 00, 00, 1],
 [00, 00, 00, 00],
 [00, 00, 00, 00]])
julia> ca.is_equal(ca.Sparsity.band(4, 0), ca.Sparsity.diag(4))
true

See also
banded, diag

Extra doc: https://github.com/casadi/casadi/wiki/L_bj

◆ banded()

static Sparsity casadi::Sparsity::banded ( casadi_int  n,
casadi_int  p 
)
static

Union of band(n, k) for all k in [-p, p]: banded(n, 0) equals diag(n) and banded(n, 1) is tridiagonal.

Parameters
nSize of the square pattern
pHalf-bandwidth; p >= n gives a dense pattern and a negative p an all-zero pattern

>>> DM(Sparsity.banded(4, 1), 1)
DM(
[[1, 1, 00, 00],
 [1, 1, 1, 00],
 [00, 1, 1, 1],
 [00, 00, 1, 1]])
>>> Sparsity.banded(4, 1).bw_upper(), Sparsity.banded(4, 1).bw_lower()
(1, 1)

>> DM(Sparsity.banded(4, 1), 1)
[[1, 1, 00, 00],
 [1, 1, 1, 00],
 [00, 1, 1, 1],
 [00, 00, 1, 1]]
>> [Sparsity.banded(4, 1).bw_upper(), Sparsity.banded(4, 1).bw_lower()]
1 1

julia> ca.DM(ca.Sparsity.banded(4, 1), 1)
DM(
[[1, 1, 00, 00],
 [1, 1, 1, 00],
 [00, 1, 1, 1],
 [00, 00, 1, 1]])
julia> ca.bw_upper(ca.Sparsity.banded(4, 1)), ca.bw_lower(ca.Sparsity.banded(4, 1))
(1, 1)

See also
band, bw_upper, bw_lower

Extra doc: https://github.com/casadi/casadi/wiki/L_bk

◆ btf()

casadi_int casadi::Sparsity::btf ( std::vector< casadi_int > &  rowperm,
std::vector< casadi_int > &  colperm,
std::vector< casadi_int > &  rowblock,
std::vector< casadi_int > &  colblock,
std::vector< casadi_int > &  coarse_rowblock,
std::vector< casadi_int > &  coarse_colblock 
) const

Computes a row permutation and a column permutation that bring the pattern into block upper triangular form, see Direct Methods for Sparse Linear Systems by Davis (2006). The pattern may be rectangular.

Returns
  • the number of fine blocks nb
  • rowperm, colperm: row and column permutation vectors, so that A[rowperm, colperm] is in block upper triangular form
  • rowblock, colblock (length nb+1): block k spans rows rowblock[k] to rowblock[k+1]-1 and columns colblock[k] to colblock[k+1]-1 of the permuted matrix
  • coarse_rowblock, coarse_colblock (length 5): boundaries of the coarse decomposition into the underdetermined, square (well-determined) and overdetermined parts; coarse_colblock[3] is the structural rank (sprank)

Only structure is used: the distance of entries to the diagonal plays no role, so a randomly permuted block-diagonal matrix is not necessarily brought back to block diagonal form, and the row and column permutations differ in general, which destroys symmetry. The result is cached in the pattern.

The implementation is a modified version of cs_dmperm in CSparse Copyright(c) Timothy A. Davis, 2006-2009 Licensed as a derivative work under the GNU LGPL

>>> B = Sparsity.triplet(3, 3, [0, 0, 1, 2], [0, 2, 1, 2])
>>> DM(B, 1)
DM(
[[1, 00, 1],
 [00, 1, 00],
 [00, 00, 1]])
>>> nb, rowperm, colperm, rowblock, colblock, crb, ccb = B.btf()
>>> nb, rowperm, colperm, rowblock, colblock
(3, [2, 0, 1], [2, 0, 1], [0, 1, 2, 3], [0, 1, 2, 3])
>>> crb, ccb
([0, 0, 0, 3, 3], [0, 0, 3, 3, 3])
>>> DM(B, 1)[rowperm, colperm]
DM(
[[1, 00, 00],
 [1, 1, 00],
 [00, 00, 1]])
>>> sprank(Sparsity.nonzeros(3, 3, [0, 1, 2])), sprank(Sparsity.diag(3))
(1, 3)

>> B = Sparsity.triplet(3, 3, [0, 0, 1, 2], [0, 2, 1, 2]);
>> DM(B, 1)
[[1, 00, 1],
 [00, 1, 00],
 [00, 00, 1]]
>> [nb, rowperm, colperm, rowblock, colblock, crb, ccb] = B.btf();
>> nb, rowperm, colperm, rowblock, colblock
3
2 0 1
2 0 1
0 1 2 3
0 1 2 3
>> crb, ccb
0 0 0 3 3
0 0 3 3 3
>> Bf = DM(B, 1); disp(Bf(rowperm + 1, colperm + 1))
[[1, 00, 00],
 [1, 1, 00],
 [00, 00, 1]]
>> [sprank(Sparsity.nonzeros(3, 3, [1, 2, 3])), sprank(Sparsity.diag(3))]
1 3

julia> B = ca.Sparsity.triplet(3, 3, [0, 0, 1, 2], [0, 2, 1, 2]);
julia> ca.DM(B, 1)
DM(
[[1, 00, 1],
 [00, 1, 00],
 [00, 00, 1]])
julia> ca.btf(B)
(3, [2, 0, 1], [2, 0, 1], [0, 1, 2, 3], [0, 1, 2, 3], [0, 0, 0, 3, 3], [0, 0, 3, 3, 3])
julia> ca.sprank(ca.Sparsity.nonzeros(3, 3, [0, 1, 2])), ca.sprank(ca.Sparsity.diag(3))
(1, 3)

See also
scc, sprank, is_singular

Extra doc: https://github.com/casadi/casadi/wiki/L_d7

Examples
matrix/btf.py.

◆ bw_lower()

casadi_int casadi::Sparsity::bw_lower ( ) const

Zero for a diagonal, upper triangular or all-zero pattern.

>>> Sparsity.banded(5, 2).bw_lower(), Sparsity.band(5, 2).bw_lower()
(2, 2)
>>> Sparsity.band(5, -2).bw_lower()
0
>>> Sparsity.dense(5, 2).bw_lower()
4

>> [Sparsity.banded(5, 2).bw_lower(), Sparsity.band(5, 2).bw_lower()]
2 2
>> Sparsity.band(5, -2).bw_lower()
0
>> Sparsity.dense(5, 2).bw_lower()
4

julia> ca.bw_lower(ca.Sparsity.banded(5, 2)), ca.bw_lower(ca.Sparsity.band(5, 2))
(2, 2)
julia> ca.bw_lower(ca.Sparsity.band(5, -2))
0
julia> ca.bw_lower(ca.Sparsity.dense(5, 2))
4

See also
bw_upper, banded

Extra doc: https://github.com/casadi/casadi/wiki/L_by

◆ bw_upper()

casadi_int casadi::Sparsity::bw_upper ( ) const

Zero for a diagonal, lower triangular or all-zero pattern.

>>> Sparsity.banded(5, 2).bw_upper(), Sparsity.band(5, -2).bw_upper()
(2, 2)
>>> Sparsity.band(5, 2).bw_upper(), Sparsity.diag(3).bw_upper()
(0, 0)
>>> Sparsity(3, 3).bw_upper(), Sparsity.dense(2, 5).bw_upper()
(0, 4)

>> [Sparsity.banded(5, 2).bw_upper(), Sparsity.band(5, -2).bw_upper()]
2 2
>> [Sparsity.band(5, 2).bw_upper(), Sparsity.diag(3).bw_upper()]
0 0
>> [Sparsity(3, 3).bw_upper(), Sparsity.dense(2, 5).bw_upper()]
0 4

julia> ca.bw_upper(ca.Sparsity.banded(5, 2)), ca.bw_upper(ca.Sparsity.band(5, -2))
(2, 2)
julia> ca.bw_upper(ca.Sparsity.band(5, 2)), ca.bw_upper(ca.Sparsity.diag(3))
(0, 0)
julia> ca.bw_upper(ca.Sparsity(3, 3)), ca.bw_upper(ca.Sparsity.dense(2, 5))
(0, 4)

See also
bw_lower, banded

Extra doc: https://github.com/casadi/casadi/wiki/L_bx

◆ class_name()

std::string casadi::SharedObject::class_name ( ) const
inherited

◆ colind()

casadi_int casadi::Sparsity::colind ( casadi_int  cc) const
Parameters
ccColumn, in [0, size2()]; colind(size2()) equals nnz(). An index out of range raises an error.

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> sp.row(1), sp.colind(1), sp.colind(4)
(2, 2, 4)
>>> try: sp.row(4)
... except Exception as e: print("out of range")
out of range

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> [sp.row(1), sp.colind(1), sp.colind(4)]
2 2 4
>> try, sp.row(4); catch e, disp('out of range'); end
out of range

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> ca.row(sp, 1), ca.colind(sp, 1), ca.colind(sp, 4)
(2, 2, 4)
julia> try
           ca.row(sp, 4)
       catch e
           println("out of range")
       end
out of range

See also
row, get_colind

Extra doc: https://github.com/casadi/casadi/wiki/L_cb

◆ columns()

casadi_int casadi::Sparsity::columns ( ) const
inline

Definition at line 1549 of file sparsity.hpp.

◆ combine()

Sparsity casadi::Sparsity::combine ( const Sparsity &  y,
bool  f0x_is_zero,
bool  function0_is_zero 
) const

Models the pattern of f(x, y) applied elementwise, where y has this pattern's shape. An entry is kept in the result when both arguments are nonzero; an entry where only y is nonzero is kept unless f0x_is_zero (f(0, y) == 0) and an entry where only x is nonzero is kept unless function0_is_zero (f(x, 0) == 0). So combine(y, False, False) is the union (unite) and combine(y, True, True) is the intersection (intersect). A shape mismatch raises an error.

The C++ overload with mapping returns, per nonzero of the union, bit 1 if the first argument is nonzero, bit 2 if the second is and bit 4 if the entry was dropped from the result.

Parameters
yPattern with the same shape
f0x_is_zeroTrue if entries where only y is nonzero are structural zeros
function0_is_zeroTrue if entries where only this pattern is nonzero are structural zeros

>>> a = Sparsity.diag(2)
>>> b = Sparsity.triplet(2, 2, [0, 1], [1, 1])
>>> a.combine(b, False, False) == a + b, a.combine(b, True, True) == a * b
(True, True)
>>> DM(a.combine(b, True, False), 1)
DM(
[[1, 00],
 [00, 1]])
>>> DM(a.combine(b, False, True), 1)
DM(
[[00, 1],
 [00, 1]])

>> a = Sparsity.diag(2);
>> b = Sparsity.triplet(2, 2, [0, 1], [1, 1]);
>> a.combine(b, false, false) == a + b, a.combine(b, true, true) == a .* b
1
1
>> DM(a.combine(b, true, false), 1)
[[1, 00],
 [00, 1]]
>> DM(a.combine(b, false, true), 1)
[[00, 1],
 [00, 1]]

julia> a = ca.Sparsity.diag(2);
julia> b = ca.Sparsity.triplet(2, 2, [0, 1], [1, 1]);
julia> ca.is_equal(ca.combine(a, b, false, false), ca.unite(a, b))
true
julia> ca.DM(ca.combine(a, b, true, false), 1)
DM(
[[1, 00],
 [00, 1]])
julia> ca.DM(ca.combine(a, b, false, true), 1)
DM(
[[00, 1],
 [00, 1]])

See also
unite, intersect

Extra doc: https://github.com/casadi/casadi/wiki/L_cl

◆ compress()

std::vector<casadi_int> casadi::Sparsity::compress ( bool  canonical = true) const

Returns [nrow, ncol, colind..., row...], the layout accepted by compressed() and used for sparsity patterns in generated C code. With canonical false, a dense pattern is abbreviated to [nrow, ncol, 1] (an abbreviation that compressed() given a vector does not accept).

>>> Sparsity.diag(2).compress()
[2, 2, 0, 1, 2, 0, 1]
>>> Sparsity.dense(2, 2).compress()
[2, 2, 0, 2, 4, 0, 1, 0, 1]
>>> Sparsity.dense(2, 2).compress(False)
[2, 2, 1]
>>> Sparsity(0, 2).compress()
[0, 2, 0, 0, 0]

>> Sparsity.diag(2).compress()
2 2 0 1 2 0 1
>> Sparsity.dense(2, 2).compress()
2 2 0 2 4 0 1 0 1
>> Sparsity.dense(2, 2).compress(false)
2 2 1
>> Sparsity(0, 2).compress()
0 2 0 0 0

julia> println(ca.compress(ca.Sparsity.diag(2)))
[2, 2, 0, 1, 2, 0, 1]
julia> println(ca.compress(ca.Sparsity.dense(2, 2)))
[2, 2, 0, 2, 4, 0, 1, 0, 1]
julia> println(ca.compress(ca.Sparsity.dense(2, 2), false))
[2, 2, 1]
julia> println(ca.compress(ca.Sparsity(0, 2)))
[0, 2, 0, 0, 0]

See also
compressed, get_ccs

Extra doc: https://github.com/casadi/casadi/wiki/L_2nn

◆ compressed()

static Sparsity casadi::Sparsity::compressed ( const std::vector< casadi_int > &  v,
bool  order_rows = false 
)
static

The vector is laid out as [nrow, ncol, colind (ncol+1 entries), row (colind[ncol] entries)]. This is the format returned by compress() and used by generated C code (casadi_int arrays). When colind[ncol] equals nrow*ncol the row entries may be omitted (a dense pattern). An inconsistent vector raises an error.

Parameters
vCompact representation
order_rowsIf true, unsorted row indices within a column are sorted instead of raising an error

>>> sp = Sparsity.compressed([3, 2, 0, 1, 2, 0, 2])
>>> DM(sp, 1)
DM(
[[1, 00],
 [00, 00],
 [00, 1]])
>>> Sparsity.compressed(sp.compress()) == sp
True
>>> Sparsity.compressed([2, 2, 0, 2, 4])
Sparsity(2x2)

>> sp = Sparsity.compressed([3, 2, 0, 1, 2, 0, 2]);
>> DM(sp, 1)
[[1, 00],
 [00, 00],
 [00, 1]]
>> Sparsity.compressed(sp.compress()) == sp
1
>> Sparsity.compressed([2, 2, 0, 2, 4])
2x2

julia> sp = ca.Sparsity.compressed([3, 2, 0, 1, 2, 0, 2]);
julia> ca.DM(sp, 1)
DM(
[[1, 00],
 [00, 00],
 [00, 1]])
julia> ca.is_equal(ca.Sparsity.compressed(ca.compress(sp)), sp)
true
julia> ca.Sparsity.compressed([2, 2, 0, 2, 4])
Sparsity(2x2)

See also
compress, Sparsity(nrow, ncol, colind, row)

Extra doc: https://github.com/casadi/casadi/wiki/L_2nl

◆ debug_repr()

std::string casadi::GenericShared< SharedObject , SharedObjectInternal >::debug_repr
inherited

Definition at line 112 of file generic_shared_impl.hpp.

◆ dense() [1/2]

static Sparsity casadi::Sparsity::dense ( casadi_int  nrow,
casadi_int  ncol = 1 
)
static

All nrow*ncol entries are nonzeros, stored column by column. This is the pattern of every matrix created without an explicit sparsity, e.g. SX.sym("x", 2, 3).

Parameters
nrowNumber of rows, nonnegative
ncolNumber of columns, nonnegative; default 1 (a dense column vector)

The shape can also be given as a single pair (nrow, ncol).

>>> sp = Sparsity.dense(2, 3)
>>> sp, sp.nnz(), sp.is_dense()
(Sparsity(2x3), 6, True)
>>> sp.colind(), sp.row()
([0, 2, 4, 6], [0, 1, 0, 1, 0, 1])
>>> Sparsity.dense(3), Sparsity.dense((2, 3))
(Sparsity(3x1), Sparsity(2x3))
>>> Sparsity.dense(0, 3).nnz(), Sparsity.dense(0, 3).is_dense()
(0, True)

>> sp = Sparsity.dense(2, 3);
>> sp, sp.nnz(), sp.is_dense()
2x3
6
1
>> sp.colind(), sp.row()
0 2 4 6
0 1 0 1 0 1
>> Sparsity.dense(3), Sparsity.dense([2, 3])
3x1
2x3
>> Sparsity.dense(0, 3).nnz(), Sparsity.dense(0, 3).is_dense()
0
1

julia> sp = ca.Sparsity.dense(2, 3)
Sparsity(2x3)
julia> ca.nnz(sp), ca.is_dense(sp)
(6, true)
julia> ca.colind(sp), ca.row(sp)
([0, 2, 4, 6], [0, 1, 0, 1, 0, 1])
julia> ca.Sparsity.dense(3), ca.Sparsity.dense(2, 3)
(3x1, 2x3)
julia> ca.nnz(ca.Sparsity.dense(0, 3)), ca.is_dense(ca.Sparsity.dense(0, 3))
(0, true)

See also
Sparsity(nrow, ncol), scalar, is_dense

Extra doc: https://github.com/casadi/casadi/wiki/L_be

◆ dense() [2/2]

static Sparsity casadi::Sparsity::dense ( const std::pair< casadi_int, casadi_int > &  rc)
inlinestatic

All nrow*ncol entries are nonzeros, stored column by column. This is the pattern of every matrix created without an explicit sparsity, e.g. SX.sym("x", 2, 3).

Parameters
nrowNumber of rows, nonnegative
ncolNumber of columns, nonnegative; default 1 (a dense column vector)

The shape can also be given as a single pair (nrow, ncol).

>>> sp = Sparsity.dense(2, 3)
>>> sp, sp.nnz(), sp.is_dense()
(Sparsity(2x3), 6, True)
>>> sp.colind(), sp.row()
([0, 2, 4, 6], [0, 1, 0, 1, 0, 1])
>>> Sparsity.dense(3), Sparsity.dense((2, 3))
(Sparsity(3x1), Sparsity(2x3))
>>> Sparsity.dense(0, 3).nnz(), Sparsity.dense(0, 3).is_dense()
(0, True)

>> sp = Sparsity.dense(2, 3);
>> sp, sp.nnz(), sp.is_dense()
2x3
6
1
>> sp.colind(), sp.row()
0 2 4 6
0 1 0 1 0 1
>> Sparsity.dense(3), Sparsity.dense([2, 3])
3x1
2x3
>> Sparsity.dense(0, 3).nnz(), Sparsity.dense(0, 3).is_dense()
0
1

julia> sp = ca.Sparsity.dense(2, 3)
Sparsity(2x3)
julia> ca.nnz(sp), ca.is_dense(sp)
(6, true)
julia> ca.colind(sp), ca.row(sp)
([0, 2, 4, 6], [0, 1, 0, 1, 0, 1])
julia> ca.Sparsity.dense(3), ca.Sparsity.dense(2, 3)
(3x1, 2x3)
julia> ca.nnz(ca.Sparsity.dense(0, 3)), ca.is_dense(ca.Sparsity.dense(0, 3))
(0, true)

See also
Sparsity(nrow, ncol), scalar, is_dense

Extra doc: https://github.com/casadi/casadi/wiki/L_be

Definition at line 521 of file sparsity.hpp.

◆ density()

double casadi::Sparsity::density ( ) const

Computed in floating point, so it does not overflow for large shapes. An empty pattern (numel() == 0) is dense and gives 100.

>>> Sparsity.diag(4).density(), Sparsity.dense(2, 2).density()
(25.0, 100.0)
>>> Sparsity(0, 3).density()
100.0

>> fprintf('%g %g\n', Sparsity.diag(4).density(), Sparsity.dense(2, 2).density())
25 100
>> Sparsity(0, 3).density()
100

julia> ca.density(ca.Sparsity.diag(4)), ca.density(ca.Sparsity.dense(2, 2))
(25.0, 100.0)
julia> ca.density(ca.Sparsity(0, 3))
100.0

See also
nnz, numel, is_dense

Extra doc: https://github.com/casadi/casadi/wiki/L_br

◆ deserialize() [1/3]

static Sparsity casadi::Sparsity::deserialize ( const std::string &  s)
static

◆ deserialize() [2/3]

static Sparsity casadi::Sparsity::deserialize ( DeserializingStream &  s)
static

◆ deserialize() [3/3]

static Sparsity casadi::Sparsity::deserialize ( std::istream &  stream)
static

◆ dfs()

casadi_int casadi::Sparsity::dfs ( casadi_int  j,
casadi_int  top,
std::vector< casadi_int > &  SWIG_INOUT1xi,
std::vector< casadi_int > &  SWIG_INOUT2pstack,
const std::vector< casadi_int > &  pinv,
std::vector< bool > &  SWIG_INOUT3marked 
) const

Low-level building block of scc (cs_dfs in CSparse). Starting from column j, it visits the columns reachable through the nonzeros and writes them, in reverse finishing order, into xi below position top. See Direct Methods for Sparse Linear Systems by Davis (2006).

Parameters
jStart node (column)
topCurrent top of the output stack in xi
xiOutput stack, length at least size2(); the visited nodes are stored in xi[new_top:top]
pstackWork vector, length at least size2()
pinvInverse row permutation, or an empty vector for none
markedVisited flags per node, updated in place
Returns
The new top of the stack, with the updated xi, pstack and marked vectors

>>> Sparsity.banded(3, 1).dfs(0, 3, [0, 0, 0], [0, 0, 0], [], [False] * 3)
(0, [0, 1, 2], [1, 4, 5], [True, True, True])

>> sp = Sparsity.banded(3, 1); xi = [0, 0, 0]; pstack = [0, 0, 0];
>> [top, xi, pstack, marked] = sp.dfs(0, 3, xi, pstack, [], [false, false, false]);
>> top, xi, pstack, marked
0
0 1 2
1 4 5
1 1 1

julia> ca.dfs(ca.Sparsity.banded(3, 1), 0, 3, [0, 0, 0], [0, 0, 0], [], [false, false, false])
(0, [0, 1, 2], [1, 4, 5], Bool[1, 1, 1])

See also
scc

Extra doc: https://github.com/casadi/casadi/wiki/L_d5

◆ diag() [1/3]

static Sparsity casadi::Sparsity::diag ( casadi_int  nrow)
inlinestatic

The nonzeros are the entries (i, i) for i < min(nrow, ncol); a rectangular diagonal pattern is allowed. The shape can be given as one integer (square), as two integers or as a pair.

>>> DM(Sparsity.diag(3), 1)
DM(
[[1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]])
>>> DM(Sparsity.diag(2, 4), 1)
DM(
[[1, 00, 00, 00],
 [00, 1, 00, 00]])
>>> Sparsity.diag((4, 2)).nnz(), Sparsity.diag(0).nnz()
(2, 0)

>> DM(Sparsity.diag(3), 1)
[[1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]]
>> DM(Sparsity.diag(2, 4), 1)
[[1, 00, 00, 00],
 [00, 1, 00, 00]]
>> Sparsity.diag([4, 2]).nnz(), Sparsity.diag(0).nnz()
2
0

julia> ca.DM(ca.Sparsity.diag(3), 1)
DM(
[[1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]])
julia> ca.DM(ca.Sparsity.diag(2, 4), 1)
DM(
[[1, 00, 00, 00],
 [00, 1, 00, 00]])
julia> ca.nnz(ca.Sparsity.diag(4, 2)), ca.nnz(ca.Sparsity.diag(0))
(2, 0)

See also
band, is_diag, get_diag

Extra doc: https://github.com/casadi/casadi/wiki/L_bi

Definition at line 723 of file sparsity.hpp.

◆ diag() [2/3]

static Sparsity casadi::Sparsity::diag ( casadi_int  nrow,
casadi_int  ncol 
)
static

The nonzeros are the entries (i, i) for i < min(nrow, ncol); a rectangular diagonal pattern is allowed. The shape can be given as one integer (square), as two integers or as a pair.

>>> DM(Sparsity.diag(3), 1)
DM(
[[1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]])
>>> DM(Sparsity.diag(2, 4), 1)
DM(
[[1, 00, 00, 00],
 [00, 1, 00, 00]])
>>> Sparsity.diag((4, 2)).nnz(), Sparsity.diag(0).nnz()
(2, 0)

>> DM(Sparsity.diag(3), 1)
[[1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]]
>> DM(Sparsity.diag(2, 4), 1)
[[1, 00, 00, 00],
 [00, 1, 00, 00]]
>> Sparsity.diag([4, 2]).nnz(), Sparsity.diag(0).nnz()
2
0

julia> ca.DM(ca.Sparsity.diag(3), 1)
DM(
[[1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]])
julia> ca.DM(ca.Sparsity.diag(2, 4), 1)
DM(
[[1, 00, 00, 00],
 [00, 1, 00, 00]])
julia> ca.nnz(ca.Sparsity.diag(4, 2)), ca.nnz(ca.Sparsity.diag(0))
(2, 0)

See also
band, is_diag, get_diag

Extra doc: https://github.com/casadi/casadi/wiki/L_bi

◆ diag() [3/3]

static Sparsity casadi::Sparsity::diag ( const std::pair< casadi_int, casadi_int > &  rc)
inlinestatic

The nonzeros are the entries (i, i) for i < min(nrow, ncol); a rectangular diagonal pattern is allowed. The shape can be given as one integer (square), as two integers or as a pair.

>>> DM(Sparsity.diag(3), 1)
DM(
[[1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]])
>>> DM(Sparsity.diag(2, 4), 1)
DM(
[[1, 00, 00, 00],
 [00, 1, 00, 00]])
>>> Sparsity.diag((4, 2)).nnz(), Sparsity.diag(0).nnz()
(2, 0)

>> DM(Sparsity.diag(3), 1)
[[1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]]
>> DM(Sparsity.diag(2, 4), 1)
[[1, 00, 00, 00],
 [00, 1, 00, 00]]
>> Sparsity.diag([4, 2]).nnz(), Sparsity.diag(0).nnz()
2
0

julia> ca.DM(ca.Sparsity.diag(3), 1)
DM(
[[1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]])
julia> ca.DM(ca.Sparsity.diag(2, 4), 1)
DM(
[[1, 00, 00, 00],
 [00, 1, 00, 00]])
julia> ca.nnz(ca.Sparsity.diag(4, 2)), ca.nnz(ca.Sparsity.diag(0))
(2, 0)

See also
band, is_diag, get_diag

Extra doc: https://github.com/casadi/casadi/wiki/L_bi

Definition at line 725 of file sparsity.hpp.

◆ dim()

std::string casadi::Sparsity::dim ( bool  with_nz = false) const
Parameters
with_nzIf true, append ",<nnz>nz"

This is the string printed for a Sparsity: with the nonzero count when the pattern is not dense.

>>> sp = Sparsity.diag(2, 3)
>>> sp.dim(), sp.dim(True)
('2x3', '2x3,2nz')
>>> Sparsity.dense(2, 2).dim(), Sparsity.dense(2, 2).dim(True)
('2x2', '2x2,4nz')
>>> sp
Sparsity(2x3,2nz)

>> sp = Sparsity.diag(2, 3);
>> sp.dim(), sp.dim(true)
2x3
2x3,2nz
>> Sparsity.dense(2, 2).dim(), Sparsity.dense(2, 2).dim(true)
2x2
2x2,4nz
>> sp
2x3,2nz

julia> sp = ca.Sparsity.diag(2, 3);
julia> ca.dim(sp), ca.dim(sp, true)
("2x3", "2x3,2nz")
julia> ca.dim(ca.Sparsity.dense(2, 2)), ca.dim(ca.Sparsity.dense(2, 2), true)
("2x2", "2x2,4nz")
julia> sp
Sparsity(2x3,2nz)

See also
postfix_dim, repr_el

Extra doc: https://github.com/casadi/casadi/wiki/L_2oa

◆ disp()

void casadi::SharedObject::disp ( std::ostream &  stream,
bool  more = false 
) const
inherited

◆ enlarge()

void casadi::Sparsity::enlarge ( casadi_int  nrow,
casadi_int  ncol,
const std::vector< casadi_int > &  rr,
const std::vector< casadi_int > &  cc,
bool  ind1 = false 
)

The existing nonzeros are kept and scattered: row i of the old pattern becomes row rr[i] and column j becomes column cc[j] of the new nrow-by-ncol pattern, so that B[rr, cc] has the old pattern. The new rows and columns are structural zeros. Nonzero indices are unchanged. The object is rebound to the new pattern.

Parameters
nrowNew number of rows
ncolNew number of columns
rrNew row of every old row: length size1(), strictly increasing, entries in [0, nrow); negative entries count from the end
ccNew column of every old column: length size2(), strictly increasing, entries in [0, ncol)
ind1If true, indices are one-based

A wrong length or an index out of range raises an error.

>>> sp = Sparsity.dense(2, 2)
>>> sp.enlarge(4, 3, [0, 3], [1, 2])
>>> DM(sp, 1)
DM(
[[00, 1, 1],
 [00, 00, 00],
 [00, 00, 00],
 [00, 1, 1]])
>>> try: Sparsity.dense(2, 2).enlarge(4, 3, [0], [1, 2])
... except Exception as e: print("wrong length")
wrong length

>> sp = Sparsity.dense(2, 2);
>> sp.enlarge(4, 3, [0, 3], [1, 2]);
>> DM(sp, 1)
[[00, 1, 1],
 [00, 00, 00],
 [00, 00, 00],
 [00, 1, 1]]
>> try, Sparsity.dense(2, 2).enlarge(4, 3, 0, [1, 2]); catch e, disp('wrong length'); end
wrong length

julia> sp = ca.Sparsity.dense(2, 2);
julia> ca.enlarge(sp, 4, 3, [0, 3], [1, 2])
julia> ca.DM(sp, 1)
DM(
[[00, 1, 1],
 [00, 00, 00],
 [00, 00, 00],
 [00, 1, 1]])
julia> try
           ca.enlarge(ca.Sparsity.dense(2, 2), 4, 3, [0], [1, 2])
       catch e
           println("wrong length")
       end
wrong length

See also
enlargeRows, enlargeColumns, resize, erase

Extra doc: https://github.com/casadi/casadi/wiki/L_cr

◆ enlargeColumns()

void casadi::Sparsity::enlargeColumns ( casadi_int  ncol,
const std::vector< casadi_int > &  cc,
bool  ind1 = false 
)

Same as enlarge with the rows left unchanged.

Parameters
ncolNew number of columns
ccNew column of every old column, length size2(), strictly increasing
ind1If true, indices are one-based

>>> sp = Sparsity.dense(2, 2); sp.enlargeColumns(3, [0, 2]); print(DM(sp, 1))
[[1, 00, 1], 
 [1, 00, 1]]

>> sp = Sparsity.dense(2, 2); sp.enlargeColumns(3, [0, 2]); disp(DM(sp, 1))
[[1, 00, 1],
 [1, 00, 1]]

julia> sp = ca.Sparsity.dense(2, 2); ca.enlargeColumns(sp, 3, [0, 2]); ca.DM(sp, 1)
DM(
[[1, 00, 1],
 [1, 00, 1]])

See also
enlarge, enlargeRows

Extra doc: https://github.com/casadi/casadi/wiki/L_ct

◆ enlargeRows()

void casadi::Sparsity::enlargeRows ( casadi_int  nrow,
const std::vector< casadi_int > &  rr,
bool  ind1 = false 
)

Same as enlarge with the columns left unchanged.

Parameters
nrowNew number of rows
rrNew row of every old row, length size1(), strictly increasing
ind1If true, indices are one-based

>>> sp = Sparsity.dense(2, 2); sp.enlargeRows(3, [0, 2]); print(DM(sp, 1))
[[1, 1], 
 [00, 00], 
 [1, 1]]

>> sp = Sparsity.dense(2, 2); sp.enlargeRows(3, [0, 2]); disp(DM(sp, 1))
[[1, 1],
 [00, 00],
 [1, 1]]

julia> sp = ca.Sparsity.dense(2, 2); ca.enlargeRows(sp, 3, [0, 2]); ca.DM(sp, 1)
DM(
[[1, 1],
 [00, 00],
 [1, 1]])

See also
enlarge, enlargeColumns

Extra doc: https://github.com/casadi/casadi/wiki/L_cs

◆ erase() [1/2]

std::vector<casadi_int> casadi::Sparsity::erase ( const std::vector< casadi_int > &  rr,
bool  ind1 = false 
)

The shape is unchanged. Indices may be unsorted and negative; out of range raises an error. The object is rebound to the new pattern.

Parameters
rrFlat element indices, in [0, numel())
ind1If true, indices are one-based
Returns
Mapping of length nnz() of the result: nonzero k of the result was nonzero mapping[k] of the original pattern

>>> sp = Sparsity.dense(3, 3)
>>> sp.erase([0, 4, 8]), sp
([1, 2, 3, 5, 6, 7], Sparsity(3x3,6nz))
>>> DM(sp, 1)
DM(
[[00, 1, 1],
 [1, 00, 1],
 [1, 1, 00]])
>>> try: Sparsity.dense(3, 3).erase([9])
... except Exception as e: print("out of range")
out of range

>> sp = Sparsity.dense(3, 3);
>> sp.erase([0, 4, 8]), sp
1 2 3 5 6 7
3x3,6nz
>> DM(sp, 1)
[[00, 1, 1],
 [1, 00, 1],
 [1, 1, 00]]
>> try, Sparsity.dense(3, 3).erase(9); catch e, disp('out of range'); end
out of range

julia> sp = ca.Sparsity.dense(3, 3);
julia> println(ca.erase(sp, [0, 4, 8]))
[1, 2, 3, 5, 6, 7]
julia> ca.DM(sp, 1)
DM(
[[00, 1, 1],
 [1, 00, 1],
 [1, 1, 00]])
julia> try
           ca.erase(ca.Sparsity.dense(3, 3), [9])
       catch e
           println("out of range")
       end
out of range

See also
erase(rr, cc), find

Extra doc: https://github.com/casadi/casadi/wiki/L_cw

◆ erase() [2/2]

std::vector<casadi_int> casadi::Sparsity::erase ( const std::vector< casadi_int > &  rr,
const std::vector< casadi_int > &  cc,
bool  ind1 = false 
)

The shape is unchanged: only the nonzeros in the block rr x cc are removed. An entry is removed when its row is in rr and its column is in cc, so an empty rr or cc removes nothing. Indices may be unsorted and negative (counting from the end); out of range raises an error. The object is rebound to the new pattern.

Parameters
rrRows of the block to clear
ccColumns of the block to clear
ind1If true, indices are one-based
Returns
Mapping of length nnz() of the result: nonzero k of the result was nonzero mapping[k] of the original pattern

>>> sp = Sparsity.dense(3, 3)
>>> mapping = sp.erase([0, 2], [1])
>>> DM(sp, 1), mapping
(DM(
[[1, 00, 1],
 [1, 1, 1],
 [1, 00, 1]]), [0, 1, 2, 4, 6, 7, 8])

>> sp = Sparsity.dense(3, 3);
>> mapping = sp.erase([0, 2], 1);
>> DM(sp, 1), mapping
[[1, 00, 1],
 [1, 1, 1],
 [1, 00, 1]]
0 1 2 4 6 7 8

julia> sp = ca.Sparsity.dense(3, 3);
julia> mapping = ca.erase(sp, [0, 2], [1]);
julia> println(mapping)
[0, 1, 2, 4, 6, 7, 8]
julia> ca.DM(sp, 1)
DM(
[[1, 00, 1],
 [1, 1, 1],
 [1, 00, 1]])

See also
erase(rr), sub, enlarge

Extra doc: https://github.com/casadi/casadi/wiki/L_cv

◆ etree()

std::vector<casadi_int> casadi::Sparsity::etree ( bool  ata = false) const

Returns, for every column, the index of its parent in the elimination tree, or -1 for a root. See Direct Methods for Sparse Linear Systems by Davis (2006). With ata false the result matches MATLAB's etree(A) with zero-based indices (the pattern is treated as symmetric, only the upper triangular part is used); with ata true it matches etree(A, 'col'), the tree of A'*A.

The implementation is a modified version of cs_etree in CSparse Copyright(c) Timothy A. Davis, 2006-2009 Licensed as a derivative work under the GNU LGPL

>>> Sparsity.banded(4, 1).etree(), Sparsity.diag(4).etree()
([1, 2, 3, -1], [-1, -1, -1, -1])
>>> Sparsity.dense(2, 3).etree(True)
[1, 2, -1]

>> Sparsity.banded(4, 1).etree(), Sparsity.diag(4).etree()
1 2 3 -1
-1 -1 -1 -1
>> Sparsity.dense(2, 3).etree(true)
1 2 -1

julia> ca.etree(ca.Sparsity.banded(4, 1)), ca.etree(ca.Sparsity.diag(4))
([1, 2, 3, -1], [-1, -1, -1, -1])
julia> println(ca.etree(ca.Sparsity.dense(2, 3), true))
[1, 2, -1]

See also
ldl, qr_sparse, amd

Extra doc: https://github.com/casadi/casadi/wiki/L_d2

◆ export_code()

void casadi::Sparsity::export_code ( const std::string &  lang,
std::ostream &  stream = casadi::uout(),
const Dict &  options = Dict() 
) const

Only "matlab" is supported: the code defines the dimensions, one-based column and row indices and the nonzero values of a sparse matrix. The code is written to the standard output or to the given stream.

Parameters
langTarget language, must be "matlab"
optionsDictionary with
  • "name": name of the generated variable (default "sp")
  • "as_matrix": also emit "<name> = sparse(...)" (default true)
  • "nonzeros": list of strings used as the nonzero values (default: ones)
  • "indent_level": number of two-space indents (default 0)
  • "inline": not supported, true raises an error

An unknown option raises an error.

>>> Sparsity.diag(2, 3).export_code("matlab")
sp_m = 2;
sp_n = 3;
sp_j = [1, 2];
sp_i = [1, 2];
sp_v = ones(size(sp_i));
sp = sparse(sp_i, sp_j, sp_v, sp_m, sp_n);
>>> opts = {"name": "A", "as_matrix": False, "nonzeros": ["1.5", "2"]}
>>> Sparsity.diag(2).export_code("matlab", opts)
A_m = 2;
A_n = 2;
A_j = [1, 2];
A_i = [1, 2];
A_v = [1.5, 2];
>>> try: Sparsity.diag(2).export_code("python")
... except Exception as e: print("unsupported language")
unsupported language

>> Sparsity.diag(2, 3).export_code('matlab');
sp_m = 2;
sp_n = 3;
sp_j = [1, 2];
sp_i = [1, 2];
sp_v = ones(size(sp_i));
sp = sparse(sp_i, sp_j, sp_v, sp_m, sp_n);
>> opts = struct('name', 'A', 'as_matrix', false, 'nonzeros', {{'1.5', '2'}});
>> Sparsity.diag(2).export_code('matlab', opts);
A_m = 2;
A_n = 2;
A_j = [1, 2];
A_i = [1, 2];
A_v = [1.5, 2];
>> try, Sparsity.diag(2).export_code('python'); catch e, disp('unsupported language'); end
unsupported language

julia> ca.export_code(ca.Sparsity.diag(2, 3), "matlab")
sp_m = 2;
sp_n = 3;
sp_j = [1, 2];
sp_i = [1, 2];
sp_v = ones(size(sp_i));
sp = sparse(sp_i, sp_j, sp_v, sp_m, sp_n);
julia> opts = Dict("name" => "A", "as_matrix" => false, "nonzeros" => ["1.5", "2"]);
julia> ca.export_code(ca.Sparsity.diag(2), "matlab", opts)
A_m = 2;
A_n = 2;
A_j = [1, 2];
A_i = [1, 2];
A_v = [1.5, 2];
julia> try
           ca.export_code(ca.Sparsity.diag(2), "python")
       catch e
           println("unsupported language")
       end
unsupported language

See also
spy_matlab, compress

Extra doc: https://github.com/casadi/casadi/wiki/L_dj

◆ find()

std::vector<casadi_int> casadi::Sparsity::find ( bool  ind1 = SWIG_IND1) const

Returns, in nonzero order, the position each nonzero would have in a dense column-major matrix of the same shape: row + col*size1(). Indexing a dense matrix A of this shape with the result picks the entries that are nonzeros of the pattern. Inverse of nonzeros(). For a dense pattern this is 0, ..., numel()-1.

Parameters
ind1If true, the indices are one-based

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> sp.find(), sp.find(True)
([0, 2, 7, 9], [1, 3, 8, 10])
>>> Sparsity.dense(2, 2).find(), Sparsity(2, 2).find(), Sparsity(0, 3).find()
([0, 1, 2, 3], [], [])

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> sp.find(), sp.find(false)
1 3 8 10
0 2 7 9
>> Sparsity.dense(2, 2).find()
1 2 3 4
>> [isempty(Sparsity(2, 2).find()), isempty(Sparsity(0, 3).find())]
1 1

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> ca.find(sp), ca.find(sp, true)
([0, 2, 7, 9], [1, 3, 8, 10])
julia> println(ca.find(ca.Sparsity.dense(2, 2)))
[0, 1, 2, 3]
julia> ca.find(ca.Sparsity(2, 2)), ca.find(ca.Sparsity(0, 3))
(Int64[], Int64[])

See also
nonzeros, get_nz, makeDense

Extra doc: https://github.com/casadi/casadi/wiki/L_da

◆ from_file()

static Sparsity casadi::Sparsity::from_file ( const std::string &  filename,
const std::string &  format_hint = "" 
)
static
Parameters
filenamePath of the file to read; a missing file raises an error
format_hintFormat name, e.g. "mtx", when the extension does not tell
See also
to_file

Extra doc: https://github.com/casadi/casadi/wiki/L_2nt

◆ get_ccs()

void casadi::Sparsity::get_ccs ( std::vector< casadi_int > &  colind,
std::vector< casadi_int > &  row 
) const

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> colind, row = sp.get_ccs()
>>> colind, row
([0, 2, 2, 3, 4], [0, 2, 1, 0])

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> [colind, row] = sp.get_ccs(); disp(colind), disp(row)
0 2 2 3 4
0 2 1 0

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> colind, row = ca.get_ccs(sp);
julia> colind, row
([0, 2, 2, 3, 4], [0, 2, 1, 0])

See also
get_crs, get_triplet, get_colind, get_row

Extra doc: https://github.com/casadi/casadi/wiki/L_2ny

◆ get_col()

std::vector<casadi_int> casadi::Sparsity::get_col ( ) const

Length nnz(). Together with get_row() this gives the pattern in sparse triplet format.

See also
get_row, get_triplet

Extra doc: https://github.com/casadi/casadi/wiki/L_cd

◆ get_colind()

std::vector<casadi_int> casadi::Sparsity::get_colind ( ) const

Length size2()+1: entry j is the index of the first nonzero of column j and the last entry equals nnz(). In the target languages this method is called colind(), the same name as the single-column accessor.

See also
get_row, get_ccs

Extra doc: https://github.com/casadi/casadi/wiki/L_ca

◆ get_crs()

void casadi::Sparsity::get_crs ( std::vector< casadi_int > &  rowind,
std::vector< casadi_int > &  col 
) const

Equivalent to the compressed column storage of the transpose. Note that the resulting order of the nonzeros (row-major) differs from the storage order of the pattern.

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> rowind, col = sp.get_crs()
>>> rowind, col
([0, 2, 3, 4], [0, 3, 2, 0])

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> [rowind, col] = sp.get_crs(); disp(rowind), disp(col)
0 2 3 4
0 3 2 0

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> rowind, col = ca.get_crs(sp);
julia> rowind, col
([0, 2, 3, 4], [0, 3, 2, 0])

See also
get_ccs, T

Extra doc: https://github.com/casadi/casadi/wiki/L_2nz

◆ get_diag()

Sparsity casadi::Sparsity::get_diag ( std::vector< casadi_int > &  mapping) const

If the pattern is not a vector, the result is the min(nrow, ncol)-by-1 pattern of the main diagonal: it has a nonzero for every diagonal entry (i, i) present in the pattern. If the pattern is a row or column vector of length n, the result is the n-by-n pattern with the vector entries on the diagonal.

Returns
The pattern and a mapping: mapping[k] is the nonzero index in the original pattern of nonzero k of the result

>>> sp, mapping = Sparsity.banded(3, 1).get_diag()
>>> sp, mapping
(Sparsity(3x1), [0, 3, 6])
>>> sp, mapping = Sparsity.unit(3, 1).get_diag()
>>> DM(sp, 1), mapping
(DM(
[[00, 00, 00],
 [00, 1, 00],
 [00, 00, 00]]), [0])
>>> sp, mapping = Sparsity(2, 3).get_diag()
>>> sp, mapping
(Sparsity(2x1,0nz), [])

>> [sp, mapping] = Sparsity.banded(3, 1).get_diag(); disp(sp), disp(mapping)
3x1
0 3 6
>> [sp, mapping] = Sparsity.unit(3, 1).get_diag(); disp(DM(sp, 1)), disp(mapping)
[[00, 00, 00],
 [00, 1, 00],
 [00, 00, 00]]
0
>> [sp, mapping] = Sparsity(2, 3).get_diag(); disp(sp), disp(isempty(mapping))
2x1,0nz
1

julia> ca.get_diag(ca.Sparsity.banded(3, 1))
(3x1, [0, 3, 6])
julia> ca.get_diag(ca.Sparsity.unit(3, 1))
(3x3,1nz, [0])
julia> ca.get_diag(ca.Sparsity(2, 3))
(2x1,0nz, Int64[])

See also
diag, nnz_diag

Extra doc: https://github.com/casadi/casadi/wiki/L_2nm

◆ get_lower()

std::vector<casadi_int> casadi::Sparsity::get_lower ( ) const

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> sp.get_lower(), sp.get_upper()
([0, 1], [0, 2, 3])
>>> Sparsity.dense(2, 2).get_lower(), Sparsity.dense(2, 2).get_upper()
([0, 1, 3], [0, 2, 3])

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> sp.get_lower(), sp.get_upper()
0 1
0 2 3
>> Sparsity.dense(2, 2).get_lower(), Sparsity.dense(2, 2).get_upper()
0 1 3
0 2 3

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> ca.get_lower(sp), ca.get_upper(sp)
([0, 1], [0, 2, 3])
julia> ca.get_lower(ca.Sparsity.dense(2, 2)), ca.get_upper(ca.Sparsity.dense(2, 2))
([0, 1, 3], [0, 2, 3])

See also
get_upper, nnz_lower, tril

Extra doc: https://github.com/casadi/casadi/wiki/L_2nw

◆ get_nz() [1/3]

casadi_int casadi::Sparsity::get_nz ( casadi_int  rr,
casadi_int  cc 
) const

Negative indices count from the end. An index out of bounds raises an error. For a dense pattern the result is rr + cc*size1(). The returned index addresses the nonzeros() vector of a matrix with this pattern.

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> sp.get_nz(0, 0), sp.get_nz(2, 0), sp.get_nz(1, 0), sp.get_nz(-1, 0)
(0, 1, -1, 1)
>>> try: sp.get_nz(3, 0)
... except Exception as e: print("out of bounds")
out of bounds

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> [sp.get_nz(0, 0), sp.get_nz(2, 0), sp.get_nz(1, 0), sp.get_nz(-1, 0)]
0 1 -1 1
>> try, sp.get_nz(3, 0); catch e, disp('out of bounds'); end
out of bounds

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> ca.get_nz(sp, 0, 0), ca.get_nz(sp, 2, 0), ca.get_nz(sp, 1, 0), ca.get_nz(sp, -1, 0)
(0, 1, -1, 1)
julia> try
           ca.get_nz(sp, 3, 0)
       catch e
           println("out of bounds")
       end
out of bounds

See also
has_nz, add_nz, find

Extra doc: https://github.com/casadi/casadi/wiki/L_cf

◆ get_nz() [2/3]

std::vector<casadi_int> casadi::Sparsity::get_nz ( const std::vector< casadi_int > &  rr,
const std::vector< casadi_int > &  cc 
) const

Returns one index per (row, column) combination, in column-major order over the block (all rows of the first column first); -1 marks a structural zero. Indices must be in range (no negative indices); otherwise an error is raised.

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> sp.get_nz([0, 2], [0, 3])
[0, 1, 3, -1]

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> sp.get_nz([0, 2], [0, 3])
0 1 3 -1

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> println(ca.get_nz(sp, [0, 2], [0, 3]))
[0, 1, 3, -1]

See also
get_nz(rr, cc), sub

Extra doc: https://github.com/casadi/casadi/wiki/L_cg

◆ get_nz() [3/3]

void casadi::Sparsity::get_nz ( std::vector< casadi_int > &  indices) const

Each entry of indices is replaced by the nonzero index of that element, or by -1 if the element is a structural zero. Entries that are already negative are left alone. The indices need not be sorted. An index of numel() or more raises an error.

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> sp.get_nz([0, 2, 4, 9, 1])
[0, 1, -1, 3, -1]
>>> Sparsity.dense(2, 2).get_nz([3, 0])
[3, 0]

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> sp.get_nz([0, 2, 4, 9, 1])
0 1 -1 3 -1
>> Sparsity.dense(2, 2).get_nz([3, 0])
3 0

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> ca.get_nz(sp, [0, 2, 4, 9, 1])
5-element Vector{Int64}:
  0
  1
 -1
  3
 -1
julia> ca.get_nz(ca.Sparsity.dense(2, 2), [3, 0])
2-element Vector{Int64}:
 3
 0

See also
find, nonzeros

Extra doc: https://github.com/casadi/casadi/wiki/L_ch

◆ get_row()

std::vector<casadi_int> casadi::Sparsity::get_row ( ) const

Length nnz(). Together with get_colind() this is the compressed column storage of the pattern; together with get_col() it is the triplet form. In the target languages this method is called row(), the same name as the single-element accessor.

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> DM(sp, 1)
DM(
[[1, 00, 00, 1],
 [00, 00, 1, 00],
 [1, 00, 00, 00]])
>>> sp.row(), sp.colind(), sp.get_col()
([0, 2, 1, 0], [0, 2, 2, 3, 4], [0, 0, 2, 3])
>>> Sparsity.dense(2, 2).row(), Sparsity(2, 2).colind()
([0, 1, 0, 1], [0, 0, 0])
>>> Sparsity(0, 2).colind(), Sparsity(2, 0).colind()
([0, 0, 0], [0])

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> DM(sp, 1)
[[1, 00, 00, 1],
 [00, 00, 1, 00],
 [1, 00, 00, 00]]
>> sp.row(), sp.colind(), sp.get_col()
0 2 1 0
0 2 2 3 4
0 0 2 3
>> Sparsity.dense(2, 2).row(), Sparsity(2, 2).colind()
0 1 0 1
0 0 0
>> Sparsity(0, 2).colind(), Sparsity(2, 0).colind()
0 0 0
0

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> ca.row(sp), ca.colind(sp), ca.get_col(sp)
([0, 2, 1, 0], [0, 2, 2, 3, 4], [0, 0, 2, 3])
julia> ca.row(ca.Sparsity.dense(2, 2)), ca.colind(ca.Sparsity(2, 2))
([0, 1, 0, 1], [0, 0, 0])
julia> ca.colind(ca.Sparsity(0, 2)), ca.colind(ca.Sparsity(2, 0))
([0, 0, 0], [0])

See also
get_colind, get_col, get_ccs, get_triplet

Extra doc: https://github.com/casadi/casadi/wiki/L_c9

◆ get_str()

std::string casadi::SharedObject::get_str ( bool  more = false) const
inlineinherited

Definition at line 91 of file shared_object.hpp.

◆ get_triplet()

void casadi::Sparsity::get_triplet ( std::vector< casadi_int > &  row,
std::vector< casadi_int > &  col 
) const

Inverse of triplet(): Sparsity.triplet(nrow, ncol, row, col) rebuilds the pattern.

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> row, col = sp.get_triplet()
>>> row, col
([0, 2, 1, 0], [0, 0, 2, 3])

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> [row, col] = sp.get_triplet(); disp(row), disp(col)
0 2 1 0
0 0 2 3

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> row, col = ca.get_triplet(sp);
julia> row, col
([0, 2, 1, 0], [0, 0, 2, 3])

See also
triplet, get_row, get_col

Extra doc: https://github.com/casadi/casadi/wiki/L_2o0

◆ get_upper()

std::vector<casadi_int> casadi::Sparsity::get_upper ( ) const

◆ has_nz()

bool casadi::Sparsity::has_nz ( casadi_int  rr,
casadi_int  cc 
) const

Same index rules as get_nz.

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> sp.has_nz(2, 0), sp.has_nz(1, 0)
(True, False)

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> [sp.has_nz(2, 0), sp.has_nz(1, 0)]
1 0

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> ca.has_nz(sp, 2, 0), ca.has_nz(sp, 1, 0)
(true, false)

See also
get_nz

Extra doc: https://github.com/casadi/casadi/wiki/L_2nv

◆ hash()

std::size_t casadi::Sparsity::hash ( ) const

Equal patterns have equal hashes; the hash is used for the pattern cache. In Python, Sparsity objects are not hashable with the built-in hash(); use this method.

>>> sp = Sparsity.diag(2, 3)
>>> sp.hash() == Sparsity.diag(2, 3).hash(), sp.hash() == Sparsity.dense(2, 3).hash()
(True, False)

>> sp = Sparsity.diag(2, 3);
>> class(sp.hash())
uint64
>> [sp.hash() == Sparsity.diag(2, 3).hash(), sp.hash() == Sparsity.dense(2, 3).hash()]
1 0

julia> sp = ca.Sparsity.diag(2, 3);
julia> ca.hash(sp) == ca.hash(ca.Sparsity.diag(2, 3)), ca.hash(sp) == ca.hash(ca.Sparsity.dense(2, 3))
(true, false)
julia> sp == ca.Sparsity.diag(2, 3), hash(sp) == hash(ca.Sparsity.diag(2, 3))
(true, true)

See also
is_equal

Extra doc: https://github.com/casadi/casadi/wiki/L_2oc

◆ info()

Dict casadi::Sparsity::info ( ) const

An empty dictionary for a null object.

>>> Sparsity.diag(2, 3).info()
{'colind': [0, 1, 2, 2], 'ncol': 3, 'nrow': 2, 'row': [0, 1]}
>>> Sparsity().info()
{}

>> s = Sparsity.diag(2, 3).info(); disp(s)
colind: [0 1 2 2]
ncol: 3
nrow: 2
row: [0 1]
>> isempty(fieldnames(Sparsity().info()))
1

julia> ca.info(ca.Sparsity.diag(2, 3))
Dict{String, Any} with 4 entries:
  "nrow" => 2
  "colind" => [0, 1, 2, 2]
  "ncol" => 3
  "row" => [0, 1]
julia> ca.info(ca.Sparsity())
Dict{String, Any}()

See also
get_ccs, compress

Extra doc: https://github.com/casadi/casadi/wiki/L_2nr

◆ intersect()

Sparsity casadi::Sparsity::intersect ( const Sparsity &  y) const

The pattern of the elementwise product x * y for matrices with these patterns. A shape mismatch raises an error. In MATLAB this is the .* operator; * and mtimes give the pattern of the matrix product.

>>> a = Sparsity.diag(2)
>>> b = Sparsity.triplet(2, 2, [0, 1], [1, 1])
>>> DM(a.intersect(b), 1)
DM(
[[00, 00],
 [00, 1]])

>> a = Sparsity.diag(2);
>> b = Sparsity.triplet(2, 2, [0, 1], [1, 1]);
>> DM(a.intersect(b), 1)
[[00, 00],
 [00, 1]]

julia> a = ca.Sparsity.diag(2);
julia> b = ca.Sparsity.triplet(2, 2, [0, 1], [1, 1]);
julia> ca.DM(ca.intersect(a, b), 1)
DM(
[[00, 00],
 [00, 1]])

See also
unite, combine

Extra doc: https://github.com/casadi/casadi/wiki/L_cn

◆ is_column()

bool casadi::Sparsity::is_column ( ) const

>>> Sparsity.dense(3, 1).is_column(), Sparsity.dense(1, 3).is_column()
(True, False)
>>> Sparsity(1, 1).is_column()
True

>> [Sparsity.dense(3, 1).is_column(), Sparsity.dense(1, 3).is_column()]
1 0
>> Sparsity(1, 1).is_column()
1

julia> ca.is_column(ca.Sparsity.dense(3, 1)), ca.is_column(ca.Sparsity.dense(1, 3))
(true, false)
julia> ca.is_column(ca.Sparsity(1, 1))
true

See also
is_row, is_vector

Extra doc: https://github.com/casadi/casadi/wiki/L_cy

◆ is_compactible()

bool casadi::Sparsity::is_compactible ( std::vector< casadi_int > &  row,
std::vector< casadi_int > &  col 
) const

If true, returns the (sorted) row and column index sets such that nz(i, j) <-> i in row and j in col. The nonzero buffer of a compactible matrix in CCS is laid out exactly as a column-major dense row.size() x col.size() matrix, so it can be consumed by dense kernels without gather/scatter. The index sets are returned in either case (the nonempty rows and columns); a pattern without nonzeros is compactible.

>>> ok, row, col = Sparsity.rowcol([0, 2], [0, 2], 3, 3).is_compactible()
>>> ok, row, col
(True, [0, 2], [0, 2])
>>> ok, row, col = Sparsity.diag(3).is_compactible()
>>> ok, row, col
(False, [0, 1, 2], [0, 1, 2])

>> [ok, row, col] = Sparsity.rowcol([0, 2], [0, 2], 3, 3).is_compactible();
>> ok, row, col
1
0 2
0 2
>> [ok, row, col] = Sparsity.diag(3).is_compactible(); disp(ok), disp(row), disp(col)
0
0 1 2
0 1 2

julia> ca.is_compactible(ca.Sparsity.rowcol([0, 2], [0, 2], 3, 3))
(true, [0, 2], [0, 2])
julia> ca.is_compactible(ca.Sparsity.diag(3))
(false, [0, 1, 2], [0, 1, 2])

See also
rowcol

Extra doc: https://github.com/casadi/casadi/wiki/L_2gf

◆ is_dense()

bool casadi::Sparsity::is_dense ( ) const

An empty pattern (a zero dimension) is dense. Note that a DM built from a nested list is dense even if it holds numerical zeros.

>>> Sparsity.dense(2, 3).is_dense(), Sparsity.diag(3).is_dense()
(True, False)
>>> Sparsity(0, 3).is_dense(), Sparsity(1, 1).is_dense()
(True, False)
>>> DM([[1, 0], [0, 1]]).sparsity().is_dense()
True

>> [Sparsity.dense(2, 3).is_dense(), Sparsity.diag(3).is_dense()]
1 0
>> [Sparsity(0, 3).is_dense(), Sparsity(1, 1).is_dense()]
1 0
>> sparsity(DM([1, 0; 0, 1])).is_dense()
1

julia> ca.is_dense(ca.Sparsity.dense(2, 3)), ca.is_dense(ca.Sparsity.diag(3))
(true, false)
julia> ca.is_dense(ca.Sparsity(0, 3)), ca.is_dense(ca.Sparsity(1, 1))
(true, false)
julia> ca.is_dense(ca.sparsity(ca.DM([1 0; 0 1])))
true

See also
dense, density, makeDense

Extra doc: https://github.com/casadi/casadi/wiki/L_2o9

◆ is_diag()

bool casadi::Sparsity::is_diag ( ) const

True only for Sparsity.diag(n) (including n == 0); a rectangular diagonal pattern, an all-zero square pattern or a pattern with off-diagonal entries is not diagonal.

>>> Sparsity.diag(3).is_diag(), Sparsity.diag(2, 3).is_diag()
(True, False)
>>> Sparsity.dense(1, 1).is_diag(), Sparsity(2, 2).is_diag()
(True, False)
>>> Sparsity(0, 0).is_diag(), Sparsity.dense(2, 2).is_diag()
(True, False)

>> [Sparsity.diag(3).is_diag(), Sparsity.diag(2, 3).is_diag()]
1 0
>> [Sparsity.dense(1, 1).is_diag(), Sparsity(2, 2).is_diag()]
1 0
>> [Sparsity(0, 0).is_diag(), Sparsity.dense(2, 2).is_diag()]
1 0

julia> ca.is_diag(ca.Sparsity.diag(3)), ca.is_diag(ca.Sparsity.diag(2, 3))
(true, false)
julia> ca.is_diag(ca.Sparsity.dense(1, 1)), ca.is_diag(ca.Sparsity(2, 2))
(true, false)
julia> ca.is_diag(ca.Sparsity(0, 0)), ca.is_diag(ca.Sparsity.dense(2, 2))
(true, false)

See also
diag, nnz_diag

Extra doc: https://github.com/casadi/casadi/wiki/L_247

◆ is_empty()

bool casadi::Sparsity::is_empty ( bool  both = false) const
Parameters
bothIf false (default), true when the number of rows or the number of columns is zero; if true, only when both are zero

A pattern without nonzeros but with positive dimensions is not empty.

>>> Sparsity(0, 3).is_empty(), Sparsity(0, 3).is_empty(True)
(True, False)
>>> Sparsity(0, 0).is_empty(True)
True
>>> Sparsity(3, 3).is_empty(), Sparsity(3, 3).nnz()
(False, 0)

>> Sparsity(0, 3).is_empty(), Sparsity(0, 3).is_empty(true)
1
0
>> Sparsity(0, 0).is_empty(true)
1
>> Sparsity(3, 3).is_empty(), Sparsity(3, 3).nnz()
0
0

julia> ca.is_empty(ca.Sparsity(0, 3)), ca.is_empty(ca.Sparsity(0, 3), true)
(true, false)
julia> ca.is_empty(ca.Sparsity(0, 0), true)
true
julia> ca.is_empty(ca.Sparsity(3, 3)), ca.nnz(ca.Sparsity(3, 3))
(false, 0)

See also
numel, nnz

Extra doc: https://github.com/casadi/casadi/wiki/L_bs

◆ is_equal() [1/2]

bool casadi::Sparsity::is_equal ( casadi_int  nrow,
casadi_int  ncol,
const std::vector< casadi_int > &  colind,
const std::vector< casadi_int > &  row 
) const

True when the dimensions and the nonzero positions coincide. This is the comparison behind the == operator. Shared (cached) patterns are detected in constant time; otherwise colind and row are compared. The second overload compares against a pattern given in compressed column storage vectors.

>>> a = Sparsity.diag(2)
>>> a.is_equal(Sparsity.diag(2)), a == Sparsity.diag(2), a != Sparsity.dense(2, 2)
(True, True, True)
>>> a.is_equal(2, 2, [0, 1, 2], [0, 1])
True
>>> Sparsity.dense(2, 2) == Sparsity.dense(2, 3)
False
>>> Sparsity(2, 2) == Sparsity.dense(2, 2)
False

>> a = Sparsity.diag(2);
>> a.is_equal(Sparsity.diag(2)), a == Sparsity.diag(2)
1
1
>> a ~= Sparsity.dense(2, 2)
1
>> a.is_equal(2, 2, [0, 1, 2], [0, 1])
1
>> Sparsity.dense(2, 2) == Sparsity.dense(2, 3)
0
>> Sparsity(2, 2) == Sparsity.dense(2, 2)
0

julia> a = ca.Sparsity.diag(2);
julia> ca.is_equal(a, ca.Sparsity.diag(2)), !ca.is_equal(a, ca.Sparsity.dense(2, 2))
(true, true)
julia> ca.is_equal(a, 2, 2, [0, 1, 2], [0, 1])
true
julia> ca.is_equal(ca.Sparsity.dense(2, 2), ca.Sparsity.dense(2, 3))
false
julia> ca.is_equal(ca.Sparsity(2, 2), ca.Sparsity.dense(2, 2))
false

See also
is_subset, is_transpose, is_reshape, hash

Extra doc: https://github.com/casadi/casadi/wiki/L_2no

◆ is_equal() [2/2]

bool casadi::Sparsity::is_equal ( const Sparsity &  y) const

True when the dimensions and the nonzero positions coincide. This is the comparison behind the == operator. Shared (cached) patterns are detected in constant time; otherwise colind and row are compared. The second overload compares against a pattern given in compressed column storage vectors.

>>> a = Sparsity.diag(2)
>>> a.is_equal(Sparsity.diag(2)), a == Sparsity.diag(2), a != Sparsity.dense(2, 2)
(True, True, True)
>>> a.is_equal(2, 2, [0, 1, 2], [0, 1])
True
>>> Sparsity.dense(2, 2) == Sparsity.dense(2, 3)
False
>>> Sparsity(2, 2) == Sparsity.dense(2, 2)
False

>> a = Sparsity.diag(2);
>> a.is_equal(Sparsity.diag(2)), a == Sparsity.diag(2)
1
1
>> a ~= Sparsity.dense(2, 2)
1
>> a.is_equal(2, 2, [0, 1, 2], [0, 1])
1
>> Sparsity.dense(2, 2) == Sparsity.dense(2, 3)
0
>> Sparsity(2, 2) == Sparsity.dense(2, 2)
0

julia> a = ca.Sparsity.diag(2);
julia> ca.is_equal(a, ca.Sparsity.diag(2)), !ca.is_equal(a, ca.Sparsity.dense(2, 2))
(true, true)
julia> ca.is_equal(a, 2, 2, [0, 1, 2], [0, 1])
true
julia> ca.is_equal(ca.Sparsity.dense(2, 2), ca.Sparsity.dense(2, 3))
false
julia> ca.is_equal(ca.Sparsity(2, 2), ca.Sparsity.dense(2, 2))
false

See also
is_subset, is_transpose, is_reshape, hash

Extra doc: https://github.com/casadi/casadi/wiki/L_2no

◆ is_null()

bool casadi::GenericShared< SharedObject , SharedObjectInternal >::is_null
inherited

Definition at line 116 of file generic_shared_impl.hpp.

◆ is_orthonormal()

bool casadi::Sparsity::is_orthonormal ( bool  allow_empty = false) const

Without allow_empty the pattern must also be square with exactly one nonzero per row and column (a permutation pattern). With allow_empty, rows and columns without nonzeros are disregarded and the shape may be rectangular.

Parameters
allow_emptyDisregard empty rows and columns in the analysis

>>> Sparsity.diag(3).is_orthonormal()
True
>>> Sparsity.triplet(3, 3, [0, 1], [0, 1]).is_orthonormal()
False
>>> Sparsity.triplet(3, 3, [0, 1], [0, 1]).is_orthonormal(True)
True
>>> Sparsity.triplet(3, 3, [0, 0], [0, 1]).is_orthonormal(True)
False
>>> Sparsity.diag(2, 3).is_orthonormal(), Sparsity.diag(2, 3).is_orthonormal(True)
(False, True)

>> Sparsity.diag(3).is_orthonormal()
1
>> Sparsity.triplet(3, 3, [0, 1], [0, 1]).is_orthonormal()
0
>> Sparsity.triplet(3, 3, [0, 1], [0, 1]).is_orthonormal(true)
1
>> Sparsity.triplet(3, 3, [0, 0], [0, 1]).is_orthonormal(true)
0
>> [Sparsity.diag(2, 3).is_orthonormal(), Sparsity.diag(2, 3).is_orthonormal(true)]
0 1

julia> ca.is_orthonormal(ca.Sparsity.diag(3))
true
julia> ca.is_orthonormal(ca.Sparsity.triplet(3, 3, [0, 1], [0, 1]))
false
julia> ca.is_orthonormal(ca.Sparsity.triplet(3, 3, [0, 1], [0, 1]), true)
true
julia> ca.is_orthonormal(ca.Sparsity.triplet(3, 3, [0, 0], [0, 1]), true)
false
julia> sp = ca.Sparsity.diag(2, 3);
julia> ca.is_orthonormal(sp), ca.is_orthonormal(sp, true)
(false, true)

See also
is_orthonormal_rows, is_orthonormal_columns, is_permutation

Extra doc: https://github.com/casadi/casadi/wiki/L_24f

◆ is_orthonormal_columns()

bool casadi::Sparsity::is_orthonormal_columns ( bool  allow_empty = false) const

Without allow_empty the pattern must have at most as many columns as rows and exactly one nonzero per column. With allow_empty, columns without nonzeros are disregarded.

Parameters
allow_emptyDisregard empty columns in the analysis
See also
is_orthonormal_rows, is_orthonormal

Extra doc: https://github.com/casadi/casadi/wiki/L_24h

◆ is_orthonormal_rows()

bool casadi::Sparsity::is_orthonormal_rows ( bool  allow_empty = false) const

Without allow_empty the pattern must have at most as many rows as columns and exactly one nonzero per row. With allow_empty, rows without nonzeros are disregarded.

Parameters
allow_emptyDisregard empty rows in the analysis

>>> sp = Sparsity.diag(2, 3)
>>> sp.is_orthonormal_rows(), sp.is_orthonormal_columns()
(True, False)
>>> sp.T.is_orthonormal_rows(), sp.T.is_orthonormal_columns()
(False, True)

>> sp = Sparsity.diag(2, 3);
>> [sp.is_orthonormal_rows(), sp.is_orthonormal_columns()]
1 0
>> [sp.T.is_orthonormal_rows(), sp.T.is_orthonormal_columns()]
0 1

julia> sp = ca.Sparsity.diag(2, 3);
julia> ca.is_orthonormal_rows(sp), ca.is_orthonormal_columns(sp)
(true, false)
julia> ca.is_orthonormal_rows(ca.T(sp)), ca.is_orthonormal_columns(ca.T(sp))
(false, true)

See also
is_orthonormal_columns, is_selection

Extra doc: https://github.com/casadi/casadi/wiki/L_24g

◆ is_permutation()

bool casadi::Sparsity::is_permutation ( ) const

A square pattern with exactly one nonzero in every row and every column, so that multiplying a dense vector permutes its entries. Equivalent to is_orthonormal().

>>> Sparsity.permutation([1, 2, 0]).is_permutation()
True
>>> Sparsity.diag(3).is_permutation()
True
>>> Sparsity.dense(2, 2).is_permutation(), Sparsity.diag(2, 3).is_permutation()
(False, False)

>> Sparsity.permutation([1, 2, 0]).is_permutation()
1
>> Sparsity.diag(3).is_permutation()
1
>> [Sparsity.dense(2, 2).is_permutation(), Sparsity.diag(2, 3).is_permutation()]
0 0

julia> ca.is_permutation(ca.Sparsity.permutation([1, 2, 0]))
true
julia> ca.is_permutation(ca.Sparsity.diag(3))
true
julia> ca.is_permutation(ca.Sparsity.dense(2, 2)), ca.is_permutation(ca.Sparsity.diag(2, 3))
(false, false)

See also
permutation, permutation_vector, is_selection, is_orthonormal

Extra doc: https://github.com/casadi/casadi/wiki/L_24d

◆ is_reshape()

bool casadi::Sparsity::is_reshape ( const Sparsity &  y) const

True when both have the same number of elements and the same flat (column-major) nonzero positions, i.e. reshape(A, y.size()) has pattern y.

>>> Sparsity.dense(2, 3).is_reshape(Sparsity.dense(6, 1))
True
>>> Sparsity.diag(2).is_reshape(Sparsity.nonzeros(4, 1, [0, 3]))
True
>>> Sparsity.diag(2).is_reshape(Sparsity.nonzeros(4, 1, [0, 2]))
False

>> Sparsity.dense(2, 3).is_reshape(Sparsity.dense(6, 1))
1
>> Sparsity.diag(2).is_reshape(Sparsity.nonzeros(4, 1, [1, 4]))
1
>> Sparsity.diag(2).is_reshape(Sparsity.nonzeros(4, 1, [1, 3]))
0

julia> ca.is_reshape(ca.Sparsity.dense(2, 3), ca.Sparsity.dense(6, 1))
true
julia> ca.is_reshape(ca.Sparsity.diag(2), ca.Sparsity.nonzeros(4, 1, [0, 3]))
true
julia> ca.is_reshape(ca.Sparsity.diag(2), ca.Sparsity.nonzeros(4, 1, [0, 2]))
false

See also
reshape, find

Extra doc: https://github.com/casadi/casadi/wiki/L_2o3

◆ is_row()

bool casadi::Sparsity::is_row ( ) const

The number of columns (including zero) and the nonzeros play no role.

>>> Sparsity.dense(1, 3).is_row(), Sparsity.dense(3, 1).is_row()
(True, False)
>>> Sparsity(1, 0).is_row()
True

>> [Sparsity.dense(1, 3).is_row(), Sparsity.dense(3, 1).is_row()]
1 0
>> Sparsity(1, 0).is_row()
1

julia> ca.is_row(ca.Sparsity.dense(1, 3)), ca.is_row(ca.Sparsity.dense(3, 1))
(true, false)
julia> ca.is_row(ca.Sparsity(1, 0))
true

See also
is_column, is_vector

Extra doc: https://github.com/casadi/casadi/wiki/L_cx

◆ is_scalar()

bool casadi::Sparsity::is_scalar ( bool  scalar_and_dense = false) const
Parameters
scalar_and_denseIf true, additionally require the single entry to be a nonzero (a 1-by-1 pattern with zero nonzeros is a structural zero)

>>> Sparsity.dense(1, 1).is_scalar(), Sparsity(1, 1).is_scalar()
(True, True)
>>> Sparsity(1, 1).is_scalar(True), Sparsity.dense(2, 1).is_scalar()
(False, False)

>> [Sparsity.dense(1, 1).is_scalar(), Sparsity(1, 1).is_scalar()]
1 1
>> [Sparsity(1, 1).is_scalar(true), Sparsity.dense(2, 1).is_scalar()]
0 0

julia> ca.is_scalar(ca.Sparsity.dense(1, 1)), ca.is_scalar(ca.Sparsity(1, 1))
(true, true)
julia> ca.is_scalar(ca.Sparsity(1, 1), true), ca.is_scalar(ca.Sparsity.dense(2, 1))
(false, false)

See also
scalar, is_dense

Extra doc: https://github.com/casadi/casadi/wiki/L_2o8

◆ is_selection()

bool casadi::Sparsity::is_selection ( bool  allow_empty = false) const

A selection matrix S picks a subset of the entries of a dense vector: S @ v is a vector of distinct entries of v. The pattern has at most one nonzero per column and exactly one per row. Equivalent to is_orthonormal_rows(allow_empty).

Parameters
allow_emptyIf true, rows without nonzeros are allowed (the result may contain structural zeros)

>>> S = Sparsity.triplet(2, 3, [0, 1], [2, 0])
>>> DM(S, 1) @ DM([10, 20, 30])
DM([30, 10])
>>> S.is_selection(), Sparsity.triplet(2, 3, [0], [2]).is_selection()
(True, False)
>>> Sparsity.triplet(2, 3, [0], [2]).is_selection(True)
True
>>> Sparsity.diag(3, 2).is_selection()
False

>> S = Sparsity.triplet(2, 3, [0, 1], [2, 0]);
>> DM(S, 1) * DM([10; 20; 30])
[30, 10]
>> [S.is_selection(), Sparsity.triplet(2, 3, 0, 2).is_selection()]
1 0
>> Sparsity.triplet(2, 3, 0, 2).is_selection(true)
1
>> Sparsity.diag(3, 2).is_selection()
0

julia> S = ca.Sparsity.triplet(2, 3, [0, 1], [2, 0]);
julia> ca.DM(S, 1) * ca.DM([10, 20, 30])
DM([30, 10])
julia> ca.is_selection(S), ca.is_selection(ca.Sparsity.triplet(2, 3, [0], [2]))
(true, false)
julia> ca.is_selection(ca.Sparsity.triplet(2, 3, [0], [2]), true)
true
julia> ca.is_selection(ca.Sparsity.diag(3, 2))
false

See also
is_permutation, is_orthonormal_rows

Extra doc: https://github.com/casadi/casadi/wiki/L_24e

◆ is_singular()

bool casadi::Sparsity::is_singular ( ) const

True when the structural rank (sprank) is smaller than the size, i.e. no choice of nonzero values can make a matrix with this pattern invertible. A non-square pattern raises an error.

>>> Sparsity.diag(3).is_singular(), Sparsity(3, 3).is_singular()
(False, True)
>>> Sparsity.nonzeros(3, 3, [0, 1, 2]).is_singular(), Sparsity(0, 0).is_singular()
(True, False)
>>> try: Sparsity.dense(2, 3).is_singular()
... except Exception as e: print("not square")
not square

>> [Sparsity.diag(3).is_singular(), Sparsity(3, 3).is_singular()]
0 1
>> [Sparsity.nonzeros(3, 3, [1, 2, 3]).is_singular(), Sparsity(0, 0).is_singular()]
1 0
>> try, Sparsity.dense(2, 3).is_singular(); catch e, disp('not square'); end
not square

julia> ca.is_singular(ca.Sparsity.diag(3)), ca.is_singular(ca.Sparsity(3, 3))
(false, true)
julia> ca.is_singular(ca.Sparsity.nonzeros(3, 3, [0, 1, 2]))
true
julia> ca.is_singular(ca.Sparsity(0, 0))
false
julia> try
           ca.is_singular(ca.Sparsity.dense(2, 3))
       catch e
           println("not square")
       end
not square

See also
sprank, btf

Extra doc: https://github.com/casadi/casadi/wiki/L_24c

◆ is_square()

bool casadi::Sparsity::is_square ( ) const

>>> Sparsity.dense(2, 2).is_square(), Sparsity.dense(2, 3).is_square()
(True, False)
>>> Sparsity(0, 0).is_square()
True

>> [Sparsity.dense(2, 2).is_square(), Sparsity.dense(2, 3).is_square()]
1 0
>> Sparsity(0, 0).is_square()
1

julia> ca.is_square(ca.Sparsity.dense(2, 2)), ca.is_square(ca.Sparsity.dense(2, 3))
(true, false)
julia> ca.is_square(ca.Sparsity(0, 0))
true

Extra doc: https://github.com/casadi/casadi/wiki/L_248

◆ is_stacked()

bool casadi::Sparsity::is_stacked ( const Sparsity &  y,
casadi_int  n 
) const

True when this pattern equals horzcat(y, ..., y) with n repetitions, i.e. the pattern of repmat(y, 1, n). The patterns are compared structurally, so a dense pattern of the right shape does not count as a stack of a sparse one.

>>> sp = horzcat(Sparsity.diag(2), Sparsity.diag(2), Sparsity.diag(2))
>>> sp.is_stacked(Sparsity.diag(2), 3), sp.is_stacked(Sparsity.diag(2), 2)
(True, False)
>>> Sparsity.dense(2, 6).is_stacked(Sparsity.diag(2), 3)
False

>> sp = [Sparsity.diag(2), Sparsity.diag(2), Sparsity.diag(2)];
>> sp.is_stacked(Sparsity.diag(2), 3), sp.is_stacked(Sparsity.diag(2), 2)
1
0
>> Sparsity.dense(2, 6).is_stacked(Sparsity.diag(2), 3)
0

julia> sp = ca.repmat(ca.Sparsity.diag(2), 1, 3)
Sparsity(2x6,6nz)
julia> ca.is_stacked(sp, ca.Sparsity.diag(2), 3), ca.is_stacked(sp, ca.Sparsity.diag(2), 2)
(true, false)
julia> ca.is_stacked(ca.Sparsity.dense(2, 6), ca.Sparsity.diag(2), 3)
false

See also
is_equal, horzcat

Extra doc: https://github.com/casadi/casadi/wiki/L_2np

◆ is_subset()

bool casadi::Sparsity::is_subset ( const Sparsity &  rhs) const

Both patterns must have the same shape, otherwise an error is raised. A pattern is a subset of itself and an all-zero pattern is a subset of any pattern of its shape.

>>> Sparsity.diag(3).is_subset(Sparsity.dense(3, 3))
True
>>> Sparsity.dense(3, 3).is_subset(Sparsity.diag(3))
False
>>> Sparsity(3, 3).is_subset(Sparsity.diag(3))
True
>>> Sparsity.diag(3).is_subset(Sparsity.diag(3))
True

>> Sparsity.diag(3).is_subset(Sparsity.dense(3, 3))
1
>> Sparsity.dense(3, 3).is_subset(Sparsity.diag(3))
0
>> Sparsity(3, 3).is_subset(Sparsity.diag(3))
1
>> Sparsity.diag(3).is_subset(Sparsity.diag(3))
1

julia> ca.is_subset(ca.Sparsity.diag(3), ca.Sparsity.dense(3, 3))
true
julia> ca.is_subset(ca.Sparsity.dense(3, 3), ca.Sparsity.diag(3))
false
julia> ca.is_subset(ca.Sparsity(3, 3), ca.Sparsity.diag(3))
true
julia> ca.is_subset(ca.Sparsity.diag(3), ca.Sparsity.diag(3))
true

See also
unite, intersect, is_equal

Extra doc: https://github.com/casadi/casadi/wiki/L_2o4

◆ is_symmetric()

bool casadi::Sparsity::is_symmetric ( ) const

Structural symmetry only: (i, j) is a nonzero if and only if (j, i) is. Required by amd, ldl and the star colorings. A rectangular pattern is never symmetric.

>>> Sparsity.banded(3, 1).is_symmetric(), Sparsity.upper(3).is_symmetric()
(True, False)
>>> Sparsity(3, 3).is_symmetric(), Sparsity.dense(2, 3).is_symmetric()
(True, False)

>> [Sparsity.banded(3, 1).is_symmetric(), Sparsity.upper(3).is_symmetric()]
1 0
>> [Sparsity(3, 3).is_symmetric(), Sparsity.dense(2, 3).is_symmetric()]
1 0

julia> ca.is_symmetric(ca.Sparsity.banded(3, 1)), ca.is_symmetric(ca.Sparsity.upper(3))
(true, false)
julia> ca.is_symmetric(ca.Sparsity(3, 3)), ca.is_symmetric(ca.Sparsity.dense(2, 3))
(true, false)

See also
is_transpose, T

Extra doc: https://github.com/casadi/casadi/wiki/L_249

◆ is_transpose()

bool casadi::Sparsity::is_transpose ( const Sparsity &  y) const

>>> Sparsity.band(3, 1).is_transpose(Sparsity.band(3, -1))
True
>>> Sparsity.band(3, 1).is_transpose(Sparsity.band(3, 1))
False
>>> Sparsity.dense(2, 3).is_transpose(Sparsity.dense(3, 2))
True

>> Sparsity.band(3, 1).is_transpose(Sparsity.band(3, -1))
1
>> Sparsity.band(3, 1).is_transpose(Sparsity.band(3, 1))
0
>> Sparsity.dense(2, 3).is_transpose(Sparsity.dense(3, 2))
1

julia> ca.is_transpose(ca.Sparsity.band(3, 1), ca.Sparsity.band(3, -1))
true
julia> ca.is_transpose(ca.Sparsity.band(3, 1), ca.Sparsity.band(3, 1))
false
julia> ca.is_transpose(ca.Sparsity.dense(2, 3), ca.Sparsity.dense(3, 2))
true

See also
T, is_symmetric

Extra doc: https://github.com/casadi/casadi/wiki/L_2o2

◆ is_tril()

bool casadi::Sparsity::is_tril ( bool  strictly = false) const
Parameters
strictlyIf true, require row > col (no diagonal entries)

>>> Sparsity.lower(3).is_tril(), Sparsity.lower(3).is_tril(True)
(True, False)
>>> Sparsity.band(3, 1).is_tril(True), Sparsity.diag(3).is_tril()
(True, True)
>>> Sparsity.dense(3, 1).is_tril(), Sparsity.dense(1, 3).is_tril()
(True, False)

>> [Sparsity.lower(3).is_tril(), Sparsity.lower(3).is_tril(true)]
1 0
>> [Sparsity.band(3, 1).is_tril(true), Sparsity.diag(3).is_tril()]
1 1
>> [Sparsity.dense(3, 1).is_tril(), Sparsity.dense(1, 3).is_tril()]
1 0

julia> ca.is_tril(ca.Sparsity.lower(3)), ca.is_tril(ca.Sparsity.lower(3), true)
(true, false)
julia> ca.is_tril(ca.Sparsity.band(3, 1), true), ca.is_tril(ca.Sparsity.diag(3))
(true, true)
julia> ca.is_tril(ca.Sparsity.dense(3, 1)), ca.is_tril(ca.Sparsity.dense(1, 3))
(true, false)

See also
is_triu, lower, tril, nnz_lower

Extra doc: https://github.com/casadi/casadi/wiki/L_24b

◆ is_triu()

bool casadi::Sparsity::is_triu ( bool  strictly = false) const
Parameters
strictlyIf true, require row < col (no diagonal entries)

Defined for any shape; a pattern without nonzeros is upper triangular.

>>> Sparsity.upper(3).is_triu(), Sparsity.upper(3).is_triu(True)
(True, False)
>>> Sparsity.band(3, -1).is_triu(True), Sparsity(3, 3).is_triu()
(True, True)
>>> Sparsity.dense(1, 3).is_triu(), Sparsity.dense(3, 1).is_triu()
(True, False)

>> [Sparsity.upper(3).is_triu(), Sparsity.upper(3).is_triu(true)]
1 0
>> [Sparsity.band(3, -1).is_triu(true), Sparsity(3, 3).is_triu()]
1 1
>> [Sparsity.dense(1, 3).is_triu(), Sparsity.dense(3, 1).is_triu()]
1 0

julia> ca.is_triu(ca.Sparsity.upper(3)), ca.is_triu(ca.Sparsity.upper(3), true)
(true, false)
julia> ca.is_triu(ca.Sparsity.band(3, -1), true), ca.is_triu(ca.Sparsity(3, 3))
(true, true)
julia> ca.is_triu(ca.Sparsity.dense(1, 3)), ca.is_triu(ca.Sparsity.dense(3, 1))
(true, false)

See also
is_tril, upper, triu, nnz_upper

Extra doc: https://github.com/casadi/casadi/wiki/L_24a

◆ is_vector()

bool casadi::Sparsity::is_vector ( ) const

A 1-by-1 pattern is a vector; a 0-by-3 pattern is not.

>>> Sparsity.dense(3, 1).is_vector(), Sparsity.dense(1, 3).is_vector()
(True, True)
>>> Sparsity.dense(1, 1).is_vector(), Sparsity.dense(2, 2).is_vector()
(True, False)
>>> Sparsity(0, 3).is_vector()
False

>> [Sparsity.dense(3, 1).is_vector(), Sparsity.dense(1, 3).is_vector()]
1 1
>> [Sparsity.dense(1, 1).is_vector(), Sparsity.dense(2, 2).is_vector()]
1 0
>> Sparsity(0, 3).is_vector()
0

julia> ca.is_vector(ca.Sparsity.dense(3, 1)), ca.is_vector(ca.Sparsity.dense(1, 3))
(true, true)
julia> ca.is_vector(ca.Sparsity.dense(1, 1)), ca.is_vector(ca.Sparsity.dense(2, 2))
(true, false)
julia> ca.is_vector(ca.Sparsity(0, 3))
false

See also
is_row, is_column

Extra doc: https://github.com/casadi/casadi/wiki/L_cz

◆ kkt()

static Sparsity casadi::Sparsity::kkt ( const Sparsity &  H,
const Sparsity &  J,
bool  with_x_diag = true,
bool  with_lam_g_diag = true 
)
static

Block pattern of the KKT matrix of an NLP with Hessian H (square, n-by-n) and constraint Jacobian J (m-by-n), where I1 and I2 are the n-by-n and m-by-m diagonal patterns that are included on request. Shape (n+m)-by-(n+m).

Parameters
HHessian pattern, must be square
JJacobian pattern, its number of columns must equal the size of H
with_x_diagAdd the diagonal to the H block
with_lam_g_diagMake the lower right block diagonal instead of all-zero

>>> DM(Sparsity.kkt(Sparsity.diag(2), Sparsity.dense(1, 2)), 1)
DM(
[[1, 00, 1],
 [00, 1, 1],
 [1, 1, 1]])
>>> DM(Sparsity.kkt(Sparsity(2, 2), Sparsity.dense(1, 2), False, False), 1)
DM(
[[00, 00, 1],
 [00, 00, 1],
 [1, 1, 00]])
>>> try: Sparsity.kkt(Sparsity.diag(2), Sparsity.dense(1, 3))
... except Exception as e: print("dimension mismatch")
dimension mismatch

>> DM(Sparsity.kkt(Sparsity.diag(2), Sparsity.dense(1, 2)), 1)
[[1, 00, 1],
 [00, 1, 1],
 [1, 1, 1]]
>> DM(Sparsity.kkt(Sparsity(2, 2), Sparsity.dense(1, 2), false, false), 1)
[[00, 00, 1],
 [00, 00, 1],
 [1, 1, 00]]
>> J = Sparsity.dense(1, 3);
>> try, Sparsity.kkt(Sparsity.diag(2), J); catch e, disp('dimension mismatch'); end
dimension mismatch

julia> ca.DM(ca.Sparsity.kkt(ca.Sparsity.diag(2), ca.Sparsity.dense(1, 2)), 1)
DM(
[[1, 00, 1],
 [00, 1, 1],
 [1, 1, 1]])
julia> ca.DM(ca.Sparsity.kkt(ca.Sparsity(2, 2), ca.Sparsity.dense(1, 2), false, false), 1)
DM(
[[00, 00, 1],
 [00, 00, 1],
 [1, 1, 00]])
julia> try
           ca.Sparsity.kkt(ca.Sparsity.diag(2), ca.Sparsity.dense(1, 3))
       catch e
           println("dimension mismatch")
       end
dimension mismatch

See also
blockcat

Extra doc: https://github.com/casadi/casadi/wiki/L_dk

◆ largest_first()

std::vector<casadi_int> casadi::Sparsity::largest_first ( ) const

Columns with the same number of nonzeros keep their relative order. Used as the ordering of the star colorings.

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> sp.largest_first(), Sparsity.diag(3).largest_first()
([0, 2, 3, 1], [0, 1, 2])

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> sp.largest_first(), Sparsity.diag(3).largest_first()
0 2 3 1
0 1 2

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> ca.largest_first(sp), ca.largest_first(ca.Sparsity.diag(3))
([0, 2, 3, 1], [0, 1, 2])

See also
star_coloring

Extra doc: https://github.com/casadi/casadi/wiki/L_de

◆ ldl()

Sparsity casadi::Sparsity::ldl ( std::vector< casadi_int > &  p,
bool  amd = true 
) const

Computes the pattern of the factor in A[p, p] = L*D*L^T, where L is unit lower triangular. Returns the pattern of the strictly upper triangular L^T (the unit diagonal is not stored) and the ordering p. A non-symmetric pattern raises an error. The numerical counterpart is ldl() applied to a matrix.

Parameters
amdIf true (default), a fill-reducing AMD ordering is computed and returned in p; if false, p is the identity
Returns
Pattern of L^T and the permutation vector p

>>> Lt, p = Sparsity.banded(4, 1).ldl(False)
>>> DM(Lt, 1), p
(DM(
[[00, 1, 00, 00],
 [00, 00, 1, 00],
 [00, 00, 00, 1],
 [00, 00, 00, 00]]), [0, 1, 2, 3])
>>> A = Sparsity.nonzeros(4, 4, [0, 3, 5, 10, 12, 15])
>>> Lt, p = A.ldl()
>>> Lt.nnz(), p
(1, [1, 2, 0, 3])
>>> try: Sparsity.upper(3).ldl()
... except Exception as e: print("not symmetric")
not symmetric

>> [Lt, p] = Sparsity.banded(4, 1).ldl(false);
>> DM(Lt, 1), p
[[00, 1, 00, 00],
 [00, 00, 1, 00],
 [00, 00, 00, 1],
 [00, 00, 00, 00]]
0 1 2 3
>> A = Sparsity.nonzeros(4, 4, [1, 4, 6, 11, 13, 16]);
>> [Lt, p] = A.ldl(); disp(Lt.nnz()), disp(p)
1
1 2 0 3
>> try, Sparsity.upper(3).ldl(); catch e, disp('not symmetric'); end
not symmetric

julia> ca.ldl(ca.Sparsity.banded(4, 1), false)
(4x4,3nz, [0, 1, 2, 3])
julia> A = ca.Sparsity.nonzeros(4, 4, [0, 3, 5, 10, 12, 15]);
julia> ca.nnz(first(ca.ldl(A)))
1
julia> try
           ca.ldl(ca.Sparsity.upper(3))
       catch e
           println("not symmetric")
       end
not symmetric

The implementation is a modified version of LDL Copyright(c) Timothy A. Davis, 2005-2013 Licensed as a derivative work under the GNU LGPL

See also
amd, etree, qr_sparse

Extra doc: https://github.com/casadi/casadi/wiki/L_d3

◆ lower()

static Sparsity casadi::Sparsity::lower ( casadi_int  n)
static

Column j contains the rows j, ..., n-1, so the diagonal is included and the pattern has n*(n+1)/2 nonzeros.

Parameters
nSize of the square pattern, nonnegative

>>> DM(Sparsity.lower(3), 1)
DM(
[[1, 00, 00],
 [1, 1, 00],
 [1, 1, 1]])
>>> SX.sym("x", Sparsity.lower(2))
SX(
[[x_0, 00],
 [x_1, x_2]])

>> DM(Sparsity.lower(3), 1)
[[1, 00, 00],
 [1, 1, 00],
 [1, 1, 1]]
>> SX.sym('x', Sparsity.lower(2))
[[x_0, 00],
 [x_1, x_2]]

julia> ca.DM(ca.Sparsity.lower(3), 1)
DM(
[[1, 00, 00],
 [1, 1, 00],
 [1, 1, 1]])
julia> ca.SX.sym("x", ca.Sparsity.lower(2))
SX(
[[x_0, 00],
 [x_1, x_2]])

See also
upper, tril, is_tril

Extra doc: https://github.com/casadi/casadi/wiki/L_bh

◆ makeDense()

Sparsity casadi::Sparsity::makeDense ( std::vector< casadi_int > &  mapping) const
Returns
The dense pattern and a mapping of length nnz(): mapping[k] is the flat (column-major) element index of nonzero k, as returned by find()

>>> sp = Sparsity.triplet(3, 2, [0, 2], [0, 1])
>>> dense, mapping = sp.makeDense()
>>> dense, mapping
(Sparsity(3x2), [0, 5])

>> sp = Sparsity.triplet(3, 2, [0, 2], [0, 1]);
>> [dense, mapping] = sp.makeDense(); disp(dense), disp(mapping)
3x2
0 5

julia> sp = ca.Sparsity.triplet(3, 2, [0, 2], [0, 1]);
julia> ca.makeDense(sp)
(3x2, [0, 5])

See also
find, dense

Extra doc: https://github.com/casadi/casadi/wiki/L_cu

◆ nnz()

casadi_int casadi::Sparsity::nnz ( ) const

Equals colind[size2()] and the length of the row vector. Zero for an empty pattern and for a pattern created with Sparsity(nrow, ncol).

See also
numel, density, nnz_upper, nnz_lower, nnz_diag

Extra doc: https://github.com/casadi/casadi/wiki/L_bt

◆ nnz_diag()

casadi_int casadi::Sparsity::nnz_diag ( ) const

◆ nnz_lower()

casadi_int casadi::Sparsity::nnz_lower ( bool  strictly = false) const
Parameters
strictlyIf true, exclude the diagonal (count i > j only)
See also
nnz_upper, nnz_diag, get_lower, is_tril

Extra doc: https://github.com/casadi/casadi/wiki/L_bv

◆ nnz_upper()

casadi_int casadi::Sparsity::nnz_upper ( bool  strictly = false) const
Parameters
strictlyIf true, exclude the diagonal (count i < j only)

Defined for any shape, not only square patterns.

>>> sp = Sparsity.dense(3, 3)
>>> sp.nnz_upper(), sp.nnz_upper(True), sp.nnz_lower(), sp.nnz_lower(True)
(6, 3, 6, 3)
>>> sp.nnz_diag()
3
>>> sp = Sparsity.dense(2, 4)
>>> sp.nnz_upper(), sp.nnz_lower(), sp.nnz_diag()
(7, 3, 2)
>>> Sparsity.lower(3).nnz_upper(), Sparsity.lower(3).nnz_upper(True)
(3, 0)

>> sp = Sparsity.dense(3, 3);
>> [sp.nnz_upper(), sp.nnz_upper(true), sp.nnz_lower(), sp.nnz_lower(true)]
6 3 6 3
>> sp.nnz_diag()
3
>> sp = Sparsity.dense(2, 4);
>> [sp.nnz_upper(), sp.nnz_lower(), sp.nnz_diag()]
7 3 2
>> [Sparsity.lower(3).nnz_upper(), Sparsity.lower(3).nnz_upper(true)]
3 0

julia> sp = ca.Sparsity.dense(3, 3);
julia> ca.nnz_upper(sp), ca.nnz_upper(sp, true), ca.nnz_lower(sp), ca.nnz_lower(sp, true)
(6, 3, 6, 3)
julia> ca.nnz_diag(sp)
3
julia> sp = ca.Sparsity.dense(2, 4);
julia> ca.nnz_upper(sp), ca.nnz_lower(sp), ca.nnz_diag(sp)
(7, 3, 2)
julia> ca.nnz_upper(ca.Sparsity.lower(3)), ca.nnz_upper(ca.Sparsity.lower(3), true)
(3, 0)

See also
nnz_lower, nnz_diag, get_upper, is_triu

Extra doc: https://github.com/casadi/casadi/wiki/L_bu

◆ nonzeros()

static Sparsity casadi::Sparsity::nonzeros ( casadi_int  nrow,
casadi_int  ncol,
const std::vector< casadi_int > &  nz,
bool  ind1 = SWIG_IND1 
)
static

Inverse of find(): Sparsity.nonzeros(sp.size1(), sp.size2(), sp.find()) equals sp. Duplicates are merged.

Parameters
nrowNumber of rows, must be positive
ncolNumber of columns
nzFlat indices, each in [0, nrow*ncol); an index out of range raises an error
ind1If true, the indices are one-based

>>> DM(Sparsity.nonzeros(3, 2, [0, 4]), 1)
DM(
[[1, 00],
 [00, 1],
 [00, 00]])
>>> sp = Sparsity.banded(3, 1)
>>> Sparsity.nonzeros(3, 3, sp.find()) == sp
True
>>> Sparsity.nonzeros(3, 2, [1, 5], True) == Sparsity.nonzeros(3, 2, [0, 4])
True

>> DM(Sparsity.nonzeros(3, 2, [1, 5]), 1)
[[1, 00],
 [00, 1],
 [00, 00]]
>> sp = Sparsity.banded(3, 1);
>> Sparsity.nonzeros(3, 3, sp.find()) == sp
1
>> Sparsity.nonzeros(3, 2, [0, 4], false) == Sparsity.nonzeros(3, 2, [1, 5])
1

julia> ca.DM(ca.Sparsity.nonzeros(3, 2, [0, 4]), 1)
DM(
[[1, 00],
 [00, 1],
 [00, 00]])
julia> sp = ca.Sparsity.banded(3, 1);
julia> ca.is_equal(ca.Sparsity.nonzeros(3, 3, ca.find(sp)), sp)
true
julia> sp1 = ca.Sparsity.nonzeros(3, 2, [1, 5], true);
julia> ca.is_equal(sp1, ca.Sparsity.nonzeros(3, 2, [0, 4]))
true

See also
find, triplet

Extra doc: https://github.com/casadi/casadi/wiki/L_23g

◆ numel()

casadi_int casadi::Sparsity::numel ( ) const

The product may overflow for very large shapes; nnz() never exceeds it.

>>> sp = Sparsity.diag(2, 3)
>>> sp.numel(), sp.nnz(), Sparsity(0, 3).numel()
(6, 2, 0)

>> sp = Sparsity.diag(2, 3);
>> fprintf('%d %d %d\n', sp.numel(), sp.nnz(), Sparsity(0, 3).numel())
6 2 0

julia> sp = ca.Sparsity.diag(2, 3);
julia> ca.numel(sp), ca.nnz(sp), ca.numel(ca.Sparsity(0, 3))
(6, 2, 0)

See also
nnz, size

Extra doc: https://github.com/casadi/casadi/wiki/L_bq

◆ operator!=()

bool casadi::Sparsity::operator!= ( const Sparsity &  y) const
inline

Definition at line 1443 of file sparsity.hpp.

◆ operator*()

Sparsity casadi::Sparsity::operator* ( const Sparsity &  b) const

The pattern of the elementwise product x * y for matrices with these patterns. A shape mismatch raises an error. In MATLAB this is the .* operator; * and mtimes give the pattern of the matrix product.

>>> a = Sparsity.diag(2)
>>> b = Sparsity.triplet(2, 2, [0, 1], [1, 1])
>>> DM(a.intersect(b), 1)
DM(
[[00, 00],
 [00, 1]])

>> a = Sparsity.diag(2);
>> b = Sparsity.triplet(2, 2, [0, 1], [1, 1]);
>> DM(a.intersect(b), 1)
[[00, 00],
 [00, 1]]

julia> a = ca.Sparsity.diag(2);
julia> b = ca.Sparsity.triplet(2, 2, [0, 1], [1, 1]);
julia> ca.DM(ca.intersect(a, b), 1)
DM(
[[00, 00],
 [00, 1]])

See also
unite, combine

Extra doc: https://github.com/casadi/casadi/wiki/L_cn

◆ operator+()

Sparsity casadi::Sparsity::operator+ ( const Sparsity &  b) const

The pattern of x + y for matrices with these patterns. A shape mismatch raises an error.

>>> a = Sparsity.diag(2)
>>> b = Sparsity.triplet(2, 2, [0, 1], [1, 1])
>>> DM(a.unite(b), 1)
DM(
[[1, 1],
 [00, 1]])
>>> a + b == a.unite(b), a * b == a.intersect(b)
(True, True)
>>> try: a + Sparsity.dense(3, 3)
... except Exception as e: print("dimension mismatch")
dimension mismatch

>> a = Sparsity.diag(2);
>> b = Sparsity.triplet(2, 2, [0, 1], [1, 1]);
>> DM(a.unite(b), 1)
[[1, 1],
 [00, 1]]
>> a + b == a.unite(b), a .* b == a.intersect(b)
1
1
>> try, a + Sparsity.dense(3, 3); catch e, disp('dimension mismatch'); end
dimension mismatch

julia> a = ca.Sparsity.diag(2);
julia> b = ca.Sparsity.triplet(2, 2, [0, 1], [1, 1]);
julia> ca.DM(ca.unite(a, b), 1)
DM(
[[1, 1],
 [00, 1]])
julia> try
           ca.unite(a, ca.Sparsity.dense(3, 3))
       catch e
           println("dimension mismatch")
       end
dimension mismatch

See also
intersect, combine, is_subset

Extra doc: https://github.com/casadi/casadi/wiki/L_cm

◆ operator==()

bool casadi::Sparsity::operator== ( const Sparsity &  y) const
inline

True when the dimensions and the nonzero positions coincide. This is the comparison behind the == operator. Shared (cached) patterns are detected in constant time; otherwise colind and row are compared. The second overload compares against a pattern given in compressed column storage vectors.

>>> a = Sparsity.diag(2)
>>> a.is_equal(Sparsity.diag(2)), a == Sparsity.diag(2), a != Sparsity.dense(2, 2)
(True, True, True)
>>> a.is_equal(2, 2, [0, 1, 2], [0, 1])
True
>>> Sparsity.dense(2, 2) == Sparsity.dense(2, 3)
False
>>> Sparsity(2, 2) == Sparsity.dense(2, 2)
False

>> a = Sparsity.diag(2);
>> a.is_equal(Sparsity.diag(2)), a == Sparsity.diag(2)
1
1
>> a ~= Sparsity.dense(2, 2)
1
>> a.is_equal(2, 2, [0, 1, 2], [0, 1])
1
>> Sparsity.dense(2, 2) == Sparsity.dense(2, 3)
0
>> Sparsity(2, 2) == Sparsity.dense(2, 2)
0

julia> a = ca.Sparsity.diag(2);
julia> ca.is_equal(a, ca.Sparsity.diag(2)), !ca.is_equal(a, ca.Sparsity.dense(2, 2))
(true, true)
julia> ca.is_equal(a, 2, 2, [0, 1, 2], [0, 1])
true
julia> ca.is_equal(ca.Sparsity.dense(2, 2), ca.Sparsity.dense(2, 3))
false
julia> ca.is_equal(ca.Sparsity(2, 2), ca.Sparsity.dense(2, 2))
false

See also
is_subset, is_transpose, is_reshape, hash

Extra doc: https://github.com/casadi/casadi/wiki/L_2no

Definition at line 1439 of file sparsity.hpp.

◆ pattern_inverse()

Sparsity casadi::Sparsity::pattern_inverse ( ) const

The result has the same shape; a dense pattern becomes all-zero and an all-zero pattern becomes dense.

>>> DM(Sparsity.diag(2).pattern_inverse(), 1)
DM(
[[00, 1],
 [1, 00]])
>>> Sparsity.dense(2, 2).pattern_inverse(), Sparsity(2, 2).pattern_inverse()
(Sparsity(2x2,0nz), Sparsity(2x2))

>> DM(Sparsity.diag(2).pattern_inverse(), 1)
[[00, 1],
 [1, 00]]
>> Sparsity.dense(2, 2).pattern_inverse(), Sparsity(2, 2).pattern_inverse()
2x2,0nz
2x2

julia> ca.DM(ca.pattern_inverse(ca.Sparsity.diag(2)), 1)
DM(
[[00, 1],
 [1, 00]])
julia> ca.pattern_inverse(ca.Sparsity.dense(2, 2)), ca.pattern_inverse(ca.Sparsity(2, 2))
(2x2,0nz, 2x2)

See also
unite, intersect

Extra doc: https://github.com/casadi/casadi/wiki/L_2o5

◆ permutation()

static Sparsity casadi::Sparsity::permutation ( const std::vector< casadi_int > &  p,
bool  invert = false 
)
static

P is square with one nonzero per row and column, placed such that multiplying a column vector v from the left gives the same result as indexing it: P @ v == v[p]. The inverse of a permutation matrix is its transpose, so invert true returns the transpose pattern, for which P @ v puts v[i] at position p[i].

Parameters
pPermutation vector: every integer in [0, len(p)) exactly once; anything else raises an error
invertIf true, build the inverse (transposed) permutation

>>> P = Sparsity.permutation([2, 0, 1])
>>> DM(P, 1)
DM(
[[00, 00, 1],
 [1, 00, 00],
 [00, 1, 00]])
>>> DM(P, 1) @ DM([10, 20, 30])
DM([30, 10, 20])
>>> DM(Sparsity.permutation([2, 0, 1], True), 1) @ DM([10, 20, 30])
DM([20, 30, 10])
>>> Sparsity.permutation([2, 0, 1], True) == P.T
True
>>> try: Sparsity.permutation([0, 0, 1])
... except Exception as e: print("not a permutation")
not a permutation

>> P = Sparsity.permutation([2, 0, 1]);
>> DM(P, 1)
[[00, 00, 1],
 [1, 00, 00],
 [00, 1, 00]]
>> DM(P, 1) * DM([10; 20; 30])
[30, 10, 20]
>> DM(Sparsity.permutation([2, 0, 1], true), 1) * DM([10; 20; 30])
[20, 30, 10]
>> Sparsity.permutation([2, 0, 1], true) == P.T
1
>> try, Sparsity.permutation([0, 0, 1]); catch e, disp('not a permutation'); end
not a permutation

julia> P = ca.Sparsity.permutation([2, 0, 1]);
julia> ca.DM(P, 1)
DM(
[[00, 00, 1],
 [1, 00, 00],
 [00, 1, 00]])
julia> ca.DM(P, 1) * ca.DM([10, 20, 30])
DM([30, 10, 20])
julia> ca.DM(ca.Sparsity.permutation([2, 0, 1], true), 1) * ca.DM([10, 20, 30])
DM([20, 30, 10])
julia> ca.is_equal(ca.Sparsity.permutation([2, 0, 1], true), ca.T(P))
true
julia> try
           ca.Sparsity.permutation([0, 0, 1])
       catch e
           println("not a permutation")
       end
not a permutation

See also
permutation_vector, is_permutation, pmult

Extra doc: https://github.com/casadi/casadi/wiki/L_244

◆ permutation_vector()

const std::vector<casadi_int> casadi::Sparsity::permutation_vector ( bool  invert = false) const

Inverse of permutation(): Sparsity.permutation(p).permutation_vector() returns p. Raises an error if is_permutation() is false.

Parameters
invertIf true, return the inverse permutation instead

>>> Sparsity.permutation([2, 0, 1]).permutation_vector()
[2, 0, 1]
>>> Sparsity.permutation([2, 0, 1]).permutation_vector(True)
[1, 2, 0]
>>> try: Sparsity.dense(2, 2).permutation_vector()
... except Exception as e: print("not a permutation matrix")
not a permutation matrix

>> Sparsity.permutation([2, 0, 1]).permutation_vector()
2 0 1
>> Sparsity.permutation([2, 0, 1]).permutation_vector(true)
1 2 0
>> try, Sparsity.dense(2, 2).permutation_vector(); catch e, disp('not a permutation'); end
not a permutation

julia> ca.permutation_vector(ca.Sparsity.permutation([2, 0, 1]))
3-element Vector{Int64}:
 2
 0
 1
julia> ca.permutation_vector(ca.Sparsity.permutation([2, 0, 1]), true)
3-element Vector{Int64}:
 1
 2
 0
julia> try
           ca.permutation_vector(ca.Sparsity.dense(2, 2))
       catch e
           println("not a permutation matrix")
       end
not a permutation matrix

See also
permutation, is_permutation

Extra doc: https://github.com/casadi/casadi/wiki/L_245

◆ pmult()

Sparsity casadi::Sparsity::pmult ( const std::vector< casadi_int > &  p,
bool  permute_rows = true,
bool  permute_columns = true,
bool  invert_permutation = false 
) const

Nonzero (i, j) moves to (p[i], p[j]) when both rows and columns are permuted, to (p[i], j) for rows only and to (i, p[j]) for columns only. In matrix terms this is P^T*A*P, P^T*A or A*P with P the matrix of Sparsity.permutation(p). With invert_permutation the inverse of p is used instead, so that pmult(p, True, True, True) is the pattern of A[p, p].

Parameters
pPermutation vector; its length must equal the number of rows (if permute_rows) and the number of columns (if permute_columns)
permute_rowsPermute the rows
permute_columnsPermute the columns
invert_permutationUse the inverse permutation

>>> A = Sparsity.triplet(3, 3, [0, 1, 2, 0], [1, 2, 0, 0])
>>> DM(A, 1)
DM(
[[1, 1, 00],
 [00, 00, 1],
 [1, 00, 00]])
>>> p = [2, 0, 1]
>>> DM(A.pmult(p), 1)
DM(
[[00, 1, 00],
 [00, 00, 1],
 [1, 00, 1]])
>>> P = DM(Sparsity.permutation(p), 1)
>>> A.pmult(p) == (P.T @ DM(A, 1) @ P).sparsity()
True
>>> A.pmult(p, True, True, True) == A.sub(p, p)[0]
True
>>> DM(A.pmult(p, True, False), 1)
DM(
[[00, 00, 1],
 [1, 00, 00],
 [1, 1, 00]])

>> A = Sparsity.triplet(3, 3, [0, 1, 2, 0], [1, 2, 0, 0]);
>> DM(A, 1)
[[1, 1, 00],
 [00, 00, 1],
 [1, 00, 00]]
>> p = [2, 0, 1];
>> DM(A.pmult(p), 1)
[[00, 1, 00],
 [00, 00, 1],
 [1, 00, 1]]
>> P = DM(Sparsity.permutation(p), 1);
>> A.pmult(p) == sparsity(P' * DM(A, 1) * P)
1
>> [sub, mapping] = A.sub(p, p); disp(A.pmult(p, true, true, true) == sub)
1
>> DM(A.pmult(p, true, false), 1)
[[00, 00, 1],
 [1, 00, 00],
 [1, 1, 00]]

julia> A = ca.Sparsity.triplet(3, 3, [0, 1, 2, 0], [1, 2, 0, 0]);
julia> ca.DM(A, 1)
DM(
[[1, 1, 00],
 [00, 00, 1],
 [1, 00, 00]])
julia> p = [2, 0, 1];
julia> ca.DM(ca.pmult(A, p), 1)
DM(
[[00, 1, 00],
 [00, 00, 1],
 [1, 00, 1]])
julia> P = ca.DM(ca.Sparsity.permutation(p), 1);
julia> ca.is_equal(ca.pmult(A, p), ca.sparsity(P' * ca.DM(A, 1) * P))
true
julia> ca.is_equal(ca.pmult(A, p, true, true, true), first(ca.sub(A, p, p)))
true
julia> ca.DM(ca.pmult(A, p, true, false), 1)
DM(
[[00, 00, 1],
 [1, 00, 00],
 [1, 1, 00]])

See also
permutation, sub

Extra doc: https://github.com/casadi/casadi/wiki/L_df

◆ postfix_dim()

std::string casadi::Sparsity::postfix_dim ( ) const

Rules:

  1. Dense scalar: ""
  2. 0-by-0: "[]"
  3. Dense column vector: "[5]"
  4. Other dense pattern: "[5x10]"
  5. Otherwise: "[5x10,3nz]"

>>> repr(Sparsity.dense(1, 1).postfix_dim()), repr(Sparsity(0, 0).postfix_dim())
("''", "'[]'")
>>> Sparsity.dense(5).postfix_dim(), Sparsity.dense(5, 10).postfix_dim()
('[5]', '[5x10]')
>>> Sparsity.diag(5, 10).postfix_dim(), Sparsity(1, 1).postfix_dim()
('[5x10,5nz]', '[1x1,0nz]')
>>> Sparsity.dense(1, 5).postfix_dim(), Sparsity(0, 3).postfix_dim()
('[1x5]', '[0x3]')

>> fprintf('"%s" "%s"\n', Sparsity.dense(1, 1).postfix_dim(), Sparsity(0, 0).postfix_dim())
"" "[]"
>> Sparsity.dense(5).postfix_dim(), Sparsity.dense(5, 10).postfix_dim()
[5]
[5x10]
>> Sparsity.diag(5, 10).postfix_dim(), Sparsity(1, 1).postfix_dim()
[5x10,5nz]
[1x1,0nz]
>> Sparsity.dense(1, 5).postfix_dim(), Sparsity(0, 3).postfix_dim()
[1x5]
[0x3]

julia> ca.postfix_dim(ca.Sparsity.dense(1, 1)), ca.postfix_dim(ca.Sparsity(0, 0))
("", "[]")
julia> ca.postfix_dim(ca.Sparsity.dense(5)), ca.postfix_dim(ca.Sparsity.dense(5, 10))
("[5]", "[5x10]")
julia> ca.postfix_dim(ca.Sparsity.diag(5, 10)), ca.postfix_dim(ca.Sparsity(1, 1))
("[5x10,5nz]", "[1x1,0nz]")
julia> ca.postfix_dim(ca.Sparsity.dense(1, 5)), ca.postfix_dim(ca.Sparsity(0, 3))
("[1x5]", "[0x3]")

See also
dim

Extra doc: https://github.com/casadi/casadi/wiki/L_dg

◆ qr_sparse()

void casadi::Sparsity::qr_sparse ( Sparsity &  V,
Sparsity &  R,
std::vector< casadi_int > &  prinv,
std::vector< casadi_int > &  pc,
bool  amd = true 
) const

Computes the patterns of V (the Householder vectors, a compact representation of Q) and R for the factorization of this pattern with its columns permuted by pc, plus the row permutation prinv used by the numerical factorization (qr_sparse on a matrix) and solution. V and R may have more rows than the pattern (the matrix is extended with zero rows when it has fewer rows than columns in the structural sense).

Parameters
amdIf true (default), the columns are reordered with the AMD ordering of A^T*A, returned in pc; if false, pc is the identity
Returns
V, R, prinv, pc

>>> V, R, prinv, pc = Sparsity.dense(3, 2).qr_sparse()
>>> V, R, prinv, pc
(Sparsity(3x2,5nz), Sparsity(3x2,3nz), [0, 1, 2], [0, 1])
>>> V, R, prinv, pc = Sparsity.banded(4, 1).qr_sparse(False)
>>> V, R, prinv, pc
(Sparsity(4x4,7nz), Sparsity(4x4,9nz), [0, 1, 2, 3], [0, 1, 2, 3])

>> [V, R, prinv, pc] = Sparsity.dense(3, 2).qr_sparse();
>> V, R, prinv, pc
3x2,5nz
3x2,3nz
0 1 2
0 1
>> [V, R, prinv, pc] = Sparsity.banded(4, 1).qr_sparse(false);
>> V, R, prinv, pc
4x4,7nz
4x4,9nz
0 1 2 3
0 1 2 3

julia> V, R, prinv, pc = ca.qr_sparse(ca.Sparsity.dense(3, 2));
julia> V, R, prinv, pc
(3x2,5nz, 3x2,3nz, [0, 1, 2], [0, 1])
julia> V, R, prinv, pc = ca.qr_sparse(ca.Sparsity.banded(4, 1), false);
julia> V, R, prinv, pc
(4x4,7nz, 4x4,9nz, [0, 1, 2, 3], [0, 1, 2, 3])

The implementation is a modified version of CSparse Copyright(c) Timothy A. Davis, 2006-2009 Licensed as a derivative work under the GNU LGPL

See also
ldl, amd, etree

Extra doc: https://github.com/casadi/casadi/wiki/L_d4

◆ removeDuplicates()

void casadi::Sparsity::removeDuplicates ( std::vector< casadi_int > &  mapping)

Patterns created through the public interface have no duplicates, so this is a no-op for them. The entries of mapping (one per nonzero) corresponding to the removed duplicates are removed as well.

Parameters
mappingVector of length nnz(), filtered in the same way as the nonzeros

>>> sp = Sparsity.banded(3, 1)
>>> m = sp.removeDuplicates([0, 1, 2, 3, 4, 5, 6])
>>> m, sp
([0, 1, 2, 3, 4, 5, 6], Sparsity(3x3,7nz))

>> sp = Sparsity.banded(3, 1);
>> m = sp.removeDuplicates([0, 1, 2, 3, 4, 5, 6]);
>> m, sp
0 1 2 3 4 5 6
3x3,7nz

julia> sp = ca.Sparsity.banded(3, 1);
julia> m = ca.removeDuplicates(sp, [0, 1, 2, 3, 4, 5, 6]);
julia> m, sp
([0, 1, 2, 3, 4, 5, 6], 3x3,7nz)

See also
rowsSequential, triplet

Extra doc: https://github.com/casadi/casadi/wiki/L_d1

◆ repr_el()

std::string casadi::Sparsity::repr_el ( casadi_int  k) const

Gives "(row i, col j)", prefixed with "nonzero index k " when the pattern is not dense. Indices follow the global start_index option (zero-based by default). k must be in [0, nnz()); it is not checked.

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> sp.repr_el(1)
'nonzero index 1 (row 2, col 0)'
>>> Sparsity.dense(2, 2).repr_el(3)
'(row 1, col 1)'

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> sp.repr_el(1)
nonzero index 2 (row 3, col 1)
>> Sparsity.dense(2, 2).repr_el(3)
(row 2, col 2)

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> ca.repr_el(sp, 1)
"nonzero index 1 (row 2, col 0)"
julia> ca.repr_el(ca.Sparsity.dense(2, 2), 3)
"(row 1, col 1)"

See also
dim, get_nz

Extra doc: https://github.com/casadi/casadi/wiki/L_2ob

◆ resize()

void casadi::Sparsity::resize ( casadi_int  nrow,
casadi_int  ncol 
)

Nonzeros with row >= nrow or column >= ncol are dropped; growing adds structural zeros. Unlike reshape, the (row, col) position of the kept nonzeros is unchanged. The object is rebound to the new pattern; other references to the old pattern are unaffected.

Parameters
nrowNew number of rows, nonnegative
ncolNew number of columns, nonnegative

>>> sp = Sparsity.dense(3, 3); sp.resize(2, 2); print(sp)
2x2
>>> sp.resize(4, 4); print(DM(sp, 1))
[[1, 1, 00, 00], 
 [1, 1, 00, 00], 
 [00, 00, 00, 00], 
 [00, 00, 00, 00]]
>>> sp.resize(0, 2); print(sp)
0x2

>> sp = Sparsity.dense(3, 3); sp.resize(2, 2); disp(sp)
2x2
>> sp.resize(4, 4); disp(DM(sp, 1))
[[1, 1, 00, 00],
 [1, 1, 00, 00],
 [00, 00, 00, 00],
 [00, 00, 00, 00]]
>> sp.resize(0, 2); disp(sp)
0x2

julia> sp = ca.Sparsity.dense(3, 3); ca.resize(sp, 2, 2); sp
Sparsity(2x2)
julia> ca.resize(sp, 4, 4); ca.DM(sp, 1)
DM(
[[1, 1, 00, 00],
 [1, 1, 00, 00],
 [00, 00, 00, 00],
 [00, 00, 00, 00]])
julia> ca.resize(sp, 0, 2); sp
Sparsity(0x2)

See also
enlarge, reshape

Extra doc: https://github.com/casadi/casadi/wiki/L_2nu

◆ row()

casadi_int casadi::Sparsity::row ( casadi_int  el) const
Parameters
elNonzero index, in [0, nnz()); out of range raises an error
See also
colind, get_row

Extra doc: https://github.com/casadi/casadi/wiki/L_cc

◆ rowcol()

static Sparsity casadi::Sparsity::rowcol ( const std::vector< casadi_int > &  row,
const std::vector< casadi_int > &  col,
casadi_int  nrow,
casadi_int  ncol 
)
static

Every combination of a row index and a column index becomes a nonzero; the block need not be contiguous. Duplicate indices are merged.

Parameters
rowRow indices, each in [0, nrow)
colColumn indices, each in [0, ncol)
nrowNumber of rows of the pattern
ncolNumber of columns of the pattern

>>> DM(Sparsity.rowcol([0, 2], [1, 2], 3, 4), 1)
DM(
[[00, 1, 1, 00],
 [00, 00, 00, 00],
 [00, 1, 1, 00]])
>>> Sparsity.rowcol([], [1], 3, 4).nnz()
0

>> DM(Sparsity.rowcol([0, 2], [1, 2], 3, 4), 1)
[[00, 1, 1, 00],
 [00, 00, 00, 00],
 [00, 1, 1, 00]]
>> Sparsity.rowcol([], [1], 3, 4).nnz()
0

julia> ca.DM(ca.Sparsity.rowcol([0, 2], [1, 2], 3, 4), 1)
DM(
[[00, 1, 1, 00],
 [00, 00, 00, 00],
 [00, 1, 1, 00]])
julia> ca.nnz(ca.Sparsity.rowcol([], [1], 3, 4))
0

See also
triplet

Extra doc: https://github.com/casadi/casadi/wiki/L_bl

◆ rows()

casadi_int casadi::Sparsity::rows ( ) const
inline

Definition at line 1543 of file sparsity.hpp.

◆ rowsSequential()

bool casadi::Sparsity::rowsSequential ( bool  strictly = true) const

A pattern constructed through the public interface always satisfies this: row indices are sorted and unique within a column.

Parameters
strictlyIf true (default), duplicate rows within a column are not allowed

>>> Sparsity.banded(3, 1).rowsSequential()
True
>>> Sparsity.dense(2, 2).rowsSequential(False)
True

>> Sparsity.banded(3, 1).rowsSequential()
1
>> Sparsity.dense(2, 2).rowsSequential(false)
1

julia> ca.rowsSequential(ca.Sparsity.banded(3, 1))
true
julia> ca.rowsSequential(ca.Sparsity.dense(2, 2), false)
true

See also
removeDuplicates

Extra doc: https://github.com/casadi/casadi/wiki/L_d0

◆ scalar()

static Sparsity casadi::Sparsity::scalar ( bool  dense_scalar = true)
inlinestatic
Parameters
dense_scalarIf true (default), the single entry is a nonzero; if false, the pattern is 1-by-1 with zero nonzeros (a structurally zero scalar)

>>> Sparsity.scalar(), Sparsity.scalar().nnz()
(Sparsity(1x1), 1)
>>> Sparsity.scalar(False), Sparsity.scalar(False).nnz()
(Sparsity(1x1,0nz), 0)
>>> Sparsity.scalar() == Sparsity.dense(1, 1)
True

>> Sparsity.scalar(), Sparsity.scalar().nnz()
1x1
1
>> Sparsity.scalar(false), Sparsity.scalar(false).nnz()
1x1,0nz
0
>> Sparsity.scalar() == Sparsity.dense(1, 1)
1

julia> ca.Sparsity.scalar(), ca.nnz(ca.Sparsity.scalar())
(1x1, 1)
julia> ca.Sparsity.scalar(false), ca.nnz(ca.Sparsity.scalar(false))
(1x1,0nz, 0)
julia> ca.is_equal(ca.Sparsity.scalar(), ca.Sparsity.dense(1, 1))
true

See also
dense, is_scalar

Extra doc: https://github.com/casadi/casadi/wiki/L_bd

Definition at line 454 of file sparsity.hpp.

◆ scc()

casadi_int casadi::Sparsity::scc ( std::vector< casadi_int > &  index,
std::vector< casadi_int > &  offset 
) const

Node j is the j-th row/column and nonzero (i, j) is an edge from j to i. See Direct Methods for Sparse Linear Systems by Davis (2006).

Returns
The number of components n, the node indices grouped by component, and the offsets (length n+1): component i consists of the nodes index[offset[i]], ..., index[offset[i+1]-1], in increasing order.

The components are ordered so that the symmetric permutation A[index, index] is block upper triangular with n diagonal blocks; for a symmetric pattern it is block diagonal, with the block boundaries given by offset.

The implementation is a modified version of cs_scc in CSparse Copyright(c) Timothy A. Davis, 2006-2009 Licensed as a derivative work under the GNU LGPL

>>> A = Sparsity.nonzeros(4, 4, [0, 2, 5, 7, 10, 13, 15])
>>> DM(A, 1)
DM(
[[1, 00, 00, 00],
 [00, 1, 00, 1],
 [1, 00, 1, 00],
 [00, 1, 00, 1]])
>>> n, index, offset = A.scc()
>>> n, index, offset
(3, [2, 0, 1, 3], [0, 1, 2, 4])
>>> DM(A, 1)[index, index]
DM(
[[1, 1, 00, 00],
 [00, 1, 00, 00],
 [00, 00, 1, 1],
 [00, 00, 1, 1]])
>>> Sparsity.diag(3).scc(), Sparsity.dense(3, 3).scc(), Sparsity(0, 0).scc()
((3, [0, 1, 2], [0, 1, 2, 3]), (1, [0, 1, 2], [0, 3]), (0, [], [0]))

>> A = Sparsity.nonzeros(4, 4, [1, 3, 6, 8, 11, 14, 16]);
>> DM(A, 1)
[[1, 00, 00, 00],
 [00, 1, 00, 1],
 [1, 00, 1, 00],
 [00, 1, 00, 1]]
>> [n, index, offset] = A.scc(); disp(n), disp(index), disp(offset)
3
2 0 1 3
0 1 2 4
>> Af = DM(A, 1); disp(Af(index + 1, index + 1))
[[1, 1, 00, 00],
 [00, 1, 00, 00],
 [00, 00, 1, 1],
 [00, 00, 1, 1]]
>> [n, index, offset] = Sparsity.diag(3).scc(); disp(n), disp(index), disp(offset)
3
0 1 2
0 1 2 3
>> [n, index, offset] = Sparsity.dense(3, 3).scc(); disp(n), disp(index), disp(offset)
1
0 1 2
0 3
>> [n, index, offset] = Sparsity(0, 0).scc(); disp(n), disp(isempty(index)), disp(offset)
0
1
0

julia> A = ca.Sparsity.nonzeros(4, 4, [0, 2, 5, 7, 10, 13, 15]);
julia> ca.DM(A, 1)
DM(
[[1, 00, 00, 00],
 [00, 1, 00, 1],
 [1, 00, 1, 00],
 [00, 1, 00, 1]])
julia> ca.scc(A)
(3, [2, 0, 1, 3], [0, 1, 2, 4])
julia> ca.scc(ca.Sparsity.diag(3)), ca.scc(ca.Sparsity.dense(3, 3))
((3, [0, 1, 2], [0, 1, 2, 3]), (1, [0, 1, 2], [0, 3]))
julia> ca.scc(ca.Sparsity(0, 0))
(0, Int64[], [0])

See also
btf, dfs

Extra doc: https://github.com/casadi/casadi/wiki/L_d6

Examples
matrix/scc.py.

◆ serialize() [1/2]

std::string casadi::Sparsity::serialize ( ) const

The string can be stored and turned back into an equal pattern with deserialize(). A null object serializes and deserializes as a null object. Pickling in Python uses this mechanism.

>>> s = Sparsity.diag(2, 3).serialize()
>>> type(s).__name__, Sparsity.deserialize(s) == Sparsity.diag(2, 3)
('str', True)
>>> Sparsity.deserialize(Sparsity().serialize()).is_null()
True
>>> import pickle
>>> pickle.loads(pickle.dumps(Sparsity.diag(2, 3)))
Sparsity(2x3,2nz)

>> s = Sparsity.diag(2, 3).serialize();
>> class(s), Sparsity.deserialize(s) == Sparsity.diag(2, 3)
char
1
>> Sparsity.deserialize(Sparsity().serialize()).is_null()
1

julia> s = ca.serialize(ca.Sparsity.diag(2, 3));
julia> typeof(s), ca.is_equal(ca.Sparsity.deserialize(s), ca.Sparsity.diag(2, 3))
(String, true)
julia> ca.is_null(ca.Sparsity.deserialize(ca.serialize(ca.Sparsity())))
true

See also
deserialize, compress

Extra doc: https://github.com/casadi/casadi/wiki/L_c2

◆ serialize() [2/2]

void casadi::Sparsity::serialize ( SerializingStream &  s) const

◆ size() [1/2]

std::pair<casadi_int, casadi_int> casadi::Sparsity::size ( ) const

>>> sp = Sparsity.diag(2, 3)
>>> sp.size(), sp.size(1), sp.size(2), sp.shape
((2, 3), 2, 3, (2, 3))

>> sp = Sparsity.diag(2, 3);
>> size(sp), sp.size(1), sp.size(2)
2 3
2
3
>> [m, n] = size(sp); fprintf('%d %d\n', m, n)
2 3

julia> sp = ca.Sparsity.diag(2, 3);
julia> ca.size(sp), ca.size(sp, 1), ca.size(sp, 2)
((2, 3), 2, 3)

See also
size1, size2, numel

Extra doc: https://github.com/casadi/casadi/wiki/L_bz

◆ size() [2/2]

casadi_int casadi::Sparsity::size ( casadi_int  axis) const
Parameters
axis1 for the number of rows, 2 for the number of columns; any other value raises an error

Extra doc: https://github.com/casadi/casadi/wiki/L_c0

◆ size1()

casadi_int casadi::Sparsity::size1 ( ) const

>>> sp = Sparsity.diag(2, 3)
>>> sp.size1(), sp.rows(), sp.size2(), sp.columns()
(2, 2, 3, 3)

>> sp = Sparsity.diag(2, 3);
>> fprintf('%d %d %d %d\n', sp.size1(), sp.rows(), sp.size2(), sp.columns())
2 2 3 3

julia> sp = ca.Sparsity.diag(2, 3);
julia> ca.size1(sp), ca.rows(sp), ca.size2(sp), ca.columns(sp)
(2, 2, 3, 3)

See also
size2, size, numel

Extra doc: https://github.com/casadi/casadi/wiki/L_2nq

◆ size2()

casadi_int casadi::Sparsity::size2 ( ) const

◆ sparsity_cast_mod()

Sparsity casadi::Sparsity::sparsity_cast_mod ( const Sparsity &  X,
const Sparsity &  Y 
) const

X and Y have the same number of nonzeros and sparsity_cast(X, Y) maps nonzero k of X to nonzero k of Y. Given that this pattern is a subset of X, the result is the subset of Y made of the nonzeros of Y whose counterpart in X is in this pattern.

>>> X = Sparsity.diag(4)
>>> Y = Sparsity.dense(2, 2)
>>> x = Sparsity.nonzeros(4, 4, [0, 10, 15])
>>> DM(x.sparsity_cast_mod(X, Y), 1)
DM(
[[1, 1],
 [00, 1]])

>> X = Sparsity.diag(4);
>> Y = Sparsity.dense(2, 2);
>> x = Sparsity.nonzeros(4, 4, [1, 11, 16]);
>> DM(x.sparsity_cast_mod(X, Y), 1)
[[1, 1],
 [00, 1]]

julia> X = ca.Sparsity.diag(4);
julia> Y = ca.Sparsity.dense(2, 2);
julia> x = ca.Sparsity.nonzeros(4, 4, [0, 10, 15]);
julia> ca.DM(ca.sparsity_cast_mod(x, X, Y), 1)
DM(
[[1, 1],
 [00, 1]])

See also
sparsity_cast, is_subset

Extra doc: https://github.com/casadi/casadi/wiki/L_246

◆ spy()

void casadi::Sparsity::spy ( std::ostream &  stream = casadi::uout()) const

Writes one line per row, with "*" for a structural nonzero and "." for a structural zero, to the standard output (or the given stream). Large patterns produce nrow lines of ncol characters.

See also
spy_matlab, export_code

Extra doc: https://github.com/casadi/casadi/wiki/L_dh

◆ spy_matlab()

void casadi::Sparsity::spy_matlab ( const std::string &  mfile) const

The file is overwritten. The script defines a sparse matrix A of ones with this pattern (see export_code) and ends with spy(A).

Parameters
mfilePath of the .m file to write

>>> import os, tempfile
>>> d = tempfile.mkdtemp()
>>> f = os.path.join(d, "show_pattern.m")
>>> Sparsity.diag(2, 3).spy_matlab(f)
>>> print(open(f).read())
% This function was automatically generated by CasADi
A_m = 2;
A_n = 3;
A_j = [1, 2];
A_i = [1, 2];
A_v = ones(size(A_i));
A = sparse(A_i, A_j, A_v, A_m, A_n);
spy(A);
>>> os.remove(f); os.rmdir(d)

>> f = [tempname '.m'];
>> Sparsity.diag(2, 3).spy_matlab(f);
>> fileread(f)
% This function was automatically generated by CasADi
A_m = 2;
A_n = 3;
A_j = [1, 2];
A_i = [1, 2];
A_v = ones(size(A_i));
A = sparse(A_i, A_j, A_v, A_m, A_n);
spy(A);
>> delete(f);

julia> d = mktempdir();
julia> f = joinpath(d, "show_pattern.m");
julia> ca.spy_matlab(ca.Sparsity.diag(2, 3), f)
julia> print(read(f, String))
% This function was automatically generated by CasADi
A_m = 2;
A_n = 3;
A_j = [1, 2];
A_i = [1, 2];
A_v = ones(size(A_i));
A = sparse(A_i, A_j, A_v, A_m, A_n);
spy(A);
julia> rm(d, recursive=true)

See also
spy, export_code

Extra doc: https://github.com/casadi/casadi/wiki/L_di

◆ star_coloring()

Sparsity casadi::Sparsity::star_coloring ( casadi_int  ordering = 1,
casadi_int  cutoff = std::numeric_limits< casadi_int >::max() 
) const

Algorithm 4.1 in Gebremedhin, Manne and Pothen, What Color Is Your Jacobian?, SIAM Rev. 47(4), 2006. Exploits symmetry so that fewer colors than uni_coloring are needed to recover all nonzeros of a Hessian. A non-symmetric pattern raises an error.

Parameters
ordering0 for the natural column order, 1 (default) to color in largest_first() order
cutoffIf more than this many colors are needed, a null Sparsity is returned
Returns
A size2()-by-ncolors pattern: column c lists the columns with color c

>>> H = Sparsity.banded(4, 1)
>>> DM(H.star_coloring(), 1)
DM(
[[00, 1, 00],
 [1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]])
>>> Sparsity.diag(5).star_coloring()
Sparsity(5x1)
>>> Sparsity.dense(4, 4).star_coloring(1, 2).is_null()
True

>> H = Sparsity.banded(4, 1);
>> DM(H.star_coloring(), 1)
[[00, 1, 00],
 [1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]]
>> Sparsity.diag(5).star_coloring()
5x1
>> Sparsity.dense(4, 4).star_coloring(1, 2).is_null()
1

julia> H = ca.Sparsity.banded(4, 1);
julia> ca.DM(ca.star_coloring(H, 1, 1000), 1)
DM(
[[00, 1, 00],
 [1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]])
julia> ca.star_coloring(ca.Sparsity.diag(5), 1, 1000)
Sparsity(5x1)
julia> ca.is_null(ca.star_coloring(ca.Sparsity.dense(4, 4), 0, 2))
true

See also
star_coloring_new, star_coloring2, uni_coloring, largest_first

Extra doc: https://github.com/casadi/casadi/wiki/L_dc

◆ star_coloring2()

Sparsity casadi::Sparsity::star_coloring2 ( casadi_int  ordering = 1,
casadi_int  cutoff = std::numeric_limits< casadi_int >::max() 
) const

Algorithm 4.1 in Gebremedhin, Tarafdar, Manne and Pothen, New Acyclic and Star Coloring Algorithms with Application to Computing Hessians, SIAM J. Sci. Comput. 29(3), 2007. Same arguments and return value as star_coloring.

>>> H = Sparsity.banded(4, 1)
>>> DM(H.star_coloring2(), 1)
DM(
[[00, 1, 00],
 [1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]])

>> H = Sparsity.banded(4, 1);
>> DM(H.star_coloring2(), 1)
[[00, 1, 00],
 [1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]]

julia> H = ca.Sparsity.banded(4, 1);
julia> ca.DM(ca.star_coloring2(H, 1, 1000), 1)
DM(
[[00, 1, 00],
 [1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]])

See also
star_coloring, star_coloring_new

Extra doc: https://github.com/casadi/casadi/wiki/L_dd

◆ star_coloring_new()

Sparsity casadi::Sparsity::star_coloring_new ( std::vector< casadi_int > &  which_color,
const Dict &  opts = Dict() 
) const

Front end to star_coloring and star_coloring2 for compressed Hessian evaluation. A non-symmetric pattern raises an error.

Parameters
optsOptions: "new_algo" (bool, default false) selects star_coloring2 instead of star_coloring; "largest_first" (bool, default true) selects the largest-first ordering; "cutoff" (int) returns a null pattern when more colors are needed
Returns
The coloring (a size2()-by-ncolors pattern as in uni_coloring) and which_color, one entry per nonzero: the color whose directional derivative yields that nonzero, or -1 when the nonzero is obtained from its symmetric counterpart instead (the lowest color index is preferred)

>>> H = Sparsity.banded(4, 1)
>>> coloring, which_color = H.star_coloring_new()
>>> DM(coloring, 1)
DM(
[[00, 1, 00],
 [1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]])
>>> for k in range(H.nnz()): print(H.row()[k], H.get_col()[k], which_color[k])
0 0 1
1 0 -1
0 1 0
1 1 0
2 1 0
1 2 -1
2 2 1
3 2 1
2 3 -1
3 3 2
>>> try: Sparsity.upper(3).star_coloring_new()
... except Exception as e: print("not symmetric")
not symmetric

>> H = Sparsity.banded(4, 1);
>> [coloring, which_color] = H.star_coloring_new();
>> DM(coloring, 1)
[[00, 1, 00],
 [1, 00, 00],
 [00, 1, 00],
 [00, 00, 1]]
>> [H.row(); H.get_col(); which_color]'
0 0 1
1 0 -1
0 1 0
1 1 0
2 1 0
1 2 -1
2 2 1
3 2 1
2 3 -1
3 3 2
>> try, Sparsity.upper(3).star_coloring_new(); catch e, disp('not symmetric'); end
not symmetric

julia> H = ca.Sparsity.banded(4, 1);
julia> ca.star_coloring_new(H)
(4x3,4nz, [1, -1, 0, 0, 0, -1, 1, 1, -1, 2])
julia> try
           ca.star_coloring_new(ca.Sparsity.upper(3))
       catch e
           println("not symmetric")
       end
not symmetric

See also
star_coloring, star_coloring2, uni_coloring

Extra doc: https://github.com/casadi/casadi/wiki/L_2jz

◆ sub() [1/2]

Sparsity casadi::Sparsity::sub ( const std::vector< casadi_int > &  rr,
const Sparsity &  sp,
std::vector< casadi_int > &  mapping,
bool  ind1 = false 
) const

rr lists one flat (column-major) element index per nonzero of sp. The result has the shape of sp and keeps the nonzeros of sp whose element in this pattern is a structural nonzero. This is the sparsity counterpart of indexing a matrix with a Sparsity or with a list of element indices.

Parameters
rrFlat element indices, length sp.nnz(); negative indices count from the end, out of range raises an error
spPattern that lays out the result
ind1If true, indices are one-based
Returns
The pattern and a mapping: nonzero k of the result is nonzero mapping[k] of this pattern

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> sub, mapping = sp.sub([0, 2, 9], Sparsity.dense(3, 1))
>>> sub, mapping
(Sparsity(3x1), [0, 1, 3])
>>> sub, mapping = sp.sub([0, 1, 2, 3], Sparsity.dense(2, 2))
>>> DM(sub, 1), mapping
(DM(
[[1, 1],
 [00, 00]]), [0, 1])
>>> try: sp.sub([0, 2], Sparsity.dense(3, 1))
... except Exception as e: print("length mismatch")
length mismatch

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> [sub, mapping] = sp.sub([0, 2, 9], Sparsity.dense(3, 1)); disp(sub), disp(mapping)
3x1
0 1 3
>> [sub, mapping] = sp.sub([0, 1, 2, 3], Sparsity.dense(2, 2));
>> DM(sub, 1), mapping
[[1, 1],
 [00, 00]]
0 1
>> try, sp.sub([0, 2], Sparsity.dense(3, 1)); catch e, disp('length mismatch'); end
length mismatch

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> ca.sub(sp, [0, 2, 9], ca.Sparsity.dense(3, 1))
(3x1, [0, 1, 3])
julia> ca.sub(sp, [0, 1, 2, 3], ca.Sparsity.dense(2, 2))
(2x2,2nz, [0, 1])
julia> try
           ca.sub(sp, [0, 2], ca.Sparsity.dense(3, 1))
       catch e
           println("length mismatch")
       end
length mismatch

See also
get_nz, find

Extra doc: https://github.com/casadi/casadi/wiki/L_cj

◆ sub() [2/2]

Sparsity casadi::Sparsity::sub ( const std::vector< casadi_int > &  rr,
const std::vector< casadi_int > &  cc,
std::vector< casadi_int > &  mapping,
bool  ind1 = false 
) const

This is the sparsity counterpart of slicing a matrix as A[rr, cc]. Indices may repeat and may be negative (counting from the end); an index out of range raises an error.

Parameters
rrRow indices of the submatrix
ccColumn indices of the submatrix
ind1If true, indices are one-based
Returns
The len(rr)-by-len(cc) pattern and a mapping with one entry per nonzero of the result: nonzero k of the submatrix is nonzero mapping[k] of this pattern

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> sub, mapping = sp.sub([0, 2], [0, 3])
>>> DM(sub, 1), mapping
(DM(
[[1, 1],
 [1, 00]]), [0, 1, 3])
>>> sub, mapping = sp.sub([-1], [0])
>>> sub, mapping
(Sparsity(1x1), [1])
>>> sub, mapping = sp.sub([0, 0], [0])
>>> sub, mapping
(Sparsity(2x1), [0, 0])
>>> try: sp.sub([3], [0])
... except Exception as e: print("out of range")
out of range

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> [sub, mapping] = sp.sub([0, 2], [0, 3]); disp(DM(sub, 1)), disp(mapping)
[[1, 1],
 [1, 00]]
0 1 3
>> [sub, mapping] = sp.sub(-1, 0); disp(sub), disp(mapping)
1x1
1
>> [sub, mapping] = sp.sub([0, 0], 0); disp(sub), disp(mapping)
2x1
0 0
>> try, sp.sub(3, 0); catch e, disp('out of range'); end
out of range

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> ca.sub(sp, [0, 2], [0, 3])
(2x2,3nz, [0, 1, 3])
julia> ca.sub(sp, [-1], [0])
(1x1, [1])
julia> ca.sub(sp, [0, 0], [0])
(2x1, [0, 0])
julia> try
           ca.sub(sp, [3], [0])
       catch e
           println("out of range")
       end
out of range

See also
get_nz, erase, pmult

Extra doc: https://github.com/casadi/casadi/wiki/L_ci

◆ T()

Sparsity casadi::Sparsity::T ( ) const

In Python, T is a property (sp.T); the method transpose() also returns the nonzero reordering.

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> DM(sp.T, 1)
DM(
[[1, 00, 1],
 [00, 00, 00],
 [00, 1, 00],
 [1, 00, 00]])
>>> sp.T.colind(), sp.T.row()
([0, 2, 3, 4], [0, 3, 2, 0])
>>> Sparsity.dense(2, 3).T, Sparsity(0, 3).T
(Sparsity(3x2), Sparsity(3x0))

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> DM(sp.T, 1)
[[1, 00, 1],
 [00, 00, 00],
 [00, 1, 00],
 [1, 00, 00]]
>> sp.T.colind(), sp.T.row()
0 2 3 4
0 3 2 0
>> Sparsity.dense(2, 3).T, Sparsity(0, 3).T
3x2
3x0

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> ca.DM(ca.T(sp), 1)
DM(
[[1, 00, 1],
 [00, 00, 00],
 [00, 1, 00],
 [1, 00, 00]])
julia> ca.colind(ca.T(sp)), ca.row(ca.T(sp))
([0, 2, 3, 4], [0, 3, 2, 0])
julia> ca.T(ca.Sparsity.dense(2, 3)), ca.T(ca.Sparsity(0, 3))
(3x2, 3x0)

See also
transpose, is_transpose, get_crs

Extra doc: https://github.com/casadi/casadi/wiki/L_2o1

◆ test_cast()

static bool casadi::Sparsity::test_cast ( const SharedObjectInternal *  ptr)
static

◆ to_file()

void casadi::Sparsity::to_file ( const std::string &  filename,
const std::string &  format_hint = "" 
) const

The only supported format is Matrix Market ("mtx", coordinate pattern general), with one-based (row, col) pairs. The format is taken from the file extension unless format_hint is given; an unknown format raises an error. The file is overwritten.

Parameters
filenamePath of the file to write
format_hintFormat name, e.g. "mtx", when the extension does not tell

>>> import os, tempfile
>>> d = tempfile.mkdtemp()
>>> f = os.path.join(d, "pattern.mtx")
>>> sp = Sparsity.triplet(3, 2, [0, 2, 1], [0, 0, 1])
>>> sp.to_file(f)
>>> print(open(f).read())
%%MatrixMarket matrix coordinate pattern general
3 2 3
1 1
3 1
2 2
>>> print(Sparsity.from_file(f) == sp)
True
>>> os.remove(f); os.rmdir(d)
>>> try: sp.to_file("pattern.txt")
... except Exception as e: print("unknown extension")
unknown extension

>> f = [tempname '.mtx'];
>> sp = Sparsity.triplet(3, 2, [0, 2, 1], [0, 0, 1]);
>> sp.to_file(f);
>> fileread(f)
%%MatrixMarket matrix coordinate pattern general
3 2 3
1 1
3 1
2 2
>> Sparsity.from_file(f) == sp
1
>> delete(f);
>> try, sp.to_file('pattern.txt'); catch e, disp('unknown extension'); end
unknown extension

julia> d = mktempdir();
julia> f = joinpath(d, "pattern.mtx");
julia> sp = ca.Sparsity.triplet(3, 2, [0, 2, 1], [0, 0, 1]);
julia> ca.to_file(sp, f)
julia> print(read(f, String))
%%MatrixMarket matrix coordinate pattern general
3 2 3
1 1
3 1
2 2
julia> ca.is_equal(ca.Sparsity.from_file(f), sp)
true
julia> rm(d, recursive=true)
julia> try
           ca.to_file(sp, "pattern.txt")
       catch e
           println("unknown extension")
       end
unknown extension

See also
from_file, DM::to_file

Extra doc: https://github.com/casadi/casadi/wiki/L_2ns

◆ transpose()

Sparsity casadi::Sparsity::transpose ( std::vector< casadi_int > &  mapping,
bool  invert_mapping = false 
) const
Parameters
invert_mappingDirection of the mapping
Returns
The transposed pattern and a mapping of length nnz(). By default mapping[k] is the nonzero of the original pattern that becomes nonzero k of the transpose; with invert_mapping true, mapping[k] is the nonzero of the transpose that original nonzero k becomes.

>>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3])
>>> spT, mapping = sp.transpose()
>>> spT, mapping
(Sparsity(4x3,4nz), [0, 3, 2, 1])

>> sp = Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
>> [spT, mapping] = sp.transpose(); disp(spT), disp(mapping)
4x3,4nz
0 3 2 1

julia> sp = ca.Sparsity.triplet(3, 4, [0, 2, 1, 0], [0, 0, 2, 3]);
julia> ca.transpose(sp, false)
(4x3,4nz, [0, 3, 2, 1])

See also
T

Extra doc: https://github.com/casadi/casadi/wiki/L_ck

◆ triplet() [1/2]

static Sparsity casadi::Sparsity::triplet ( casadi_int  nrow,
casadi_int  ncol,
const std::vector< casadi_int > &  row,
const std::vector< casadi_int > &  col 
)
static

The entries may be given in any order; duplicates are merged. An index out of range or vectors of different length raise an error.

Parameters
nrowNumber of rows
ncolNumber of columns
rowRow index of each entry, in [0, nrow)
colColumn index of each entry, in [0, ncol), same length as row
invert_mappingSelects the direction of the returned mapping (see below)

The overload with invert_mapping additionally returns a mapping between the given entries and the nonzeros of the result (which are in column-major order). With invert_mapping false, mapping[k] is the position in the input of nonzero k (length nnz(); for duplicates the first occurrence). With invert_mapping true, mapping[i] is the nonzero index of input entry i (length of the input).

>>> DM(Sparsity.triplet(3, 3, [0, 2, 1], [0, 0, 2]), 1)
DM(
[[1, 00, 00],
 [00, 00, 1],
 [1, 00, 00]])
>>> Sparsity.triplet(2, 2, [0, 0, 1], [0, 0, 1]).nnz()
2
>>> sp, mapping = Sparsity.triplet(3, 3, [2, 0, 1], [1, 0, 0], False)
>>> mapping
[1, 2, 0]
>>> sp, mapping = Sparsity.triplet(3, 3, [2, 0, 1], [1, 0, 0], True)
>>> mapping
[2, 0, 1]
>>> try: Sparsity.triplet(2, 2, [0, 2], [0, 0])
... except Exception as e: print("out of bounds")
out of bounds

>> DM(Sparsity.triplet(3, 3, [0, 2, 1], [0, 0, 2]), 1)
[[1, 00, 00],
 [00, 00, 1],
 [1, 00, 00]]
>> Sparsity.triplet(2, 2, [0, 0, 1], [0, 0, 1]).nnz()
2
>> [sp, mapping] = Sparsity.triplet(3, 3, [2, 0, 1], [1, 0, 0], false); disp(mapping)
1 2 0
>> [sp, mapping] = Sparsity.triplet(3, 3, [2, 0, 1], [1, 0, 0], true); disp(mapping)
2 0 1
>> try, Sparsity.triplet(2, 2, [0, 2], [0, 0]); catch e, disp('out of bounds'); end
out of bounds

julia> ca.DM(ca.Sparsity.triplet(3, 3, [0, 2, 1], [0, 0, 2]), 1)
DM(
[[1, 00, 00],
 [00, 00, 1],
 [1, 00, 00]])
julia> ca.nnz(ca.Sparsity.triplet(2, 2, [0, 0, 1], [0, 0, 1]))
2
julia> sp, mapping = ca.Sparsity.triplet(3, 3, [2, 0, 1], [1, 0, 0], false);
julia> mapping
3-element Vector{Int64}:
 1
 2
 0
julia> sp, mapping = ca.Sparsity.triplet(3, 3, [2, 0, 1], [1, 0, 0], true);
julia> mapping
3-element Vector{Int64}:
 2
 0
 1
julia> try
           ca.Sparsity.triplet(2, 2, [0, 2], [0, 0])
       catch e
           println("out of bounds")
       end
out of bounds

See also
get_triplet, rowcol, nonzeros, Sparsity(nrow, ncol, colind, row)

Extra doc: https://github.com/casadi/casadi/wiki/L_bm

◆ triplet() [2/2]

static Sparsity casadi::Sparsity::triplet ( casadi_int  nrow,
casadi_int  ncol,
const std::vector< casadi_int > &  row,
const std::vector< casadi_int > &  col,
std::vector< casadi_int > &  mapping,
bool  invert_mapping 
)
static

The entries may be given in any order; duplicates are merged. An index out of range or vectors of different length raise an error.

Parameters
nrowNumber of rows
ncolNumber of columns
rowRow index of each entry, in [0, nrow)
colColumn index of each entry, in [0, ncol), same length as row
invert_mappingSelects the direction of the returned mapping (see below)

The overload with invert_mapping additionally returns a mapping between the given entries and the nonzeros of the result (which are in column-major order). With invert_mapping false, mapping[k] is the position in the input of nonzero k (length nnz(); for duplicates the first occurrence). With invert_mapping true, mapping[i] is the nonzero index of input entry i (length of the input).

>>> DM(Sparsity.triplet(3, 3, [0, 2, 1], [0, 0, 2]), 1)
DM(
[[1, 00, 00],
 [00, 00, 1],
 [1, 00, 00]])
>>> Sparsity.triplet(2, 2, [0, 0, 1], [0, 0, 1]).nnz()
2
>>> sp, mapping = Sparsity.triplet(3, 3, [2, 0, 1], [1, 0, 0], False)
>>> mapping
[1, 2, 0]
>>> sp, mapping = Sparsity.triplet(3, 3, [2, 0, 1], [1, 0, 0], True)
>>> mapping
[2, 0, 1]
>>> try: Sparsity.triplet(2, 2, [0, 2], [0, 0])
... except Exception as e: print("out of bounds")
out of bounds

>> DM(Sparsity.triplet(3, 3, [0, 2, 1], [0, 0, 2]), 1)
[[1, 00, 00],
 [00, 00, 1],
 [1, 00, 00]]
>> Sparsity.triplet(2, 2, [0, 0, 1], [0, 0, 1]).nnz()
2
>> [sp, mapping] = Sparsity.triplet(3, 3, [2, 0, 1], [1, 0, 0], false); disp(mapping)
1 2 0
>> [sp, mapping] = Sparsity.triplet(3, 3, [2, 0, 1], [1, 0, 0], true); disp(mapping)
2 0 1
>> try, Sparsity.triplet(2, 2, [0, 2], [0, 0]); catch e, disp('out of bounds'); end
out of bounds

julia> ca.DM(ca.Sparsity.triplet(3, 3, [0, 2, 1], [0, 0, 2]), 1)
DM(
[[1, 00, 00],
 [00, 00, 1],
 [1, 00, 00]])
julia> ca.nnz(ca.Sparsity.triplet(2, 2, [0, 0, 1], [0, 0, 1]))
2
julia> sp, mapping = ca.Sparsity.triplet(3, 3, [2, 0, 1], [1, 0, 0], false);
julia> mapping
3-element Vector{Int64}:
 1
 2
 0
julia> sp, mapping = ca.Sparsity.triplet(3, 3, [2, 0, 1], [1, 0, 0], true);
julia> mapping
3-element Vector{Int64}:
 2
 0
 1
julia> try
           ca.Sparsity.triplet(2, 2, [0, 2], [0, 0])
       catch e
           println("out of bounds")
       end
out of bounds

See also
get_triplet, rowcol, nonzeros, Sparsity(nrow, ncol, colind, row)

Extra doc: https://github.com/casadi/casadi/wiki/L_bm

◆ type_name()

static std::string casadi::Sparsity::type_name ( )
inlinestatic

Definition at line 5925 of file sparsity.hpp.

◆ uni_coloring()

Sparsity casadi::Sparsity::uni_coloring ( const Sparsity &  AT = Sparsity(),
casadi_int  cutoff = std::numeric_limits< casadi_int >::max() 
) const

Greedy distance-2 coloring (Algorithm 3.1 in Gebremedhin, Manne and Pothen, What Color Is Your Jacobian?, SIAM Rev. 47(4), 2006): columns that have no row in common may share a color, so that one directional derivative per color recovers all nonzeros. This is the coloring used for forward-mode Jacobians (and, applied to the transpose, for reverse mode).

Parameters
ATThe transpose of this pattern, if already available; a null Sparsity (default) computes it
cutoffIf more than this many colors are needed, a null Sparsity is returned instead
Returns
A size2()-by-ncolors pattern: column c lists the columns of this pattern that received color c

>>> A = Sparsity.triplet(3, 4, [0, 1, 2, 0], [0, 1, 2, 3])
>>> DM(A, 1)
DM(
[[1, 00, 00, 1],
 [00, 1, 00, 00],
 [00, 00, 1, 00]])
>>> c = A.uni_coloring()
>>> DM(c, 1)
DM(
[[1, 00],
 [1, 00],
 [1, 00],
 [00, 1]])
>>> c.size2(), [c.row()[c.colind()[j]:c.colind()[j + 1]] for j in range(c.size2())]
(2, [[0, 1, 2], [3]])
>>> A.uni_coloring(Sparsity(), 1).is_null()
True
>>> Sparsity.dense(3, 3).uni_coloring(), Sparsity.diag(3).uni_coloring()
(Sparsity(3x3,3nz), Sparsity(3x1))

>> A = Sparsity.triplet(3, 4, [0, 1, 2, 0], [0, 1, 2, 3]);
>> DM(A, 1)
[[1, 00, 00, 1],
 [00, 1, 00, 00],
 [00, 00, 1, 00]]
>> c = A.uni_coloring();
>> DM(c, 1)
[[1, 00],
 [1, 00],
 [1, 00],
 [00, 1]]
>> disp(c.size2()), ci = c.colind(); r = c.row();
2
>> for j = 1:c.size2(), disp(r(ci(j) + 1:ci(j + 1))), end
0 1 2
3
>> A.uni_coloring(Sparsity(), 1).is_null()
1
>> Sparsity.dense(3, 3).uni_coloring(), Sparsity.diag(3).uni_coloring()
3x3,3nz
3x1

julia> A = ca.Sparsity.triplet(3, 4, [0, 1, 2, 0], [0, 1, 2, 3]);
julia> ca.DM(A, 1)
DM(
[[1, 00, 00, 1],
 [00, 1, 00, 00],
 [00, 00, 1, 00]])
julia> c = ca.uni_coloring(A, ca.Sparsity(), 1000);
julia> ca.DM(c, 1)
DM(
[[1, 00],
 [1, 00],
 [1, 00],
 [00, 1]])
julia> ca.size2(c), [ca.row(c)[ca.colind(c)[j]+1:ca.colind(c)[j+1]] for j in 1:ca.size2(c)]
(2, [[0, 1, 2], [3]])
julia> ca.is_null(ca.uni_coloring(A, ca.Sparsity(), 1))
true
julia> ca.uni_coloring(ca.Sparsity.dense(3, 3), ca.Sparsity(), 1000)
Sparsity(3x3,3nz)
julia> ca.uni_coloring(ca.Sparsity.diag(3), ca.Sparsity(), 1000)
Sparsity(3x1)

See also
star_coloring, star_coloring_new

Extra doc: https://github.com/casadi/casadi/wiki/L_db

Examples
matrix/coloring.py.

◆ unit()

static Sparsity casadi::Sparsity::unit ( casadi_int  n,
casadi_int  el 
)
static
Parameters
nLength of the column vector
elRow of the nonzero, in [0, n); an index outside this range raises an error

>>> DM(Sparsity.unit(4, 1), 1)
DM([00, 1, 00, 00])
>>> Sparsity.unit(4, 1).row()
[1]

>> DM(Sparsity.unit(4, 1), 1)
[00, 1, 00, 00]
>> Sparsity.unit(4, 1).row()
1

julia> ca.DM(ca.Sparsity.unit(4, 1), 1)
DM([00, 1, 00, 00])
julia> ca.row(ca.Sparsity.unit(4, 1))
1-element Vector{Int64}:
 1

See also
nonzeros, triplet

Extra doc: https://github.com/casadi/casadi/wiki/L_bf

◆ unite()

Sparsity casadi::Sparsity::unite ( const Sparsity &  y) const

The pattern of x + y for matrices with these patterns. A shape mismatch raises an error.

>>> a = Sparsity.diag(2)
>>> b = Sparsity.triplet(2, 2, [0, 1], [1, 1])
>>> DM(a.unite(b), 1)
DM(
[[1, 1],
 [00, 1]])
>>> a + b == a.unite(b), a * b == a.intersect(b)
(True, True)
>>> try: a + Sparsity.dense(3, 3)
... except Exception as e: print("dimension mismatch")
dimension mismatch

>> a = Sparsity.diag(2);
>> b = Sparsity.triplet(2, 2, [0, 1], [1, 1]);
>> DM(a.unite(b), 1)
[[1, 1],
 [00, 1]]
>> a + b == a.unite(b), a .* b == a.intersect(b)
1
1
>> try, a + Sparsity.dense(3, 3); catch e, disp('dimension mismatch'); end
dimension mismatch

julia> a = ca.Sparsity.diag(2);
julia> b = ca.Sparsity.triplet(2, 2, [0, 1], [1, 1]);
julia> ca.DM(ca.unite(a, b), 1)
DM(
[[1, 1],
 [00, 1]])
julia> try
           ca.unite(a, ca.Sparsity.dense(3, 3))
       catch e
           println("dimension mismatch")
       end
dimension mismatch

See also
intersect, combine, is_subset

Extra doc: https://github.com/casadi/casadi/wiki/L_cm

◆ upper()

static Sparsity casadi::Sparsity::upper ( casadi_int  n)
static

Column j contains the rows 0, ..., j, so the diagonal is included and the pattern has n*(n+1)/2 nonzeros.

Parameters
nSize of the square pattern, nonnegative

>>> DM(Sparsity.upper(3), 1)
DM(
[[1, 1, 1],
 [00, 1, 1],
 [00, 00, 1]])
>>> Sparsity.upper(3).nnz(), Sparsity.upper(3).is_triu()
(6, True)

>> DM(Sparsity.upper(3), 1)
[[1, 1, 1],
 [00, 1, 1],
 [00, 00, 1]]
>> Sparsity.upper(3).nnz(), Sparsity.upper(3).is_triu()
6
1

julia> ca.DM(ca.Sparsity.upper(3), 1)
DM(
[[1, 1, 1],
 [00, 1, 1],
 [00, 00, 1]])
julia> ca.nnz(ca.Sparsity.upper(3)), ca.is_triu(ca.Sparsity.upper(3))
(6, true)

See also
lower, triu, is_triu

Extra doc: https://github.com/casadi/casadi/wiki/L_bg


The documentation for this class was generated from the following file: