In order to split your matrix in situ (that is, without copying it), you want a representation that can handle both the original and the split pieces -- which will make it easier to define recursive algorithms, and so forth:
template <class elt> class MatRef {
elt* m_data;
unsigned m_rows, m_cols;
unsigned m_step;
unsigned index(unsigned row, unsigned col)
{
assert(row < m_rows && col < m_cols);
return m_step * row + col;
}
public: // access
elt& operator() (unsigned row, unsigned col)
{
return m_data[index(row,col)];
}
public: // constructors
MatRef(unsigned rows, unsigned cols, elt* backing) // original matrix
: m_rows(rows)
, m_cols(cols)
, m_step(cols)
, m_data(backing)
{}
MatRef(unsigned start_row, unsigned start_col,
unsigned rows, unsigned cols, MatRef &orig) // sub-matrix
: m_rows(rows)
, m_cols(cols)
, m_step(orig.m_step)
, m_data(orig.m_data + orig.index(start_row, start_col))
{
assert(start_row+rows <= orig.m_rows && start_col+cols <= orig.m_cols);
}
};
The original matrix constructor assumes its backing
argument points to an array of data elements which is at least rows*cols
long, for storing the matrix data. The dimensions of the matrix are defined by data members m_rows
and m_cols
.
Data member m_step
indicates how many data elements there are from the start of one row to the start of the next. For the original matrix, this is the same as m_cols
. Note that the m_cols
of a sub-matrix may be smaller than that of the original matrix it refers to -- that's how a sub-matrix "skips" elements of the original matrix that are not part of the sub-matrix. For this to work properly, m_step
will necessarily be the same as in the original matrix.
Regardless of whether the matrix is skipping elements, data member m_data
always points to the first element of the matrix. The assert()
in the sub-matrix constructor ensures that each new sub-matrix fits inside the matrix it is derived from.
I'm not sure if this counts as an "interesting algorithm", but it is an efficient and convenient way to define and access submatrices.