#include "distributionPlusCategory.h" distributionPlusCategory::distributionPlusCategory(const distribution* pBaseDist, MDOUBLE baseDistProb,MDOUBLE categoryVal,MDOUBLE globalRate) : _globalRate(globalRate), _categoryVal(categoryVal), _baseDistProb(baseDistProb) { if (pBaseDist!= NULL) _pBaseDist = pBaseDist->clone(); if ((baseDistProb < 0.0) || (baseDistProb>1.0) ) { errorMsg::reportError("illegal baseDistProb in distributionPlusCategory::distributionPlusCategory"); } } distributionPlusCategory::distributionPlusCategory() : _globalRate(1.0), _pBaseDist(NULL), _categoryVal(1.0), _baseDistProb(0.0) { } distributionPlusCategory::distributionPlusCategory(const distributionPlusCategory& other) { (*this) = other; } distributionPlusCategory& distributionPlusCategory::operator=(const distributionPlusCategory &other) { if (this != &other) { _globalRate = other._globalRate; if (other._pBaseDist) { _pBaseDist = other._pBaseDist->clone(); } else { _pBaseDist = NULL; } _categoryVal = other._categoryVal; _baseDistProb = other._baseDistProb; } return *this; } distributionPlusCategory::~distributionPlusCategory() { if (_pBaseDist) delete _pBaseDist; } const int distributionPlusCategory::categories() const { return _pBaseDist->categories()+1; } const MDOUBLE distributionPlusCategory::rates(const int category) const { if (category < _pBaseDist->categories()) return _pBaseDist->rates(category); else return _categoryVal; } const MDOUBLE distributionPlusCategory::ratesProb(const int category) const { if (category < _pBaseDist->categories()) return _pBaseDist->ratesProb(category) * _baseDistProb; else return (1-_baseDistProb); //category prob } //gets cumulative probability till a certain point const MDOUBLE distributionPlusCategory::getCumulativeProb(const MDOUBLE x) const { MDOUBLE res(0.0); if (x < 0) errorMsg::reportError("x < 0 in distributionPlusCategory::getCumulativeProb()"); if (x > _categoryVal - EPSILON) res += 1-_baseDistProb; res += _baseDistProb * _pBaseDist->getCumulativeProb(x); return res; } void distributionPlusCategory::change_number_of_categories(int in_number_of_categories) { _pBaseDist->change_number_of_categories(in_number_of_categories); } void distributionPlusCategory::setBaseDistProb(MDOUBLE baseDistProb) { if ((baseDistProb < 0.0) || (baseDistProb > 1.0) ) { errorMsg::reportError("illegal baseDistProb in distributionPlusCategory::setBaseDistProb"); } _baseDistProb = baseDistProb; }