keb*_*ebs 4 c++ matrix sparse-matrix eigen
我需要一个模板化的稀疏矩阵实现,但只是为了减少内存占用,而不是做任何数值求解.所以我尝试使用Eigen,即使我不需要数学部分.为什么?它碰巧躺在我的机器上,我已经用它来做其他东西了.但我肯定不是本征专家!
背景:我有一个类型T(比如struct T{int a; float b; vector<int> c; };,我需要存储的大型矩阵这个(比如超过1000×1000)和大部分值为null /无关.
由于我没有做任何数学运算,我认为提供存储/检索操作就足以提供存储/检索操作,如下所示:
int main()
{
Eigen::SparseMatrix<MyClass> mat(1000,1000); // 1000000 elements
MyClass b{ 5, 1.2 };
mat.insert( 3, 4 ) = b;
}
Run Code Online (Sandbox Code Playgroud)
所以这是一个数据类型,我认为是必要的:
struct MyClass
{
int a;
float b;
std::vector<int> v_things;
MyClass( int aa, float bb ) : a(aa), b(bb) {}
MyClass( const MyClass& other ) // copy constructor
{
a = other.a;
b = other.b;
v_things = other.v_things;
}
MyClass& operator=( const MyClass& arg )
{
if( this != &arg )
{
MyClass tmp(arg);
std::swap( tmp, *this );
}
return *this;
}
};
Run Code Online (Sandbox Code Playgroud)
但这无法编译,因为它似乎要求一些特殊形式的赋值运算符:
/usr/include/eigen3/Eigen/src/SparseCore/SparseMatrix.h:1146:27: error: no match for ‘operator=’ (operand types are ‘Eigen::internal::CompressedStorage<MyClass, int>::Scalar {aka MyClass}’ and ‘int’)
return (m_data.value(p) = 0);'
Run Code Online (Sandbox Code Playgroud)
(编译器:GCC 5.3,-std = c ++ 11)
问题:
相关的本征手册页:
实际上,由于它被设计为存储数值,因此您的类型应该是可从文字中构造/赋值的0.需要确保insert(i,j)返回对初始化为0的标量的引用.
所以你可以通过添加一个虚拟来解决operator=:
MyClass& operator=(int x) { assert(x==0); /* ... */ return *this; }
Run Code Online (Sandbox Code Playgroud)
编辑:
为了使用setFromTriplets,您还需要提供operator+=.原因是默认情况下,重复的条目汇总在一起.在Eigen 3.3中,传递函子(例如,lambda)以setFromTriplets定义重复应该如何合并更为清晰.在您的情况下,如果调用它,您可以传递一个触发运行时断言的仿函数:
mat.setFromTriplets(begin,end, [] (const MyClass& a,const MyClass &) {
assert(false && "found duplicates"); return a; } );
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您不需要定义 MyClass::operator+=
| 归档时间: |
|
| 查看次数: |
267 次 |
| 最近记录: |