2012-06-27 107 views
2

我使用来自stl的bitset或来自boost的dynamic_bitset <>(我可以使用任何我想要的)代表位图(矩阵行x列)。我需要得到尺寸较小的矩阵的子矩阵(例如 a(2,2)a(2,3)a(3,2)a(3,3)的大小为2)。有没有任何有效的结构来表示矩阵的位,并获得从startindex和长度的子矩阵,没有迭代?获取更小尺寸的矩阵的子矩阵

+0

与提升范围和切片相同的概念。不确定确切的实施。 –

回答

2

在矩阵和子矩阵之间有效地共享数据是可能的。诀窍是跟踪你班上的三个变量。

  • row_stride
  • 开始
  • 数据

data需要是shared_ptr状结构,使基础数据的,一旦你用它做被破坏。 start将是一个指向data,row_stride引用的数据的指针,告诉你要走多远到达下一行。

你可能想追踪其他事情

  • 柱跨度(这可以让你把其他有趣的观点到矩阵,并支持高效转)。
  • 行和列的长度 - 这些可以方便地进行调试,或者如果你想让你的循环,并乘以更容易处理。

下面是如何寻找一个非基于位的方法(我已经省略了很多..但希望你能得到要点)。

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()正确地访问数据。