Esempio n. 1
0
TEST_F(HullTest, IntegrateHullSegments) {
    // covers methods integrateSegment and normalizeHull
    double integral, integral1;
    double result;
    integral = (exp(h_x0 - hull.upper_hull_max - x0 * hp_x0) / hp_x0) * (exp(hp_x0 * z0) - exp(0.0));
    integral = log(integral);
    result = hull.integrateSegment(hull.hull[0], 0.0);
    EXPECT_DOUBLE_EQ(integral, result);
    EXPECT_DOUBLE_EQ(integral, hull.hull[0].raw_integral);
    EXPECT_DOUBLE_EQ(integral, hull.hull[0].raw_cumulative_integral);

    integral1 = (exp(h_x1 - hull.upper_hull_max - x1 * hp_x1) / fabs(hp_x1)) * (exp(hp_x1 * z0));
    integral1 = log(integral1);
    result = hull.integrateSegment(hull.hull[1], hull.hull[0].z);
    EXPECT_DOUBLE_EQ(integral1, result);
    EXPECT_DOUBLE_EQ(integral1, hull.hull[1].raw_integral);
    EXPECT_DOUBLE_EQ(logspaceAdd(integral, integral1), hull.hull[1].raw_cumulative_integral);

    EXPECT_EQ(0.0, hull.hull[1].cum_prob);
    EXPECT_EQ(integral - logspaceAdd(integral, integral1), hull.hull[0].cum_prob);
    double gamma_args[] = {2.0, 2.0};
    hull.initialize(.25, 3.0, gamma_args);
    h_x0 = hull.hull[0].h_x;
    x0 = .25;
    z0 = hull.hull[0].z;
    hp_x0 = hull.hull[0].hprime_x;
    EXPECT_GT(hp_x0, 0.0);
    integral = (exp(h_x0 - hull.upper_hull_max - x0 * hp_x0) / hp_x0) * (exp(hp_x0 * z0) - exp(0.0));
    result = hull.integrateSegment(hull.hull[0], 0.0);
    EXPECT_DOUBLE_EQ(log(integral), result);
}
Esempio n. 2
0
double logspaceAdd(const double loga, const double logb) {
    if (!R_FINITE(loga))
        return logb;
    if (loga > logb)
        return logspaceAdd(logb, loga);
    return logb + log1p(exp(loga - logb));
}
Esempio n. 3
0
/* Primary function for computing the gains/losses of a trait over
 * an entire phylogeny.
 * INPUTS:
 * tree: a PhyTree object
 * n_max: max n for which to compute probability
 * rate_0_to_1, rate_1_to_0: rates of transition between states
 * root_node_prob_0: probability root node is in state 0
 * dist_type: either "prior" or "posterior" is computed
 * gains: if true, gains (0->1) distribution is computed, else losses (1->0)
 *  distribution is computed
 *
 * OUTPUTS:
 * arma::mat of dimension (n_max + 1, 1), whose k-th element
 * is the (prior/posterior) probability of k (gains/losses) over
 * the given phylogeny at the given rates and root distribution.
 */
arma::mat convolveTree(const PhyTree & tree, const int & n_max,
        const double & rate_0_to_1, const double & rate_1_to_0,
        const double & root_node_prob_0, const std::string & dist_type,
        const bool gains) {
    PhyConvolver conv(n_max, tree.getNumNodes(), gains);
    conv.initializeTransdist(tree, dist_type);
    conv.fillQProbs(tree, rate_0_to_1, rate_1_to_0);
    for(int i = 0; i < tree.getNumEdges(); i += 2) {
        conv.fillNodeProbs(i, tree);
    }

    // root node is now a rescaled probability
    const int root_node_idx = tree.getNumTips();
    IntegerVector tip_states_copy(tree.getNumTips());
    for(int i = 0; i < tree.getNumTips(); i++) {
        tip_states_copy[i] = tree.getTipState(i);
    }

    arma::vec arma_root_dist(2);
    arma_root_dist(0) = root_node_prob_0;
    arma_root_dist(1) = 1.0 - root_node_prob_0;

    // get likelihood of tip data if we are computing posterior
    if (dist_type == "posterior") {
        const double post_lik = TwoStatePhyloLikelihood(tree.getEdgeMatrix() + 1,
                tip_states_copy, tree.getBranchLengths(), rate_0_to_1,
                rate_1_to_0, arma_root_dist);
        conv.rescale -= log(post_lik);
    }
    // gather root node vectors
    arma::mat root_dists = conv.getRootDists(root_node_idx);

    // transform output to log scale, rescale, and combine
    root_dists.transform(ip_log());
    root_dists.col(0) += conv.rescale + log(root_node_prob_0);
    root_dists.col(1) += conv.rescale + log(1.0 - root_node_prob_0);

    arma::vec output(n_max + 1);
    for(int i = 0; i < output.n_rows; i++){
        output(i) = logspaceAdd(root_dists(i, 0), root_dists(i, 1));
    }

    return output;
}