Beispiel #1
0
def kpsvd(A, bshape, cshape):
    r"""Compute the Kronecker Product SVD.

    Given matrix :math:`A`, find matrices :math:`B_i` and :math:`C_i`,
    of the specified sizes, such that

    .. math::
      A = \sum_i \sigma_i B_i \otimes C_i

    and :math:`\sum_i^n \sigma_i B_i \otimes C_i` is the best :math:`n`
    term approximation to :math:`A` :cite:`loan-2000-ubiquitous`.

    Parameters
    ----------
    A : array_like
      2D input array
    bshape : tuple (Mb, Nb)
      The desired shape of arrays :math:`B_i`
    cshape : tuple (Mc, Nc)
      The desired shape of arrays :math:`C_i`

    Returns
    -------
    S : ndarray
      1D array of :math:`\sigma_i` values
    B : ndarray
      3D array of :math:`B_i` matrices with index :math:`i` on the last
      axis
    C : ndarray
      3D array of :math:`C_i` matrices with index :math:`i` on the last
      axis
    """

    ashape = A.shape
    if ashape[0] != bshape[0] * cshape[0] or \
       ashape[1] != bshape[1] * cshape[1]:
        raise ValueError("Shape of A is not compatible with bshape and cshape")

    atshape = (bshape[0] * bshape[1], cshape[0] * cshape[1])
    Atilde = subsample_array(A, cshape).transpose().reshape(atshape)
    U, S, Vt = np.linalg.svd(Atilde, full_matrices=False)
    B = U.reshape(bshape + (U.shape[1], ), order='F')
    C = Vt.T.reshape(cshape + (Vt.shape[0], ), order='F')
    return S, B, C
Beispiel #2
0
def nkp(A, bshape, cshape):
    r"""Solve the Nearest Kronecker Product problem.

    Given matrix :math:`A`, find matrices :math:`B` and :math:`C`, of the
    specified sizes, such that :math:`B` and :math:`C` solve the problem
    :cite:`loan-2000-ubiquitous`

    .. math::
      \mathrm{argmin}_{B, C} \| A - B \otimes C \| \;.

    Parameters
    ----------
    A : array_like
      2D input array
    bshape : tuple (Mb, Nb)
      The desired shape of returned array :math:`B`
    cshape : tuple (Mc, Nc)
      The desired shape of returned array :math:`C`

    Returns
    -------
    B : ndarray
      2D output array :math:`B`
    C : ndarray
      2D output array :math:`C`
    """

    ashape = A.shape
    if ashape[0] != bshape[0] * cshape[0] or \
       ashape[1] != bshape[1] * cshape[1]:
        raise ValueError("Shape of A is not compatible with bshape and cshape")

    atshape = (bshape[0] * bshape[1], cshape[0] * cshape[1])
    Atilde = subsample_array(A, cshape).transpose().reshape(atshape)
    U, S, Vt = np.linalg.svd(Atilde, full_matrices=False)
    B = np.sqrt(S[0]) * U[:, [0]].reshape(bshape, order='F')
    C = np.sqrt(S[0]) * Vt[[0], :].reshape(cshape, order='F')
    return B, C
Beispiel #3
0
 def test_07(self):
     x = np.arange(20).reshape((4, 5))
     y = array.subsample_array(x, (2, 2), pad=True)
     assert y.shape == (2, 2, 2, 3)
     assert y[0, 0, -1, -1] == 14