Source code for pyCP_APR.numpy_backend.ttv_sptensor
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Python implementation of ttv 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
from . tt_dimscheck import tt_dimscheck
from . sptensor import SP_TENSOR
from . tensor import TENSOR
from . accum import accum as accumarray
[docs]def ttv(X, vecs, dims=[]):
"""
Tensor times vector for KRUSKAL tensor M.
Parameters
----------
X : object
Sparse tensor. sptensor.SP_TENSOR.
vecs : array
coluumn vector.
dims : list
list of dimension indices.
Returns
-------
c : array
product of KRUSKAL tensor X with a (column) vector vecs.
"""
dims, vidx = tt_dimscheck(dims, X.Dimensions, len(vecs))
remdims = np.setdiff1d(np.arange(X.Dimensions), vidx)
for d in range(len(dims)):
if vecs[str(vidx[d])].shape[0] != X.Size[dims[d]]:
raise Exception('Multiplicand is wrong size')
newvals = X.data
subs = X.Coords
if len(subs) == 0:
newsubs = []
for n in range(len(dims)):
idx = X.Coords[:, dims[n]]
w = vecs[str(vidx[n])]
bigw = w[idx]
newvals = np.multiply(newvals, bigw)
newsubs = subs[:, remdims]
# Case 0: If all dimensions were used, then just return the su
if len(remdims) == 0:
c = np.sum(newvals)
return c
# Otherwise, figure new subscripts and accumulate the results.
newsiz = np.array(X.Size)[remdims]
# Case I: Result is a vector
if len(remdims) == 1:
c = accumarray(accmap=newsubs, a=newvals, size=newsiz)
if np.count_nonzero(c) <= .5 * newsiz[0]:
c = SP_TENSOR(np.arange(0, newsiz).T, c, newsiz)
else:
c = TENSOR(c)
return c
# Case II: Result is a multiway array
c = SP_TENSOR(newsubs, newvals, newsiz)
return c