def unit_variance_mlpg_matrix(windows, T): """Compute MLPG matrix assuming input is normalized to have unit-variances. Let :math:`\mu` is the input mean sequence (``num_windows*T x static_dim``), :math:`W` is a window matrix ``(T x num_windows*T)``, assuming input is normalized to have unit-variances, MLPG can be written as follows: .. math:: y = R \mu where .. math:: R = (W^{T} W)^{-1} W^{T} Here we call :math:`R` as the MLPG matrix. Args: windows: (list): List of windows. T (int): Number of frames. Returns: numpy.ndarray: MLPG matrix (``T x nun_windows*T``). See also: :func:`nnmnkwii.autograd.UnitVarianceMLPG`, :func:`nnmnkwii.paramgen.mlpg`. Examples: >>> from nnmnkwii import paramgen as G >>> import numpy as np >>> windows = [ ... (0, 0, np.array([1.0])), ... (1, 1, np.array([-0.5, 0.0, 0.5])), ... (1, 1, np.array([1.0, -2.0, 1.0])), ... ] >>> G.unit_variance_mlpg_matrix(windows, 3) array([[ 2.73835927e-01, 1.95121944e-01, 9.20177400e-02, 9.75609720e-02, -9.09090936e-02, -9.75609720e-02, -3.52549881e-01, -2.43902430e-02, 1.10864742e-02], [ 1.95121944e-01, 3.41463417e-01, 1.95121944e-01, 1.70731708e-01, -5.55111512e-17, -1.70731708e-01, -4.87804860e-02, -2.92682916e-01, -4.87804860e-02], [ 9.20177400e-02, 1.95121944e-01, 2.73835927e-01, 9.75609720e-02, 9.09090936e-02, -9.75609720e-02, 1.10864742e-02, -2.43902430e-02, -3.52549881e-01]], dtype=float32) """ win_mats = build_win_mats(windows, T) sdw = np.max([win_mat.l + win_mat.u for win_mat in win_mats]) P = bm.zeros(sdw, sdw, T) for win_index, win_mat in enumerate(win_mats): bm.dot_mm_plus_equals(win_mat.T, win_mat, target_bm=P) chol_bm = bla.cholesky(P, lower=True) Pinv = cholesky_inv_banded(chol_bm.full(), width=chol_bm.l + chol_bm.u + 1) cocatenated_window = full_window_mat(win_mats, T) return Pinv.dot(cocatenated_window.T).astype(np.float32)
def gen_chol_factor_BandMat(size, depth=None, contrib_rank=2, transposed=None): """Generates a random Cholesky factor BandMat. This works by generating a random positive definite matrix and then computing its Cholesky factor, since using a random matrix as a Cholesky factor seems to often lead to ill-conditioned matrices. """ if transposed is None: transposed = rand_bool() mat_bm = gen_pos_def_BandMat(size, depth=depth, contrib_rank=contrib_rank) chol_bm = bla.cholesky(mat_bm, lower=rand_bool()) if transposed: chol_bm = chol_bm.T assert chol_bm.l == 0 or chol_bm.u == 0 assert chol_bm.l + chol_bm.u == mat_bm.l randomize_extra_entries_bm(chol_bm) return chol_bm
def test_cholesky(self, its=50): for it in range(its): size = random.choice([0, 1, randint(0, 10), randint(0, 100)]) mat_bm = gen_pos_def_BandMat(size) depth = mat_bm.l lower = rand_bool() alternative = rand_bool() chol_bm = bla.cholesky(mat_bm, lower=lower, alternative=alternative) assert chol_bm.l == (depth if lower else 0) assert chol_bm.u == (0 if lower else depth) assert not np.may_share_memory(chol_bm.data, mat_bm.data) if lower != alternative: mat_bm_again = bm.dot_mm(chol_bm, chol_bm.T) else: mat_bm_again = bm.dot_mm(chol_bm.T, chol_bm) assert_allclose(mat_bm_again.full(), mat_bm.full())