Re-compose a Tensor after tensor factorization
<p>I am trying to decompose a 3D matrix using python library <a href="https://github.com/mnick/scikit-tensor">scikit-tensor</a>. I managed to decompose my Tensor (with dimensions 100x50x5) into three matrices. My question is how can I compose the initial matrix again using the decomposed matrix produced with Tensor factorization? I want to check if the decomposition has any meaning. My code is the following:</p>

<pre><code>import logging
from scipy.io.matlab import loadmat
from sktensor import dtensor, cp_als
import numpy as np

//Set logging to DEBUG to see CP-ALS information
logging.basicConfig(level=logging.DEBUG)
T = np.ones((400, 50))
T = dtensor(T)
P, fit, itr, exectimes = cp_als(T, 10, init='random')
// how can I re-compose the Matrix T? TA = np.dot(P.U[0], P.U[1].T)
</code></pre>

<p>I am using the canonical decomposition as provided from the scikit-tensor library function cp_als. Also what is the expected dimensionality of the decomposed matrices?</p>

<p>The CP product of, for example, 4 matrices</p>

<p><img src="https://chart.googleapis.com/chart?cht=tx&amp;chl=X_%7Babcd%7D+%3D+%5Cdisplaystyle%5Csum_%7Bz%3D0%7D%5E%7BZ%7D%7BA_%7Baz%7D+B_%7Bbz%7D+C_%7Bcz%7D+D_%7Bdz%7D%7D+%2B+%5Cepsilon_%7Babcd%7D" alt="X_{abcd} = \displaystyle\sum_{z=0}^{Z}{A_{az} B_{bz} C_{cz} D_{dz} + \epsilon_{abcd}}"></p>

<p>can be expressed using <a href="https://en.wikipedia.org/wiki/Einstein_notation" rel="nofollow">Einstein notation</a> as</p>

<p><img src="https://chart.googleapis.com/chart?cht=tx&amp;chl=X_%7Babcd%7D+%3D+A_%7Baz%7D+B_%7Bbz%7D+C_%7Bcz%7D+D_%7Bdz%7D+%2B+%5Cepsilon_%7Babcd%7D" alt="X_{abcd} = A_{az} B_{bz} C_{cz} D_{dz} + \epsilon_{abcd}"></p>

<p>or in numpy as</p>

<pre><code>numpy.einsum('az,bz,cz,dz -&gt; abcd', A, B, C, D)
</code></pre>

<p>so in your case you would use</p>

<pre><code>numpy.einsum('az,bz-&gt;ab', P.U[0], P.U[1])
</code></pre>

<p>or, in your 3-matrix case</p>

<pre><code>numpy.einsum('az,bz,cz-&gt;abc', P.U[0], P.U[1], P.U[2])
</code></pre>

<p><code>sktensor.ktensor.ktensor</code> also have a method <code>totensor()</code> that does exactly this:</p>

<pre><code>np.allclose(np.einsum('az,bz-&gt;ab', P.U[0], P.U[1]), P.totensor())
&gt;&gt;&gt; True
</code></pre>

python math data-science scikits