Raw File
tucker.py
from .base import unfold, tensor_to_vec
from .tenalg import multi_mode_dot
from .tenalg import kronecker

# Author: Jean Kossaifi <jean.kossaifi+tensors@gmail.com>


def tucker_to_tensor(core, factors, skip_factor=None, transpose_factors=False):
    """Converts the Tucker tensor into a full tensor

    Parameters
    ----------
    core : ndarray
       core tensor
    factors : ndarray list
       list of matrices of shape (s_i, core.shape[i])
    skip_factor : None or int, optional, default is None
        if not None, index of a matrix to skip
        Note that in any case, `modes`, if provided, should have a lengh of `tensor.ndim`
    transpose_factors : bool, optional, default is False
        if True, the matrices or vectors in in the list are transposed

    Returns
    -------
    2D-array
       full tensor of shape `(factors[0].shape[0], ..., factors[-1].shape[0])`

    Notes
    -----
    This implementation is equivalent to:

    >>> def tucker_to_tensor(core, factors):
    ...     for i, matrix in enumerate(factors):
    ...         if not i:
    ...             res = mode_dot(core, matrix, i)
    ...         else:
    ...             res = mode_dot(res, matrix, i)
    ...     return res
    """
    return multi_mode_dot(core, factors, skip=skip_factor, transpose=transpose_factors)


def tucker_to_unfolded(core, factors, mode=0, skip_factor=None, transpose_factors=False):
    """Converts the Tucker decomposition into an unfolded tensor (i.e. a matrix)

    Parameters
    ----------
    core : ndarray
        core tensor
    factors : ndarray list
        list of matrices
    mode : None or int list, optional, default is None
    skip_factor : None or int, optional, default is None
        if not None, index of a matrix to skip
        Note that in any case, `modes`, if provided, should have a lengh of `tensor.ndim`
    transpose_factors : bool, optional, default is False
        if True, the matrices or vectors in in the list are transposed

    Returns
    -------
    2D-array
        unfolded tensor
    """
    return unfold(tucker_to_tensor(core, factors, skip_factor=skip_factor, transpose_factors=transpose_factors), mode)


def tucker_to_vec(core, factors, skip_factor=None, transpose_factors=False):
    """Converts a Tucker decomposition into a vectorised tensor

    Parameters
    ----------
    core : ndarray
        core tensor
    factors : ndarray list
        list of factor matrices
    skip_factor : None or int, optional, default is None
        if not None, index of a matrix to skip
        Note that in any case, `modes`, if provided, should have a lengh of `tensor.ndim`
    transpose_factors : bool, optional, default is False
        if True, the matrices or vectors in in the list are transposed

    Returns
    -------
    1D-array
        vectorised tensor

    Notes
    -----
    Mathematically equivalent but much slower,
    you can obtain the same result using:

    >>> def tucker_to_vec(core, factors):
    ...     return kronecker(factors).dot(tensor_to_vec(core))
    """
    return tensor_to_vec(tucker_to_tensor(core, factors, skip_factor=skip_factor, transpose_factors=transpose_factors))

back to top