获得由向量向量表示的矩阵的第一列 [英] Get the first column of a matrix represented by a vector of vectors
问题描述
假设我使用 std :: vector
表示一个矩阵 foo
:
Suppose I'm representing a matrix foo
of values using std::vector
:
int rows = 5;
int cols = 10;
auto foo = vector<vector<double>>(rows, vector<double>(cols));
有一个聪明的方法让我获得一个向量< int&包含foo的第一个列的 c $
Is there a cleverly simple way for me to get a vector<int>
of size rows
that contains the first "column" of foo:
{foo[0][0], foo[0][1], foo[0][2], foo[0][3], foo[0][4] }
Put another way, can I "transpose" foo so that the following three things are true:
换句话说,我可以转置foo,使以下三个条件成立:
foo_transpose.size() == cols
foo_transpose[0].size() == rows
foo_transpose[0] == {foo[0][0], foo[0][1], foo[0][2], foo[0][3], foo[0][4] }
Clarifying Note
There are a few good suggestions for alternative ways to represent a "matrix". When I use the term "matrix" I simply mean that each of the second level vector
's will be the same size. I don't mean to suggest that I will be using this data structure for linear algebra type operation. I actually DO need a vector of vectors, or a data structure from which you can "pull out" 1D vectors, because I have functions that operate on vectors like:
澄清笔记
表示矩阵。当我使用术语矩阵,我只是意味着每个第二级向量
的将是相同的大小。我不是建议我将使用这种数据结构进行线性代数运算。我实际上需要一个向量的向量或数据结构,从中你可以拉出一维向量,因为我有一些向下操作的函数:
double sum(vector<double> const & v);
That I call by:
我呼叫:
It's just in a special case I came up to a situation that need to do:
只是在特殊情况下,我想到了一个需要做的事情:
sum({foo[0][0], foo[0][1], foo[0][2], foo[0][3], foo[0][4] };
For Loop Solution
There is an obvious for loop solution, but I was looking for something more robust and efficient.
推荐答案
正如我在评论中提到的,使用vector-of-vector表示矩阵是不实际的,原因如下:
As I mentioned in the comments, it's not practical to represent matrices using vector-of-vector for a few reasons:
- 很难改变;
- 缓存位置不好。
这是一个非常简单的类,我已经创建了一个2D矩阵在一个单一的向量。这是怎么软件像MATLAB它的...虽然一个巨大的简单化。
Here is a very simple class I have created that will hold a 2D matrix in a single vector. This is pretty much how software like MATLAB does it... albeit a huge simplification.
template <class T>
class SimpleMatrix
{
public:
SimpleMatrix( int rows, int cols, const T& initVal = T() );
// Size and structure
int NumRows() const { return m_rows; }
int NumColumns() const { return m_cols; }
int NumElements() const { return m_data.size(); }
// Direct vector access and indexing
operator const vector<T>& () const { return m_data; }
int Index( int row, int col ) const { return row * m_cols + col; }
// Get a single value
T & Value( int row, int col ) { return m_data[Index(row,col)]; }
const T & Value( int row, int col ) const { return m_data[Index(row,col)]; }
T & operator[]( size_t idx ) { return m_data[idx]; }
const T & operator[]( size_t idx ) const { return m_data[idx]; }
// Simple row or column slices
vector<T> Row( int row, int colBegin = 0, int colEnd = -1 ) const;
vector<T> Column( int row, int colBegin = 0, int colEnd = -1 ) const;
private:
vector<T> StridedSlice( int start, int length, int stride ) const;
int m_rows;
int m_cols;
vector<T> m_data;
};
这个类基本上是围绕单个函数的糖衣 - StridedSlice
。其实现是:
This class is basically sugar-coating around a single function -- StridedSlice
. The implementation of that is:
template <class T>
vector<T> SimpleMatrix<T>::StridedSlice( int start, int length, int stride ) const
{
vector<T> result;
result.reserve( length );
const T *pos = &m_data[start];
for( int i = 0; i < length; i++ ) {
result.push_back(*pos);
pos += stride;
}
return result;
}
其他很简单:
template <class T>
SimpleMatrix<T>::SimpleMatrix( int rows, int cols, const T& initVal )
: m_data( rows * cols, initVal )
, m_rows( rows )
, m_cols( cols )
{
}
template <class T>
vector<T> SimpleMatrix<T>::Row( int row, int colBegin, int colEnd ) const
{
if( colEnd < 0 ) colEnd = m_cols-1;
if( colBegin <= colEnd )
return StridedSlice( Index(row,colBegin), colEnd-colBegin+1, 1 );
else
return StridedSlice( Index(row,colBegin), colBegin-colEnd+1, -1 );
}
template <class T>
vector<T> SimpleMatrix<T>::Column( int col, int rowBegin, int rowEnd ) const
{
if( rowEnd < 0 ) rowEnd = m_rows-1;
if( rowBegin <= rowEnd )
return StridedSlice( Index(rowBegin,col), rowEnd-rowBegin+1, m_cols );
else
return StridedSlice( Index(rowBegin,col), rowBegin-rowEnd+1, -m_cols );
}
注意行
和列
函数的设置方式使得您可以轻松请求整个行或列,但功能更强大,因为您可以通过传递一个范围或两个以上的参数。是的,您可以通过使开始值大于结束值来返回行/列。
Note that the Row
and Column
functions are set up in such a way that you can easily request an entire row or column, but are a little more powerful because you can slice a range by passing one or two more parameters. And yes, you can return the row/column in reverse by making your start value larger than your end value.
这些函数没有内置的边界检查,但是
There is no bounds-checking built into these functions, but you can easily add that.
您还可以添加一些东西以返回一个区域切片作为另一个 SimpleMatrix< T>
。
You could also add something to return an area slice as another SimpleMatrix<T>
.
有乐趣。
这篇关于获得由向量向量表示的矩阵的第一列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!