/working/auteur.extended/src/ouweights.cpp

http://github.com/eastman/auteur · C++ · 102 lines · 75 code · 14 blank · 13 comment · 8 complexity · 419f668696119b6e2e618005e2a9e120 MD5 · raw file

  1. #include <Rcpp.h>
  2. #include <vector>
  3. /* internal C++: computes the contribution of each ancestral edge for a species to the weights matrix */
  4. void process_epochs ( std::vector<double> const &epochs,
  5. double const &alphasq,
  6. std::vector<double> &y )
  7. {
  8. int i, np = epochs.size();
  9. double t;
  10. for (i = 0; i < np; i++) {
  11. t = epochs[0]-epochs[i];
  12. y.push_back( exp(-alphasq*t) );
  13. }
  14. for (i = 0; i < np-1; i++) {
  15. y[i] -= y[i+1];
  16. }
  17. }
  18. /* internal C++: builds a binary array for each species, signifying in which selective regime the ancestor of the species is bounded */
  19. void process_beta ( std::vector<int> &beta,
  20. std::vector<int> const &ancestors,
  21. std::vector<double> const &regimes,
  22. std::vector<double> const &optima )
  23. {
  24. int np, r, k, nreg=optima.size();
  25. np=ancestors.size();
  26. beta.assign(np*nreg, 0);
  27. for(r=0; r<np; r++) {
  28. for(k=0; k<nreg; k++){
  29. if(regimes.at( ancestors.at(r)-1 )==optima.at(k))
  30. {
  31. beta.at(r+k*np)=1;
  32. }
  33. }
  34. }
  35. }
  36. /* C++ | R INTERFACE; main function */
  37. RcppExport SEXP ouweights ( SEXP PHYLO )
  38. {
  39. /*
  40. * PHYLO:
  41. * - epochs: list of branching times for each segment from tip to root [T=t1>t2>...>troot=0] for each species
  42. * - ancestors: list of nodes from tip to root for each species
  43. * - regimes: array of optima associated with each edge; order from node 1 to node 2N-2
  44. * - optima: array of unique selective regimes across the tree
  45. * - alpha: constraint factor for the Ornstein-Uhlenbeck process; herein, alpha is expected given as alpha^2
  46. * - tips: number of species in tree
  47. */
  48. try {
  49. Rcpp::List phylo(PHYLO);
  50. Rcpp::List epochs = phylo["epochs"];
  51. Rcpp::List ancestors = phylo["ancestors"];
  52. std::vector<double> regimes = phylo["regimes"];
  53. std::vector<double> optima = phylo["optima"];
  54. double alphasq = Rcpp::as<double> ( phylo["alpha"] );
  55. int ntip = Rcpp::as<int> ( phylo["tips"] );
  56. int nreg = optima.size();
  57. int t, r, q;
  58. int segments;
  59. std::vector<double> y;
  60. std::vector<double> W;
  61. W.assign(ntip*nreg,0);
  62. std::vector<int> tbeta;
  63. for(t=0; t<ntip; t++) {
  64. std::vector<int> tancestors=ancestors[t];
  65. process_beta(tbeta, tancestors, regimes, optima);
  66. std::vector<double> tepochs=epochs[t];
  67. segments=tepochs.size();
  68. y.reserve(segments);
  69. process_epochs(tepochs, alphasq, y);
  70. for(r=0; r<nreg; r++) {
  71. for(q=0; q<segments; q++) {
  72. W[t+r*ntip] += y[q]*tbeta[q+r*segments];
  73. }
  74. }
  75. std::vector<double>().swap(y);
  76. std::vector<double>().swap(tepochs);
  77. std::vector<int>().swap(tancestors);
  78. std::vector<int>().swap(tbeta);
  79. }
  80. /* PREPARE OUTPUT FOR R */
  81. return Rcpp::List::create(Rcpp::Named("weights", W));
  82. } catch( std::exception &ex ) {
  83. forward_exception_to_r( ex );
  84. } catch(...) {
  85. ::Rf_error( "c++ exception (unknown reason)" );
  86. }
  87. return R_NilValue;
  88. }