我使用来自 STL 的 bitset 或来自 boost 的 dynamic_bitset<> 的位表示映射(矩阵行 x 列)(我可以使用任何我想要的)。我需要获得该矩阵的较小尺寸的子矩阵(例如 a(2,2) a(2,3) a(3,2) a(3,3) 大小为 2 )。是否有任何有效的结构来用位表示矩阵并从起始索引和长度获取子矩阵而无需迭代?
最佳答案
可以在矩阵和子矩阵之间有效地共享数据。诀窍是跟踪类(class)中的三个变量。
- 行步幅
- 开始
- 数据
data
需要是一个类似shared_ptr
的结构,以便在您使用完后可以销毁底层数据。 start
将是指向由 data
引用的数据的指针,row_stride
告诉您移动多远才能到达下一行。
您可能想跟踪的其他内容是
- 列步幅(这可以让您将其他有趣的 View 带入矩阵,并有效地支持转置)。
- 行和列的长度 - 这些可以方便地进行调试,或者如果您想使循环和乘法更容易处理。
这是寻找非基于位的方法的方法(我省略了很多……但希望您能理解要点)。
template<typename T>
struct MatrixData
{
T * data;
explicit MatrixData( size_t N ) { new T[N]; }
~MatrixData() { delete [] data; }
private:
MatrixData( const MatrixData & );
MatrixData& operator=( const MatrixData & );
};
template<typename T>
class Matrix
{
Matrix(size_t nni, size_t nnj) :
data( new MatrixData( nni*nnj ) ),
ni(nni),
nj(nnj),
row_stride(ni),
col_stride(1)
{
}
T operator()( size_t i, size_t j)
{
assert( i < ni );
assert( j < nj );
return start + i * col_stride + j * row_stride;
}
Matrix submatrix( size_t i_start, size_t j_start, size_t new_ni, size_t new_nj )
{
assert( i_start + new_ni < ni );
assert( j_start + new_nj < nj );
Matrix retval(*this);
retval.start += i_start * col_stride + j_start * row_stride;
retval.ni = new_ni;
retval.nj = new_nj;
return retval;
}
Matrix transpose()
{
Matrix retval(*this);
std::swap(retval.ni,retval.nj);
std::swap(retval.row_stride,retval.col_stride);
}
private:
shared_ptr<MatrixData> data;
T* start;
size_t ni;
size_t nj;
size_t row_stride;
size_t col_stride;
};
使这项工作适用于基于位的版本将意味着更改 MatrixData
以包含一个基于 bot 的结构,将 start
更改为结构的索引并更改您的 operator()
才能正确访问数据。
关于c++ - 获取尺寸较小的矩阵的子矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11221660/