Skip to content

Commit

Permalink
Added Tree method to do NNI. At the moment it just does a NNI. What I…
Browse files Browse the repository at this point in the history
… really need is for it to suggest a NNI, calculate the likelihood, and then accept or reject it
  • Loading branch information
jhellewell14 committed Oct 9, 2024
1 parent 3468ab3 commit fbbe614
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 2 deletions.
15 changes: 15 additions & 0 deletions src/branch_optimise.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use argmin::core::{Error, CostFunction, Gradient, Hessian};
use crate::tree::Tree;
use crate::rate_matrix::RateMatrix;

// impl<T: RateMatrix> CostFunction for Tree<T> {
// type Param = Vec<f64>;
// type Output = f64;

// fn cost(&self, param: &Self::Param) -> Result<Self::Output, Error> {

// self.rate_matrix.update_params(*param);
// self.initialise_likelihood();
// return Ok(self.get_tree_likelihood())
// }
// }
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ mod tree;
mod tree_iterators;
mod tree_to_newick;
mod rate_matrix;
mod branch_optimise;
mod tree_moves;

use rand::Rng;

use crate::build_tree::*;
use crate::tree::Tree;
Expand Down Expand Up @@ -41,4 +45,5 @@ pub fn main() {
eprintln!("Done in {}s", end.duration_since(start).as_secs());
eprintln!("Done in {}ms", end.duration_since(start).as_millis());
}

}
3 changes: 1 addition & 2 deletions src/tree.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::mutation::{create_list, Mutation};
use crate::node::Node;
use crate::rate_matrix::{self, RateMatrix};
use crate::rate_matrix::GTR;
use crate::rate_matrix::{RateMatrix};
use crate::vector_to_tree;
use needletail::*;
use std::collections::HashMap;
Expand Down
76 changes: 76 additions & 0 deletions src/tree_moves.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use crate::newick_to_vector;
use crate::tree::Tree;
use crate::rate_matrix::RateMatrix;
use rand::Rng;

// Rooted Nearest Neighbour Interchange
// Select random internal node - v
// Assign new parent as parent-of-parent
// Assign parent as having this node as parent

impl<T: RateMatrix> Tree<T> {

pub fn nni(&mut self) -> () {
// Get vector of all internal nodes that can be swapped
let mut int_nodes: Vec<usize> = self.postorder_notips(self.get_root()).map(|node| node.index).collect();
int_nodes.pop(); // Last element is root, which we can't swap with parent so pop it off
let ind = rand::thread_rng().gen_range(0..int_nodes.len());
let child_index = int_nodes[ind]; // was sample

// Children and parent of selected node
let child_node_children = self.nodes[child_index].children;
let child_node_parent = self.nodes[child_index].parent.unwrap();

// Children and parent of selected node's parent
let (lp, rp) = self.nodes[child_node_parent].children;
let parent_node_parent = self.nodes[child_node_parent].parent;

// Assign new parent and children to selected node's parent
self.nodes[child_node_parent].children = child_node_children;
let (lc, rc) = child_node_children;

// Update parents parent's children
let parent_node_parent = self.nodes[child_node_parent].parent.unwrap();
// if pp.is_none() {
// Needed for when parent's parent is root
// }

let (lpc, rpc) = self.nodes[parent_node_parent].children;
if lpc == Some(child_node_parent) {
self.nodes[parent_node_parent].children = (Some(child_index), rpc);
} else {
self.nodes[parent_node_parent].children = (lpc, Some(child_index));
}

self.nodes[child_node_parent].parent = Some(child_index);
// Update parent of moved children
self.nodes[lc.unwrap()].parent = Some(child_node_parent);
self.nodes[rc.unwrap()].parent = Some(child_node_parent);

// Assign new parent and children to selected node
self.nodes[child_index].parent = Some(parent_node_parent);

if lp == Some(child_index) {
self.nodes[child_index].children = (Some(child_node_parent), rp);
self.nodes[rp.unwrap()].parent = Some(child_index);
} else {
self.nodes[child_index].children = (lp, Some(child_node_parent));
self.nodes[lp.unwrap()].parent = Some(child_index);
}

// The new parent needs adding to changes for likelihood recalculation
let d: usize = self.nodes[child_node_parent].depth;
match self.changes.get(&d) {
None => {
self.changes.insert(d, vec![child_node_parent]);
}
Some(_) => {
self.changes.get_mut(&d).unwrap().push(child_node_parent);
}
}

// Update tree vector
self.tree_vec = newick_to_vector(&self.newick(), self.count_leaves());
}

}

0 comments on commit fbbe614

Please sign in to comment.