void Alignment::set_parameter(string name, double value) { ParameterList pl; enum class THING{LIKELIHOOD, RATES, MODEL}; // The 'thing' to update after setting parameter THING thing; if (likelihood) { pl = likelihood->getParameters(); thing = THING::LIKELIHOOD; } else if (rates) { pl = rates->getIndependentParameters(); thing = THING::RATES; } else if (model) { pl = model->getIndependentParameters(); thing = THING::MODEL; } else { throw Exception("Could not retrieve parameter list"); } if (pl.hasParameter(name)) { pl.setParameterValue(name, value); switch (thing) { case THING::LIKELIHOOD: likelihood->setParametersValues(pl); break; case THING::RATES: rates->setParametersValues(pl); rates->fireParameterChanged(pl); break; case THING::MODEL: model->setParametersValues(pl); model->fireParameterChanged(pl); break; } } else { throw Exception("Could not find that parameter"); } }
double Alignment::get_parameter(string name) { ParameterList pl; if (likelihood) { pl = likelihood->getParameters(); } else if (rates) { pl = rates->getIndependentParameters(); } else if (model) { pl = model->getIndependentParameters(); } else { throw Exception("Could not retrieve parameter list"); } if (pl.hasParameter(name)) { return pl.getParameterValue(name); } else { throw Exception("Could not find that parameter"); } }
void ThreePointsNumericalDerivative::updateDerivatives(const ParameterList & parameters) throw (ParameterNotFoundException, ConstraintException) { if(computeD1_ && variables_.size() > 0) { if(function1_) function1_->enableFirstOrderDerivatives(false); if(function2_) function2_->enableSecondOrderDerivatives(false); function_->setParameters(parameters); f2_ = function_->getValue(); string lastVar; ParameterList p; for(unsigned int i = 0; i < variables_.size(); i++) { string var = variables_[i]; if (!parameters.hasParameter(var)) continue; if(i > 0) { vector<string> vars(2); vars[0] = var; vars[1] = lastVar; p = parameters.subList(vars); } else { p = parameters.subList(var); } lastVar = var; double value = function_->getParameterValue(var); double h = (1. + std::abs(value)) * h_; //Compute one other point: try { p[0]->setValue(value - h); function_->setParameters(p); //also reset previous parameter... p = p.subList(0); f1_ = function_->getValue(); try { p[0]->setValue(value + h); function_->setParameters(p); f3_ = function_->getValue(); //No limit raised, use central approximation: der1_[i] = (-f1_ + f3_) / (2.*h); der2_[i] = (f1_ -2*f2_ + f3_) / (h*h); } catch(ConstraintException & ce) { //Right limit raised, use backward approximation: p[0]->setValue(value - h); function_->setParameters(p); f1_ = function_->getValue(); p[0]->setValue(value - 2*h); function_->setParameters(p); f3_ = function_->getValue(); der1_[i] = (f2_ - f1_) / h; der2_[i] = (f2_ - 2.*f1_ + f3_) / (h*h); } } catch(ConstraintException & ce) { //Left limit raised, use forward approximation: p[0]->setValue(value + h); function_->setParameters(p); f3_ = function_->getValue(); p[0]->setValue(value + 2*h); function_->setParameters(p); f1_ = function_->getValue(); der1_[i] = (f3_ - f2_) / h; der2_[i] = (f1_ - 2.*f3_ + f2_) / (h*h); } } if(computeCrossD2_) { string lastVar1, lastVar2; for(unsigned int i = 0; i < variables_.size(); i++) { string var1 = variables_[i]; if(!parameters.hasParameter(var1)) continue; for(unsigned int j = 0; j < variables_.size(); j++) { if(j==i) { crossDer2_(i,j) = der2_[i]; continue; } string var2 = variables_[j]; if (!parameters.hasParameter(var2)) continue; vector<string> vars(2); vars[0] = var1; vars[1] = var2; if(i > 0 && j > 0) { if(lastVar1 != var1 && lastVar1 != var2) vars.push_back(lastVar1); if(lastVar2 != var1 && lastVar2 != var2) vars.push_back(lastVar2); } p = parameters.subList(vars); double value1 = function_->getParameterValue(var1); double value2 = function_->getParameterValue(var2); double h1 = (1. + std::abs(value1)) * h_; double h2 = (1. + std::abs(value2)) * h_; //Compute 4 additional points: try { p[0]->setValue(value1 - h1); p[1]->setValue(value2 - h2); function_->setParameters(p); //also reset previous parameter... vector<unsigned int> tmp(2); tmp[0] = 0; tmp[1] = 1; p = p.subList(tmp); //removed the previous parameters. f11_ = function_->getValue(); p[1]->setValue(value2 + h2); function_->setParameters(p.subList(1)); f12_ = function_->getValue(); p[0]->setValue(value1 + h1); function_->setParameters(p.subList(0)); f22_ = function_->getValue(); p[1]->setValue(value2 - h2); function_->setParameters(p.subList(1)); f21_ = function_->getValue(); crossDer2_(i,j) = ((f22_ - f21_) - (f12_ - f11_)) / (4 * h1 * h2); } catch(ConstraintException & ce) { throw Exception("ThreePointsNumericalDerivative::setParameters. Could not compute cross derivatives at limit."); } lastVar1 = var1; lastVar2 = var2; } } } //Reset last parameter and compute analytical derivatives if any. if(function1_) function1_->enableFirstOrderDerivatives(computeD1_); if(function2_) function2_->enableSecondOrderDerivatives(computeD2_); function_->setParameters(parameters.subList(lastVar)); } else { //Reset initial value and compute analytical derivatives if any. if(function1_) function1_->enableFirstOrderDerivatives(computeD1_); if(function2_) function2_->enableSecondOrderDerivatives(computeD2_); function_->setParameters(parameters); //Just in case derivatives are not computed: f2_ = function_->getValue(); } }
void ThreePointsNumericalDerivative::updateDerivatives(const ParameterList parameters) throw (ParameterNotFoundException, ConstraintException) { if (computeD1_ && variables_.size() > 0) { if (function1_) function1_->enableFirstOrderDerivatives(false); if (function2_) function2_->enableSecondOrderDerivatives(false); function_->setParameters(parameters); f2_ = function_->getValue(); if ((abs(f2_) >= NumConstants::VERY_BIG()) || std::isnan(f2_)) { for (size_t i = 0; i < variables_.size(); ++i) { der1_[i] = log(-1); der2_[i] = log(-1); } return; } string lastVar; bool functionChanged = false; ParameterList p; bool start = true; for (size_t i = 0; i < variables_.size(); ++i) { string var = variables_[i]; if (!parameters.hasParameter(var)) continue; if (!start) { vector<string> vars(2); vars[0] = var; vars[1] = lastVar; p = parameters.subList(vars); } else { p = parameters.subList(var); start = false; } lastVar = var; functionChanged = true; double value = function_->getParameterValue(var); double h = -(1. + std::abs(value)) * h_; if (abs(h) < p[0].getPrecision()) h = h < 0 ? -p[0].getPrecision() : p[0].getPrecision(); double hf1(0), hf3(0); unsigned int nbtry = 0; // Compute f1_ while (hf1 == 0) { try { p[0].setValue(value + h); function_->setParameters(p); // also reset previous parameter... p = p.subList(0); f1_ = function_->getValue(); if ((abs(f1_) >= NumConstants::VERY_BIG()) || std::isnan(f1_)) throw ConstraintException("f1_ too large", &p[0], f1_); else hf1 = h; } catch (ConstraintException& ce) { if (++nbtry == 10) // no possibility to compute derivatives break; else if (h < 0) h = -h; // try on the right else h /= -2; // try again on the left with smaller interval } } if (hf1 != 0) { // Compute f3_ if (h < 0) h = -h; // on the right else h /= 2; // on the left with smaller interval nbtry = 0; while (hf3 == 0) { try { p[0].setValue(value + h); function_->setParameters(p); // also reset previous parameter... p = p.subList(0); f3_ = function_->getValue(); if ((abs(f3_) >= NumConstants::VERY_BIG()) || std::isnan(f3_)) throw ConstraintException("f3_ too large", &p[0], f3_); else hf3 = h; } catch (ConstraintException& ce) { if (++nbtry == 10) // no possibility to compute derivatives break; else if (h < 0) h = -h; // try on the right else h /= -2; // try again on the left with smaller interval } } } if (hf3 == 0) { der1_[i] = log(-1); der2_[i] = log(-1); } else { der1_[i] = (f1_ - f3_) / (hf1 - hf3); der2_[i] = ((f1_ - f2_) / hf1 - (f3_ - f2_) / hf3) * 2 / (hf1 - hf3); } } if (computeCrossD2_) { string lastVar1, lastVar2; for (unsigned int i = 0; i < variables_.size(); i++) { string var1 = variables_[i]; if (!parameters.hasParameter(var1)) continue; for (unsigned int j = 0; j < variables_.size(); j++) { if (j == i) { crossDer2_(i, j) = der2_[i]; continue; } string var2 = variables_[j]; if (!parameters.hasParameter(var2)) continue; vector<string> vars(2); vars[0] = var1; vars[1] = var2; if (i > 0 && j > 0) { if (lastVar1 != var1 && lastVar1 != var2) vars.push_back(lastVar1); if (lastVar2 != var1 && lastVar2 != var2) vars.push_back(lastVar2); } p = parameters.subList(vars); double value1 = function_->getParameterValue(var1); double value2 = function_->getParameterValue(var2); double h1 = (1. + std::abs(value1)) * h_; double h2 = (1. + std::abs(value2)) * h_; // Compute 4 additional points: try { p[0].setValue(value1 - h1); p[1].setValue(value2 - h2); function_->setParameters(p); // also reset previous parameter... vector<size_t> tmp(2); tmp[0] = 0; tmp[1] = 1; p = p.subList(tmp); // removed the previous parameters. f11_ = function_->getValue(); p[1].setValue(value2 + h2); function_->setParameters(p.subList(1)); f12_ = function_->getValue(); p[0].setValue(value1 + h1); function_->setParameters(p.subList(0)); f22_ = function_->getValue(); p[1].setValue(value2 - h2); function_->setParameters(p.subList(1)); f21_ = function_->getValue(); crossDer2_(i, j) = ((f22_ - f21_) - (f12_ - f11_)) / (4 * h1 * h2); } catch (ConstraintException& ce) { throw Exception("ThreePointsNumericalDerivative::setParameters. Could not compute cross derivatives at limit."); } lastVar1 = var1; lastVar2 = var2; } } } // Reset last parameter and compute analytical derivatives if any. if (function1_) function1_->enableFirstOrderDerivatives(computeD1_); if (function2_) function2_->enableSecondOrderDerivatives(computeD2_); if (functionChanged) function_->setParameters(parameters.subList(lastVar)); } else { // Reset initial value and compute analytical derivatives if any. if (function1_) function1_->enableFirstOrderDerivatives(computeD1_); if (function2_) function2_->enableSecondOrderDerivatives(computeD2_); function_->setParameters(parameters); // Just in case derivatives are not computed: f2_ = function_->getValue(); } }
void TwoPointsNumericalDerivative::updateDerivatives(const ParameterList parameters) throw (ParameterNotFoundException, ConstraintException) { if (computeD1_ && variables_.size() > 0) { if (function1_) function1_->enableFirstOrderDerivatives(false); if (function2_) function2_->enableSecondOrderDerivatives(false); function_->setParameters(parameters); f1_ = function_->getValue(); string lastVar; bool functionChanged = false; bool start = true; for (unsigned int i = 0; i < variables_.size(); i++) { string var = variables_[i]; if (!parameters.hasParameter(var)) continue; ParameterList p; if (!start) { vector<string> vars(2); vars[0] = var; vars[1] = lastVar; lastVar = var; functionChanged = true; p = parameters.subList(vars); } else { p = parameters.subList(var); lastVar = var; functionChanged = true; start = false; } double value = function_->getParameterValue(var); double h = (1 + std::abs(value)) * h_; // Compute one other point: try { p[0].setValue(value + h); function_->setParameters(p); f2_ = function_->getValue(); } catch (ConstraintException& ce1) { // Right limit raised, use backward approximation: try { p[0].setValue(value - h); function_->setParameters(p); f2_ = function_->getValue(); der1_[i] = (f1_ - f2_) / h; } catch (ConstraintException& ce2) { // PB: can't compute derivative, because of a two narrow interval (lower than h) throw ce2; } } // No limit raised, use forward approximation: der1_[i] = (f2_ - f1_) / h; } // Reset last parameter and compute analytical derivatives if any: if (function1_) function1_->enableFirstOrderDerivatives(computeD1_); if (functionChanged) function_->setParameters(parameters.subList(lastVar)); } else { // Reset initial value and compute analytical derivatives if any. if (function1_) function1_->enableFirstOrderDerivatives(computeD1_); if (function2_) function2_->enableSecondOrderDerivatives(computeD2_); // Just in case derivatives are not computed: function_->setParameters(parameters); f1_ = function_->getValue(); } }
int main(int args, char ** argv) { cout << "******************************************************************" << endl; cout << "* Bio++ Distance Methods, version 2.2.0 *" << endl; cout << "* Author: J. Dutheil Created 05/05/07 *" << endl; cout << "* Last Modif. 04/02/15 *" << endl; cout << "******************************************************************" << endl; cout << endl; if(args == 1) { help(); return 0; } try { BppApplication bppdist(args, argv, "BppDist"); bppdist.startTimer(); Alphabet* alphabet = SequenceApplicationTools::getAlphabet(bppdist.getParams(), "", false); auto_ptr<GeneticCode> gCode; CodonAlphabet* codonAlphabet = dynamic_cast<CodonAlphabet*>(alphabet); if (codonAlphabet) { string codeDesc = ApplicationTools::getStringParameter("genetic_code", bppdist.getParams(), "Standard", "", true, true); ApplicationTools::displayResult("Genetic Code", codeDesc); gCode.reset(SequenceApplicationTools::getGeneticCode(codonAlphabet->getNucleicAlphabet(), codeDesc)); } VectorSiteContainer* allSites = SequenceApplicationTools::getSiteContainer(alphabet, bppdist.getParams()); VectorSiteContainer* sites = SequenceApplicationTools::getSitesToAnalyse(* allSites, bppdist.getParams()); delete allSites; ApplicationTools::displayResult("Number of sequences", TextTools::toString(sites->getNumberOfSequences())); ApplicationTools::displayResult("Number of sites", TextTools::toString(sites->getNumberOfSites())); SubstitutionModel* model = PhylogeneticsApplicationTools::getSubstitutionModel(alphabet, gCode.get(), sites, bppdist.getParams()); DiscreteDistribution* rDist = 0; if (model->getNumberOfStates() > model->getAlphabet()->getSize()) { //Markov-modulated Markov model! rDist = new ConstantRateDistribution(); } else { rDist = PhylogeneticsApplicationTools::getRateDistribution(bppdist.getParams()); } DistanceEstimation distEstimation(model, rDist, sites, 1, false); string method = ApplicationTools::getStringParameter("method", bppdist.getParams(), "nj"); ApplicationTools::displayResult("Tree reconstruction method", method); TreeTemplate<Node>* tree; AgglomerativeDistanceMethod* distMethod = 0; if(method == "wpgma") { PGMA* wpgma = new PGMA(true); distMethod = wpgma; } else if(method == "upgma") { PGMA* upgma = new PGMA(false); distMethod = upgma; } else if(method == "nj") { NeighborJoining* nj = new NeighborJoining(); nj->outputPositiveLengths(true); distMethod = nj; } else if(method == "bionj") { BioNJ* bionj = new BioNJ(); bionj->outputPositiveLengths(true); distMethod = bionj; } else throw Exception("Unknown tree reconstruction method."); string type = ApplicationTools::getStringParameter("optimization.method", bppdist.getParams(), "init"); ApplicationTools::displayResult("Model parameters estimation method", type); if (type == "init") type = OptimizationTools::DISTANCEMETHOD_INIT; else if (type == "pairwise") type = OptimizationTools::DISTANCEMETHOD_PAIRWISE; else if (type == "iterations") type = OptimizationTools::DISTANCEMETHOD_ITERATIONS; else throw Exception("Unknown parameter estimation procedure '" + type + "'."); unsigned int optVerbose = ApplicationTools::getParameter<unsigned int>("optimization.verbose", bppdist.getParams(), 2); string mhPath = ApplicationTools::getAFilePath("optimization.message_handler", bppdist.getParams(), false, false); OutputStream* messenger = (mhPath == "none") ? 0 : (mhPath == "std") ? ApplicationTools::message : new StlOutputStream(new ofstream(mhPath.c_str(), ios::out)); ApplicationTools::displayResult("Message handler", mhPath); string prPath = ApplicationTools::getAFilePath("optimization.profiler", bppdist.getParams(), false, false); OutputStream* profiler = (prPath == "none") ? 0 : (prPath == "std") ? ApplicationTools::message : new StlOutputStream(new ofstream(prPath.c_str(), ios::out)); if(profiler) profiler->setPrecision(20); ApplicationTools::displayResult("Profiler", prPath); // Should I ignore some parameters? ParameterList allParameters = model->getParameters(); allParameters.addParameters(rDist->getParameters()); ParameterList parametersToIgnore; string paramListDesc = ApplicationTools::getStringParameter("optimization.ignore_parameter", bppdist.getParams(), "", "", true, false); bool ignoreBrLen = false; StringTokenizer st(paramListDesc, ","); while (st.hasMoreToken()) { try { string param = st.nextToken(); if (param == "BrLen") ignoreBrLen = true; else { if (allParameters.hasParameter(param)) { Parameter* p = &allParameters.getParameter(param); parametersToIgnore.addParameter(*p); } else ApplicationTools::displayWarning("Parameter '" + param + "' not found."); } } catch (ParameterNotFoundException& pnfe) { ApplicationTools::displayError("Parameter '" + pnfe.getParameter() + "' not found, and so can't be ignored!"); } } unsigned int nbEvalMax = ApplicationTools::getParameter<unsigned int>("optimization.max_number_f_eval", bppdist.getParams(), 1000000); ApplicationTools::displayResult("Max # ML evaluations", TextTools::toString(nbEvalMax)); double tolerance = ApplicationTools::getDoubleParameter("optimization.tolerance", bppdist.getParams(), .000001); ApplicationTools::displayResult("Tolerance", TextTools::toString(tolerance)); //Here it is: ofstream warn("warnings", ios::out); ApplicationTools::warning = new StlOutputStreamWrapper(&warn); tree = OptimizationTools::buildDistanceTree(distEstimation, *distMethod, parametersToIgnore, !ignoreBrLen, type, tolerance, nbEvalMax, profiler, messenger, optVerbose); warn.close(); delete ApplicationTools::warning; ApplicationTools::warning = ApplicationTools::message; string matrixPath = ApplicationTools::getAFilePath("output.matrix.file", bppdist.getParams(), false, false, "", false); if (matrixPath != "none") { ApplicationTools::displayResult("Output matrix file", matrixPath); string matrixFormat = ApplicationTools::getAFilePath("output.matrix.format", bppdist.getParams(), false, false, "", false); string format = ""; bool extended = false; std::map<std::string, std::string> unparsedArguments_; KeyvalTools::parseProcedure(matrixFormat, format, unparsedArguments_); if (unparsedArguments_.find("type") != unparsedArguments_.end()) { if (unparsedArguments_["type"] == "extended") { extended = true; } else if (unparsedArguments_["type"] == "classic") extended = false; else ApplicationTools::displayWarning("Argument '" + unparsedArguments_["type"] + "' for parameter 'Phylip#type' is unknown. " + "Default used instead: not extended."); } else ApplicationTools::displayWarning("Argument 'Phylip#type' not found. Default used instead: not extended."); ODistanceMatrix* odm = IODistanceMatrixFactory().createWriter(IODistanceMatrixFactory::PHYLIP_FORMAT, extended); odm->write(*distEstimation.getMatrix(), matrixPath, true); delete odm; } PhylogeneticsApplicationTools::writeTree(*tree, bppdist.getParams()); //Output some parameters: if (type == OptimizationTools::DISTANCEMETHOD_ITERATIONS) { // Write parameters to screen: ParameterList parameters = model->getParameters(); for (unsigned int i = 0; i < parameters.size(); i++) { ApplicationTools::displayResult(parameters[i].getName(), TextTools::toString(parameters[i].getValue())); } parameters = rDist->getParameters(); for (unsigned int i = 0; i < parameters.size(); i++) { ApplicationTools::displayResult(parameters[i].getName(), TextTools::toString(parameters[i].getValue())); } // Write parameters to file: string parametersFile = ApplicationTools::getAFilePath("output.estimates", bppdist.getParams(), false, false); if (parametersFile != "none") { ofstream out(parametersFile.c_str(), ios::out); parameters = model->getParameters(); for (unsigned int i = 0; i < parameters.size(); i++) { out << parameters[i].getName() << " = " << parameters[i].getValue() << endl; } parameters = rDist->getParameters(); for (unsigned int i = 0; i < parameters.size(); i++) { out << parameters[i].getName() << " = " << parameters[i].getValue() << endl; } out.close(); } } //Bootstrap: unsigned int nbBS = ApplicationTools::getParameter<unsigned int>("bootstrap.number", bppdist.getParams(), 0); if(nbBS > 0) { ApplicationTools::displayResult("Number of bootstrap samples", TextTools::toString(nbBS)); bool approx = ApplicationTools::getBooleanParameter("bootstrap.approximate", bppdist.getParams(), true); ApplicationTools::displayResult("Use approximate bootstrap", TextTools::toString(approx ? "yes" : "no")); if(approx) { type = OptimizationTools::DISTANCEMETHOD_INIT; parametersToIgnore = allParameters; ignoreBrLen = true; } bool bootstrapVerbose = ApplicationTools::getBooleanParameter("bootstrap.verbose", bppdist.getParams(), false, "", true, false); string bsTreesPath = ApplicationTools::getAFilePath("bootstrap.output.file", bppdist.getParams(), false, false); ofstream *out = NULL; if(bsTreesPath != "none") { ApplicationTools::displayResult("Bootstrap trees stored in file", bsTreesPath); out = new ofstream(bsTreesPath.c_str(), ios::out); } Newick newick; vector<Tree *> bsTrees(nbBS); ApplicationTools::displayTask("Bootstrapping", true); for(unsigned int i = 0; i < nbBS; i++) { ApplicationTools::displayGauge(i, nbBS-1, '='); VectorSiteContainer * sample = SiteContainerTools::bootstrapSites(*sites); if(approx) model->setFreqFromData(*sample); distEstimation.setData(sample); bsTrees[i] = OptimizationTools::buildDistanceTree( distEstimation, *distMethod, parametersToIgnore, ignoreBrLen, type, tolerance, nbEvalMax, NULL, NULL, (bootstrapVerbose ? 1 : 0) ); if(out && i == 0) newick.write(*bsTrees[i], bsTreesPath, true); if(out && i > 0) newick.write(*bsTrees[i], bsTreesPath, false); delete sample; } if(out) out->close(); if(out) delete out; ApplicationTools::displayTaskDone(); ApplicationTools::displayTask("Compute bootstrap values"); TreeTools::computeBootstrapValues(*tree, bsTrees); ApplicationTools::displayTaskDone(); for(unsigned int i = 0; i < nbBS; i++) delete bsTrees[i]; //Write resulting tree: PhylogeneticsApplicationTools::writeTree(*tree, bppdist.getParams()); } delete alphabet; delete sites; delete distMethod; delete tree; bppdist.done();} catch(exception & e) { cout << e.what() << endl; return 1; } return 0; }