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