3

我使用来自 stl 的 bitset 或来自 boost 的 dynamic_bitset<> 用位表示地图(矩阵行 x 列)(我可以使用任何我想要的东西)。我需要获得具有较小尺寸的该矩阵的子矩阵(例如 a(2,2) a(2,3) a(3,2) a(3,3) 尺寸为 2 )。是否有任何有效的结构可以用位表示矩阵并从 startindex 和 length 获取子矩阵而无需迭代?

4

1 回答 1

3

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

  • row_stride
  • 开始
  • 数据

data需要是类似的shared_ptr结构,以便在完成后可以销毁基础数据。start将是指向 引用的数据的指针datarow_stride告诉您要移动多远才能到达下一行。

您可能想要跟踪的其他内容是

  • column 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为保存基于机器人的结构之一,更改start为结构的索引并更改您operator()以正确访问数据。

于 2012-06-27T08:11:36.107 回答