特征:比较两个稀疏矩阵,其稀疏性模式可能不同
Eigen: Compare two sparse matrix with probably different sparsity pattern
我想比较两个Eigen::SparseMatrix
存在res.isApprox(ans)
方法,但不幸的是,据我所知,在不同的稀疏性模式的情况下,它因断言而失败
AffineInvariantDeformerTest01: Eigen/src/SparseCore/SparseMatrix.h:934: void Eigen::internal::set_from_triplets(const InputIterator&, const InputIterator&, SparseMatrixType&, DupFunctor) [with InputIterator = __gnu_cxx::__normal_iterator<Eigen::Triplet<double, int>*, std::vector<Eigen::Triplet<double, int>, std::allocator<Eigen::Triplet<double, int> > > >; SparseMatrixType = Eigen::SparseMatrix<double, 0, int>; DupFunctor = Eigen::internal::scalar_sum_op<double, double>]: Assertion `it->row()>=0 && it->row()<mat.rows() && it->col()>=0 && it->col()<mat.cols()' failed.
我希望它用于单元测试,所以如果它不会那么快也没关系。也许我可以将我的稀疏矩阵转换为密集矩阵,但我希望存在更优雅的解决方案
编辑:只是一种可以比较两个矩阵的稀疏模式的方法对我来说也可以
首先,即使使用不同的稀疏模式,isApprox()
也能正常工作。看起来您的错误在其他地方(当您使用 setFromTriplets()
设置矩阵时可能已经存在(
当给定两个具有不同稀疏模式的矩阵时,如果不同的条目(几乎(为零,则它们将被视为近似相等。以下应计算true
两次(增加1e-19
以查看差异(:
#include <Eigen/SparseCore>
#include <iostream>
#include <array>
int main() {
Eigen::SparseMatrix<double> Mat1(2,2), Mat2(2,2);
std::array<Eigen::Triplet<double,int>, 2> data1 {{{0,0,1.0}, {1,1, 1e-19}}};
std::array<Eigen::Triplet<double,int>, 2> data2 {{{0,0,1.0}, {1,0, 1e-19}}};
Mat1.setFromTriplets(data1.begin(), data1.end());
Mat2.setFromTriplets(data2.begin(), data2.end());
std::cout << "Mat1.isApprox(Mat1) == " << Mat1.isApprox(Mat1) << "nMat1.isApprox(Mat2) == " << Mat1.isApprox(Mat2) << "n";
}
如果要比较稀疏模式,可以从内部和外部索引指针开始检查数据(对两者都使用 Map(。如果两个矩阵具有相同的类型并被压缩,则以下内容有效:
template<class Derived>
bool hasSamePattern(Eigen::SparseCompressedBase<Derived> const& A, Eigen::SparseCompressedBase<Derived> const& B)
{
assert(A.isCompressed() && B.isCompressed());
if(A.rows() != B.rows() || A.cols() != B.cols() || A.nonZeros() != B.nonZeros())
return false;
typedef Eigen::Matrix<typename Derived::StorageIndex, Eigen::Dynamic, 1> IndexVector;
Eigen::Index outerSize = A.outerSize(), nnz = A.nonZeros();
if(IndexVector::Map(A.outerIndexPtr(), outerSize) != IndexVector::Map(B.outerIndexPtr(), outerSize))
return false;
if(IndexVector::Map(A.innerIndexPtr(), nnz) != IndexVector::Map(B.innerIndexPtr(), nnz))
return false;
return true;
}
相关文章:
- 如何在C++中从两个单独的for循环中添加两个数组
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 如何返回一个类的两个对象相加的结果
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 两个字符串在 c++ 中不相等
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 两个文件使用彼此的功能-如何解决
- 特征:比较两个稀疏矩阵,其稀疏性模式可能不同
- 分配两个双精度值,保证产生相同的位集模式
- 将两个uint32_t转换为uint64_t,然后根据位模式而不是值变回双精度
- 两个附带的类层次结构-一个好的设计模式
- 两个相同的函数(一个使用模板模式,另一个不使用)
- 在附加模式下使用来自两个不同进程的流
- 在Event Sourcing模式中,您是否有两个不同的类来读取和写入事件?
- 在or条件语句中是否存在强制对两个表达式求值的模式或技巧?
- 为什么我得到两个不同的结果,而使用sregex_iterator与regex变量模式vs构造模式
- 设计模式-如何在C++中组合共享同一基类的两个类
- Qt:如何在大小写不敏感模式下减去QString的两个QSet