Skip to content

Instantly share code, notes, and snippets.

@kindlychung
Last active September 19, 2016 23:26
Show Gist options
  • Save kindlychung/c599810dabcb80dc05890145711acf70 to your computer and use it in GitHub Desktop.
Save kindlychung/c599810dabcb80dc05890145711acf70 to your computer and use it in GitHub Desktop.
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`.
#[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);
}
}
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`.
#[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