-
-
Save kindlychung/c599810dabcb80dc05890145711acf70 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cargo test | |
Compiling algorithms_in_a_nutshell v0.1.0 (file:///Users/kaiyin/Documents/workspace-eclipse-neon/algorithms_in_a_nutshell) | |
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements | |
--> src/needleman_wunsch.rs:30:2 | |
| | |
30 | fn align<'a, 'b>(&'a self, vec: &'a Vec<T>, similarity: &'b Fn(&T, &T) -> i64, gap_penalty: i64) -> (Vec<Option<&'a T>>, Vec<Option<&'a T>>) { | |
| ^ | |
| | |
help: consider using an explicit lifetime parameter as shown: fn align<'c, 'a, | |
'b>(&'a self, vec: &'a Vec<T>, similarity: &'b Fn(&T, &T) -> i64, | |
gap_penalty: i64) -> (Vec<Option<&'a T>>, Vec<Option<&'a T>>) | |
--> src/needleman_wunsch.rs:30:2 | |
| | |
30 | fn align<'a, 'b>(&'a self, vec: &'a Vec<T>, similarity: &'b Fn(&T, &T) -> i64, gap_penalty: i64) -> (Vec<Option<&'a T>>, Vec<Option<&'a T>>) { | |
| ^ | |
error: aborting due to previous error | |
Build failed, waiting for other jobs to finish... | |
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements | |
--> src/needleman_wunsch.rs:30:2 | |
| | |
30 | fn align<'a, 'b>(&'a self, vec: &'a Vec<T>, similarity: &'b Fn(&T, &T) -> i64, gap_penalty: i64) -> (Vec<Option<&'a T>>, Vec<Option<&'a T>>) { | |
| ^ | |
| | |
help: consider using an explicit lifetime parameter as shown: fn align<'c, 'a, | |
'b>(&'a self, vec: &'a Vec<T>, similarity: &'b Fn(&T, &T) -> i64, | |
gap_penalty: i64) -> (Vec<Option<&'a T>>, Vec<Option<&'a T>>) | |
--> src/needleman_wunsch.rs:30:2 | |
| | |
30 | fn align<'a, 'b>(&'a self, vec: &'a Vec<T>, similarity: &'b Fn(&T, &T) -> i64, gap_penalty: i64) -> (Vec<Option<&'a T>>, Vec<Option<&'a T>>) { | |
| ^ | |
error: aborting due to previous error | |
error: Could not compile `algorithms_in_a_nutshell`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[derive(Debug, Copy, Clone)] | |
pub enum Direction { | |
Match, // go diagonally, left and up | |
Left, | |
Up, | |
Border, // you have reached the border, time to stop | |
Undefined, | |
} | |
#[derive(Debug, Copy, Clone)] | |
pub struct ResultEntry { | |
pub score: i64, | |
pub direction: Direction, | |
} | |
impl ResultEntry { | |
fn new(s: i64, d: Direction) -> ResultEntry { | |
ResultEntry { | |
score: s, | |
direction: d, | |
} | |
} | |
} | |
trait NeedlemanWunsch<T> { | |
fn align(&self, vec: &Vec<T>, similarity: &Fn(&T, &T) -> i64, gap_penalty: i64) -> (Vec<Option<&T>>, Vec<Option<&T>>); | |
} | |
impl<T> NeedlemanWunsch<T> for Vec<T> where T: Eq + Ord + Clone { | |
fn align<'a, 'b>(&'a self, vec: &'a Vec<T>, similarity: &'b Fn(&T, &T) -> i64, gap_penalty: i64) -> (Vec<Option<&'a T>>, Vec<Option<&'a T>>) { | |
let mut mat = init_align_matrix(self.len() , vec.len()); | |
fill_align_matrix(&mut mat, self, vec, similarity, gap_penalty); | |
let mut vec1: Vec<Option<&T>> = Vec::new(); | |
let mut vec2: Vec<Option<&T>> = Vec::new(); | |
let mut i = self.len() - 1; | |
let mut j = vec.len() - 1; | |
let mut node = mat[i][j]; | |
loop { | |
match node.direction { | |
Direction::Match => { | |
vec1.insert(0, Some(&self[i])); | |
vec2.insert(0, Some(&vec[j])); | |
i -= 1; | |
j -= 1; | |
}, | |
Direction::Left => { | |
vec1.insert(0, None); | |
vec2.insert(0, Some(&vec[i])); | |
j -= 1; | |
}, | |
Direction::Up => { | |
vec1.insert(0, Some(&self[i])); | |
vec2.insert(0, None); | |
i -= 1; | |
}, | |
Direction::Undefined => { | |
break; | |
} | |
} | |
} | |
return (vec1, vec2); | |
} | |
} | |
type AlignMatrix = Vec<Vec<ResultEntry>>; | |
/// len1: Length of the first vector, or number of rows for the alignment matrix. | |
/// len2: Length of the second vector, or number of cols for the alignment matrix. | |
fn init_align_matrix(len1: usize, len2: usize) -> AlignMatrix { | |
// starting point has undefined direction | |
let mut mat: AlignMatrix = vec![vec![ResultEntry::new(0, Direction::Undefined); len2]; len1]; | |
// first row all go left | |
for i in 1..len2 { | |
mat[0][i] = ResultEntry::new(-(i as i64), Direction::Left); | |
} | |
// first col all go up | |
for i in 1..len1 { | |
mat[i][0] = ResultEntry::new(-(i as i64), Direction::Up); | |
} | |
mat | |
} | |
fn fill_align_matrix<T>(mat: &mut AlignMatrix, vec1: &Vec<T>, vec2: &Vec<T>, similarity: &Fn(&T, &T) -> i64, gap_penalty: i64) { | |
assert!(mat.len() == vec1.len()); | |
assert!(mat[0].len() == vec2.len()); | |
fn get_score_set_direction<U>(mat: &mut AlignMatrix, vec1: &Vec<U>, vec2: &Vec<U>, similarity: &Fn(&U, &U) -> i64, gap_penalty: i64, i: usize, j: usize) -> i64 { | |
match mat[i][j].direction { | |
Direction::Undefined => { | |
let up_left = get_score_set_direction(mat, vec1, vec2, similarity, gap_penalty, i - 1, j - 1); | |
let up = get_score_set_direction(mat, vec1, vec2, similarity, gap_penalty, i - 1, j); | |
let left = get_score_set_direction(mat, vec1, vec2, similarity, gap_penalty, i, j - 1); | |
let similarity_score = similarity(&vec1[i], &vec2[j]); | |
let match_score = up_left + similarity_score; | |
let up_score = up + gap_penalty; | |
let left_score = left + gap_penalty; | |
let m = *[match_score, up_score, left_score].iter().max().unwrap(); | |
if m == match_score { | |
mat[i][j] = ResultEntry::new(m, Direction::Match); | |
} else if m == up_score { | |
mat[i][j] = ResultEntry::new(m, Direction::Up); | |
} else { | |
mat[i][j] = ResultEntry::new(m, Direction::Left); | |
} | |
m | |
}, | |
_ => mat[i][j].score | |
} | |
} | |
for i in 1..vec1.len() { | |
for j in 1..vec2.len() { | |
get_score_set_direction(mat, vec1, vec2, similarity, gap_penalty, i, j); | |
} | |
} | |
} | |
mod test { | |
use super::init_align_matrix; | |
#[test] | |
fn test_needleman() { | |
let m = init_align_matrix(5, 5); | |
println!("{:?}", m); | |
assert!(false); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
error: no method named `len` found for type `(std::vec::Vec<std::option::Option<char>>, std::vec::Vec<std::option::Option<char>>)` in the current scope | |
--> src/main.rs:20:22 | |
| | |
20 | println!("{}", res.len()); | |
| ^^^ | |
error: aborting due to previous error | |
error: Could not compile `algorithms_in_a_nutshell`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[macro_use] | |
extern crate algorithms_in_a_nutshell; | |
use algorithms_in_a_nutshell::point::Point; | |
use algorithms_in_a_nutshell::naive_convex_hull; | |
use std::collections::BTreeSet; | |
use algorithms_in_a_nutshell::needleman_wunsch::NeedlemanWunsch; | |
fn main() { | |
fn similarity(c1: &char, c2: &char) -> i64 { | |
if c1 == c2 { | |
1 | |
} else { | |
-1 | |
} | |
} | |
let vec1: Vec<char> = "what".chars().collect(); | |
let vec2: Vec<char> = "white".chars().collect(); | |
let res = vec1.align(&vec2, &similarity, -1); | |
println!("{}", res.len()); | |
for x in res.0 { | |
match x { | |
Some(c) => println!("{}", c), | |
_ => println!("_") | |
} | |
} | |
for x in res.1 { | |
match x { | |
Some(c) => println!("{}", c), | |
_ => println!("_") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment