在Java库ojAlgo中如何截取或提取子矩阵?
在ojAlgo中正确提取子矩阵的方法
我懂你在使用ojAlgo的SparseStore时,尝试用slice方法截取子矩阵却没得到预期结果的烦恼。其实ojAlgo的矩阵API设计和你预想的slice(a,b,c,d)逻辑不太一样,咱们来梳理下正确的操作方式。
先看你的示例场景:
原矩阵A是3x3的:
MatrixStore<Double> A = SparseStore.FACTORY.rows(new double[][]{{1,2,3},{4,5,6},{7,8,9}});
你想要提取**行1到3(左闭右开,对应原矩阵第2、3行)和列1到3(对应原矩阵第2、3列)**的子矩阵,也就是[[5,6],[8,9]]。
为什么SparseStore的slice方法不适用?
SparseStore的slice方法是针对其内部一维存储结构设计的,并非直接用于二维行列范围的截取,所以用它来实现你的需求自然会出错。
正确的两种实现方式
方式1:用subMatrix结合Range范围(推荐)
ojAlgo的MatrixStore接口提供了subMatrix方法,支持通过Range定义行和列的范围来提取子矩阵,完全匹配你想要的slice(a,b,c,d)逻辑:
// 定义行范围:索引1到3(左闭右开,包含索引1、2的行) Range rowRange = Range.of(1, 3); // 定义列范围:索引1到3(包含索引1、2的列) Range colRange = Range.of(1, 3); // 提取目标子矩阵 MatrixStore<Double> subMatrix = A.subMatrix(rowRange, colRange);
执行后subMatrix就是你期望的[[5,6],[8,9]]。
方式2:分步选择行和列
如果需要更灵活的选择(比如非连续的行/列),可以分步调用rows和columns方法:
// 先选择索引1、2的行 MatrixStore<Double> targetRows = A.rows(1, 2); // 再从这些行中选择索引1、2的列 MatrixStore<Double> subMatrix = targetRows.columns(1, 2);
这种方式也能得到完全一致的结果。
注意事项
- ojAlgo的矩阵索引是从0开始的,所以要注意
Range.of(start, end)是左闭右开的规则,end参数是你想要的最后一个索引+1。 - 不管是
SparseStore还是DenseStore,只要实现了MatrixStore接口,这些方法都适用。
内容的提问来源于stack exchange,提问作者JYY
相关产品推荐
相关产品推荐

