def fixNegsEven(self): """Returns copy of self w/o negative off-diags, using 'even' heuristic. If a negative off-diagonal is encountered, sets it to 0. Distributes the negative score evenly among the other elements. """ m = without_diag(self._data) for i, row in enumerate(m): is_neg = row < 0 if any(is_neg): num_negs = sum(is_neg) sum_negs = sum(is_neg*row) is_not_neg = logical_not(is_neg) num_not_neg = sum(is_not_neg) new_row = (row + (sum_negs/(num_not_neg+1)))*is_not_neg m[i] = new_row return self.__class__(with_diag(m, -sum(m,1)), self.Alphabet)
def rates_to_array(rates, to_fill, without_diagonal=False): """Fills rates into a pre-existing array object. Assumes that all keys in rates are valid indices into to_fill, and that the last dimension of to_fill is the same size as the flattened values in rates. If without_diagonal is True (False by default), removes the diagonals from the data before placing in the array. Note that we can't call this without_diag or we collide with the function we want to call to strip the diagonal. WARNING: size of to_fill array must be adjusted to be the right size as the inputs, i.e. last dimension same as flat array with/without diagonals. """ if without_diagonal: for key, val in rates.items(): to_fill[key] = ravel(without_diag(val._data)) else: for key, val in rates.items(): to_fill[key] = ravel(val._data) return to_fill
def fixNegsConstrainedOpt(self, to_minimize=norm_diff, badness=1e6): """Uses constrained minimization to find approx q matrix. to_minimize: metric for comparing orig result and new result. badness: scale factor for penalizing negative off-diagonal values. """ if not sum_neg_off_diags(self._data): return self q = ravel(without_diag(self._data)) p = expm(self._data)(t=1) def err_f(q): new_q = reshape(array(q), (4,3)) new_q = with_diag(new_q, -sum(new_q, 1)) p_new = expm(new_q)(t=1) result = to_minimize(ravel(p), ravel(p_new)) if q.min() < 0: result += -q.min() * badness return result a = array(q) xmin = fmin(func=err_f, x0=a, disp=0) r = reshape(xmin, (4,3)) new_q = with_diag(r, -sum(r, 1)) return self.__class__(new_q, self.Alphabet)
def test_without_diag(self): """without_diag should omit diagonal from matrix""" a = array([[1,2,3],[4,5,6],[7,8,9]]) b = without_diag(a) self.assertEqual(b, array([[2,3],[4,6],[7,8]]))
def test_without_diag(self): """without_diag should omit diagonal from matrix""" a = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) b = without_diag(a) self.assertEqual(b, array([[2, 3], [4, 6], [7, 8]]))