C++ 矩阵和向量设计
Posted
技术标签:
【中文标题】C++ 矩阵和向量设计【英文标题】:C++ matrix and vector design 【发布时间】:2013-06-10 21:12:13 【问题描述】:我正在为数值计算制作自定义向量和矩阵类。
我想将矩阵的每一行和每一列都视为一个向量。另外,我不想使用额外的内存,因此,我创建了 VectorView 类,它直接使用矩阵中的数据(如 GSL 库)。这是我的矩阵类的大纲。
class Matrix
priavte:
T data[];
....
public:
VectorView row(int n);
VectorView colum(int n);
;
我定义了一个使用 VectorView 的函数。
myFunc(VectorView& v);
我的 VectorView 类有一些额外的数据,因此我想使用 VectorView 作为参考来节省内存。
但是,当我调用这样的函数时遇到了问题。
Matrix m;
...
...
myFunc(m.row(i));
问题是 m.row(i) 返回临时对象,因此我不能使用引用类型来处理它。但是
auto v = m.row(i);
myFunc(v);
这不会出错,即使它完全相同但使用 v 的原因不清楚。我想使用上面的那个。这类问题有什么绝妙的解决方案吗?
【问题讨论】:
【参考方案1】:row
返回一个右值引用 (VectorView&&
),它不能作为非 const 左值引用 (VectorView&
) 传递。您可以将myFunc
重新定义为myFunc(const VectorView& v)
或myFunc(VectorView&& v)
,具体取决于您的要求和VectorView
的行为。
如果myFunc
需要访问VectorView
的非常量成员,您需要定义后者,这将使用移动语义将row
的返回值传递给myFunc
。但是,由于VectorView
只是原始数据的“视图”,它可能没有(或不需要)任何非常量成员,在这种情况下,您应该使用前者。
【讨论】:
【参考方案2】:使用 valarray 和 gslice
http://www.cplusplus.com/reference/valarray/gslice/
N-D(包括 2D)矩阵是 Bjarne 添加 gslices (AFAIK) 的原因
【讨论】:
【参考方案3】:不要重新发明***并使用 Eigen
eigen.tuxfamily.org
是一个只有头文件的 c++ 矩阵库,具有非常好的支持和性能
【讨论】:
【参考方案4】:猜猜你的矢量视图只包含一个指向原始数据的指针和一个用于步骤的整数(1 表示行,n 表示列)。在这种情况下,将其视为值对象就可以了(只要您确保矩阵的生命周期良好)。所以如果你想要语法,你可以在 myFunc 中使用 value。喜欢:myFunc(VectorView) ...
【讨论】:
【参考方案5】:写两个VectorView
s:VectorView
和ConstVectorView
。第一个包含一个数据切片的视图,一个方法是const
,如果它不改变您正在查看的哪个切片。在VectorView
的const
方法中更改成员是可以的。
ConstVectorView
是一个向量视图,其中更改元素的值是非法的。您可以使用非const
方法更改您正在查看的内容,并且您可以使用const
方法访问要读取的元素。
您应该能够从VectorView
构造ConstVectorView
。
然后,当您返回 VectorView
并将其传递给函数时,该函数应该按值获取它,或者通过 const&
获取它。如果函数不修改其内容,则需要ConstVectorView
。
【讨论】:
【参考方案6】:让您的生活变得简单,并坚持 C 风格的语义(这允许您使用现有的丰富的 C 线性代数代码,以及易于使用的 fortran 代码)。
您声明您担心使用额外的内存,但如果您只是担心并且没有严格的界限,请确保您以行和列格式存储矩阵。这对于从常见矩阵运算中获得任何类型的性能至关重要(因为您一次将使用整个缓存行)。
class Matrix
private:
T rowData[];
T colData[];
...
public:
T const * row(int n) const;
T const * colum(int n) const;
...
;
【讨论】:
以上是关于C++ 矩阵和向量设计的主要内容,如果未能解决你的问题,请参考以下文章