#include "optGammaMixtureLS.h" #include "likelihoodComputation.h" #include "numRec.h" //#include "optimizer.h" //#include "NRconjugateGradient.h" #include #include #include using namespace std; using namespace likelihoodComputation; optGammaMixtureLS::optGammaMixtureLS(stochasticProcess* pSp, const sequenceContainer& sc, const tree& inTree, MDOUBLE upperBoundAlpha/*=15.0*/, MDOUBLE upperBoundBeta/*=15.0*/,unObservableData* unObservableData_p) { _pSc = ≻ _pTree = &inTree; _pSp = pSp; _upperBoundAlpha = upperBoundAlpha; _upperBoundBeta = upperBoundBeta; _unObservableData_p = unObservableData_p; } optGammaMixtureLS::~optGammaMixtureLS() { } MDOUBLE optGammaMixtureLS::optimizeParam(const int maxIterations, const MDOUBLE tol, const Vdouble * pWeights, optAlg optType) { mixtureDistribution * pMixture = static_cast(_pSp->distr()); return optimizeParam(pMixture, maxIterations, tol, pWeights, optType); } MDOUBLE optGammaMixtureLS::optimizeParam(mixtureDistribution * pMixture, const int maxIterations, const MDOUBLE tol, const Vdouble * pWeights, optAlg optType) { switch (optType) { case ONE_DIM: return optimizeParamOneDim(pMixture, maxIterations, tol, pWeights); break; //case POWELL: // return optimizeParamPowell(pMixture, maxIterations, tol, pWeights, pOutF); // break; //case CONJUGATE_DERIVATIVES: // return optimizeParamConjugateDeriv(pMixture, maxIterations, tol, pWeights, pOutF); // break; default: errorMsg::reportError("unknown optimization algorithm in optGammaMixtureLS::optimizeParam()"); return -1; } } //this function finds the best mixture param using a line search maximization. Each time only one parameter is optimized using the regular brent algorithm. //CAN BE USED FOR 2 COMPONENTS ONLY (the maximization on components probabilities maximize only P1, the prob of the first component, while the prob of the second is set to 1-P1) // ...Note: if more than 2 components, all the others are scaled by P1 //total there are 5 parameters to optimize: alpha1, beta1, alpha2, beta2, and P1 MDOUBLE optGammaMixtureLS::optimizeParamOneDim(mixtureDistribution * pMixture, const int maxIterations, const MDOUBLE tol, const Vdouble * pWeights) { MDOUBLE lowerBound = 0.0; MDOUBLE newL = VERYSMALL; //newL is the LL after a single param optimization. //MDOUBLE curL = VERYSMALL; //the current LL. MDOUBLE curL = likelihoodComputation::getTreeLikelihoodAllPosAlphTheSame(*_pTree,*_pSc,*_pSp,pWeights,_unObservableData_p); //the current LL. MDOUBLE prevIterL = VERYSMALL; //The LL of the previous iteration. the loop quit if the increase in LL between iterations is smaller than tol MDOUBLE bestA=0, bestB=0, bestW = 0; for (int it = 0; it < maxIterations; ++it) { //prevIterL = newL; prevIterL = curL; for (int comp = 0; comp < pMixture->getComponentsNum(); ++comp) { //optimize alpha MDOUBLE oldAlpha = pMixture->getAlpha(comp); newL = -brent(lowerBound,oldAlpha, _upperBoundAlpha, C_evalAlphaMixture(*_pTree,*_pSc,_pSp,comp,pWeights,_unObservableData_p), tol, &bestA); if (newL < curL) { //the Likelihood wend down pMixture->setAlpha(oldAlpha, comp); if(_unObservableData_p){ _unObservableData_p->setLforMissingData(*_pTree,_pSp); } LOG(5, <<"likelihood went down in optGammaMixtureLS::optimizeParam()"<getComponentsNum(); ++comp) { pMixture->setAlpha(param[paramNum++], comp); pMixture->setBeta(param[paramNum++], comp); pMixture->setComponentWeight(param[paramNum++], comp); } pMixture->normalizeProbabilities(); if (pOutF != NULL) { *pOutF <