File Exchange

image thumbnail

TPROD -- arbitary tensor products between n-d arrays

version 1.4.0.0 (43.2 KB) by Jason Farquhar
TPROD -- efficiently allows any type of tensor product between 2 multi-dimensional arrays

5 Downloads

Updated 09 Mar 2012

View License

Multi-dimensional generalization of matrix multiplication

This function computes a generalized multi-dimensional matrix product based upon the einstein summation convention (plus extras). This means given 2 n-d inputs:
X = [ A x B x C x E .... ]
Y = [ D x F x G x H .... ]
we define the result, Z, to be (in ESC)
Z_{c,e,d,f} = X_{a,b,c,e} Y_{d,f,a,b}
(N.B. This syntax can be used directly with the etprod wrapper script).
This translates into tprod syntax as:
Z = tprod(X,[-1 -2 1 2],Y,[3 4 -1 -2])
N.B. if Y==[], then it is assumed to be a copy of X.
This result is produced by forming an inner-product (multiply+sum) for the pairs of dimensions which have the same (negative) label (i.e. -1 => X dim 1 and Y dim 3, and -2 => X dim 2 and Y dim 4) and forming an outer product for all the remaining dimensions, with the positive label determining where this dimension is placed in the output.

Cite As

Jason Farquhar (2020). TPROD -- arbitary tensor products between n-d arrays (https://www.mathworks.com/matlabcentral/fileexchange/16275-tprod-arbitary-tensor-products-between-n-d-arrays), MATLAB Central File Exchange. Retrieved .

Comments and Ratings (30)

boris fain

Ah. My previous comment was wrong. If you remove the previously compiled mex files, this package will default to a matlab (slower) implementation so at least your code will work. Otherwise, I've given up trying to compile the mex files by hand for various reasons.

b.

boris fain

Hello everyone. Indeed this version does not with the newer Matlab versions. However, I've downloaded the zip file from
http://www.socsci.ru.nl/jdrf/download.html and it works fine on R2019b

Haishi Li

This function does not work on MATLAB R2018b. Does anyone share the same problem?

Michael

@bawazeer: your implementation does not work for the suggested examples of tpod, e.g.
X = randn(100,1); % make 100 1-d data points
Z = tprod(X,1,X,1); % element-wise multiply, =X.*X
or
X=randn(10,100); % 10d points x 100 trials
Z=tprod(X,[-1 2],X,[-1 2]); % squared norm of each trial, =sum(X.*X)

This function is useful for me.However, I am not able to compile it. So, I wrote it entirely in Matlab, without the need for mex. The following function can be used instead of the original. I test it in my project, where it is working perfectly. Note: it needs more testing.

function [ss]=tprod(X,iX,Y,iY)
[res,ia,ib]=intersect(iX,iY);
%check sizes
%need to add some tests for dimensions
numer_of_sums=length(res(res<0));

[fX,ifX]=setdiff(iX,res);
[fY,ifY]=setdiff(iY,res);

res1=[res fX];
ia1 =[ia ifX];
ib1 =[ib [1:length(fX)]+length(iY)];

res2=[res1 fY];
ia2 =[ia1 [1:length(fY)]+length(iX)];
ib2 =[ib1 ifY];

[fS,iS]=sort(res2);
ia2(iS);
ib2(iS);

ss=permute(X,ia2(iS)).*permute(Y,ib2(iS));
for i=1:numer_of_sums
ss=sum(ss,i);
end
S=size(ss);
ss=reshape(ss,S(numer_of_sums+1:end));
return;

Runhai Feng

I am having a problem with this code in mac os High Sierra with Matlab 2017b.
It seems does not work and I always get an empty matrix.
There is no error information during the mex compiling process.
I also changed the code according to malin cik.
Does anyone know why?

Running the test suit on MATLAB R2015b under 64 bit Linux, it turns out that MATLAB's built-in functions are significantly faster than tprod.

Same error as "Premyslaw Bienias" and "Alexandre HYAFIL" on Matlab 2017b and windows10

I get the same error as Alexandre HYAFIL on Matlab R2017a and macOS Sierra
as well as on Windows 10.

It looks wonderful but not working on PC with Matlab 2017 and MinGW64 Compiler (C).
See the simplest example:
X = randn(100,1); % make 100 1-d data points
Z = tprod(X,1,X,1); % element-wise multiply, =X.*X
Error using tprod
tprod:Less X indicies than dimensions

Alas it is not working for me on ubuntu/linux mint using gcc-4.9
The mex operation compiles successfully with some warnings about incompatible point types.

I then run
X = randn(10,9,8,7,6);
Z = tprod(X,[1 2 -3 -4 3],X,[1 2 -3 -4 3]);

and get this error:
Warning: tprod: Empty matrix input!
> In tprod (line 158)
Error using tprod
Requested 10x4294967304x10 (3200.0GB) array exceeds maximum array size preference. Creation of
arrays greater than this limit may take a long time and cause MATLAB to become unresponsive.
See array size limit or preference panel for more information.

Error in tprod (line 158)
[varargout{1:nargout}] = feval(mfilename, varargin{:});

The input data was somehow trashed prior to execution.

malin cik

It seems that tprod cannot handle large sparse matrices. If one passes the full matrix to tprod instead, it takes forever (in particular it becomes much slower than a simple matlab for-loop).

Is it possible to update it?

Also, there is a problem running tprod with the mac OS mex compiler (Xcode), as the definition and usage of the INLINE function has been changed in the last edition. Currently the two files mxInfo.h and tprod.h contain the piece of code:

/* check the compilier state to use the appropriate inline directive */
#ifdef __GNUC__ /* use the GNUC special form */
#define INLINE __inline__
#elif defined(__STDC__) && __STDC_VERSION__ >= 199901L /*C99 compat compilier*/
#define INLINE static inline
#else /* fall back on C89 version, i.e. *no inlines* */
#define INLINE
#endif

If one replaces it by

/* check the compilier state to use the appropriate inline directive */
#if defined(__STDC__) && __STDC_VERSION__ >= 199901L /*C99 compat compilier*/
#define INLINE static inline
#elif defined(__GNUC__) /* use the GNUC special form */
#define INLINE __inline__
#else /* fall back on C89 version, i.e. *no inlines* */
#define INLINE
#endif

then tprod works properly.

Mahdi

Lennart

Maybe some extra explanation about the syntax would help the people less known with Tensor Algebra like myself.

Lennart

Extremely useful, ridiculous that matlab cant do this normally. When your functions get single precision input more than half of the inbuilt tests fail by the way.

Sounds great, but I get accuracy error in tprod_testcases:

****************
Double Real X, Single Real Y
******************
dRsR OuterProduct, [1],[2] = 5.96e-08 Passed
dRsR Inner product, [-1],[-1] = 3.76e-08 Passed
dRsR Matrix product, [1 -1],[-1 2] = 3.22e-06 Passed
dRsR transposed matrix product, [-1 1],[-1 2] = 3.56e-06 Passed
dRsR Matrix frobenius norm, [-1 -2],[-1 -2] = 6.94e-07 Passed
dRsR transposed matrix frobenius norm, [-1 -2],[-2 -1] = 7.48e-07 Passed
dRsR ignored dims, [0 -2],[-2 2 1] = 4.49e-06 Passed
dRsR spatio-temporal filter [-1 -2 1],[-1 -2] = 7.2e-05 **FAILED***

The above was from MATLAB 7.14.0.739 (R2012a), OSX Xcode 4.3. I've also tried it with MATLAB 7.13.0.564 (R2011b), OSX Xcode 4.3 and I also get an accuracy error, but at a different spot:

****************
Double Real X, Single Real Y
******************
dRsR OuterProduct, [1],[2] = 5.96e-08 Passed
dRsR Inner product, [-1],[-1] = 2.88e-07 Passed
dRsR Matrix product, [1 -1],[-1 2] = 2.94e-06 Passed
dRsR transposed matrix product, [-1 1],[-1 2] = 3.55e-06 Passed
dRsR Matrix frobenius norm, [-1 -2],[-1 -2] = 3.65e-05 **FAILED***
Warning: dRsR Matrix frobenius norm, [-1 -2],[-1 -2]: failed!

Great tool, thanks. (how) would it be possible to create a simulink block with this functionality?

Please consider re-writing the help text to better explain the syntax. Some examples provided cause syntax error. See the link:
http://www.mathworks.com/matlabcentral/answers/14046-i-didn-t-understand-how-put-the-inputs-in-tprod-function

Mark

Those interested in tensor operations may also be interested in the Tensor Toolbox from Sandia National Labs:

http://csmr.ca.sandia.gov/~tgkolda/TensorToolbox/

Steven

Invaluable and has become a constantly utilized function for image processing. Have you thought about adding GPU capability?

How is the speed of this code, in comparison to unfolding the tensors manually into matrix-vector form, and then doing the multiplication with matlab ?

Ira ekhaus

Hi Again,
I contacted the author and he was fast&accurate at helping to get going with a new TPROD rev that works with matlab's internal lcc compiler.

Excellent!

Ira ekhaus

Has anyone successfully run this package with matlab R2007b ?

Thx

Brilliant! I couldn't do without this code. By the way it is very stable and easy to use (once you get the hang of it).

Carl Rasmussen

The 2008-06-26 version works flawlessly. Thank you Jason for writing this. Disgraceful that mathworks don't provide even something as simple as a multidimensional product...

marc deisenroth

excellent code, easy to use (especially after adding the etprod wrapper). cool stuff!

Timothy Wilson

This package highlights an area where MATLAB falls short: multiplying high order tensors.
The code is well optimised and simple to use compared with other similar packages.
The input is based on Einstien Summation therefore easily accessble to anyone working with high rank tensors.

Updates

1.4.0.0

Updated the examples in tprod.m to show the equlivalent matlab code, and to include more complex examples

1.3.0.0

(Another) fix to make it compile with pedantic c-compilers, e.g. lcc.

1.2.0.0

Updated to work with very restrictive C dialects (such as LCC's) -- particularly when used on windows.

1.1.0.0

Bug fixes -- 1) problem with certain unusual calling orders.
2) compilation with lcc

1.0.0.0

A couple of bug-fixes to prevent memory management errors

Bug fix

Bug Fix -- fixed a memory management bug when using mixed double/single inputs

Fixed a bug when result causes out of memory errors.
Updated calling syntax to be more like try ESC.
Added a new m-file wrapper, etprod, which makes tprod calls look much more like ESC.
Added support for single and mixed single/double matrices

Fixed a bug when using mixed complex/real inputs. Also updates to the test-case code.

Fixed a bug in the processing of mixed complex/real products

Updated description to reflect functions actual operation

MATLAB Release Compatibility
Created with R13
Compatible with any release
Platform Compatibility
Windows macOS Linux