ribi::BinaryNewickVector ribi::BinaryNewickVector::TermIsNotOne(const int i) const noexcept { assert(m_v[i]>1); std::vector<int> v(m_v); --v[i]; return BinaryNewickVector(v); }
//Does the following conversions: // (5,(5,1)) -> (5,6) // (4,(5,1)) -> (4,6) // (4,(3,1)) -> (4,4) // (4,(1,1)) -> (4,2) // string_pos points at an index in the string current.newick after the '1' // For example, for (4,(3,1)) the string_pos equals 7 // num is the other value between brackets // For example, for (4,(3,1)) num will equal 3 // (5,(5,1)) -> (5,6) // -> sz = 9 // -> bracket_open_pos = 3 // -> bracket_close_pos = 7 // -> sz_loss = 4 = 7 - 3 = bracket_close_pos - bracket_open_pos // -> new_sz = 5 ribi::BinaryNewickVector ribi::BinaryNewickVector::LoseBrackets(const int x, const int i) const noexcept { assert(i >= 0); assert(i < Size()); assert(m_v[i] == 1); assert(x>0); std::vector<int> v_copy = m_v; const int bracket_open_pos = Newick().FindPosBefore(m_v,ribi::Newick::bracket_open,i); assert(bracket_open_pos > -1); const int bracket_close_pos = Newick().FindPosAfter(m_v,Newick::bracket_close,i); assert(bracket_close_pos < Size()); const int sz = Size(); const int sz_lose = bracket_close_pos - bracket_open_pos; const int sz_new = sz - sz_lose; v_copy[bracket_open_pos] = x+1; const std::vector<int>::iterator begin_iter(&v_copy[bracket_close_pos+1]); const std::vector<int>::iterator output_iter(&v_copy[bracket_open_pos+1]); std::copy(begin_iter,v_copy.end(),output_iter); v_copy.resize(sz_new); return BinaryNewickVector(v_copy); }
//--------------------------------------------------------------------------- //Ewensprobability = probability * num_of_combinations const std::string Test::GetEwensProbability() const { const BigInteger n_combinations = Newick::CalcNumOfCombinations( BinaryNewickVector(GetNewick()).Get()); try { const int i = n_combinations.toInt(); const double d = boost::numeric_cast<double>(i); const double ewens_probability = d * GetProbability(); return boost::lexical_cast<std::string>(ewens_probability); } catch (...) { const std::string s = bigIntegerToString(n_combinations) + std::string(" * ") + boost::lexical_cast<std::string>(GetProbability()); return s; } }
//TermIsOne is called whenever a '1' is found in a newick structure //string_pos has the index of the character after this '1' // (when a string has multiple 1's, TermIsOne is called for each '1', // with each time a different string_pos) //If this '1' is between two brackets, with one other number, // these two numbers are added and the brackets are removed //If this '1' is not between two brackets, // the newick string returned is empty //Conversion examples // (3,(15,1)), string_pos 8 -> (3,16) // ^ EXIT1 // (2,(23,1)), string_pos 8 -> (2,24) // ^ EXIT1 // (1,(20,5)), string_pos 2 -> [empty] // ^ EXIT-2 // (1,(1,1)), string_pos 2 -> [empty] // ^ EXIT-2 // (1,(1,1)), string_pos 5 -> (1,2) // ^ EXIT-2 // (1,(1,1)), string_pos 7 -> (1,2) // ^ EXIT-1 // ((1,2,3),3), string_pos 3 -> (3,3) //Might be incorrect: algorithm holds for two numbers between brackets // ^ ribi::BinaryNewickVector ribi::BinaryNewickVector::TermIsOne(const int i) const noexcept { const int sz = m_v.size(); //assert(new_newick.empty()); assert(i < sz); assert(m_v[i] == 1); //Must be a 1 const bool open_bracket_left = IsOpenBracketLeft(i); const bool close_bracket_right = IsCloseBracketRight(i); if (open_bracket_left == true && close_bracket_right == true) { //Find other_value int other_value = 0; //If adjecent to the left is a comma // and subsequently a value, if (i > 0 && m_v[i-1] > 0) { other_value = m_v[i-1]; } else if (i + 1 < sz && m_v[i+1] > 0) { other_value = m_v[i+1]; } assert(other_value >= 1); return LoseBrackets(other_value,i); } //Return an empty SortedBinaryNewickVector return BinaryNewickVector(std::vector<int>()); }
//--------------------------------------------------------------------------- ///ProjectRampalTest is the testing facility of ProjectRampal. ///A newly developed brach of the project can be tested with ///this program in terms of obtaining the right output and speed. ///ProjectRampalTest forbids the use of a release mode, ///because its purpose is to test the code. int main(int argc, char* argv[]) { if (argc == 1) { QApplication a(argc, argv); DialogRampalTest d; d.show(); return a.exec(); } std::cout << GetCurrentFolder(argv[0]) << "/" << argv[0] << " (version 300.0)\n"; #ifdef NDEBUG std::cout << "ProjectTest cannot be run in no-debug mode!\n" << "Please recompile without the NDEBUG #define" << std::endl; return 1; #endif if (argc!=4) { ShowCorrectUse(); return 0; } const std::string argv1 = StrToLower(argv[1]); const std::string argv2 = StrToLower(argv[2]); //Check if the fourth argument is an integer try { boost::lexical_cast<int>(argv[3]); } catch (boost::bad_lexical_cast&) { ShowCorrectUse(); return 1; } const int argv3 = boost::lexical_cast<int>(argv[3]); //Test sanity of input //First parameter: theta { try { boost::lexical_cast<double>(argv1); } //Is it a double? catch(...) { if (argv1!="-m" && argv1!="-r") { ShowCorrectUse(); return 0; } } } //Second parameter: phylogeny { try { BinaryNewickVector n(argv2); } //Is it a newick? catch(...) { if (argv2!="-m" && argv2!="-r" ) { ShowCorrectUse(); return 0; } } } //Third parameter: test { if (argv3 <= 0 || argv3 > 63) { ShowCorrectUse(); return 0; } } //Input is sane RandomizeTimer(); std::ofstream file("Results.txt"); file << "Results of " << argv[0] << " " << argv[1] << " " << argv[2] << " " << argv[3] << "\n"; file.close(); std::cout << std::setprecision(10); while (1) { //Obtain theta //Theta input parameters: // -any positive non-zero value, for example '10.0' // -f: theta values from file 'test_thetas.txt' // -m: manual input of thetas double theta = 0.0; if (argv1 == "-m") { theta = AskUserForTheta(); if (theta==0.0) break; } else if (argv1 == "-r") { theta = GetRandomUniform() * 100.0; } else { theta = boost::lexical_cast<double>(argv1); } //Obtain newick std::string newick; //Input parameters: // -any newick string, for example '(1,(2,3))' // -m: manual input of newick strings // -p: predefined newick strings // -r: random newick strings if (argv2 == "-m") { newick = AskUserForNewick(); if (newick.empty()) break; } else if (argv2 == "-r") { newick = Newick::CreateRandomNewick(7,7); } else { newick = argv2; } std::ofstream file("Results.txt", std::ios_base::app); file << std::setprecision(99); //Create all tests std::vector<boost::shared_ptr<Test> > tests = Test::CreateTests(newick,theta,argv3); //Execute all tests BOOST_FOREACH(boost::shared_ptr<Test> t,tests) { t->Execute(); } //Show test results std::cout << '\n' << "Theta: '" << theta << "'\n" << "Newick: '" << newick << "'\n" << "Number of combinations: " << Newick::CalcNumOfCombinations(BinaryNewickVector(newick).Get()) << "\n\n\n\n\n" << "TestName\t\t\tProbability\tTime\n"; BOOST_FOREACH(boost::shared_ptr<Test> t,tests) { std::cout << t->GetTestName() << "\t" << t->GetProbability() //<< '\t' << t->GetEwensProbability() << '\t' << t->GetTime() << '\n'; file << t->GetTestName() << '\t' << t->GetNewick() << '\t' << t->GetProbability() << '\t' << t->GetEwensProbability() << '\t' << t->GetTime() << '\n'; } //Probably we're done, //except if the user wants to input another value manually if (argv1!="-m" && argv2!="-m") break; }