获得较小尺寸的矩阵子矩阵

时间:2012-06-27 07:51:28

标签: c++ algorithm boost stl

我使用来自stl或dynamic_bitset<>的bitset来表示具有位的映射(矩阵行x列)来自提升(我可以使用我想要的任何东西)。我需要获得更小尺寸的矩阵的子矩阵(例如 a(2,2)a(2,3)a(3,2)a(3,3)的大小为2)。是否有任何有效的结构用于表示具有位的矩阵并从startindex和长度获得子矩阵而不进行迭代?

1 个答案:

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