blob: 0768281b9cd1621ede01c38cb13df9a4132cc9e9 [file] [log] [blame]
/* ----------------------------------------------------------------------- *//**
*
* @file Matrix.hpp
*
* @brief MADlib mutable matrix class -- a thin wrapper around arma::Mat
*
*//* ----------------------------------------------------------------------- */
/**
* @brief MADlib mutable matrix class -- a thin wrapper around arma::Mat
*
* Armadillo does not provide a public interface to rebind the chunk of memory
* an arma::Mat<eT> object is using. We therefore need this subclass to
* make matrix objects first-class citizen in the C++ DBAL.
*
* @internal Inheritance is not without issues here, and in a future version
* we might want to switch to composition instead of inheritance (in order
* to make it less likely that changes in the superclass break our
* implementation).
*/
template<typename eT>
class Matrix : public arma::Mat<eT> {
public:
inline Matrix()
: arma::Mat<eT>(
NULL,
0,
0,
false /* copy_aux_mem */,
true /* strict */),
mMemoryHandle() { }
inline Matrix(
AllocatorSPtr inAllocator,
const uint32_t inNumRows,
const uint32_t inNumCols)
: arma::Mat<eT>(
NULL,
inNumRows,
inNumCols,
false /* copy_aux_mem */,
true /* strict */),
mMemoryHandle(
inAllocator->allocateArray(
inNumRows * inNumCols,
static_cast<eT*>(NULL) /* pure type parameter */)) {
arma::access::rw(arma::Mat<eT>::mem) = mMemoryHandle->ptr();
}
inline Matrix(
const MemHandleSPtr inHandle,
const uint32_t inNumRows,
const uint32_t inNumCols)
: arma::Mat<eT>(
static_cast<eT*>(inHandle->ptr()),
inNumRows,
inNumCols,
false /* copy_aux_mem */,
true /* strict */),
mMemoryHandle(inHandle)
{ }
inline Matrix(
const Matrix<eT> &inMat)
: arma::Mat<eT>(
NULL,
inMat.n_rows,
inMat.n_cols,
false /* copy_aux_mem */,
true /* strict */),
mMemoryHandle(AbstractHandle::cloneIfNotGlobal(inMat.mMemoryHandle)) {
arma::access::rw(arma::Mat<eT>::mem) = static_cast<eT*>(
mMemoryHandle->ptr());
}
template<typename T1>
inline const Matrix &operator=(const arma::Base<eT,T1>& X) {
using arma::Mat;
Mat<eT>::operator=(X.get_ref());
return *this;
}
/**
* @brief Rebind the array to a different chunk of memory (referred to by a
* memory handle)
*
* @param inHandle the memory handle
* @param inNumRows number of rows after the reallocation
* @param inNumCols number of columns after the reallocation
*/
inline Matrix &rebind(
const MemHandleSPtr inHandle,
const uint32_t inNumRows,
const uint32_t inNumCols) {
using arma::access;
using arma::Mat;
access::rw(Mat<eT>::n_rows) = inNumRows;
access::rw(Mat<eT>::n_cols) = inNumCols;
access::rw(Mat<eT>::n_elem) = inNumRows * inNumCols;
access::rw(Mat<eT>::mem) = static_cast<eT*>(inHandle->ptr());
mMemoryHandle = inHandle;
return *this;
}
inline MemHandleSPtr memoryHandle() const {
return mMemoryHandle;
}
protected:
MemHandleSPtr mMemoryHandle;
};