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
    $\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 Jan 4 '16 at 18:19
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$
  • $\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 Jan 5 '16 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 Jan 5 '16 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 Jan 5 '16 at 21:29
  • $\begingroup$ If you replace Norm[#]^2 & with #.# &, it should even be quicker. $\endgroup$ – J. M. is away Feb 22 '16 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 Feb 22 '16 at 12:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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