fn build_score_matrix(
        &self,
        m: &mut ScoreMatrix,
        p: &mut ScoreMatrix,
        choice: &str,
        pattern: &str,
        compressed: bool,
        case_sensitive: bool,
    ) {
        for i in 0..m.rows {
            m.set_score(i, 0, MATRIX_CELL_NEG_INFINITY);
            m.set_movement(i, 0, Movement::Skip);
        }

        for j in 0..m.cols {
            m.set_score(0, j, MATRIX_CELL_NEG_INFINITY);
            m.set_movement(0, j, Movement::Skip);
        }

        for i in 0..p.rows {
            p.set_score(i, 0, MATRIX_CELL_NEG_INFINITY);
            p.set_movement(i, 0, Movement::Skip);
        }

        // p[0][j]: the score of best alignment of p[] and c[..=j] where c[j] is not matched
        for j in 0..p.cols {
            p.set_score(0, j, self.score_config.gap_extension);
            p.set_movement(0, j, Movement::Skip);
        }

        // update the matrix;
        for (i, p_ch) in pattern.chars().enumerate() {
            let mut prev_ch = '\0';

            for (j, c_ch) in choice.chars().enumerate() {
                let row = self.adjust_row_idx(i + 1, compressed);
                let row_prev = self.adjust_row_idx(i, compressed);
                let col = j + 1;
                let col_prev = j;

                // update M matrix
                // M[i][j] = match(i, j) + max(M[i-1][j-1], P[i-1][j-1])
                if let Some(match_score) =
                    self.calculate_match_score(prev_ch, c_ch, p_ch, i, j, case_sensitive)
                {
                    let prev_match_score = m.get_score(row_prev, col_prev);
                    let prev_skip_score = p.get_score(row_prev, col_prev);
                    if prev_match_score >= prev_skip_score {
                        m.set_movement(row, col, Movement::Match);
                    }
                    m.set_score(
                        row,
                        col,
                        (match_score as i32)
                            + max(
                                prev_match_score + self.score_config.bonus_consecutive,
                                prev_skip_score,
                            ),
                    );
                } else {
                    m.set_score(row, col, MATRIX_CELL_NEG_INFINITY);
                    m.set_movement(row, col, Movement::Skip);
                }

                // update P matrix
                // P[i][j] = max(gap_start + gap_extend + M[i][j-1], gap_extend + P[i][j-1])
                let prev_match_score = self.score_config.gap_start
                    + self.score_config.gap_extension
                    + m.get_score(row, col_prev);
                let prev_skip_score = self.score_config.gap_extension + p.get_score(row, col_prev);
                if prev_match_score >= prev_skip_score {
                    p.set_score(row, col, prev_match_score);
                    p.set_movement(row, col, Movement::Match);
                } else {
                    p.set_score(row, col, prev_skip_score);
                    p.set_movement(row, col, Movement::Skip);
                }

                prev_ch = c_ch;
            }
        }
    }
/// Build the score matrix using the algorithm described above
Build the score matrix using the algorithm described above
Build the score matrix using the algorithm described above
fn build_score_matrix(
        &self,
        m: &mut ScoreMatrix,
        p: &mut ScoreMatrix,
        choice: &str,
        pattern: &str,
        compressed: bool,
        case_sensitive: bool,
    ) {
        for i in 0..m.rows {
            m.set_score(i, 0, MATRIX_CELL_NEG_INFINITY);
            m.set_movement(i, 0, Movement::Skip);
        }
        for j in 0..m.cols {
            m.set_score(0, j, MATRIX_CELL_NEG_INFINITY);
            m.set_movement(0, j, Movement::Skip);
        }
        for i in 0..p.rows {
            p.set_score(i, 0, MATRIX_CELL_NEG_INFINITY);
            p.set_movement(i, 0, Movement::Skip);
        }
        // p[0][j]: the score of best alignment of p[] and c[..=j] where c[j] is not matched
        for j in 0..p.cols {
            p.set_score(0, j, self.score_config.gap_extension);
            p.set_movement(0, j, Movement::Skip);
        }
        // update the matrix;
        for (i, p_ch) in pattern.chars().enumerate() {
            let mut prev_ch = '\0';
            for (j, c_ch) in choice.chars().enumerate() {
                let row = self.adjust_row_idx(i + 1, compressed);
                let row_prev = self.adjust_row_idx(i, compressed);
                let col = j + 1;
                let col_prev = j;
                // update M matrix
                // M[i][j] = match(i, j) + max(M[i-1][j-1], P[i-1][j-1])
                if let Some(match_score) =
                    self.calculate_match_score(prev_ch, c_ch, p_ch, i, j, case_sensitive)
                {
                    let prev_match_score = m.get_score(row_prev, col_prev);
                    let prev_skip_score = p.get_score(row_prev, col_prev);
                    if prev_match_score >= prev_skip_score {
                        m.set_movement(row, col, Movement::Match);
                    }
                    m.set_score(
                        row,
                        col,
                        (match_score as i32)
                            + max(
                                prev_match_score + self.score_config.bonus_consecutive,
                                prev_skip_score,
                            ),
                    );
                } else {
                    m.set_score(row, col, MATRIX_CELL_NEG_INFINITY);
                    m.set_movement(row, col, Movement::Skip);
                }
                // update P matrix
                // P[i][j] = max(gap_start + gap_extend + M[i][j-1], gap_extend + P[i][j-1])
                let prev_match_score = self.score_config.gap_start
                    + self.score_config.gap_extension
                    + m.get_score(row, col_prev);
                let prev_skip_score = self.score_config.gap_extension + p.get_score(row, col_prev);
                if prev_match_score >= prev_skip_score {
                    p.set_score(row, col, prev_match_score);
                    p.set_movement(row, col, Movement::Match);
                } else {
                    p.set_score(row, col, prev_skip_score);
                    p.set_movement(row, col, Movement::Skip);
                }
                prev_ch = c_ch;
            }
        }
    }
fn build_score_matrix ( & self , m : & mut ScoreMatrix , p : & mut ScoreMatrix , choice : & str , pattern : & str , compressed : bool , case_sensitive : bool , ) { for i in 0 .. m . rows { m . set_score ( i , 0 , MATRIX_CELL_NEG_INFINITY ) ; m . set_movement ( i , 0 , Movement :: Skip ) ; } for j in 0 .. m . cols { m . set_score ( 0 , j , MATRIX_CELL_NEG_INFINITY ) ; m . set_movement ( 0 , j , Movement :: Skip ) ; } for i in 0 .. p . rows { p . set_score ( i , 0 , MATRIX_CELL_NEG_INFINITY ) ; p . set_movement ( i , 0 , Movement :: Skip ) ; } // p[0][j]: the score of best alignment of p[] and c[..=j] where c[j] is not matched for j in 0 .. p . cols { p . set_score ( 0 , j , self . score_config . gap_extension ) ; p . set_movement ( 0 , j , Movement :: Skip ) ; } // update the matrix; for ( i , p_ch ) in pattern . chars ( ) . enumerate ( ) { let mut prev_ch = '\0' ; for ( j , c_ch ) in choice . chars ( ) . enumerate ( ) { let row = self . adjust_row_idx ( i + 1 , compressed ) ; let row_prev = self . adjust_row_idx ( i , compressed ) ; let col = j + 1 ; let col_prev = j ; // update M matrix // M[i][j] = match(i, j) + max(M[i-1][j-1], P[i-1][j-1]) if let Some ( match_score ) = self . calculate_match_score ( prev_ch , c_ch , p_ch , i , j , case_sensitive ) { let prev_match_score = m . get_score ( row_prev , col_prev ) ; let prev_skip_score = p . get_score ( row_prev , col_prev ) ; if prev_match_score >= prev_skip_score { m . set_movement ( row , col , Movement :: Match ) ; } m . set_score ( row , col , ( match_score as i32 ) + max ( prev_match_score + self . score_config . bonus_consecutive , prev_skip_score , ) , ) ; } else { m . set_score ( row , col , MATRIX_CELL_NEG_INFINITY ) ; m . set_movement ( row , col , Movement :: Skip ) ; } // update P matrix // P[i][j] = max(gap_start + gap_extend + M[i][j-1], gap_extend + P[i][j-1]) let prev_match_score = self . score_config . gap_start + self . score_config . gap_extension + m . get_score ( row , col_prev ) ; let prev_skip_score = self . score_config . gap_extension + p . get_score ( row , col_prev ) ; if prev_match_score >= prev_skip_score { p . set_score ( row , col , prev_match_score ) ; p . set_movement ( row , col , Movement :: Match ) ; } else { p . set_score ( row , col , prev_skip_score ) ; p . set_movement ( row , col , Movement :: Skip ) ; } prev_ch = c_ch ; } } }
Build the score matrix using the algorithm described above
Build the score matrix using the algorithm described above
&self
m
&mut ScoreMatrix
p
&mut ScoreMatrix
choice
&str
pattern
&str
compressed
bool
case_sensitive
bool