// Extracts the inverted covariance matrix for a given branch from the full covariance matrix. void branch_inverted_covariance_matrix(Model &Mod, Array2 &Covfull, long b, Array2 &Covbri) { long i,j; ublas::matrix<double> CC(Mod.df, Mod.df); ublas::matrix<double> II(Mod.df, Mod.df); for(i=0; i < Mod.df; i++) { for(j=0; j< Mod.df; j++) { CC(i,j) = Covfull[Mod.df*b + i][Mod.df*b + j]; } } bool res = matrix_inverse(CC, II); if (!res) { throw std::out_of_range( "Could not invert the Covariance matrix." ); } Covbri.resize(Mod.df); for(i=0; i < Mod.df; i++) { Covbri[i].resize(Mod.df); for(j=0; j< Mod.df; j++) { Covbri[i][j] = II(i,j); } } }
// Computes the full covariance matrix for the MLE, using observed Fisher info. void full_MLE_observed_covariance_matrix(Tree &T, Model &Mod, Parameters &Par, Counts &data, Array2 &Cov) { long i, j; long npars = Mod.df*T.nedges + Mod.rdf; ublas::matrix<double> CC(npars, npars); ublas::matrix<double> II(npars, npars); Array2 I; Observed_Fisher_information(T, Mod, Par, data, I); // Need to convert from Matrix to ublas::matrix<double> for(i=0; i < npars; i++) { for(j=0; j < npars; j++) { II(i, j) = I[i][j]; } } bool res = matrix_inverse(II, CC); if (!res) { throw std::out_of_range("Could not invert the Fisher information matrix."); } Cov.resize(npars); for(i=0; i < npars; i++) { Cov[i].resize(npars); for(j=0; j < npars; j++) { Cov[i][j] = CC(i,j); } } }
// Extracts the covariance matrix for a given branch from the full covariance matrix. void branch_covariance_matrix(Model &Mod, Array2 &Covfull, long b, Array2 &Covbr) { long i,j; Covbr.resize(Mod.df); for(i=0; i < Mod.df; i++) { Covbr[i].resize(Mod.df); for(j=0; j< Mod.df; j++) { Covbr[i][j] = Covfull[Mod.df*b + i][Mod.df*b + j]; } } }
void fill_pcond1(Tree &T, Model &Mod, StateList &sl, Parameters &Par, Array2 &pcond1) { long i,j,l,u,v; long k,e,a,b; double p; long npars = T.nedges*Mod.np + Mod.rdf + 1; // Initializations pcond1.resize(T.nstleaves); for (i=0; i < T.nstleaves; i++) { pcond1[i].resize(npars); for(k=0; k < npars; k++) { pcond1[i][k] = 0; } } // Loop over all states for (i=0; i < T.nstleaves; i++) { for(j=0; j < T.nsthidden; j++) { // Loop over edges for(e=0; e < T.nedges; e++) { // Compute cond1 probabilities p = Par.r[rootstate(sl.h[j])]; for(l=0; l < T.nedges; l++) { if (l == e) continue; edgestate(T, l, sl.h[j], sl.l[i], u, v); p = p*Par.tm[l][u][v]; } edgestate(T, e, sl.h[j], sl.l[i], a, b); k = erc2param(Mod, e, a, b); pcond1[i][k] = pcond1[i][k] + p; } // Take care of root parameters in pcond1 p = 1; for(l=0; l < T.nedges; l++) { edgestate(T, l, sl.h[j], sl.l[i], u, v); p = p*Par.tm[l][u][v]; } k = root2param(T, Mod, rootstate(sl.h[j])); pcond1[i][k] = pcond1[i][k] + p; } } }
void Fisher_information_free(Tree &T, Model &Mod, Array2 &Imod, Array2 &Ifree) { long i, j, e, p, l; long l1, l2; long nfreepar = Mod.df*T.nedges + Mod.rdf; long nmodpar = Mod.np*T.nedges + Mod.rdf + 1; Ifree.resize(nfreepar); for(i=0; i < nfreepar; i++) { Ifree[i].resize(nfreepar); for(j=0; j < nfreepar; j++) { Ifree[i][j] = 0; } } // Counts the number of times a parameter appears in the the transition matrices and root dist. std::vector<double> coeff; coeff.resize(nmodpar); for(i=0; i < nmodpar; i++) { coeff[i] = 0; } for(e=0; e < T.nedges; e++) { for(i=0; i < T.nalpha; i++) { for(j=0; j < T.nalpha; j++) { p = erc2param(Mod, e, i, j); coeff[p] = coeff[p] + 1; // adds one to the corresponding parameter index. } } } for (i=0; i < T.nalpha; i++) { p = root2param(T, Mod, i); coeff[p] = coeff[p] + 1; } // translation between free parameters and model parameters. std::vector<long> modpar; // corresponding model parameter index std::vector<long> modparkill; // corresponding model parameter which is killed. modpar.resize(nfreepar); modparkill.resize(nfreepar); // Transition matrices for(e=0; e < T.nedges; e++) { for(i=0; i < T.nalpha; i++) { for(j=0; j < T.nalpha; j++) { l = erc2freeparam(T, Mod, e, i, j); if (l < 0) continue; // negative l means the parameter is killed. modpar[l] = erc2param(Mod, e, i, j); modparkill[l] = erc2param(Mod, e, i, i); } } } // Root if (Mod.rdf > 0) { for(i=0; i < T.nalpha; i++) { l = root2freeparam(T, Mod, i); if (l < 0) continue; // negative l means the parameter is killed. modpar[l] = root2param(T, Mod, i); modparkill[l] = root2param(T, Mod, 0); } } double c1, c2; for(l1=0; l1 < nfreepar ; l1++) { c1 = coeff[modpar[l1]]/coeff[modparkill[l1]]; for(l2=0; l2 < nfreepar; l2++) { c2 = coeff[modpar[l2]]/coeff[modparkill[l2]]; Ifree[l1][l2] = Imod[modpar[l1]][modpar[l2]] - c1 * Imod[modparkill[l1]][modpar[l2]] - c2 * Imod[modpar[l1]][modparkill[l2]] + c1*c2 * Imod[modparkill[l1]][modparkill[l2]]; } } }
void Fisher_information_model(Tree &T, Model &Mod, Parameters &Par, long N, Counts *data, Array2 &Imod) { long i, j, k; double factor; std::vector<double> param; Array1 pleaf; Array2 pcond1; Array3 pcond2; StateList sl; long npars = Mod.np*T.nedges + Mod.rdf + 1; Array2 Ineg; Ineg.resize(npars); Imod.resize(npars); for (i=0; i < npars; i++) { Ineg[i].resize(npars); Imod[i].resize(npars); for(j=0; j < npars; j++) { Ineg[i][j] = 0; Imod[i][j] = 0; } } if (data != NULL && data->nspecies != T.nleaves) { throw std::length_error("ERROR: In Fisher_information_model. Counts don't match the tree."); } sl = create_state_list(T); // Fills stuff fill_pleaf(T, sl, Par, pleaf); fill_pcond1(T, Mod, sl, Par, pcond1); fill_pcond2(T, Mod, sl, Par, pcond2); get_param_vector(T, Mod, Par, param); // Fills entries of Imod one by one. for (i=0; i < npars; i++) { for(j=0; j < npars; j++) { for(k=0; k < T.nstleaves; k++) { if (data == NULL) { // Expected Fisher factor = (double) N; } else { // Observed Fisher factor = data->c[k] / pleaf[k]; } Imod[i][j] = Imod[i][j] + factor * pcond1[k][i] * pcond1[k][j] / pleaf[k]; Ineg[i][j] = Ineg[i][j] + factor * pcond2[k][i][j]; } // We add up the negatives apart to minimize numerical errors. Imod[i][j] = Imod[i][j] - Ineg[i][j]; } } }