Skip to content

Commit

Permalink
All Topology moves now have the TreeMove trait
Browse files Browse the repository at this point in the history
  • Loading branch information
jhellewell14 committed Nov 29, 2024
1 parent d1edf0b commit 22ead15
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 165 deletions.
11 changes: 6 additions & 5 deletions src/branchlength.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::Topology;
use crate::{rate_matrix::RateMatrix, treestate::TreeMove};

impl Topology {
pub fn update_branchlength(mut self, index: usize) {


pub struct BranchMove{}

impl<R: RateMatrix> TreeMove<R> for BranchMove {
fn generate(&self, ts: &crate::treestate::TreeState<R>) -> crate::treestate::TreeState<R> {
todo!()
}
}
204 changes: 161 additions & 43 deletions src/moves.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::env::current_exe;

use crate::genetic_data;
use crate::newick_to_vector;
use crate::Topology;
use crate::CandidateTopology;
use rand::Rng;
use crate::treestate::TreeMove;
use crate::TreeState;
use crate::RateMatrix;

pub trait MoveFn {
fn generate_move(&self, current_topology: &Topology) -> CandidateTopology;
Expand All @@ -14,14 +15,16 @@ pub struct ExactMove {
pub target_vector: Vec<usize>,
}

impl MoveFn for ExactMove {
fn generate_move(&self, current_topology: &Topology) -> CandidateTopology {

let new_topology: Topology = Topology::from_vec(&self.target_vector);
let changes: Option<Vec<usize>> = current_topology.find_changes(&new_topology);
CandidateTopology{
new_topology,
changes,
impl<R:RateMatrix> TreeMove<R> for ExactMove {
fn generate(&self, ts: &TreeState<R>) -> TreeState<R> {
let new_topology = Topology::from_vec(&self.target_vector);
let changes: Option<Vec<usize>> = ts.top.find_changes(&new_topology);
let mat = ts.mat;
TreeState{
top: new_topology,
mat: mat,
ll: ts.ll,
changed_nodes: changes,
}
}
}
Expand All @@ -30,9 +33,10 @@ pub struct PeturbVec {
pub n: usize,
}

impl MoveFn for PeturbVec {
fn generate_move(&self, current_topology: &Topology) -> CandidateTopology {
let mut vout = current_topology.tree_vec.to_vec();
impl<R: RateMatrix> TreeMove<R> for PeturbVec {
fn generate(&self, ts: &TreeState<R>) -> TreeState<R> {
let mut vout = ts.top.tree_vec.to_vec();

let mut rng = rand::thread_rng();
let ind_rng = rand::thread_rng();
let distr = rand::distributions::Bernoulli::new(0.5).unwrap();
Expand Down Expand Up @@ -66,14 +70,62 @@ impl MoveFn for PeturbVec {
};

let new_topology: Topology = Topology::from_vec(&vout);
let changes: Option<Vec<usize>> = current_topology.find_changes(&new_topology);
CandidateTopology{
new_topology,
changes,
let changes: Option<Vec<usize>> = ts.top.find_changes(&new_topology);

TreeState{
top: new_topology,
mat: ts.mat,
ll: ts.ll,
changed_nodes: changes,
}

}
}

// impl MoveFn for PeturbVec {
// fn generate_move(&self, current_topology: &Topology) -> CandidateTopology {
// let mut vout = current_topology.tree_vec.to_vec();
// let mut rng = rand::thread_rng();
// let ind_rng = rand::thread_rng();
// let distr = rand::distributions::Bernoulli::new(0.5).unwrap();
// let ind_distr = rand::distributions::Uniform::new(0, vout.len());

// let samp_n: usize = match self.n.gt(&vout.len()) {
// true => {vout.len()},
// false => {self.n},
// };

// let mut inds: Vec<usize> = ind_rng.sample_iter(ind_distr).take(samp_n).collect();
// inds.sort();

// for ind in inds {
// if ind.eq(&0) {
// continue;
// }

// match rng.sample(distr) {
// true => {
// if vout[ind].lt(&(2 * (ind - 1))) {
// vout[ind] += 1;
// }
// }
// false => {
// if vout[ind].gt(&0) {
// vout[ind] -= 1;
// }
// }
// };
// };

// let new_topology: Topology = Topology::from_vec(&vout);
// let changes: Option<Vec<usize>> = current_topology.find_changes(&new_topology);
// CandidateTopology{
// new_topology,
// changes,
// }
// }
// }

// pub struct NearestNeighbour{

// }
Expand Down Expand Up @@ -145,36 +197,30 @@ pub struct ChildSwap{

}

impl MoveFn for ChildSwap {
fn generate_move(&self, current_topology: &Topology) -> CandidateTopology {
impl<R: RateMatrix> TreeMove<R> for ChildSwap {
fn generate(&self, ts: &TreeState<R>) -> TreeState<R> {
// Create new topology
let mut new_topology: Topology = Topology{
nodes: current_topology.nodes.clone(),
tree_vec: current_topology.tree_vec.clone(),
nodes: ts.top.nodes.clone(),
tree_vec: ts.top.tree_vec.clone(),
likelihood: None,
};

// Select indices of internal nodes
let mut int_nodes: Vec<usize> = current_topology.postorder_notips(current_topology.get_root()).map(|n| n.get_id()).collect();
let mut int_nodes: Vec<usize> = ts.top.postorder_notips(ts.top.get_root()).map(|n| n.get_id()).collect();
// Pop off root
int_nodes.pop();
// Randomly choose an internal node
let ind = int_nodes.remove(rand::thread_rng().gen_range(0..int_nodes.len()));
// Get index of node and its parent
let node = current_topology.nodes[ind].get_id();
let parent = current_topology.get_parent(&current_topology.nodes[node]).unwrap().get_id();
let node = ts.top.nodes[ind].get_id();
let parent = ts.top.get_parent(&ts.top.nodes[node]).unwrap().get_id();
// Get children of node and its parent
let (par_lc, par_rc) = (current_topology.nodes[parent].get_lchild(), current_topology.nodes[parent].get_rchild());
let (node_lc, node_rc) = (current_topology.nodes[node].get_lchild(), current_topology.nodes[node].get_rchild());
let (par_lc, par_rc) = (ts.top.nodes[parent].get_lchild(), ts.top.nodes[parent].get_rchild());
let (node_lc, node_rc) = (ts.top.nodes[node].get_lchild(), ts.top.nodes[node].get_rchild());
// This vector will store all the nodes whose depth needs updating (required for correct Newick String generation later)
let mut all_subnodes: Vec<usize>;

// println!("node: {:?}", current_topology.nodes[node]);
// println!("parent: {:?}", current_topology.nodes[parent]);
// println!("node lchild {:?}", current_topology.nodes[node_lc.unwrap()]);
// println!("node rchild {:?}", current_topology.nodes[node_rc.unwrap()]);
// println!("parent lchild {:?}", current_topology.nodes[par_lc.unwrap()]);
// println!("parent rchild {:?}", current_topology.nodes[par_rc.unwrap()]);

if node.eq(&par_lc.unwrap()) {
// left child of parent, swap right children
new_topology.nodes[node].set_rchild(par_rc);
Expand All @@ -195,13 +241,6 @@ impl MoveFn for ChildSwap {
.map(|n| n.get_id()).collect();
};

// println!("new node: {:?}", new_topology.nodes[node]);
// println!("new parent: {:?}", new_topology.nodes[parent]);
// println!("new node lchild {:?}", new_topology.nodes[node_lc.unwrap()]);
// println!("new node rchild {:?}", new_topology.nodes[node_rc.unwrap()]);
// println!("new parent lchild {:?}", new_topology.nodes[par_lc.unwrap()]);
// println!("new parent rchild {:?}", new_topology.nodes[par_rc.unwrap()]);

// This guarantees correct ordering of depth updating
all_subnodes.sort();
all_subnodes.reverse();
Expand All @@ -214,14 +253,93 @@ impl MoveFn for ChildSwap {

new_topology.tree_vec = newick_to_vector(&new_topology.get_newick(), new_topology.count_leaves());

CandidateTopology{
new_topology,
changes: Some(vec![node, parent]),
TreeState{
top: new_topology,
mat: ts.mat,
ll: ts.ll,
changed_nodes: Some(vec![node, parent]),
}

}
}

// impl MoveFn for ChildSwap {
// fn generate_move(&self, current_topology: &Topology) -> CandidateTopology {
// // Create new topology
// let mut new_topology: Topology = Topology{
// nodes: current_topology.nodes.clone(),
// tree_vec: current_topology.tree_vec.clone(),
// likelihood: None,
// };
// // Select indices of internal nodes
// let mut int_nodes: Vec<usize> = current_topology.postorder_notips(current_topology.get_root()).map(|n| n.get_id()).collect();
// // Pop off root
// int_nodes.pop();
// // Randomly choose an internal node
// let ind = int_nodes.remove(rand::thread_rng().gen_range(0..int_nodes.len()));
// // Get index of node and its parent
// let node = current_topology.nodes[ind].get_id();
// let parent = current_topology.get_parent(&current_topology.nodes[node]).unwrap().get_id();
// // Get children of node and its parent
// let (par_lc, par_rc) = (current_topology.nodes[parent].get_lchild(), current_topology.nodes[parent].get_rchild());
// let (node_lc, node_rc) = (current_topology.nodes[node].get_lchild(), current_topology.nodes[node].get_rchild());
// // This vector will store all the nodes whose depth needs updating (required for correct Newick String generation later)
// let mut all_subnodes: Vec<usize>;

// // println!("node: {:?}", current_topology.nodes[node]);
// // println!("parent: {:?}", current_topology.nodes[parent]);
// // println!("node lchild {:?}", current_topology.nodes[node_lc.unwrap()]);
// // println!("node rchild {:?}", current_topology.nodes[node_rc.unwrap()]);
// // println!("parent lchild {:?}", current_topology.nodes[par_lc.unwrap()]);
// // println!("parent rchild {:?}", current_topology.nodes[par_rc.unwrap()]);

// if node.eq(&par_lc.unwrap()) {
// // left child of parent, swap right children
// new_topology.nodes[node].set_rchild(par_rc);
// new_topology.nodes[par_rc.unwrap()].set_parent(Some(node));
// new_topology.nodes[parent].set_rchild(node_rc);
// new_topology.nodes[node_rc.unwrap()].set_parent(Some(parent));
// all_subnodes = new_topology.postorder(&new_topology.nodes[par_rc.unwrap()])
// .chain(new_topology.postorder(&new_topology.nodes[node_rc.unwrap()]))
// .map(|n| n.get_id()).collect();
// } else {
// // right child of parent, swap left children
// new_topology.nodes[node].set_lchild(par_lc);
// new_topology.nodes[par_lc.unwrap()].set_parent(Some(node));
// new_topology.nodes[parent].set_lchild(node_lc);
// new_topology.nodes[node_lc.unwrap()].set_parent(Some(parent));
// all_subnodes = new_topology.postorder(&new_topology.nodes[par_lc.unwrap()])
// .chain(new_topology.postorder(&new_topology.nodes[node_lc.unwrap()]))
// .map(|n| n.get_id()).collect();
// };

// // println!("new node: {:?}", new_topology.nodes[node]);
// // println!("new parent: {:?}", new_topology.nodes[parent]);
// // println!("new node lchild {:?}", new_topology.nodes[node_lc.unwrap()]);
// // println!("new node rchild {:?}", new_topology.nodes[node_rc.unwrap()]);
// // println!("new parent lchild {:?}", new_topology.nodes[par_lc.unwrap()]);
// // println!("new parent rchild {:?}", new_topology.nodes[par_rc.unwrap()]);

// // This guarantees correct ordering of depth updating
// all_subnodes.sort();
// all_subnodes.reverse();
// // println!("all_subnodes: {:?}", all_subnodes);
// // Update depths in substrees that have been moved
// for n in all_subnodes {
// let d = new_topology.get_parent(&new_topology.nodes[n]).unwrap().get_depth() + 1;
// new_topology.nodes[n].set_depth(d);
// }

// new_topology.tree_vec = newick_to_vector(&new_topology.get_newick(), new_topology.count_leaves());

// CandidateTopology{
// new_topology,
// changes: Some(vec![node, parent]),
// }

// }
// }


pub fn hillclimb_accept(old_ll: &f64, new_ll: &f64) -> bool {
new_ll.gt(old_ll)
Expand Down
Loading

0 comments on commit 22ead15

Please sign in to comment.