Source code for pyCP_APR.numpy_backend.ttm_sptensor

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Python implementation of ttm utility with Numpy backend from the MATLAB Tensor Toolbox [1].

References
========================================
[1] General software, latest release: Brett W. Bader, Tamara G. Kolda and others, Tensor Toolbox for MATLAB, Version 3.2.1, www.tensortoolbox.org, April 5, 2021.\n
"""
import numpy as np
import copy

from . sptensor import SP_TENSOR
from . tt_dimscheck import tt_dimscheck
from . tensor import TENSOR
from . tenmat_sptensor import tenmat

[docs]def ttm(X, V, varargin={}): """ Tensor times matrix operation. Parameters ---------- X : object Sparse tensor. sptensor.SP_TENSOR. V : np.ndarray Numpy array. varargin : dict Optional parameter to specify tflag and or mode settings. Returns ------- Y : object Sparse tensor. sptensor.SP_TENSOR. """ # # Create 'n' and 'tflag' arguments from varargin # n = np.arange(0, X.Dimensions) tflag = '' ver = 0 if len(varargin) == 1: if 'tflag' in varargin: tflag = varargin['tflag'] else: n = varargin['n'] elif len(varargin) == 2: n = varargin['n'] tflag = varargin['tflag'] elif len(varargin) == 3: n = varargin['n'] tflag = varargin['tflag'] ver = varargin['ver'] # # Handle cell array # if isinstance(V, list): dims = n dims, vidx = tt_dimscheck(dims, X.Dimensions, len(V)) Y = ttm(copy.deepcopy(X), V[vidx[0]], varargin={'n':dims[0], 'tflag':tflag}) for k in range(1, len(dims)): Y = ttm(copy.deepcopy(Y), V[vidx[k]], varargin={'n':dims[k], 'tflag':tflag}) else: # # COMPUTE SINGLE N-MODE PRODUCT # if tflag == 't': V = V.T cdims = [n] rdims = list(set(list(np.arange(0, X.Dimensions))) - set([n])) siz = list(X.Size) siz[n] = V.shape[0] siz = np.array(siz) order = rdims + cdims Xnt = tenmat(X, n) Z = np.dot(Xnt.T, V.T) c = np.transpose(np.nonzero(Z)) nnz_values = Z[np.nonzero(Z)] a = np.transpose(np.unravel_index(c[:,0], siz[rdims])) b = np.transpose(np.unravel_index(c[:,1], siz[cdims])) new_order = [0] * len(order) for old_idx, new_idx in enumerate(order): new_order[new_idx] = old_idx nnz_coords = np.hstack([a,b])[:,new_order] Y = SP_TENSOR(nnz_coords, nnz_values, siz) return Y