xref: /aosp_15_r20/external/eigen/doc/SparseQuickReference.dox (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Linamespace Eigen {
2*bf2c3715SXin Li/** \eigenManualPage SparseQuickRefPage Quick reference guide for sparse matrices
3*bf2c3715SXin Li\eigenAutoToc
4*bf2c3715SXin Li
5*bf2c3715SXin Li<hr>
6*bf2c3715SXin Li
7*bf2c3715SXin LiIn this page, we give a quick summary of the main operations available for sparse matrices in the class SparseMatrix. First, it is recommended to read  the introductory tutorial at \ref TutorialSparse. The important point to have in mind when working on sparse matrices is how they are stored :
8*bf2c3715SXin Lii.e either row major or column major. The default is column major. Most arithmetic operations on sparse matrices will assert that they have the same storage order.
9*bf2c3715SXin Li
10*bf2c3715SXin Li\section SparseMatrixInit Sparse Matrix Initialization
11*bf2c3715SXin Li<table class="manual">
12*bf2c3715SXin Li<tr><th> Category </th> <th> Operations</th> <th>Notes</th></tr>
13*bf2c3715SXin Li<tr><td>Constructor</td>
14*bf2c3715SXin Li<td>
15*bf2c3715SXin Li\code
16*bf2c3715SXin Li  SparseMatrix<double> sm1(1000,1000);
17*bf2c3715SXin Li  SparseMatrix<std::complex<double>,RowMajor> sm2;
18*bf2c3715SXin Li\endcode
19*bf2c3715SXin Li</td> <td> Default is ColMajor</td> </tr>
20*bf2c3715SXin Li<tr class="alt">
21*bf2c3715SXin Li<td> Resize/Reserve</td>
22*bf2c3715SXin Li<td>
23*bf2c3715SXin Li \code
24*bf2c3715SXin Li    sm1.resize(m,n);      // Change sm1 to a m x n matrix.
25*bf2c3715SXin Li    sm1.reserve(nnz);     // Allocate room for nnz nonzeros elements.
26*bf2c3715SXin Li  \endcode
27*bf2c3715SXin Li</td>
28*bf2c3715SXin Li<td> Note that when calling reserve(), it is not required that nnz is the exact number of nonzero elements in the final matrix. However, an exact estimation will avoid multiple reallocations during the insertion phase. </td>
29*bf2c3715SXin Li</tr>
30*bf2c3715SXin Li<tr>
31*bf2c3715SXin Li<td> Assignment </td>
32*bf2c3715SXin Li<td>
33*bf2c3715SXin Li\code
34*bf2c3715SXin Li  SparseMatrix<double,Colmajor> sm1;
35*bf2c3715SXin Li // Initialize sm2 with sm1.
36*bf2c3715SXin Li  SparseMatrix<double,Rowmajor> sm2(sm1), sm3;
37*bf2c3715SXin Li  // Assignment and evaluations modify the storage order.
38*bf2c3715SXin Li  sm3 = sm1;
39*bf2c3715SXin Li \endcode
40*bf2c3715SXin Li</td>
41*bf2c3715SXin Li<td> The copy constructor can be used to convert from a storage order to another</td>
42*bf2c3715SXin Li</tr>
43*bf2c3715SXin Li<tr class="alt">
44*bf2c3715SXin Li<td> Element-wise Insertion</td>
45*bf2c3715SXin Li<td>
46*bf2c3715SXin Li\code
47*bf2c3715SXin Li// Insert a new element;
48*bf2c3715SXin Li sm1.insert(i, j) = v_ij;
49*bf2c3715SXin Li
50*bf2c3715SXin Li// Update the value v_ij
51*bf2c3715SXin Li sm1.coeffRef(i,j) = v_ij;
52*bf2c3715SXin Li sm1.coeffRef(i,j) += v_ij;
53*bf2c3715SXin Li sm1.coeffRef(i,j) -= v_ij;
54*bf2c3715SXin Li\endcode
55*bf2c3715SXin Li</td>
56*bf2c3715SXin Li<td> insert() assumes that the element does not already exist; otherwise, use coeffRef()</td>
57*bf2c3715SXin Li</tr>
58*bf2c3715SXin Li<tr>
59*bf2c3715SXin Li<td> Batch insertion</td>
60*bf2c3715SXin Li<td>
61*bf2c3715SXin Li\code
62*bf2c3715SXin Li  std::vector< Eigen::Triplet<double> > tripletList;
63*bf2c3715SXin Li  tripletList.reserve(estimation_of_entries);
64*bf2c3715SXin Li  // -- Fill tripletList with nonzero elements...
65*bf2c3715SXin Li  sm1.setFromTriplets(TripletList.begin(), TripletList.end());
66*bf2c3715SXin Li\endcode
67*bf2c3715SXin Li</td>
68*bf2c3715SXin Li<td>A complete example is available at \link TutorialSparseFilling Triplet Insertion \endlink.</td>
69*bf2c3715SXin Li</tr>
70*bf2c3715SXin Li<tr class="alt">
71*bf2c3715SXin Li<td> Constant or Random Insertion</td>
72*bf2c3715SXin Li<td>
73*bf2c3715SXin Li\code
74*bf2c3715SXin Lism1.setZero();
75*bf2c3715SXin Li\endcode
76*bf2c3715SXin Li</td>
77*bf2c3715SXin Li<td>Remove all non-zero coefficients</td>
78*bf2c3715SXin Li</tr>
79*bf2c3715SXin Li</table>
80*bf2c3715SXin Li
81*bf2c3715SXin Li
82*bf2c3715SXin Li\section SparseBasicInfos Matrix properties
83*bf2c3715SXin LiBeyond the basic functions rows() and cols(), there are some useful functions that are available to easily get some information from the matrix.
84*bf2c3715SXin Li<table class="manual">
85*bf2c3715SXin Li<tr>
86*bf2c3715SXin Li  <td> \code
87*bf2c3715SXin Li  sm1.rows();         // Number of rows
88*bf2c3715SXin Li  sm1.cols();         // Number of columns
89*bf2c3715SXin Li  sm1.nonZeros();     // Number of non zero values
90*bf2c3715SXin Li  sm1.outerSize();    // Number of columns (resp. rows) for a column major (resp. row major )
91*bf2c3715SXin Li  sm1.innerSize();    // Number of rows (resp. columns) for a row major (resp. column major)
92*bf2c3715SXin Li  sm1.norm();         // Euclidian norm of the matrix
93*bf2c3715SXin Li  sm1.squaredNorm();  // Squared norm of the matrix
94*bf2c3715SXin Li  sm1.blueNorm();
95*bf2c3715SXin Li  sm1.isVector();     // Check if sm1 is a sparse vector or a sparse matrix
96*bf2c3715SXin Li  sm1.isCompressed(); // Check if sm1 is in compressed form
97*bf2c3715SXin Li  ...
98*bf2c3715SXin Li  \endcode </td>
99*bf2c3715SXin Li</tr>
100*bf2c3715SXin Li</table>
101*bf2c3715SXin Li
102*bf2c3715SXin Li\section SparseBasicOps Arithmetic operations
103*bf2c3715SXin LiIt is easy to perform arithmetic operations on sparse matrices provided that the dimensions are adequate and that the matrices have the same storage order. Note that the evaluation can always be done in a matrix with a different storage order. In the following, \b sm denotes a sparse matrix, \b dm a dense matrix and \b dv a dense vector.
104*bf2c3715SXin Li<table class="manual">
105*bf2c3715SXin Li<tr><th> Operations </th> <th> Code </th> <th> Notes </th></tr>
106*bf2c3715SXin Li
107*bf2c3715SXin Li<tr>
108*bf2c3715SXin Li  <td> add subtract </td>
109*bf2c3715SXin Li  <td> \code
110*bf2c3715SXin Li  sm3 = sm1 + sm2;
111*bf2c3715SXin Li  sm3 = sm1 - sm2;
112*bf2c3715SXin Li  sm2 += sm1;
113*bf2c3715SXin Li  sm2 -= sm1; \endcode
114*bf2c3715SXin Li  </td>
115*bf2c3715SXin Li  <td>
116*bf2c3715SXin Li  sm1 and sm2 should have the same storage order
117*bf2c3715SXin Li  </td>
118*bf2c3715SXin Li</tr>
119*bf2c3715SXin Li
120*bf2c3715SXin Li<tr class="alt"><td>
121*bf2c3715SXin Li  scalar product</td><td>\code
122*bf2c3715SXin Li  sm3 = sm1 * s1;   sm3 *= s1;
123*bf2c3715SXin Li  sm3 = s1 * sm1 + s2 * sm2; sm3 /= s1;\endcode
124*bf2c3715SXin Li  </td>
125*bf2c3715SXin Li  <td>
126*bf2c3715SXin Li    Many combinations are possible if the dimensions and the storage order agree.
127*bf2c3715SXin Li</tr>
128*bf2c3715SXin Li
129*bf2c3715SXin Li<tr>
130*bf2c3715SXin Li  <td> %Sparse %Product </td>
131*bf2c3715SXin Li  <td> \code
132*bf2c3715SXin Li  sm3 = sm1 * sm2;
133*bf2c3715SXin Li  dm2 = sm1 * dm1;
134*bf2c3715SXin Li  dv2 = sm1 * dv1;
135*bf2c3715SXin Li  \endcode </td>
136*bf2c3715SXin Li  <td>
137*bf2c3715SXin Li  </td>
138*bf2c3715SXin Li</tr>
139*bf2c3715SXin Li
140*bf2c3715SXin Li<tr class='alt'>
141*bf2c3715SXin Li  <td> transposition, adjoint</td>
142*bf2c3715SXin Li  <td> \code
143*bf2c3715SXin Li  sm2 = sm1.transpose();
144*bf2c3715SXin Li  sm2 = sm1.adjoint();
145*bf2c3715SXin Li  \endcode </td>
146*bf2c3715SXin Li  <td>
147*bf2c3715SXin Li  Note that the transposition change the storage order. There is no support for transposeInPlace().
148*bf2c3715SXin Li  </td>
149*bf2c3715SXin Li</tr>
150*bf2c3715SXin Li<tr>
151*bf2c3715SXin Li<td> Permutation </td>
152*bf2c3715SXin Li<td>
153*bf2c3715SXin Li\code
154*bf2c3715SXin Liperm.indices();      // Reference to the vector of indices
155*bf2c3715SXin Lism1.twistedBy(perm); // Permute rows and columns
156*bf2c3715SXin Lism2 = sm1 * perm;    // Permute the columns
157*bf2c3715SXin Lism2 = perm * sm1;    // Permute the columns
158*bf2c3715SXin Li\endcode
159*bf2c3715SXin Li</td>
160*bf2c3715SXin Li<td>
161*bf2c3715SXin Li
162*bf2c3715SXin Li</td>
163*bf2c3715SXin Li</tr>
164*bf2c3715SXin Li<tr>
165*bf2c3715SXin Li  <td>
166*bf2c3715SXin Li  Component-wise ops
167*bf2c3715SXin Li  </td>
168*bf2c3715SXin Li  <td>\code
169*bf2c3715SXin Li  sm1.cwiseProduct(sm2);
170*bf2c3715SXin Li  sm1.cwiseQuotient(sm2);
171*bf2c3715SXin Li  sm1.cwiseMin(sm2);
172*bf2c3715SXin Li  sm1.cwiseMax(sm2);
173*bf2c3715SXin Li  sm1.cwiseAbs();
174*bf2c3715SXin Li  sm1.cwiseSqrt();
175*bf2c3715SXin Li  \endcode</td>
176*bf2c3715SXin Li  <td>
177*bf2c3715SXin Li  sm1 and sm2 should have the same storage order
178*bf2c3715SXin Li  </td>
179*bf2c3715SXin Li</tr>
180*bf2c3715SXin Li</table>
181*bf2c3715SXin Li
182*bf2c3715SXin Li\section sparseotherops Other supported operations
183*bf2c3715SXin Li<table class="manual">
184*bf2c3715SXin Li<tr><th style="min-width:initial"> Code </th> <th> Notes</th> </tr>
185*bf2c3715SXin Li<tr><td colspan="2">Sub-matrices</td></tr>
186*bf2c3715SXin Li<tr>
187*bf2c3715SXin Li<td>
188*bf2c3715SXin Li\code
189*bf2c3715SXin Li  sm1.block(startRow, startCol, rows, cols);
190*bf2c3715SXin Li  sm1.block(startRow, startCol);
191*bf2c3715SXin Li  sm1.topLeftCorner(rows, cols);
192*bf2c3715SXin Li  sm1.topRightCorner(rows, cols);
193*bf2c3715SXin Li  sm1.bottomLeftCorner( rows, cols);
194*bf2c3715SXin Li  sm1.bottomRightCorner( rows, cols);
195*bf2c3715SXin Li  \endcode
196*bf2c3715SXin Li</td><td>
197*bf2c3715SXin LiContrary to dense matrices, here <strong>all these methods are read-only</strong>.\n
198*bf2c3715SXin LiSee \ref TutorialSparse_SubMatrices and below for read-write sub-matrices.
199*bf2c3715SXin Li</td>
200*bf2c3715SXin Li</tr>
201*bf2c3715SXin Li<tr class="alt"><td colspan="2"> Range </td></tr>
202*bf2c3715SXin Li<tr class="alt">
203*bf2c3715SXin Li<td>
204*bf2c3715SXin Li\code
205*bf2c3715SXin Li  sm1.innerVector(outer);           // RW
206*bf2c3715SXin Li  sm1.innerVectors(start, size);    // RW
207*bf2c3715SXin Li  sm1.leftCols(size);               // RW
208*bf2c3715SXin Li  sm2.rightCols(size);              // RO because sm2 is row-major
209*bf2c3715SXin Li  sm1.middleRows(start, numRows);   // RO because sm1 is column-major
210*bf2c3715SXin Li  sm1.middleCols(start, numCols);   // RW
211*bf2c3715SXin Li  sm1.col(j);                       // RW
212*bf2c3715SXin Li\endcode
213*bf2c3715SXin Li</td>
214*bf2c3715SXin Li<td>
215*bf2c3715SXin LiA inner vector is either a row (for row-major) or a column (for column-major).\n
216*bf2c3715SXin LiAs stated earlier, for a read-write sub-matrix (RW), the evaluation can be done in a matrix with different storage order.
217*bf2c3715SXin Li</td>
218*bf2c3715SXin Li</tr>
219*bf2c3715SXin Li<tr><td colspan="2"> Triangular and selfadjoint views</td></tr>
220*bf2c3715SXin Li<tr>
221*bf2c3715SXin Li<td>
222*bf2c3715SXin Li\code
223*bf2c3715SXin Li  sm2 = sm1.triangularview<Lower>();
224*bf2c3715SXin Li  sm2 = sm1.selfadjointview<Lower>();
225*bf2c3715SXin Li\endcode
226*bf2c3715SXin Li</td>
227*bf2c3715SXin Li<td> Several combination between triangular views and blocks views are possible
228*bf2c3715SXin Li\code
229*bf2c3715SXin Li  \endcode </td>
230*bf2c3715SXin Li</tr>
231*bf2c3715SXin Li<tr class="alt"><td colspan="2">Triangular solve </td></tr>
232*bf2c3715SXin Li<tr class="alt">
233*bf2c3715SXin Li<td>
234*bf2c3715SXin Li\code
235*bf2c3715SXin Li dv2 = sm1.triangularView<Upper>().solve(dv1);
236*bf2c3715SXin Li dv2 = sm1.topLeftCorner(size, size)
237*bf2c3715SXin Li          .triangularView<Lower>().solve(dv1);
238*bf2c3715SXin Li\endcode
239*bf2c3715SXin Li</td>
240*bf2c3715SXin Li<td> For general sparse solve, Use any suitable module described at \ref TopicSparseSystems </td>
241*bf2c3715SXin Li</tr>
242*bf2c3715SXin Li<tr><td colspan="2"> Low-level API</td></tr>
243*bf2c3715SXin Li<tr>
244*bf2c3715SXin Li<td>
245*bf2c3715SXin Li\code
246*bf2c3715SXin Lism1.valuePtr();      // Pointer to the values
247*bf2c3715SXin Lism1.innerIndexPtr();  // Pointer to the indices.
248*bf2c3715SXin Lism1.outerIndexPtr(); // Pointer to the beginning of each inner vector
249*bf2c3715SXin Li\endcode
250*bf2c3715SXin Li</td>
251*bf2c3715SXin Li<td>
252*bf2c3715SXin LiIf the matrix is not in compressed form, makeCompressed() should be called before.\n
253*bf2c3715SXin LiNote that these functions are mostly provided for interoperability purposes with external libraries.\n
254*bf2c3715SXin LiA better access to the values of the matrix is done by using the InnerIterator class as described in \link TutorialSparse the Tutorial Sparse \endlink section</td>
255*bf2c3715SXin Li</tr>
256*bf2c3715SXin Li<tr class="alt"><td colspan="2">Mapping external buffers</td></tr>
257*bf2c3715SXin Li<tr class="alt">
258*bf2c3715SXin Li<td>
259*bf2c3715SXin Li\code
260*bf2c3715SXin Liint outerIndexPtr[cols+1];
261*bf2c3715SXin Liint innerIndices[nnz];
262*bf2c3715SXin Lidouble values[nnz];
263*bf2c3715SXin LiMap<SparseMatrix<double> > sm1(rows,cols,nnz,outerIndexPtr, // read-write
264*bf2c3715SXin Li                               innerIndices,values);
265*bf2c3715SXin LiMap<const SparseMatrix<double> > sm2(...);                  // read-only
266*bf2c3715SXin Li\endcode
267*bf2c3715SXin Li</td>
268*bf2c3715SXin Li<td>As for dense matrices, class Map<SparseMatrixType> can be used to see external buffers as an %Eigen's SparseMatrix object. </td>
269*bf2c3715SXin Li</tr>
270*bf2c3715SXin Li</table>
271*bf2c3715SXin Li*/
272*bf2c3715SXin Li}
273