namespace madlib { namespace modules { namespace stats { // Use Eigen using namespace dbal::eigen_integration; // Import names from other MADlib modules using dbal::NoSolutionFoundException; using namespace std; // ------------------------------------------------------------------------- template class CoxPHState { template friend class CoxPHState; public: CoxPHState(const AnyType &inArray) : mStorage(inArray.getAs()) { rebind(static_cast(mStorage[1])); } /** * @brief Convert to backend representation * * We define this function so that we can use TransitionState in the argument * list and as a return type. */ inline operator AnyType() const { return mStorage; } /** * @brief Initialize the transition state. Only called for first row. * * @param inAllocator Allocator for the memory transition state. Must fill * the memory block with zeros. * @param inWidthOfX Number of independent variables. The first row of data * determines the size of the transition state. This size is a quadratic * function of inWidthOfX. */ inline void initialize(const Allocator &inAllocator, uint16_t inWidthOfX, const double * inCoef = 0) { mStorage = inAllocator.allocateArray(arraySize(inWidthOfX)); rebind(inWidthOfX); widthOfX = inWidthOfX; if(inCoef){ for(uint16_t i = 0; i < widthOfX; i++) coef[i] = inCoef[i]; } this->reset(); } /** * @brief We need to support assigning the previous state */ template CoxPHState &operator=( const CoxPHState &inOtherState) { for (size_t i = 0; i < mStorage.size(); i++) mStorage[i] = inOtherState.mStorage[i]; return *this; } /** * @brief Merge with another State object by copying the intra-iteration * fields */ template CoxPHState &operator+=( const CoxPHState &inOtherState) { if (mStorage.size() != inOtherState.mStorage.size() || widthOfX != inOtherState.widthOfX) throw std::logic_error( "Internal error: Incompatible transition states"); numRows += inOtherState.numRows; grad += inOtherState.grad; S += inOtherState.S; H += inOtherState.H; logLikelihood += inOtherState.logLikelihood; V += inOtherState.V; hessian += inOtherState.hessian; return *this; } /** * @brief Reset the inter-iteration fields. */ inline void reset() { numRows = 0; S = 0; tdeath = 0; y_previous = 0; multiplier = 0; H.fill(0); V.fill(0); grad.fill(0); hessian.fill(0); logLikelihood = 0; } private: static inline size_t arraySize(const uint16_t inWidthOfX) { return 7 + 4 * inWidthOfX + 2 * inWidthOfX * inWidthOfX; } void rebind(uint16_t inWidthOfX) { // Inter iteration components numRows.rebind(&mStorage[0]); widthOfX.rebind(&mStorage[1]); multiplier.rebind(&mStorage[2]); y_previous.rebind(&mStorage[3]); coef.rebind(&mStorage[4], inWidthOfX); // Intra iteration components S.rebind(&mStorage[4+inWidthOfX]); H.rebind(&mStorage[5+inWidthOfX], inWidthOfX); grad.rebind(&mStorage[5+2*inWidthOfX],inWidthOfX); logLikelihood.rebind(&mStorage[5+3*inWidthOfX]); V.rebind(&mStorage[6+3*inWidthOfX], inWidthOfX, inWidthOfX); hessian.rebind(&mStorage[6+3*inWidthOfX+inWidthOfX*inWidthOfX], inWidthOfX, inWidthOfX); max_coef.rebind(&mStorage[6 + 3 * inWidthOfX + 2 * inWidthOfX * inWidthOfX], inWidthOfX); tdeath.rebind(&mStorage[6 + 4 * inWidthOfX + 2 * inWidthOfX * inWidthOfX]); } Handle mStorage; public: typename HandleTraits::ReferenceToUInt64 numRows; typename HandleTraits::ReferenceToUInt16 widthOfX; typename HandleTraits::ReferenceToDouble multiplier; typename HandleTraits::ReferenceToDouble y_previous; typename HandleTraits::ColumnVectorTransparentHandleMap coef; typename HandleTraits::ReferenceToDouble S; typename HandleTraits::ColumnVectorTransparentHandleMap H; typename HandleTraits::ColumnVectorTransparentHandleMap grad; typename HandleTraits::ReferenceToDouble logLikelihood; typename HandleTraits::MatrixTransparentHandleMap V; typename HandleTraits::MatrixTransparentHandleMap hessian; typename HandleTraits::ColumnVectorTransparentHandleMap max_coef; typename HandleTraits::ReferenceToDouble tdeath; }; } // namespace stats } // namespace modules } // namespace madlib