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);
}
Esempio n. 3
0
//---------------------------------------------------------------------------
//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;
  }