4
$\begingroup$

I'd like to calculate the following one-dimensional array:

OneDimArray = Table[(Norm[Sum[ MatrixA[[i,j]]VectorB[[j]],{j,N}]])^2,{i,N}]

However this takes a very long time when N goes up; for N = 1500 it already takes ~40 minutes (on my MacBook Pro).

I've heard there are certain functions in Mathematica that are optimized for speed; could I employ those (and if so: which ones?) to speed up this calculation?

Thanks a lot in advance for any help!

Steven

$\endgroup$
1
  • 1
    $\begingroup$ I'm pretty sure you can just do Abs[Dot[MatrixA, VectorB]]^2. By the way, don't use capitalized words for user-defined symbols so as not to conflict with Mathematica's built-in functions, which all start with capital letters. $\endgroup$
    – march
    Commented Jan 4, 2016 at 18:19

1 Answer 1

8
$\begingroup$

You have plenty of redundant operations here:

The equivalent code is (where a is a matrix and b is a list of 3-vectors):

Map[Norm[#]^2 &, a . b];

I have:

n = 500;
a = RandomReal[1, {n, n}];
b = RandomReal[1, {n, 3}];

oneDimArray = 
   Table[(Norm[Sum[a[[i, j]] b[[j]], {j, n}]])^2, {i, 
     n}]; // AbsoluteTiming
(* {46.5618, Null} *)

oneDimArrayMap = Map[Norm[#]^2 &, a.b]; // AbsoluteTiming
(* {0.000621823, Null} *)

oneDimArray == oneDimArrayMap
(* True *)

Thus, using Dot almost 70000 times faster than manual loops.

$\endgroup$
7
  • $\begingroup$ Apologies; my question wasn't complete/correct: the vectorB I'm working with in this case is actually an array of 3-dimensional vectors -- and, to be as complete as possible now, the MatrixA the eigenvectors of a Hamiltonian of an excitonic vibrational system. (The physics, for context: To calculate the IR absorption intensities of the normal modes of such a system one has to first multiply the local mode vectors in VectorB with their respective eigenvector contribution, then sum these products to get the normal mode vector; the intensity of the mode is then given by norm[NormalModeVector]^2.) $\endgroup$
    – Steven R
    Commented Jan 5, 2016 at 7:59
  • $\begingroup$ @StevenR Than you still can utilize the Dot with a simple Map on it. On random matrix-vector I have 70000 speed up. Try this code on your data and let us know. $\endgroup$
    – m0nhawk
    Commented Jan 5, 2016 at 8:31
  • $\begingroup$ Wow, indeed, that gives a 45000-fold speed up for my specific matrices, thank you very much for the great advice m0nhawk! $\endgroup$
    – Steven R
    Commented Jan 5, 2016 at 21:29
  • $\begingroup$ If you replace Norm[#]^2 & with #.# &, it should even be quicker. $\endgroup$ Commented Feb 22, 2016 at 12:28
  • $\begingroup$ @J.M. I have tried it, but no performance improvements, timing is the same for me (in Mathematica 10.3). $\endgroup$
    – m0nhawk
    Commented Feb 22, 2016 at 12:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.