COMPGROUPS.NET | Search | Post Question | Groups | Stream | About | Register

### Vector/Matrix Multiplication

• Email
• Follow

```I'm looking for some help in avoiding a for loop. I have a set of vectors, for all n from 1 to N (N is about 5,000):
En = [e(1,n) e(2,n) e(3,n)]

I want to create a set of matrices by multiplying these vectors with themselves. I'd wind up with a set of 3 x 3 matrices:
Fn = En' * En

I can do this easily enough by looping through all values of n and creating each Fn individually; however, I'd like to avoid that if possible - this routine will get called a number of times, and looping through this operation 5,000 times on each occasion will start to drag. What I'd like to do is combine all the En vectors into a matrix (they're already basically in a 3 x n matrix of course), perform a single operation on them, and finish with a 3 x 3 x n matrix that stacks all the Fn matrices together.

Is there a simple command or procedure that I could use to do this? Thanks.
```
 0

See related articles to this posting

```"William " <whiggins@dfsadvisory.com.au> wrote in message <ig11f1\$2t8\$1@fred.mathworks.com>...
> I'm looking for some help in avoiding a for loop. I have a set of vectors, for all n from 1 to N (N is about 5,000):
>     En = [e(1,n) e(2,n) e(3,n)]
>
> I want to create a set of matrices by multiplying these vectors with themselves. I'd wind up with a set of 3 x 3 matrices:
>     Fn = En' * En
>
> I can do this easily enough by looping through all values of n and creating each Fn individually; however, I'd like to avoid that if possible - this routine will get called a number of times, and looping through this operation 5,000 times on each occasion will start to drag. What I'd like to do is combine all the En vectors into a matrix (they're already basically in a 3 x n matrix of course), perform a single operation on them, and finish with a 3 x 3 x n matrix that stacks all the Fn matrices together.
>
> Is there a simple command or procedure that I could use to do this? Thanks.

r = reshape(e,[1 3 n]);
F = mtimesx(r,'T',r);

You can find mtimesx on the FEX here:

http://www.mathworks.com/matlabcentral/fileexchange/25977-mtimesx-fast-matrix-multiply-with-multi-dimensional-support

James Tursa
```
 0

```"James Tursa" wrote in message <ig14cp\$dai\$1@fred.mathworks.com>...
> "William " <whiggins@dfsadvisory.com.au> wrote in message <ig11f1\$2t8\$1@fred.mathworks.com>...
> > I'm looking for some help in avoiding a for loop. I have a set of vectors, for all n from 1 to N (N is about 5,000):
> >     En = [e(1,n) e(2,n) e(3,n)]
> >
> > I want to create a set of matrices by multiplying these vectors with themselves. I'd wind up with a set of 3 x 3 matrices:
> >     Fn = En' * En
> >
> > I can do this easily enough by looping through all values of n and creating each Fn individually; however, I'd like to avoid that if possible - this routine will get called a number of times, and looping through this operation 5,000 times on each occasion will start to drag. What I'd like to do is combine all the En vectors into a matrix (they're already basically in a 3 x n matrix of course), perform a single operation on them, and finish with a 3 x 3 x n matrix that stacks all the Fn matrices together.
> >
> > Is there a simple command or procedure that I could use to do this? Thanks.
>
> r = reshape(e,[1 3 n]);
> F = mtimesx(r,'T',r);
>
> You can find mtimesx on the FEX here:
>
> http://www.mathworks.com/matlabcentral/fileexchange/25977-mtimesx-fast-matrix-multiply-with-multi-dimensional-support
>
> James Tursa

Thanks a lot, this looks great. However, I don't (didn't) have a C compiler on my computer. I tried installing Microsoft Visual C++ 2010 Express (a free download), but I still get the error message "A C/C++ compiler has not been selected with mex -setup". Do you have any advice for sorting this out?
```
 0

```"William " <whiggins@dfsadvisory.com.au> wrote in message <ig36c1\$ida\$1@fred.mathworks.com>...
>
> Thanks a lot, this looks great. However, I don't (didn't) have a C compiler on my computer. I tried installing Microsoft Visual C++ 2010 Express (a free download), but I still get the error message "A C/C++ compiler has not been selected with mex -setup". Do you have any advice for sorting this out?

I'm guessing you have a 64-bit system. Does mex find the compiler you just installed? e.g., what do you get when you do this:

mex -setup
(then press Enter)

I don't have a 64-bit system to test with, so I am unsure if there is anything special you must do to mex with VC Express. Maybe someone else out there in newsgroup land can shed light on this.

James Tursa
```
 0

```Here's another approach using BSXFUN

%fake data
n=2;
E=rand(3,n);

%engine
E1=reshape(E,3,1,n);
E2=reshape(E,1,3,n);
ResultingStack=bsxfun(@times,E1,E2);
```
 0

```"James Tursa" wrote in message <ig3a5t\$msp\$1@fred.mathworks.com>...
> I'm guessing you have a 64-bit system. Does mex find the compiler you just installed? e.g., what do you get when you do this:
>
> mex -setup
> (then press Enter)
>
> I don't have a 64-bit system to test with, so I am unsure if there is anything special you must do to mex with VC Express. Maybe someone else out there in newsgroup land can shed light on this.
>
> James Tursa

Thanks for the response. I'm actually running a 32-bit system here. 'mex -setup' doesn't find the compiler I just installed; instead it just comes up with the Matlab compiler, "Lcc-win32 C 2.4.1 in C:\PROGRA~1\MATLAB\R2010a\sys\lcc", which I believe doesn't support OpenMP compiling.
```
 0

```"William " <whiggins@dfsadvisory.com.au> wrote in message <ig3bf4\$fr8\$1@fred.mathworks.com>...
> "James Tursa" wrote in message <ig3a5t\$msp\$1@fred.mathworks.com>...
> > I'm guessing you have a 64-bit system. Does mex find the compiler you just installed? e.g., what do you get when you do this:
> >
> > mex -setup
> > (then press Enter)
> >
> > I don't have a 64-bit system to test with, so I am unsure if there is anything special you must do to mex with VC Express. Maybe someone else out there in newsgroup land can shed light on this.
> >
> > James Tursa
>
> Thanks for the response. I'm actually running a 32-bit system here. 'mex -setup' doesn't find the compiler I just installed; instead it just comes up with the Matlab compiler, "Lcc-win32 C 2.4.1 in C:\PROGRA~1\MATLAB\R2010a\sys\lcc", which I believe doesn't support OpenMP compiling.

You don't need an OpenMP compiler to use mtimesx. The build routine will automatically detect that you are using lcc and not use OpenMP code. So you will not have the LOOPSOMP or SPEEDOMP modes available, but all the other modes will work. All of the features of mtimesx such as multi-dimensional support, inline code for small (4x4 or less) matrix multiplies, etc, will still be available to you.

James Tursa
```
 0

```"William " <whiggins@dfsadvisory.com.au> wrote in message <ig3bf4\$fr8\$1@fred.mathworks.com>...
>
> Thanks for the response. I'm actually running a 32-bit system here. 'mex -setup' doesn't find the compiler I just installed;
===========

I would recommend uninstall/re-installing

instead it just comes up with the Matlab compiler, "Lcc-win32 C 2.4.1 in C:\PROGRA~1\MATLAB\R2010a\sys\lcc", which I believe doesn't support OpenMP compiling.
==========

Neither does Microsoft Visual C++ 2010 Express, or at least, that's the compiler I'm using and I haven't been able to tap into the OpenMP capabilities of mtimesx.

In any case, I'm seeing about a factor of 2 speed-up using MTIMESX as compared to BSXFUN when compiling under Microsoft Visual C++ 2010 Express. I still see some speed-up using LCC, but it's much less dramatic.

%fake data
n=100000;
E=rand(3,n);
mtimesx SPEED;

tic;
E1=reshape(E,3,1,n);
E2=reshape(E,1,3,n);
ResultingStack=bsxfun(@times,E1,E2);
toc;
%Elapsed time is 0.045623 seconds.

tic;
E2 = reshape(E,[1 3 n]);
ResultingStack = mtimesx(E2,'T',E2);
toc;
%Elapsed time is 0.024509 seconds.
```
 0

```On Jan 5, 7:01=A0am, "William " <whigg...@dfsadvisory.com.au> wrote:
> I'm looking for some help in avoiding a for loop. I have a set of vectors=
, for all n from 1 to N (N is about 5,000):
> =A0 =A0 En =3D [e(1,n) e(2,n) e(3,n)]

'Set of vectors'? Why not store them in a Nx3 matrix?

> I want to create a set of matrices by multiplying these vectors with them=
selves. I'd wind up with a set of 3 x 3 matrices:
> =A0 =A0 Fn =3D En' * En

Don't do this. The memory managment of handling all these
small vectors probably dominates the run-time of the loop.

> I can do this easily enough by looping through all values of n and creati=
ng each Fn individually; however, I'd like to avoid that if possible - this=
routine will get called a number of times, and looping through this operat=
ion 5,000 times on each occasion will start to drag.

Of course it will. Computations *do* take time.

> What I'd like to do is combine all the En vectors into a matrix (they're =
already basically in a 3 x n matrix of course), perform a single operation =
on them, and finish with a 3 x 3 x n matrix that stacks all the Fn matrices=
together.
>
> Is there a simple command or procedure that I could use to do this? Thank=
s.

Probably not.

The outer product of each pair of vectors will become
a matrix, so the outcome of the whole operation will
be a 3D array.

Pre-allocate the array at the start, and fill in one
matrix per iteration in the loop.

Rune
```
 0

```"William " <whiggins@dfsadvisory.com.au> wrote in message <ig11f1\$2t8\$1@fred.mathworks.com>...
> I'm looking for some help in avoiding a for loop. I have a set of vectors, for all n from 1 to N (N is about 5,000):
>     En = [e(1,n) e(2,n) e(3,n)]
>
> I want to create a set of matrices by multiplying these vectors with themselves. I'd wind up with a set of 3 x 3 matrices:
>     Fn = En' * En
=========

Incidentally, I'd be curious to know why you want to do this. Explicitly computing outer products like Fn = En' * En is often bad/unnecessary, because for example, multiplying Fn with a vector, that is Fn*x, is more efficiently done as
En' * (En*x) rather than as
(En' * En)*x. The former requires only 6 multiplies while the latter requires 18.

```
 0

```"Matt J" wrote in message <ig3jni\$7ib\$1@fred.mathworks.com>...
> "William " <whiggins@dfsadvisory.com.au> wrote in message <ig3bf4\$fr8\$1@fred.mathworks.com>...
> >
>  instead it just comes up with the Matlab compiler, "Lcc-win32 C 2.4.1 in C:\PROGRA~1\MATLAB\R2010a\sys\lcc", which I believe doesn't support OpenMP compiling.
> ==========
>
> Neither does Microsoft Visual C++ 2010 Express, or at least, that's the compiler I'm using and I haven't been able to tap into the OpenMP capabilities of mtimesx.

Correct. Only MSVC 2005 Pro, 2008 Pro, and 2010 Pro have OpenMP capabilities. None of the earlier MSVC versions or any MSVC Standard or Express version support OpenMP.

James Tursa
```
 0

```Use BSXFUN as Matt suggestion if you can't want to compile MEX for MTIMESX.

Bruno
```
 0

```"James Tursa" wrote in message <ig3ke0\$mdh\$1@fred.mathworks.com>...
>
> > Neither does Microsoft Visual C++ 2010 Express, or at least, that's the compiler I'm using and I haven't been able to tap into the OpenMP capabilities of mtimesx.
>
> Correct. Only MSVC 2005 Pro, 2008 Pro, and 2010 Pro have OpenMP capabilities. None of the earlier MSVC versions or any MSVC Standard or Express version support OpenMP.
========

And it's only  a matter of having the right compiler? Too bad posting mex files on the FEX isn't possible. That way, you could post pre-compiled OpenMP-enabled mexes of mtimesx there for those of us without the inferior compilers...
```
 0

```"Matt J" wrote in message <ig7s0p\$t4d\$1@fred.mathworks.com>...
> "James Tursa" wrote in message <ig3ke0\$mdh\$1@fred.mathworks.com>...
> >
> > > Neither does Microsoft Visual C++ 2010 Express, or at least, that's the compiler I'm using and I haven't been able to tap into the OpenMP capabilities of mtimesx.
> >
> > Correct. Only MSVC 2005 Pro, 2008 Pro, and 2010 Pro have OpenMP capabilities. None of the earlier MSVC versions or any MSVC Standard or Express version support OpenMP.
> ========
>
> And it's only  a matter of having the right compiler? Too bad posting mex files on the FEX isn't possible. That way, you could post pre-compiled OpenMP-enabled mexes of mtimesx there for those of us without the inferior compilers...

I suppose I could do this for OpenMP stuff in general, but my past experience with BLAS/LAPACK stuff is that mex routines compiled under one version of MATLAB will not run under another version of MATLAB (at least on my 32-bit WinXP machine). I don't really know what the source of the problem is and haven't had time to track it down. So for mtimesx it becomes a bit complicated to supply pre-compiled code.

James Tursa
```
 0

```"James Tursa" wrote in message <ig7uoq\$t6u\$1@fred.mathworks.com>...
> "Matt J" wrote in message <ig7s0p\$t4d\$1@fred.mathworks.com>...

> I suppose I could do this for OpenMP stuff in general, but my past experience with BLAS/LAPACK stuff is that mex routines compiled under one version of MATLAB will not run under another version of MATLAB (at least on my 32-bit WinXP machine).

FYI James, I so have the same compiles MTIMESX 32-Mex that works on 2006B and 2010B under Matlab.

Bruno
```
 0

```"Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <ig809k\$a8a\$1@fred.mathworks.com>...
> "James Tursa" wrote in message <ig7uoq\$t6u\$1@fred.mathworks.com>...
> > "Matt J" wrote in message <ig7s0p\$t4d\$1@fred.mathworks.com>...
>
> > I suppose I could do this for OpenMP stuff in general, but my past experience with BLAS/LAPACK stuff is that mex routines compiled under one version of MATLAB will not run under another version of MATLAB (at least on my 32-bit WinXP machine).
>
> FYI James, I so have the same compiles MTIMESX 32-Mex that works on 2006B and 2010B under Matlab.
>
> Bruno

Hmmm ... when I try it it doesn't work. MTIMESX compiled on R2006b works until R2007b where it breaks.  The reverse situation also happens with me ... MTIMESX compiled in R2010a works backwards but not all the way back to R2006b. I was guessing that the break was due to the fact that the BLAS/LAPACK library was split into two files at R2007b so if it links and finds the BLAS routines in libmwlapack it can't subsequently find them if you run the compiled code in a version that has these routine split out into the separate file libmwblas. And vice-versa. But now your report that the same mex file works in 2006b and 2010b has me totally puzzled.

James Tursa
```
 0

```"Matt J" wrote in message <ig7s0p\$t4d\$1@fred.mathworks.com>...
> "James Tursa" wrote in message <ig3ke0\$mdh\$1@fred.mathworks.com>...
> >
> > > Neither does Microsoft Visual C++ 2010 Express, or at least, that's the compiler I'm using and I haven't been able to tap into the OpenMP capabilities of mtimesx.
> >
> > Correct. Only MSVC 2005 Pro, 2008 Pro, and 2010 Pro have OpenMP capabilities. None of the earlier MSVC versions or any MSVC Standard or Express version support OpenMP.
> ========
>
> And it's only  a matter of having the right compiler? Too bad posting mex files on the FEX isn't possible. That way, you could post pre-compiled OpenMP-enabled mexes of mtimesx there for those of us without the inferior compilers...

What OS and MATLAB version are you using?

James Tursa
```
 0

```"James Tursa" wrote in message <ig84f8\$ck7\$1@fred.mathworks.com>...
> "Matt J" wrote in message <ig7s0p\$t4d\$1@fred.mathworks.com>...
> > "James Tursa" wrote in message <ig3ke0\$mdh\$1@fred.mathworks.com>...
> > >
> > > > Neither does Microsoft Visual C++ 2010 Express, or at least, that's the compiler I'm using and I haven't been able to tap into the OpenMP capabilities of mtimesx.
> > >
> > > Correct. Only MSVC 2005 Pro, 2008 Pro, and 2010 Pro have OpenMP capabilities. None of the earlier MSVC versions or any MSVC Standard or Express version support OpenMP.
> > ========
> >
> > And it's only  a matter of having the right compiler? Too bad posting mex files on the FEX isn't possible. That way, you could post pre-compiled OpenMP-enabled mexes of mtimesx there for those of us without the inferior compilers...
>
> What OS and MATLAB version are you using?

Me? or Bruno?

I'm running R2010b on two machines, one running Windows XP Pro SP3 and one running Windows 7.
```
 0

```"James Tursa" wrote in message <ig84f8\$ck7\$1@fred.mathworks.com>...
> "Matt J" wrote in message <ig7s0p\$t4d\$1@fred.mathworks.com>...
> > "James Tursa" wrote in message <ig3ke0\$mdh\$1@fred.mathworks.com>...

>
> What OS and MATLAB version are you using?

The Mex is compiled with MSVS 2010 Premium + Windows7 + Matlab 2010B

It works on
-W7 2010B (of course) but also on
-Vista 2010B, and
-Vista Matlab 2006 B

Bruno
```
 0

```"Matt J" wrote in message <ig85cq\$c0g\$1@fred.mathworks.com>...
>
>  I'm running R2010b on two machines, one running Windows XP Pro SP3 and one running Windows 7.

If you want, you can send me an e-mail (see the mtimesx pdf file for the address) and I will send you an OpenMP compiled version that *may* work on your machine.

James Tursa
```
 0

```"Matt J" wrote in message <ig3k4l\$45d\$1@fred.mathworks.com>...
> "William " <whiggins@dfsadvisory.com.au> wrote in message <ig11f1\$2t8\$1@fred.mathworks.com>...
> > I'm looking for some help in avoiding a for loop. I have a set of vectors, for all n from 1 to N (N is about 5,000):
> >     En = [e(1,n) e(2,n) e(3,n)]
> >
> > I want to create a set of matrices by multiplying these vectors with themselves. I'd wind up with a set of 3 x 3 matrices:
> >     Fn = En' * En
> =========
>
> Incidentally, I'd be curious to know why you want to do this. Explicitly computing outer products like Fn = En' * En is often bad/unnecessary, because for example, multiplying Fn with a vector, that is Fn*x, is more efficiently done as
>   En' * (En*x) rather than as
> (En' * En)*x. The former requires only 6 multiplies while the latter requires 18.
>

First up, thanks everyone for your responses. This has been quite edifying.

The use I'm making of Fn, once it's calculated, is that it gets multiplied by a scalar and added to a couple of other matrices, the end result being a correlation matrix for a vector of random variables. I'm certainly open to more efficient ways to go about that. The outcome, though, is 3 x 3 x n in size.

I've run into another related issue. I'll start a new thread about it, but basically, having calculated a 3 x 3 x n matrix, I subsequently need to calculate the matrix square roots of each 3 x 3 slice. Once again, easy to do by looping through each slice individually, but if there's a more efficient way to go about it, that would of course be preferable.
```
 0