| /* ----------------------------------------------------------------------- *//** |
| * |
| * @file Vector.hpp |
| * |
| * @brief MADlib mutable vector class, a thin wrapper around arma::Col or arma::Row |
| * |
| *//* ----------------------------------------------------------------------- */ |
| |
| /** |
| * @brief MADlib mutable matrix class -- a thin wrapper around arma::Col or |
| * arma::Row |
| * |
| * 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<template <class> class T, typename eT> |
| class Vector : public T<eT> { |
| public: |
| inline Vector() |
| : T<eT>( |
| NULL, |
| 0, |
| false /* copy_aux_mem */, |
| true /* strict */), |
| mMemoryHandle() { } |
| |
| inline Vector( |
| AllocatorSPtr inAllocator, |
| const uint32_t inNumElem) |
| : T<eT>( |
| NULL, |
| inNumElem, |
| false /* copy_aux_mem */, |
| true /* strict */), |
| mMemoryHandle( |
| inAllocator->allocateArray( |
| inNumElem, |
| static_cast<eT*>(NULL) /* pure type parameter */)) { |
| |
| arma::access::rw(arma::Mat<eT>::mem) = |
| static_cast<eT*>(mMemoryHandle->ptr()); |
| } |
| |
| inline Vector( |
| const MemHandleSPtr inHandle, |
| const uint32_t inNumElem) |
| : T<eT>( |
| static_cast<eT*>(inHandle->ptr()), |
| inNumElem, |
| false /* copy_aux_mem */, |
| true /* strict */), |
| mMemoryHandle(inHandle) |
| { } |
| |
| inline Vector( |
| const Vector<T, eT> &inVec) |
| : T<eT>( |
| NULL, |
| inVec.n_elem, |
| false /* copy_aux_mem */, |
| true /* strict */), |
| mMemoryHandle( |
| AbstractHandle::cloneIfNotGlobal(inVec.mMemoryHandle)) { |
| |
| arma::access::rw(arma::Mat<eT>::mem) = |
| static_cast<eT*>(mMemoryHandle->ptr()); |
| } |
| |
| inline Vector( |
| const Array<eT> &inArray) |
| : T<eT>( |
| NULL, |
| inArray.size(), |
| false /* copy_aux_mem */, |
| true /* strict */), |
| mMemoryHandle( |
| AbstractHandle::cloneIfNotGlobal(inArray.memoryHandle())) { |
| |
| arma::access::rw(arma::Mat<eT>::mem) = |
| static_cast<eT*>(mMemoryHandle->ptr()); |
| } |
| |
| template<typename T1> |
| inline const Vector &operator=(const arma::Base<eT,T1>& X) { |
| T<eT>::operator=(X.get_ref()); |
| return *this; |
| } |
| |
| inline Vector &rebind(const MemHandleSPtr inHandle, const uint32_t inNumElem) { |
| using arma::access; |
| using arma::Mat; |
| |
| // Unfortunately, C++ does not allow to partially specialize a member |
| // function. (We would need to partially specialize the whole class |
| // template.) For that reason, we use boost::is_same to do the check |
| // at compile time instead of execution time. |
| if (boost::is_same<T<eT>, arma::Col<eT> >::value) |
| access::rw(Mat<eT>::n_rows) = inNumElem; |
| else |
| access::rw(Mat<eT>::n_cols) = inNumElem; |
| |
| access::rw(Mat<eT>::n_elem) = inNumElem; |
| access::rw(Mat<eT>::mem) = static_cast<eT*>(inHandle->ptr()); |
| mMemoryHandle = inHandle; |
| return *this; |
| } |
| |
| inline MemHandleSPtr memoryHandle() const { |
| return mMemoryHandle; |
| } |
| |
| protected: |
| MemHandleSPtr mMemoryHandle; |
| }; |