diff --git a/testbed/nanogui/ext/eigen/doc/A05_PortingFrom2To3.dox b/testbed/nanogui/ext/eigen/doc/A05_PortingFrom2To3.dox deleted file mode 100644 index 4d5f3ae1..00000000 --- a/testbed/nanogui/ext/eigen/doc/A05_PortingFrom2To3.dox +++ /dev/null @@ -1,304 +0,0 @@ -namespace Eigen { - -/** \page Eigen2ToEigen3 Porting from Eigen2 to Eigen3 - -
| Eigen 2 | Eigen 3 | -
|---|---|
| \code
-vector.start(length)
-vector.start | \code
-vector.head(length)
-vector.head |
| Eigen 2 | Eigen 3 | -
|---|---|
| \code
-matrix.corner(TopLeft,r,c)
-matrix.corner(TopRight,r,c)
-matrix.corner(BottomLeft,r,c)
-matrix.corner(BottomRight,r,c)
-matrix.corner | \code
-matrix.topLeftCorner(r,c)
-matrix.topRightCorner(r,c)
-matrix.bottomLeftCorner(r,c)
-matrix.bottomRightCorner(r,c)
-matrix.topLeftCorner |
-
| Eigen 2 | Eigen 3 |
|---|---|
| \code
-A.part |
-\code
-A.triangularView |
| \code
-A.extract |
-\code
-A.triangularView |
| \code
-A.marked |
-\code
-A.triangularView |
| \code
-A.part |
-\code
-A.selfadjointView |
| \code -UpperTriangular -LowerTriangular -UnitUpperTriangular -UnitLowerTriangular -StrictlyUpperTriangular -StrictlyLowerTriangular -\endcode | \code -Upper -Lower -UnitUpper -UnitLower -StrictlyUpper -StrictlyLower -\endcode | -
| Eigen 2 | Eigen 3 |
|---|---|
| \code A.triangularSolveInPlace | \code A.triangularView |
| Eigen 2 | -Eigen 3 | -Notes | -
|---|---|---|
| LU | -FullPivLU | -See also the new PartialPivLU, it's much faster | -
| QR | -HouseholderQR | -See also the new ColPivHouseholderQR, it's more reliable | -
| SVD | -JacobiSVD | -We currently don't have a bidiagonalizing SVD; of course this is planned. | -
| EigenSolver and friends | -\code #include |
- Moved to separate module | -
| Eigen 2 | Eigen 3 | Notes |
|---|---|---|
| \code A.lu();\endcode | -\code A.fullPivLu();\endcode | -Now A.lu() returns a PartialPivLU |
| \code A.lu().solve(B,&X);\endcode | -\code X = A.lu().solve(B); - X = A.fullPivLu().solve(B);\endcode | -The returned by value is fully optimized |
| \code A.llt().solve(B,&X);\endcode | -\code X = A.llt().solve(B);
- X = A.selfadjointView |
-The returned by value is fully optimized and \n -the selfadjointView API allows you to select the \n -triangular part to work on (default is lower part) |
| \code A.llt().solveInPlace(B);\endcode | -\code B = A.llt().solve(B);
- B = A.selfadjointView |
-In place solving |
| \code A.ldlt().solve(B,&X);\endcode | -\code X = A.ldlt().solve(B);
- X = A.selfadjointView |
-The returned by value is fully optimized and \n -the selfadjointView API allows you to select the \n -triangular part to work on |
| Eigen 2 | Eigen 3 | Notes |
|---|---|---|
| Transform3f | -Affine3f or Projective3f | -Of course 3f is just an example here | -
| Eigen 2 | Eigen 3 |
|---|---|
| \code std::vector |
- \code std::vector |
-
-EigenBase<%Matrix> - <-- DenseCoeffsBase<%Matrix> (direct access case) - <-- DenseBase<%Matrix> - <-- MatrixBase<%Matrix> - <-- PlainObjectBase<%Matrix> (matrix case) - <-- Matrix -- -The inheritance diagram for Array looks as follows: - -
-EigenBase<%Array> - <-- DenseCoeffsBase<%Array> (direct access case) - <-- DenseBase<%Array> - <-- ArrayBase<%Array> - <-- PlainObjectBase<%Array> (array case) - <-- Array -- -The inheritance diagram for some other matrix expression class, here denoted by \c SomeMatrixXpr, looks as -follows: - -
-EigenBase<SomeMatrixXpr> - <-- DenseCoeffsBase<SomeMatrixXpr> (direct access or no direct access case) - <-- DenseBase<SomeMatrixXpr> - <-- MatrixBase<SomeMatrixXpr> - <-- SomeMatrixXpr -- -The inheritance diagram for some other array expression class, here denoted by \c SomeArrayXpr, looks as -follows: - -
-EigenBase<SomeArrayXpr> - <-- DenseCoeffsBase<SomeArrayXpr> (direct access or no direct access case) - <-- DenseBase<SomeArrayXpr> - <-- ArrayBase<SomeArrayXpr> - <-- SomeArrayXpr -- -Finally, consider an example of something that is not a dense expression, for instance a diagonal matrix. The -corresponding inheritance diagram is: - -
-EigenBase<%DiagonalMatrix> - <-- DiagonalBase<%DiagonalMatrix> - <-- DiagonalMatrix -- - -*/ -} diff --git a/testbed/nanogui/ext/eigen/doc/CustomizingEigen.dox b/testbed/nanogui/ext/eigen/doc/CustomizingEigen.dox deleted file mode 100644 index 5a0890ea..00000000 --- a/testbed/nanogui/ext/eigen/doc/CustomizingEigen.dox +++ /dev/null @@ -1,188 +0,0 @@ -namespace Eigen { - -/** \page TopicCustomizingEigen Customizing/Extending Eigen - -Eigen can be extended in several ways, for instance, by defining global methods, \ref ExtendingMatrixBase "by adding custom methods to MatrixBase", adding support to \ref CustomScalarType "custom types" etc. - -\eigenAutoToc - -\section ExtendingMatrixBase Extending MatrixBase (and other classes) - -In this section we will see how to add custom methods to MatrixBase. Since all expressions and matrix types inherit MatrixBase, adding a method to MatrixBase make it immediately available to all expressions ! A typical use case is, for instance, to make Eigen compatible with another API. - -You certainly know that in C++ it is not possible to add methods to an existing class. So how that's possible ? Here the trick is to include in the declaration of MatrixBase a file defined by the preprocessor token \c EIGEN_MATRIXBASE_PLUGIN: -\code -class MatrixBase { - // ... - #ifdef EIGEN_MATRIXBASE_PLUGIN - #include EIGEN_MATRIXBASE_PLUGIN - #endif -}; -\endcode -Therefore to extend MatrixBase with your own methods you just have to create a file with your method declaration and define EIGEN_MATRIXBASE_PLUGIN before you include any Eigen's header file. - -You can extend many of the other classes used in Eigen by defining similarly named preprocessor symbols. For instance, define \c EIGEN_ARRAYBASE_PLUGIN if you want to extend the ArrayBase class. A full list of classes that can be extended in this way and the corresponding preprocessor symbols can be found on our page \ref TopicPreprocessorDirectives. - -Here is an example of an extension file for adding methods to MatrixBase: \n -\b MatrixBaseAddons.h -\code -inline Scalar at(uint i, uint j) const { return this->operator()(i,j); } -inline Scalar& at(uint i, uint j) { return this->operator()(i,j); } -inline Scalar at(uint i) const { return this->operator[](i); } -inline Scalar& at(uint i) { return this->operator[](i); } - -inline RealScalar squaredLength() const { return squaredNorm(); } -inline RealScalar length() const { return norm(); } -inline RealScalar invLength(void) const { return fast_inv_sqrt(squaredNorm()); } - -template
| Example: | Output: |
|---|---|
| -\include function_taking_eigenbase.cpp - | --\verbinclude function_taking_eigenbase.out - |
| Example: | Output: |
|---|---|
| -\include function_taking_ref.cpp - | --\verbinclude function_taking_ref.out - |
| Not optimal expression | -Evaluated as | -Optimal version (single evaluation) | -Comments | -
|---|---|---|---|
| \code -m1 += m2 * m3; \endcode | -\code -temp = m2 * m3; -m1 += temp; \endcode | -\code -m1.noalias() += m2 * m3; \endcode | -Use .noalias() to tell Eigen the result and right-hand-sides do not alias. - Otherwise the product m2 * m3 is evaluated into a temporary. | -
| - | - | \code -m1.noalias() += s1 * (m2 * m3); \endcode | -This is a special feature of Eigen. Here the product between a scalar
- and a matrix product does not evaluate the matrix product but instead it
- returns a matrix product expression tracking the scalar scaling factor. - Without this optimization, the matrix product would be evaluated into a - temporary as in the next example. |
-
| \code -m1.noalias() += (m2 * m3).adjoint(); \endcode | -\code -temp = m2 * m3; -m1 += temp.adjoint(); \endcode | -\code -m1.noalias() += m3.adjoint() -* * m2.adjoint(); \endcode | -This is because the product expression has the EvalBeforeNesting bit which - enforces the evaluation of the product by the Tranpose expression. | -
| \code -m1 = m1 + m2 * m3; \endcode | -\code -temp = m2 * m3; -m1 = m1 + temp; \endcode | -\code m1.noalias() += m2 * m3; \endcode | -Here there is no way to detect at compile time that the two m1 are the same, - and so the matrix product will be immediately evaluated. | -
| \code -m1.noalias() = m4 + m2 * m3; \endcode | -\code -temp = m2 * m3; -m1 = m4 + temp; \endcode | -\code -m1 = m4; -m1.noalias() += m2 * m3; \endcode | -First of all, here the .noalias() in the first expression is useless because - m2*m3 will be evaluated anyway. However, note how this expression can be rewritten - so that no temporary is required. (tip: for very small fixed size matrix - it is slighlty better to rewrite it like this: m1.noalias() = m2 * m3; m1 += m4; | -
| \code -m1.noalias() += (s1*m2).block(..) * m3; \endcode | -\code -temp = (s1*m2).block(..); -m1 += temp * m3; \endcode | -\code -m1.noalias() += s1 * m2.block(..) * m3; \endcode | -This is because our expression analyzer is currently not able to extract trivial - expressions nested in a Block expression. Therefore the nested scalar - multiple cannot be properly extracted. | -
| Module | Header file | Contents |
|---|---|---|
| \link Core_Module Core \endlink | \code#include | Matrix and Array classes, basic linear algebra (including triangular and selfadjoint products), array manipulation |
| \link Geometry_Module Geometry \endlink | \code#include | Transform, Translation, Scaling, Rotation2D and 3D rotations (Quaternion, AngleAxis) |
| \link LU_Module LU \endlink | \code#include | Inverse, determinant, LU decompositions with solver (FullPivLU, PartialPivLU) |
| \link Cholesky_Module Cholesky \endlink | \code#include | LLT and LDLT Cholesky factorization with solver |
| \link Householder_Module Householder \endlink | \code#include | Householder transformations; this module is used by several linear algebra modules |
| \link SVD_Module SVD \endlink | \code#include | SVD decomposition with least-squares solver (JacobiSVD) |
| \link QR_Module QR \endlink | \code#include | QR decomposition with solver (HouseholderQR, ColPivHouseholderQR, FullPivHouseholderQR) |
| \link Eigenvalues_Module Eigenvalues \endlink | \code#include | Eigenvalue, eigenvector decompositions (EigenSolver, SelfAdjointEigenSolver, ComplexEigenSolver) |
| \link Sparse_modules Sparse \endlink | \code#include | %Sparse matrix storage and related basic linear algebra (SparseMatrix, DynamicSparseMatrix, SparseVector) |
| \code#include | Includes Core, Geometry, LU, Cholesky, SVD, QR, and Eigenvalues header files | |
| \code#include | Includes %Dense and %Sparse header files (the whole Eigen library) |
| Matrices | Arrays |
|---|---|
| \code
-Matrix | \code
-Array |
| 1D objects | 2D objects | Notes | |
|---|---|---|---|
| Constructors | -\code -Vector4d v4; -Vector2f v1(x, y); -Array3i v2(x, y, z); -Vector4d v3(x, y, z, w); - -VectorXf v5; // empty object -ArrayXf v6(size); -\endcode | \code -Matrix4f m1; - - - - -MatrixXf m5; // empty object -MatrixXf m6(nb_rows, nb_columns); -\endcode | -By default, the coefficients \n are left uninitialized |
| Comma initializer | -\code -Vector3f v1; v1 << x, y, z; -ArrayXf v2(4); v2 << 1, 2, 3, 4; - -\endcode | \code -Matrix3f m1; m1 << 1, 2, 3, - 4, 5, 6, - 7, 8, 9; -\endcode | |
| Comma initializer (bis) | --\include Tutorial_commainit_02.cpp - | --output: -\verbinclude Tutorial_commainit_02.out - | -|
| Runtime info | -\code -vector.size(); - -vector.innerStride(); -vector.data(); -\endcode | \code -matrix.rows(); matrix.cols(); -matrix.innerSize(); matrix.outerSize(); -matrix.innerStride(); matrix.outerStride(); -matrix.data(); -\endcode | Inner/Outer* are storage order dependent |
| Compile-time info | -\code -ObjectType::Scalar ObjectType::RowsAtCompileTime -ObjectType::RealScalar ObjectType::ColsAtCompileTime -ObjectType::Index ObjectType::SizeAtCompileTime -\endcode | ||
| Resizing | -\code -vector.resize(size); - - -vector.resizeLike(other_vector); -vector.conservativeResize(size); -\endcode | \code -matrix.resize(nb_rows, nb_cols); -matrix.resize(Eigen::NoChange, nb_cols); -matrix.resize(nb_rows, Eigen::NoChange); -matrix.resizeLike(other_matrix); -matrix.conservativeResize(nb_rows, nb_cols); -\endcode | no-op if the new sizes match, otherwise data are lost resizing with data preservation |
| Coeff access with \n range checking | -\code -vector(i) vector.x() -vector[i] vector.y() - vector.z() - vector.w() -\endcode | \code -matrix(i,j) -\endcode | Range checking is disabled if \n NDEBUG or EIGEN_NO_DEBUG is defined |
| Coeff access without \n range checking | -\code -vector.coeff(i) -vector.coeffRef(i) -\endcode | \code -matrix.coeff(i,j) -matrix.coeffRef(i,j) -\endcode | |
| Assignment/copy | -\code
-object = expression;
-object_of_float = expression_of_double.cast | the destination is automatically resized (if possible) | |
| Fixed-size matrix or vector | -Dynamic-size matrix | -Dynamic-size vector | -
|---|---|---|
| -\code -typedef {Matrix3f|Array33f} FixedXD; -FixedXD x; - -x = FixedXD::Zero(); -x = FixedXD::Ones(); -x = FixedXD::Constant(value); -x = FixedXD::Random(); -x = FixedXD::LinSpaced(size, low, high); - -x.setZero(); -x.setOnes(); -x.setConstant(value); -x.setRandom(); -x.setLinSpaced(size, low, high); -\endcode - | --\code -typedef {MatrixXf|ArrayXXf} Dynamic2D; -Dynamic2D x; - -x = Dynamic2D::Zero(rows, cols); -x = Dynamic2D::Ones(rows, cols); -x = Dynamic2D::Constant(rows, cols, value); -x = Dynamic2D::Random(rows, cols); -N/A - -x.setZero(rows, cols); -x.setOnes(rows, cols); -x.setConstant(rows, cols, value); -x.setRandom(rows, cols); -N/A -\endcode - | --\code -typedef {VectorXf|ArrayXf} Dynamic1D; -Dynamic1D x; - -x = Dynamic1D::Zero(size); -x = Dynamic1D::Ones(size); -x = Dynamic1D::Constant(size, value); -x = Dynamic1D::Random(size); -x = Dynamic1D::LinSpaced(size, low, high); - -x.setZero(size); -x.setOnes(size); -x.setConstant(size, value); -x.setRandom(size); -x.setLinSpaced(size, low, high); -\endcode - | -
| Identity and \link MatrixBase::Unit basis vectors \endlink \matrixworld | ||
| -\code -x = FixedXD::Identity(); -x.setIdentity(); - -Vector3f::UnitX() // 1 0 0 -Vector3f::UnitY() // 0 1 0 -Vector3f::UnitZ() // 0 0 1 -\endcode - | --\code -x = Dynamic2D::Identity(rows, cols); -x.setIdentity(rows, cols); - - - -N/A -\endcode - | -\code -N/A - - -VectorXf::Unit(size,i) -VectorXf::Unit(4,1) == Vector4f(0,1,0,0) - == Vector4f::UnitY() -\endcode - | -
| Contiguous \n memory | -\code
-float data[] = {1,2,3,4};
-Map |
-
| Typical usage \n of strides | -\code
-float data[] = {1,2,3,4,5,6,7,8,9};
-Map |
-
| -add \n subtract | \code -mat3 = mat1 + mat2; mat3 += mat1; -mat3 = mat1 - mat2; mat3 -= mat1;\endcode - |
| -scalar product | \code -mat3 = mat1 * s1; mat3 *= s1; mat3 = s1 * mat1; -mat3 = mat1 / s1; mat3 /= s1;\endcode - |
| -matrix/vector \n products \matrixworld | \code -col2 = mat1 * col1; -row2 = row1 * mat1; row1 *= mat1; -mat3 = mat1 * mat2; mat3 *= mat1; \endcode - |
| -transposition \n adjoint \matrixworld | \code -mat1 = mat2.transpose(); mat1.transposeInPlace(); -mat1 = mat2.adjoint(); mat1.adjointInPlace(); -\endcode - |
| -\link MatrixBase::dot() dot \endlink product \n inner product \matrixworld | \code -scalar = vec1.dot(vec2); -scalar = col1.adjoint() * col2; -scalar = (col1.adjoint() * col2).value();\endcode - |
| -outer product \matrixworld | \code -mat = col1 * col2.transpose();\endcode - |
| -\link MatrixBase::norm() norm \endlink \n \link MatrixBase::normalized() normalization \endlink \matrixworld | \code -scalar = vec1.norm(); scalar = vec1.squaredNorm() -vec2 = vec1.normalized(); vec1.normalize(); // inplace \endcode - |
| -\link MatrixBase::cross() cross product \endlink \matrixworld | \code
-#include |
| Matrix API \matrixworld | Via Array conversions |
|---|---|
| \code -mat1.cwiseMin(mat2) -mat1.cwiseMax(mat2) -mat1.cwiseAbs2() -mat1.cwiseAbs() -mat1.cwiseSqrt() -mat1.cwiseProduct(mat2) -mat1.cwiseQuotient(mat2)\endcode - | \code -mat1.array().min(mat2.array()) -mat1.array().max(mat2.array()) -mat1.array().abs2() -mat1.array().abs() -mat1.array().sqrt() -mat1.array() * mat2.array() -mat1.array() / mat2.array() -\endcode |
| Arithmetic operators | \code -array1 * array2 array1 / array2 array1 *= array2 array1 /= array2 -array1 + scalar array1 - scalar array1 += scalar array1 -= scalar -\endcode |
| Comparisons | \code -array1 < array2 array1 > array2 array1 < scalar array1 > scalar -array1 <= array2 array1 >= array2 array1 <= scalar array1 >= scalar -array1 == array2 array1 != array2 array1 == scalar array1 != scalar -\endcode |
| Trigo, power, and \n misc functions \n and the STL variants | \code -array1.min(array2) -array1.max(array2) -array1.abs2() -array1.abs() abs(array1) -array1.sqrt() sqrt(array1) -array1.log() log(array1) -array1.exp() exp(array1) -array1.pow(exponent) pow(array1,exponent) -array1.square() -array1.cube() -array1.inverse() -array1.sin() sin(array1) -array1.cos() cos(array1) -array1.tan() tan(array1) -array1.asin() asin(array1) -array1.acos() acos(array1) -\endcode - |
| \code - 5 3 1 -mat = 2 7 8 - 9 4 6 \endcode - | \code mat.minCoeff(); \endcode | \code 1 \endcode |
| \code mat.colwise().minCoeff(); \endcode | \code 2 3 1 \endcode | |
| \code mat.rowwise().minCoeff(); \endcode | \code -1 -2 -4 -\endcode |
| Default versions | -Optimized versions when the size \n is known at compile time | - - |
|---|---|---|
| \code vec1.head(n)\endcode | \code vec1.head | the first \c n coeffs |
| \code vec1.tail(n)\endcode | \code vec1.tail | the last \c n coeffs |
| \code vec1.segment(pos,n)\endcode | \code vec1.segment |
- the \c n coeffs in the \n range [\c pos : \c pos + \c n - 1] |
| - -Read-write access to sub-matrices: | ||
| \code mat1.block(i,j,rows,cols)\endcode - \link DenseBase::block(Index,Index,Index,Index) (more) \endlink | -\code mat1.block |
- the \c rows x \c cols sub-matrix \n starting from position (\c i,\c j) |
| \code - mat1.topLeftCorner(rows,cols) - mat1.topRightCorner(rows,cols) - mat1.bottomLeftCorner(rows,cols) - mat1.bottomRightCorner(rows,cols)\endcode - | \code
- mat1.topLeftCorner| the \c rows x \c cols sub-matrix \n taken in one of the four corners | |
| \code - mat1.topRows(rows) - mat1.bottomRows(rows) - mat1.leftCols(cols) - mat1.rightCols(cols)\endcode - | \code
- mat1.topRows| specialized versions of block() \n when the block fit two corners | |
| Operation | Code |
|---|---|
| -view a vector \link MatrixBase::asDiagonal() as a diagonal matrix \endlink \n | \code -mat1 = vec1.asDiagonal();\endcode - |
| -Declare a diagonal matrix | \code
-DiagonalMatrix |
| Access the \link MatrixBase::diagonal() diagonal \endlink and \link MatrixBase::diagonal(Index) super/sub diagonals \endlink of a matrix as a vector (read/write) | -\code -vec1 = mat1.diagonal(); mat1.diagonal() = vec1; // main diagonal -vec1 = mat1.diagonal(+n); mat1.diagonal(+n) = vec1; // n-th super diagonal -vec1 = mat1.diagonal(-n); mat1.diagonal(-n) = vec1; // n-th sub diagonal -vec1 = mat1.diagonal<1>(); mat1.diagonal<1>() = vec1; // first super diagonal -vec1 = mat1.diagonal<-2>(); mat1.diagonal<-2>() = vec1; // second sub diagonal -\endcode | -
| Optimized products and inverse | -\code -mat3 = scalar * diag1 * mat1; -mat3 += scalar * mat1 * vec1.asDiagonal(); -mat3 = vec1.asDiagonal().inverse() * mat1 -mat3 = mat1 * diag1.inverse() -\endcode | -
| Operation | Code |
|---|---|
| -Reference to a triangular with optional \n -unit or null diagonal (read/write): - | \code
-m.triangularView |
| -Writing to a specific triangular part:\n (only the referenced triangular part is evaluated) - | \code
-m1.triangularView |
| -Conversion to a dense matrix setting the opposite triangular part to zero: - | \code
-m2 = m1.triangularView |
| -Products: - | \code
-m3 += s1 * m1.adjoint().triangularView |
| -Solving linear equations:\n -\f$ M_2 := L_1^{-1} M_2 \f$ \n -\f$ M_3 := {L_1^*}^{-1} M_3 \f$ \n -\f$ M_4 := M_4 U_1^{-1} \f$ - | \n \code
-L1.triangularView |
| Operation | Code |
|---|---|
| -Conversion to a dense matrix: - | \code
-m2 = m.selfadjointView |
| -Product with another general matrix or vector: - | \code
-m3 = s1 * m1.conjugate().selfadjointView |
| -Rank 1 and rank K update: \n -\f$ upper(M_1) \mathrel{{+}{=}} s_1 M_2 M_2^* \f$ \n -\f$ lower(M_1) \mathbin{{-}{=}} M_2^* M_2 \f$ - | \n \code
-M1.selfadjointView |
| -Rank 2 update: (\f$ M \mathrel{{+}{=}} s u v^* + s v u^* \f$) - | \code
-M.selfadjointView |
| -Solving linear equations:\n(\f$ M_2 := M_1^{-1} M_2 \f$) - | \code
-// via a standard Cholesky factorization
-m2 = m1.selfadjointView |
| -\link MatrixBase::asDiagonal() make a diagonal matrix \endlink \n from a vector | \code -mat1 = vec1.asDiagonal();\endcode - |
| -Declare a diagonal matrix | \code
-DiagonalMatrix |
| Access \link MatrixBase::diagonal() the diagonal and super/sub diagonals of a matrix \endlink as a vector (read/write) | -\code -vec1 = mat1.diagonal(); mat1.diagonal() = vec1; // main diagonal -vec1 = mat1.diagonal(+n); mat1.diagonal(+n) = vec1; // n-th super diagonal -vec1 = mat1.diagonal(-n); mat1.diagonal(-n) = vec1; // n-th sub diagonal -vec1 = mat1.diagonal<1>(); mat1.diagonal<1>() = vec1; // first super diagonal -vec1 = mat1.diagonal<-2>(); mat1.diagonal<-2>() = vec1; // second sub diagonal -\endcode | -
| View on a triangular part of a matrix (read/write) | -\code
-mat2 = mat1.triangularView |
| View a triangular part as a symmetric/self-adjoint matrix (read/write) | -\code
-mat2 = mat1.selfadjointView |
| Size set at run time: | Size set at compile time: |
|---|---|
| -\include QuickStart_example2_dynamic.cpp - | --\include QuickStart_example2_fixed.cpp - |
| Class | Module | Solver kind | Matrix kind | Features related to performance | -Dependencies,License | Notes |
|---|---|---|---|---|---|---|
| SimplicialLLT | \link SparseCholesky_Module SparseCholesky \endlink | Direct LLt factorization | SPD | Fill-in reducing | -built-in, LGPL | -SimplicialLDLT is often preferable |
| SimplicialLDLT | \link SparseCholesky_Module SparseCholesky \endlink | Direct LDLt factorization | SPD | Fill-in reducing | -built-in, LGPL | -Recommended for very sparse and not too large problems (e.g., 2D Poisson eq.) |
| ConjugateGradient | \link IterativeLinearSolvers_Module IterativeLinearSolvers \endlink | Classic iterative CG | SPD | Preconditionning | -built-in, MPL2 | -Recommended for large symmetric problems (e.g., 3D Poisson eq.) |
| BiCGSTAB | \link IterativeLinearSolvers_Module IterativeLinearSolvers \endlink | Iterative stabilized bi-conjugate gradient | Square | Preconditionning | -built-in, MPL2 | -To speedup the convergence, try it with the \ref IncompleteLUT preconditioner. |
| SparseLU | \link SparseLU_Module SparseLU \endlink | LU factorization | -Square | Fill-in reducing, Leverage fast dense algebra | -built-in, MPL2 | optimized for small and large problems with irregular patterns |
| SparseQR | \link SparseQR_Module SparseQR \endlink | QR factorization | -Any, rectangular | Fill-in reducing | -built-in, MPL2 | recommended for least-square problems, has a basic rank-revealing feature |
| Wrappers to external solvers | ||||||
| PastixLLT \n PastixLDLT \n PastixLU | \link PaStiXSupport_Module PaStiXSupport \endlink | Direct LLt, LDLt, LU factorizations | SPD \n SPD \n Square | Fill-in reducing, Leverage fast dense algebra, Multithreading | -Requires the PaStiX package, \b CeCILL-C | -optimized for tough problems and symmetric patterns |
| CholmodSupernodalLLT | \link CholmodSupport_Module CholmodSupport \endlink | Direct LLt factorization | SPD | Fill-in reducing, Leverage fast dense algebra | -Requires the SuiteSparse package, \b GPL | -|
| UmfPackLU | \link UmfPackSupport_Module UmfPackSupport \endlink | Direct LU factorization | Square | Fill-in reducing, Leverage fast dense algebra | -Requires the SuiteSparse package, \b GPL | -|
| SuperLU | \link SuperLUSupport_Module SuperLUSupport \endlink | Direct LU factorization | Square | Fill-in reducing, Leverage fast dense algebra | -Requires the SuperLU library, (BSD-like) | -|
| SPQR | \link SPQRSupport_Module SPQRSupport \endlink | QR factorization | -Any, rectangular | fill-in reducing, multithreaded, fast dense algebra | -requires the SuiteSparse package, \b GPL | recommended for linear least-squares problems, has a rank-revealing feature |
| Matrix | N | NNZ | UMFPACK | SUPERLU | PASTIX LU | BiCGSTAB | BiCGSTAB+ILUT | GMRES+ILUT | LDLT | CHOLMOD LDLT | PASTIX LDLT | LLT | CHOLMOD SP LLT | CHOLMOD LLT | PASTIX LLT | CG | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| vector_graphics | 12855 | 72069 | Compute Time | 0.0254549 | 0.0215677 | 0.0701827 | 0.000153388 | 0.0140107 | 0.0153709 | 0.0101601 | 0.00930502 | 0.0649689 - | |||||
| Solve Time | 0.00337835 | 0.000951826 | 0.00484373 | 0.0374886 | 0.0046445 | 0.00847754 | 0.000541813 | 0.000293696 | 0.00485376 - | ||||||||
| Total Time | 0.0288333 | 0.0225195 | 0.0750265 | 0.037642 | 0.0186552 | 0.0238484 | 0.0107019 | 0.00959871 | 0.0698227 - | ||||||||
| Error(Iter) | 1.299e-16 | 2.04207e-16 | 4.83393e-15 | 3.94856e-11 (80) | 1.03861e-12 (3) | 5.81088e-14 (6) | 1.97578e-16 | 1.83927e-16 | 4.24115e-15 - | ||||||||
| poisson_SPD | 19788 | 308232 | Compute Time | 0.425026 | 1.82378 | 0.617367 | 0.000478921 | 1.34001 | 1.33471 | 0.796419 | 0.857573 | 0.473007 | 0.814826 | 0.184719 | 0.861555 | 0.470559 | 0.000458188 - |
| Solve Time | 0.0280053 | 0.0194402 | 0.0268747 | 0.249437 | 0.0548444 | 0.0926991 | 0.00850204 | 0.0053171 | 0.0258932 | 0.00874603 | 0.00578155 | 0.00530361 | 0.0248942 | 0.239093 - | |||
| Total Time | 0.453031 | 1.84322 | 0.644241 | 0.249916 | 1.39486 | 1.42741 | 0.804921 | 0.862891 | 0.4989 | 0.823572 | 0.190501 | 0.866859 | 0.495453 | 0.239551 - | |||
| Error(Iter) | 4.67146e-16 | 1.068e-15 | 1.3397e-15 | 6.29233e-11 (201) | 3.68527e-11 (6) | 3.3168e-15 (16) | 1.86376e-15 | 1.31518e-16 | 1.42593e-15 | 3.45361e-15 | 3.14575e-16 | 2.21723e-15 | 7.21058e-16 | 9.06435e-12 (261) - | |||
| sherman2 | 1080 | 23094 | Compute Time | 0.00631754 | 0.015052 | 0.0247514 | - | 0.0214425 | 0.0217988 - | ||||||||
| Solve Time | 0.000478424 | 0.000337998 | 0.0010291 | - | 0.00243152 | 0.00246152 - | |||||||||||
| Total Time | 0.00679597 | 0.01539 | 0.0257805 | - | 0.023874 | 0.0242603 - | |||||||||||
| Error(Iter) | 1.83099e-15 | 8.19351e-15 | 2.625e-14 | 1.3678e+69 (1080) | 4.1911e-12 (7) | 5.0299e-13 (12) - | |||||||||||
| bcsstk01_SPD | 48 | 400 | Compute Time | 0.000169079 | 0.00010789 | 0.000572538 | 1.425e-06 | 9.1612e-05 | 8.3985e-05 | 5.6489e-05 | 7.0913e-05 | 0.000468251 | 5.7389e-05 | 8.0212e-05 | 5.8394e-05 | 0.000463017 | 1.333e-06 - |
| Solve Time | 1.2288e-05 | 1.1124e-05 | 0.000286387 | 8.5896e-05 | 1.6381e-05 | 1.6984e-05 | 3.095e-06 | 4.115e-06 | 0.000325438 | 3.504e-06 | 7.369e-06 | 3.454e-06 | 0.000294095 | 6.0516e-05 - | |||
| Total Time | 0.000181367 | 0.000119014 | 0.000858925 | 8.7321e-05 | 0.000107993 | 0.000100969 | 5.9584e-05 | 7.5028e-05 | 0.000793689 | 6.0893e-05 | 8.7581e-05 | 6.1848e-05 | 0.000757112 | 6.1849e-05 - | |||
| Error(Iter) | 1.03474e-16 | 2.23046e-16 | 2.01273e-16 | 4.87455e-07 (48) | 1.03553e-16 (2) | 3.55965e-16 (2) | 2.48189e-16 | 1.88808e-16 | 1.97976e-16 | 2.37248e-16 | 1.82701e-16 | 2.71474e-16 | 2.11322e-16 | 3.547e-09 (48) - | |||
| sherman1 | 1000 | 3750 | Compute Time | 0.00228805 | 0.00209231 | 0.00528268 | 9.846e-06 | 0.00163522 | 0.00162155 | 0.000789259 | 0.000804495 | 0.00438269 - | |||||
| Solve Time | 0.000213788 | 9.7983e-05 | 0.000938831 | 0.00629835 | 0.000361764 | 0.00078794 | 4.3989e-05 | 2.5331e-05 | 0.000917166 - | ||||||||
| Total Time | 0.00250184 | 0.00219029 | 0.00622151 | 0.0063082 | 0.00199698 | 0.00240949 | 0.000833248 | 0.000829826 | 0.00529986 - | ||||||||
| Error(Iter) | 1.16839e-16 | 2.25968e-16 | 2.59116e-16 | 3.76779e-11 (248) | 4.13343e-11 (4) | 2.22347e-14 (10) | 2.05861e-16 | 1.83555e-16 | 1.02917e-15 - | ||||||||
| young1c | 841 | 4089 | Compute Time | 0.00235843 | 0.00217228 | 0.00568075 | 1.2735e-05 | 0.00264866 | 0.00258236 - | ||||||||
| Solve Time | 0.000329599 | 0.000168634 | 0.00080118 | 0.0534738 | 0.00187193 | 0.00450211 - | |||||||||||
| Total Time | 0.00268803 | 0.00234091 | 0.00648193 | 0.0534865 | 0.00452059 | 0.00708447 - | |||||||||||
| Error(Iter) | 1.27029e-16 | 2.81321e-16 | 5.0492e-15 | 8.0507e-11 (706) | 3.00447e-12 (8) | 1.46532e-12 (16) - | |||||||||||
| mhd1280b | 1280 | 22778 | Compute Time | 0.00234898 | 0.00207079 | 0.00570918 | 2.5976e-05 | 0.00302563 | 0.00298036 | 0.00144525 | 0.000919922 | 0.00426444 - | |||||
| Solve Time | 0.00103392 | 0.000211911 | 0.00105 | 0.0110432 | 0.000628287 | 0.00392089 | 0.000138303 | 6.2446e-05 | 0.00097564 - | ||||||||
| Total Time | 0.0033829 | 0.0022827 | 0.00675918 | 0.0110692 | 0.00365392 | 0.00690124 | 0.00158355 | 0.000982368 | 0.00524008 - | ||||||||
| Error(Iter) | 1.32953e-16 | 3.08646e-16 | 6.734e-16 | 8.83132e-11 (40) | 1.51153e-16 (1) | 6.08556e-16 (8) | 1.89264e-16 | 1.97477e-16 | 6.68126e-09 - | ||||||||
| crashbasis | 160000 | 1750416 | Compute Time | 3.2019 | 5.7892 | 15.7573 | 0.00383515 | 3.1006 | 3.09921 - | ||||||||
| Solve Time | 0.261915 | 0.106225 | 0.402141 | 1.49089 | 0.24888 | 0.443673 - | |||||||||||
| Total Time | 3.46381 | 5.89542 | 16.1594 | 1.49473 | 3.34948 | 3.54288 - | |||||||||||
| Error(Iter) | 1.76348e-16 | 4.58395e-16 | 1.67982e-14 | 8.64144e-11 (61) | 8.5996e-12 (2) | 6.04042e-14 (5) - - |
| Category | Operations | Notes |
|---|---|---|
| Constructor | -
-\code
- SparseMatrix | Default is ColMajor |
| Resize/Reserve | -- \code - sm1.resize(m,n); //Change sm1 to a m x n matrix. - sm1.reserve(nnz); // Allocate room for nnz nonzeros elements. - \endcode - | -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. | -
| Assignment | -
-\code
- SparseMatrix |
-The copy constructor can be used to convert from a storage order to another | -
| Element-wise Insertion | --\code -// Insert a new element; - sm1.insert(i, j) = v_ij; - -// Update the value v_ij - sm1.coeffRef(i,j) = v_ij; - sm1.coeffRef(i,j) += v_ij; - sm1.coeffRef(i,j) -= v_ij; -\endcode - | -insert() assumes that the element does not already exist; otherwise, use coeffRef() | -
| Batch insertion | -
-\code
- std::vector< Eigen::Triplet |
-A complete example is available at \link TutorialSparseFilling Triplet Insertion \endlink. | -
| Constant or Random Insertion | --\code -sm1.setZero(); -\endcode - | -Remove all non-zero coefficients | -
| \code - sm1.rows(); // Number of rows - sm1.cols(); // Number of columns - sm1.nonZeros(); // Number of non zero values - sm1.outerSize(); // Number of columns (resp. rows) for a column major (resp. row major ) - sm1.innerSize(); // Number of rows (resp. columns) for a row major (resp. column major) - sm1.norm(); // Euclidian norm of the matrix - sm1.squaredNorm(); // Squared norm of the matrix - sm1.blueNorm(); - sm1.isVector(); // Check if sm1 is a sparse vector or a sparse matrix - sm1.isCompressed(); // Check if sm1 is in compressed form - ... - \endcode | -
| Operations | Code | Notes |
|---|---|---|
| add subtract | -\code - sm3 = sm1 + sm2; - sm3 = sm1 - sm2; - sm2 += sm1; - sm2 -= sm1; \endcode - | -- sm1 and sm2 should have the same storage order - | -
| - scalar product | \code - sm3 = sm1 * s1; sm3 *= s1; - sm3 = s1 * sm1 + s2 * sm2; sm3 /= s1;\endcode - | -- Many combinations are possible if the dimensions and the storage order agree. - |
| %Sparse %Product | -\code - sm3 = sm1 * sm2; - dm2 = sm1 * dm1; - dv2 = sm1 * dv1; - \endcode | -- | -
| transposition, adjoint | -\code - sm2 = sm1.transpose(); - sm2 = sm1.adjoint(); - \endcode | -- Note that the transposition change the storage order. There is no support for transposeInPlace(). - | -
| Permutation | --\code -perm.indices(); // Reference to the vector of indices -sm1.twistedBy(perm); // Permute rows and columns -sm2 = sm1 * perm; //Permute the columns -sm2 = perm * sm1; // Permute the columns -\endcode - | -- - | -
| - Component-wise ops - | -\code - sm1.cwiseProduct(sm2); - sm1.cwiseQuotient(sm2); - sm1.cwiseMin(sm2); - sm1.cwiseMax(sm2); - sm1.cwiseAbs(); - sm1.cwiseSqrt(); - \endcode | -- sm1 and sm2 should have the same storage order - | -
| Operations | Code | Notes |
|---|---|---|
| Sub-matrices | --\code - sm1.block(startRow, startCol, rows, cols); - sm1.block(startRow, startCol); - sm1.topLeftCorner(rows, cols); - sm1.topRightCorner(rows, cols); - sm1.bottomLeftCorner( rows, cols); - sm1.bottomRightCorner( rows, cols); - \endcode - | - |
| Range | --\code - sm1.innerVector(outer); - sm1.innerVectors(start, size); - sm1.leftCols(size); - sm2.rightCols(size); - sm1.middleRows(start, numRows); - sm1.middleCols(start, numCols); - sm1.col(j); -\endcode - | -A inner vector is either a row (for row-major) or a column (for column-major). As stated earlier, the evaluation can be done in a matrix with different storage order | -
| Triangular and selfadjoint views | -
-\code
- sm2 = sm1.triangularview |
-Several combination between triangular views and blocks views are possible -\code - \endcode | -
| Triangular solve | -
-\code
- dv2 = sm1.triangularView |
-For general sparse solve, Use any suitable module described at \ref TopicSparseSystems | -
| Low-level API | --\code -sm1.valuePtr(); // Pointer to the values -sm1.innerIndextr(); // Pointer to the indices. -sm1.outerIndexPtr(); //Pointer to the beginning of each inner vector -\endcode - | -If the matrix is not in compressed form, makeCompressed() should be called before. Note that these functions are mostly provided for interoperability purposes with external libraries. A 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 | -
| Example | Output |
|---|---|
| -\include TopicStorageOrders_example.cpp - | --\verbinclude TopicStorageOrders_example.out - |
| Example: | Output: |
|---|---|
| -\include TemplateKeyword_simple.cpp - | --\verbinclude TemplateKeyword_simple.out - |
| Example: | Output: |
|---|---|
| -\include TemplateKeyword_flexible.cpp - | --\verbinclude TemplateKeyword_flexible.out - |
| Example | Output |
|---|---|
| -\include TopicAliasing_block.cpp - | --\verbinclude TopicAliasing_block.out - |
| Example | Output |
|---|---|
| -\include tut_arithmetic_transpose_aliasing.cpp - | --\verbinclude tut_arithmetic_transpose_aliasing.out - |
| Example | Output |
|---|---|
| -\include TopicAliasing_block_correct.cpp - | --\verbinclude TopicAliasing_block_correct.out - |
| Example | Output |
|---|---|
| -\include tut_arithmetic_transpose_inplace.cpp - | --\verbinclude tut_arithmetic_transpose_inplace.out - |
| Original function | In-place function |
|---|---|
| MatrixBase::adjoint() | MatrixBase::adjointInPlace() |
| DenseBase::reverse() | DenseBase::reverseInPlace() |
| LDLT::solve() | LDLT::solveInPlace() |
| LLT::solve() | LLT::solveInPlace() |
| TriangularView::solve() | TriangularView::solveInPlace() |
| DenseBase::transpose() | DenseBase::transposeInPlace() |
| Example | Output |
|---|---|
| -\include TopicAliasing_cwise.cpp - | --\verbinclude TopicAliasing_cwise.out - |
| Example | Output |
|---|---|
| -\include TopicAliasing_mult1.cpp - | --\verbinclude TopicAliasing_mult1.out - |
| Example | Output |
|---|---|
| -\include TopicAliasing_mult2.cpp - | --\verbinclude TopicAliasing_mult2.out - |
| Example | Output |
|---|---|
| -\include TopicAliasing_mult3.cpp - | --\verbinclude TopicAliasing_mult3.out - |