转置一个二维向量/矩阵

3

我有以下的二维向量/矩阵 X 和一个向量 Y:

std::vector<double> Y; 
unsigned int ctr=2;
std::vector<std::vector<double> >X(ctr,Y);

我现在想创建X的转置矩阵,即Xtrans,因此将其声明如下:
std::vector<std::vector<double> >Xtrans(Y,ctr);

但是它给我以下编译错误:
test.cpp:128:58: error: no matching function for call to ‘std::vector<std::vector<double> >::vector(std::vector<double>&, unsigned int&)’
/usr/include/c++/4.5/bits/stl_vector.h:241:7: note: candidates are: std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = std::vector<double>, _Alloc = std::allocator<std::vector<double> >, std::vector<_Tp, _Alloc> = std::vector<std::vector<double> >]
/usr/include/c++/4.5/bits/stl_vector.h:227:7: note:                 std::vector<_Tp, _Alloc>::vector(std::vector::size_type, const value_type&, const allocator_type&) [with _Tp = std::vector<double>, _Alloc = std::allocator<std::vector<double> >, std::vector::size_type = unsigned int, value_type = std::vector<double>, allocator_type = std::allocator<std::vector<double> >]
/usr/include/c++/4.5/bits/stl_vector.h:215:7: note:                 std::vector<_Tp, _Alloc>::vector(const allocator_type&) [with _Tp = std::vector<double>, _Alloc = std::allocator<std::vector<double> >, allocator_type = std::allocator<std::vector<double> >]
/usr/include/c++/4.5/bits/stl_vector.h:207:7: note:                 std::vector<_Tp, _Alloc>::vector() [with _Tp = std::vector<double>, _Alloc = std::allocator<std::vector<double> >]

我该如何正确声明Xtrans?

4个回答

2
除了其他人已经提到的修复代码之外,我想评论一下使用vector<vector<double>>作为矩阵表示方式是非常低效的,而且几乎不是你想要的。我的一位同事曾经继承过一个使用这种风格的代码。将其转换为简单的vector<double>并使用适当的索引操作函数,性能提高了三十倍。抵制诱惑。
你可能需要查看一下C++中可用的许多矩阵库之一(例如eigenuBlasmtl4等;还有许多其他选择)。

1

我认为这里有两个问题 - 第一个是您可能误解了std::vector的构造方式,以及当您执行以下操作时的事实:

std::vector<std::vector<double> >Xtrans(Y,ctr); 

它产生了编译器错误,因为没有与您的声明匹配的构造函数。

std::vector 的构造函数之一(即您用来声明 X 的构造函数)声明如下:

explicit vector ( size_type n, const T& value= T(), const Allocator& = Allocator() );

所以当你执行(ctr, Y)时,这很好用 - 因为你告诉编译器你想创建一个大小为ctrstd::vector,其中包含Y的任何值。(在你的情况下,Y是一个空的std::vector<double> - 所以你得到了一个由ctr个条目组成的向量,其中每个条目都是一个空的std::vector<double>)

因此,简单地交换ctrY,希望你能得到一个转置的std::vector,在这里是行不通的。

第二个问题是如何实际转置值。你实际上需要找出一种算法来对X进行转置,然后将这些值推送到Xtrans中。转置值与实际构造向量是不同的事情。最有可能的是,你的算法会像这样 - 构造XTrans,然后迭代'X'并将值插入到XTrans中。


感谢您的解释。为构建 XTrans,我应该将其声明为二维向量并不传递任何参数吗?由于我想要转置 X,所以我是否只需在 X 上编写一个迭代器并将值插入到 XTrans 中即可。 - user1155299
是的,也许可以像你建议的那样开始构建XTrans - 将其声明为一个空的二维向量 - 即大小为ctrstd :: vector <std :: vector <double>> - 就像你为X所做的方式一样。然后遍历X。但请记住它是二维的,因此您有一个外部迭代器,它将迭代ctr个成员 - 但您的成员是std :: vector <double>,(当前为空 - 您刚刚声明了ctr个空的std :: vector <double>),因此您将为每个ctrstd :: vector <double>拥有一个内部迭代器。 - BeeBand
我忘了在迭代X以填充XTrans之前,您需要先用某些内容填充X(或者也许不需要...如果使用迭代器,算法将起作用,只是它什么也不会做 :-)) - BeeBand
你能否提供一些迭代算法的示例代码,假设X已经填充完毕。 - user1155299

0

为了让代码编译通过,你可以将Xtrans声明如下:

std::vector<double> Y;
unsigned int ctr=2;
std::vector<std::vector<double> >X(ctr,Y);
std::vector<double> ctr_vector(2);
std::vector<std::vector<double> >Xtrans(Y.size(),ctr_vector);

然而,您必须填充Xtrans才能将其用作X的转置版本


0

您似乎误解了std::vector的构造函数语法。在这里查看更多信息

调用std::vector<std::vector<double> >X(ctr,Y)会创建ctrY的副本,并将其存储到X中。因此,从根本上讲,X仍然是一个一维对象,只是在X的每个索引处,您会得到另一个std::vector,即Y的副本。

因此,您后面的语法std::vector<std::vector<double> >Xtrans(Y,ctr)不匹配任何类型std::vector的构造函数。您不能像在NumPy或Matlab中那样构造二维数组。

您可能还想看看这个链接。对您来说最好的方法可能是编写自己的转置函数,在循环中手动将条目放入新数组中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接