1.?SparseMatrix
?核心屬性與初始化
模板參數
cpp
SparseMatrix<Scalar, Options, StorageIndex>
-
Scalar
:數據類型(如?double
,?float
)。 -
Options
:存儲格式(默認?ColMajor
,可選?RowMajor
)。 -
StorageIndex
:索引類型(通常為?int
)。
關鍵屬性
屬性 | 說明 | 示例 |
---|---|---|
rows() | 矩陣行數 | int rows = mat.rows(); |
cols() | 矩陣列數 | int cols = mat.cols(); |
nonZeros() | 非零元素數量 | int nnz = mat.nonZeros(); |
isCompressed() | 是否為壓縮格式(CRS/CCS) | bool compressed = mat.isCompressed(); |
初始化方式
方法 | 示例 | 說明 |
---|---|---|
直接構造 | SparseMatrix<double> mat(100, 100); | 空矩陣(100x100) |
三重態列表(Triplet) | 見下文 | 逐元素填充 |
從稠密矩陣轉換 | SparseMatrix<double> sp = dense.sparseView(); | 自動過濾零值 |
2. 核心方法
(1) 元素插入與訪問
方法 | 參數說明 | 功能 | 示例 |
---|---|---|---|
insert(i, j, value) | i : 行索引,j : 列索引,value : 值 | 插入非零元素(若存在則覆蓋) | mat.insert(0, 1) = 3.14; |
coeffRef(i, j) | 同上 | 訪問/修改元素(若不存在則插入) | mat.coeffRef(1, 2) += 1.0; |
makeCompressed() | 無 | 壓縮存儲(CRS/CCS格式) | mat.makeCompressed(); (此后無法插入新元素) |
valuePtr() ,?innerIndexPtr() ,?outerIndexPtr() | 無 | 獲取壓縮格式的底層數組指針 | 用于直接操作底層數據(高級用法) |
(2) 矩陣操作
方法 | 參數說明 | 功能 | 示例 |
---|---|---|---|
reserve(Size) | Size : 預估非零元素數 | 預分配內存 | mat.reserve(1000); |
prune(Scalar, RealScalar) | 閾值和參考值 | 刪除絕對值小于閾值的元素 | mat.prune(1e-5, 0.0); |
transpose() | 無 | 返回轉置矩陣(視圖) | SparseMatrix<double> matT = mat.transpose(); |
sum() | 無 | 所有元素求和 | double total = mat.sum(); |
(3) 塊操作與迭代
方法 | 參數說明 | 功能 | 示例 |
---|---|---|---|
block(startRow, startCol, rows, cols) | 起始位置和塊大小 | 返回子矩陣(視圖) | auto submat = mat.block(10, 10, 5, 5); |
innerVector(outer) | outer : 列號(ColMajor) | 返回列/行向量(視圖) | SparseVector<double> col = mat.innerVector(0); |
迭代器(InnerIterator ) | 無 | 遍歷非零元素 | 見下方代碼示例 |
3. 輔助類:Triplet
用于高效構建稀疏矩陣(先收集非零元素,再一次性填充):
cpp
#include <Eigen/SparseCore>
using namespace Eigen;std::vector<Triplet<double>> triplets;
triplets.push_back(Triplet<double>(0, 1, 3.0)); // (i, j, value)
triplets.push_back(Triplet<double>(1, 2, 4.0));SparseMatrix<double> mat(3, 3);
mat.setFromTriplets(triplets.begin(), triplets.end());
4. 稀疏矩陣分解與求解
求解器類
類名 | 適用場景 | 關鍵方法 |
---|---|---|
SimplicialLLT | 對稱正定矩陣 | compute(mat) ?+?solve(b) |
SparseLU | 通用方陣 | analyzePattern() ?+?factorize() |
ConjugateGradient | 對稱正定矩陣(迭代法) | setTolerance() ?+?compute() |
求解示例
cpp
SparseMatrix<double> A;
VectorXd b, x;// 使用 SimplicialLLT 分解
SimplicialLLT<SparseMatrix<double>> solver;
solver.compute(A);
if (solver.info() == Success) {x = solver.solve(b);
}// 使用迭代法(如共軛梯度)
ConjugateGradient<SparseMatrix<double>> cg;
cg.setTolerance(1e-6);
cg.compute(A);
x = cg.solve(b);
5. 代碼示例
遍歷非零元素
cpp
for (int k = 0; k < mat.outerSize(); ++k) {for (SparseMatrix<double>::InnerIterator it(mat, k); it; ++it) {std::cout << "(" << it.row() << "," << it.col() << ") = " << it.value() << std::endl;}
}
矩陣運算
cpp
SparseMatrix<double> A, B;
A.resize(100, 100);
B.resize(100, 100);
// ... 填充 A 和 B ...// 稀疏矩陣加法
SparseMatrix<double> C = A + B;// 稀疏矩陣乘法
SparseMatrix<double> D = A * B;// 標量乘法
SparseMatrix<double> E = 2.5 * A;
6. 性能優化技巧
-
預分配內存:通過?
reserve()
?或?Triplet
?避免多次擴容。 -
壓縮存儲:操作完成后調用?
makeCompressed()
?提升計算效率。 -
選擇合適的求解器:
-
對稱正定矩陣:優先用?
SimplicialLLT
?或?ConjugateGradient
。 -
非對稱矩陣:使用?
SparseLU
?或?BiCGSTAB
。
-
7. 常見問題
-
插入效率:未壓縮模式下插入更快,但計算前需壓縮。
-
內存占用:稀疏矩陣內存 ≈?
(2 * nnz + cols + 1) * sizeof(Index) + nnz * sizeof(Scalar)
。
掌握這些方法后,可高效處理大規模稀疏線性代數問題!更多細節見?Eigen SparseMatrix 文檔。