def needleman_wunsch(string1, string2, gap_cost=1.0, sim_score=sim_ident): """ Computes the Needleman-Wunsch measure between two strings. The Needleman-Wunsch generalizes the Levenshtein distance and considers global alignment between two strings. Specifically, it is computed by assigning a score to each alignment between two input strings and choosing the score of the best alignment, that is, the maximal score. An alignment between two strings is a set of correspondences between the characters of between them, allowing for gaps. Args: string1,string2 (str) : Input strings gap_cost (float) : Cost of gap (defaults to 1.0) sim_score (function) : Similarity function to give a score for the correspondence between characters. Defaults to an identity function, where if two characters are same it returns 1.0 else returns 0. Returns: Needleman-Wunsch measure (float) Raises: TypeError : If the inputs are not strings or if one of the inputs is None. Examples: >>> needleman_wunsch('dva', 'deeva') 1.0 >>> needleman_wunsch('dva', 'deeve', 0.0) 2.0 >>> needleman_wunsch('dva', 'deeve', 1.0, sim_score=lambda s1, s2 : (2.0 if s1 == s2 else -1.0)) 1.0 >>> needleman_wunsch('GCATGCUA', 'GATTACA', gap_cost=0.5, sim_score=lambda s1, s2 : (1.0 if s1 == s2 else -1.0)) 2.5 """ # input validations utils.sim_check_for_none(string1, string2) utils.sim_check_for_string_inputs(string1, string2) dist_mat = np.zeros((len(string1) + 1, len(string2) + 1), dtype=np.float) # DP initialization for i in _range(len(string1) + 1): dist_mat[i, 0] = -(i * gap_cost) # DP initialization for j in _range(len(string2) + 1): dist_mat[0, j] = -(j * gap_cost) # Needleman-Wunsch DP calculation for i in _range(1, len(string1) + 1): for j in _range(1, len(string2) + 1): match = dist_mat[i - 1, j - 1] + sim_score(string1[i - 1], string2[j - 1]) delete = dist_mat[i - 1, j] - gap_cost insert = dist_mat[i, j - 1] - gap_cost dist_mat[i, j] = max(match, delete, insert) return dist_mat[dist_mat.shape[0] - 1, dist_mat.shape[1] - 1]
def smith_waterman(string1, string2, gap_cost=1.0, sim_score=sim_ident): """ Computes the Smith-Waterman measure between two strings. The Smith–Waterman algorithm performs local sequence alignment; that is, for determining similar regions between two strings. Instead of looking at the total sequence, the Smith–Waterman algorithm compares segments of all possible lengths and optimizes the similarity measure. Args: string1,string2 (str) : Input strings gap_cost (float) : Cost of gap (defaults to 1.0) sim_score (function) : Similarity function to give a score for the correspondence between characters. Defaults to an identity function, where if two characters are same it returns 1 else returns 0. Returns: Smith-Waterman measure (float) Raises: TypeError : If the inputs are not strings or if one of the inputs is None. Examples: >>> smith_waterman('cat', 'hat') 2.0 >>> smith_waterman('dva', 'deeve', 2.2) 1.0 >>> smith_waterman('dva', 'deeve', 1, sim_score=lambda s1, s2 : (2 if s1 == s2 else -1)) 2.0 >>> smith_waterman('GCATAGCU', 'GATTACA', gap_cost=1.4, sim_score=lambda s1, s2 : (1.5 if s1 == s2 else 0.5)) 6.5 """ # input validations utils.sim_check_for_none(string1, string2) utils.sim_check_for_string_inputs(string1, string2) dist_mat = np.zeros((len(string1) + 1, len(string2) + 1), dtype=np.float) max_value = 0 # Smith Waterman DP calculations for i in _range(1, len(string1) + 1): for j in _range(1, len(string2) + 1): match = dist_mat[i - 1, j - 1] + sim_score(string1[i - 1], string2[j - 1]) delete = dist_mat[i - 1, j] - gap_cost insert = dist_mat[i, j - 1] - gap_cost dist_mat[i, j] = max(0, match, delete, insert) max_value = max(max_value, dist_mat[i, j]) return max_value
def levenshtein(string1, string2): """ Computes the Levenshtein distance between two strings. Levenshtein distance computes the minimum cost of transforming one string into the other. Transforming a string is carried out using a sequence of the following operators: delete a character, insert a character, and substitute one character for another. Args: string1,string2 (str): Input strings Returns: Levenshtein distance (int) Raises: TypeError : If the inputs are not strings Examples: >>> levenshtein('a', '') 1 >>> levenshtein('example', 'samples') 3 >>> levenshtein('levenshtein', 'frankenstein') 6 """ # input validations utils.sim_check_for_none(string1, string2) utils.sim_check_for_string_inputs(string1, string2) if utils.sim_check_for_exact_match(string1, string2): return 0.0 ins_cost, del_cost, sub_cost, trans_cost = (1, 1, 1, 1) len_str1 = len(string1) len_str2 = len(string2) if len_str1 == 0: return len_str2 * ins_cost if len_str2 == 0: return len_str1 * del_cost d_mat = np.zeros((len_str1 + 1, len_str2 + 1), dtype=np.int) for i in _range(len_str1 + 1): d_mat[i, 0] = i * del_cost for j in _range(len_str2 + 1): d_mat[0, j] = j * ins_cost for i in _range(len_str1): for j in _range(len_str2): d_mat[i + 1, j + 1] = min( d_mat[i + 1, j] + ins_cost, d_mat[i, j + 1] + del_cost, d_mat[i, j] + (sub_cost if string1[i] != string2[j] else 0) ) return d_mat[len_str1, len_str2]