获取由vector向量表示的matrix的第一列
假设我使用std::vector
来表示值的matrixfoo
:
int rows = 5; int cols = 10; auto foo = vector<vector<double>>(rows, vector<double>(cols));
是否有一个简单的方法来获取包含foo的第一个“列”的大小rows
的vector<int>
:
{foo[0][0], foo[0][1], foo[0][2], foo[0][3], foo[0][4] }
换句话说,我可以“转置”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] }
澄清笔记
对于代表“matrix”的替代方法,有几个好的build议。 当我使用术语“matrix”时,我只是指每个第二级vector
的大小相同。 我不是说我会用这个数据结构来进行线性代数types的操作。 实际上,我需要一个vectorvector或一个数据结构,从中可以“拉出”一维vector,因为我有一些function可以对vector进行操作,例如:
double sum(vector<double> const & v);
我打电话给:
sum(foo[0]);
只是在特殊情况下,我想到了一个需要做的事情:
sum({foo[0][0], foo[0][1], foo[0][2], foo[0][3], foo[0][4] };
For Loop解决scheme
有一个明显的for循环解决scheme,但我正在寻找更强大和有效的东西。
正如我在评论中提到的那样,使用vector-of-vector来表示matrix是不现实的,原因如下:
- build立起来很麻烦;
- 很难改变;
- caching局部性不好。
这是我创build的一个非常简单的类,它将在一个vector中保存一个2Dmatrix。 这几乎是像MATLAB这样的软件做的…虽然是一个巨大的简化。
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; };
这个课程基本上是围绕一个单独的functionStridedSlice
。 执行的是:
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 ); }
请注意, Row
和Column
函数的设置方式使您可以轻松地请求整行或列,但function稍强一些,因为您可以通过传递一个或多个参数来分割一个范围。 是的,您可以通过使您的起始值大于您的最终值来反向返回行/列。
这些函数中没有内置检查,但可以轻松添加。
你也可以添加一些返回一个区域切片作为另一个SimpleMatrix<T>
。
玩的开心。