示例#1
0
def approximate(x, psi_x, thresholds: list, max_ranks: list):
    """Approximate psi_x using HOSVD and HOCUR, respectively.

    Parameters
    ----------
    x: array
        snapshot matrix
    psi_x: array
        transformed data matrix
    thresholds: list of floats
        tresholds for HOSVD
    max_ranks: list of ints
        maximum ranks for HOCUR

    Returns
    -------
    ranks_hosvd: list of lists of ints
        ranks of the approximations computed with HOSVD
    errors_hosvd: list of floats
        relative errors of the approximations computed with HOSVD
    ranks_hocur: list of lists of ints
        ranks of the approximations computed with HOCUR
    errors_hocur: list of floats
        relative errors of the approximations computed with HOCUR
    """

    # define returns
    ranks_hosvd = []
    errors_hosvd = []
    ranks_hocur = []
    errors_hocur = []

    start_time = utl.progress('Approximation in TT format', 0)

    # reshape psi_x into tensor
    psi_x_full = psi_x.reshape([number_of_boxes, number_of_boxes, 1, 1, 1, psi_x.shape[1]])

    # approximate psi_x using HOSVD
    for i in range(len(thresholds)):
        psi_approx = TT(psi_x_full, threshold=thresholds[i])
        ranks_hosvd.append(psi_approx.ranks)
        errors_hosvd.append(np.linalg.norm(psi_x_full - psi_approx.full()) / np.linalg.norm(psi_x_full))
        utl.progress('Approximation in TT format', 100 * (i + 1) / 6, cpu_time=_time.time() - start_time)

    # approximate psi_x using HOCUR
    for i in range(len(max_ranks)):
        psi_approx = tdt.hocur(x, basis_list, max_ranks[i], repeats=3, multiplier=100, progress=False)
        ranks_hocur.append(psi_approx.ranks)
        errors_hocur.append(np.linalg.norm(psi_x - psi_approx.transpose(cores=2).matricize()) / np.linalg.norm(psi_x))
        utl.progress('Approximation in TT format', 100 * (i + 4) / 6, cpu_time=_time.time() - start_time)

    return ranks_hosvd, errors_hosvd, ranks_hocur, errors_hocur
示例#2
0
    def test_hocur(self):
        """test higher-order CUR decomposition"""

        tdt_1 = tdt.basis_decomposition(self.data, self.phi_1).transpose(cores=[self.d]).matricize()
        tdt_2 = tdt.hocur(self.data, self.phi_1, 5, repeats=10, progress=False).transpose(cores=[self.d]).matricize()
        self.assertLess(np.sum(np.abs(tdt_1-tdt_2)), self.tol)








        
        
示例#3
0
def amuset_hocur(data_matrix, x_indices, y_indices, basis_list, max_rank=1000, multiplier=2, progress=False):
    """
    AMUSEt (AMUSE on tensors) using HOCUR.

    Apply tEDMD to a given data matrix by using AMUSEt with HOCUR. This procedure is a tensor-based
    version of AMUSE using the tensor-train format. For more details, see [1]_.

    Parameters
    ----------
    data_matrix : np.ndarray
        snapshot matrix
    x_indices : np.ndarray or list[np.ndarray]
        index sets for snapshot matrix x
    y_indices : np.ndarray or list[np.ndarray]
        index sets for snapshot matrix y
    basis_list : list[list[function]]
        list of basis functions in every mode
    max_rank : int, optional
        maximum ranks for HOSVD as well as HOCUR, default is 1000
    multiplier : int
        multiplier for HOCUR
    progress : boolean, optional
        whether to show progress bar, default is False

    Returns
    -------
    eigenvalues : np.ndarray or list[np.ndarray]
        tEDMD eigenvalues
    eigentensors : TT or list[TT]
        tEDMD eigentensors in TT format

    References
    ----------
    ..[1] F. Nüske, P. Gelß, S. Klus, C. Clementi. "Tensor-based EDMD for the Koopman analysis of high-dimensional
          systems", arXiv:1908.04741, 2019
    """

    # define quantities
    eigenvalues = []
    eigentensors = []

    # construct transformed data tensor in TT format using HOCUR
    psi = tdt.hocur(data_matrix, basis_list, max_rank, repeats=1, multiplier=multiplier, progress=progress)

    # left-orthonormalization
    psi = psi.ortho_left(progress=progress)

    # extract last core
    last_core = psi.cores[-1]

    # convert x_indices and y_indices to lists
    if not isinstance(x_indices, list):
        x_indices = [x_indices]
        y_indices = [y_indices]

    # loop over all index sets
    for i in range(len(x_indices)):
        # compute reduced matrix
        matrix, u, s, v = _reduced_matrix(last_core, x_indices[i], y_indices[i])

        # solve reduced eigenvalue problem
        eigenvalues_reduced, eigenvectors_reduced = np.linalg.eig(matrix)
        idx = (np.abs(eigenvalues_reduced - 1)).argsort()
        eigenvalues_reduced = np.real(eigenvalues_reduced[idx])
        eigenvectors_reduced = np.real(eigenvectors_reduced[:, idx])

        # construct eigentensors
        eigentensors_tmp = psi
        eigentensors_tmp.cores[-1] = u.dot(np.diag(np.reciprocal(s))).dot(eigenvectors_reduced)[:, :, None, None]

        # append results
        eigenvalues.append(eigenvalues_reduced)
        eigentensors.append(eigentensors_tmp)

    # only return lists if more than one set of x-indices/y-indices was given
    if len(x_indices) == 1:
        eigenvalues = eigenvalues[0]
        eigentensors = eigentensors[0]

    return eigenvalues, eigentensors