MathGroup Archive 2009

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Fast calculation of pair correlation function

Hi Marcus,

It seems that there is no way around computing all pair distances,
so essentially we need a good old doubly nested loop. The code
below may however be faster than the naively implemented
nested loop - anyway, the best I could figure:

In[1] =

   iter : {start_?NumericQ, end_?NumericQ, delta_?NumericQ},
   points : {{_?NumericQ, _?NumericQ, _?NumericQ} ..}] :=
  With[{len = Length[points]},
   2/(len*(len - 1))*
         If[#2 === {len}, {},
          Sqrt@Total[(Transpose[Drop[points, First[#2]]] - #)^2]
         iter] &,

What is being done here is that for every point, distances to all
points after it are computed at once and immediately binned, so that
they don't take space. All the binned results are then summed together
to form the final distribution.

You give this function your parameters (the distance interval and the
delta), plus your list of generated 3D points. It returns the accordingly
binned distribution.

Here are 2000 random points (each of the 3 coordinates is random in
the interval (-10,10)):

In[2] = positions = RandomReal[{-10, 10}, {2000, 3}];

It takes about 8 sec. on my not too fast 5-years old P IV laptop:

In[3] = (distr = pairDistanceDistribution[{0, 40, 1.}, positions]) // Timing

Out[3] =

{8.252, {0.000504752, 0.00324262, 0.00828264, 0.0149035, 0.0221901,
  0.0304032, 0.0385338, 0.046089, 0.0538494, 0.0599565, 0.0653697,
  0.0693417, 0.0716418, 0.0727229, 0.0724892, 0.0691691, 0.0650805,
  0.0583087, 0.0500475, 0.0406423, 0.0302661, 0.0215503, 0.0144322,
  0.00927564, 0.00569185, 0.0032051, 0.00163432, 0.000715358,
  0.000301651, 0.000121061, 0.0000325163, 3.50175*10^-6,
  1.50075*10^-6, 0., 0., 0., 0., 0., 0., 0.}}

The distribution is normalized to 1:

In[4] = Total[distr]

Out[4] = 1.

Internal compilation probably will not help all that much, since we
the problem anyway. The complexity is of course quadratic with the size
of your sample, but there seems to be no way around it. For a sample of
10000 points, my machine will then do it in roughly 3-4 minutes, and the
modern fast desktop will probably be 3-4 times faster.

Finally, it seems that your problem can be parallelized quite well,
you may try parallel constructs in Mathematica to further speed it up,
if you have a multi-core machine.


On Tue, Apr 14, 2009 at 3:19 AM, markus <markusg.phys at> wrote:

> Hi,
> I have a quite large list (length ~ 10,000) of coordinates (positions
> of particles from a simulation), e.g. data={{x1,y1,z1},
> {x2,y2,z2},...}, and I am looking for fast way to calculate the "pair
> correlation" or "radial distribution function", which tells me, for
> each value of r, how many particles are separated by a distance r (+-
> epsilon).
> Usually, this can be calculated by something like:
> Do[Do[histogr[[ Ceiling[Norm[ data[[i]]-data[[j]] ] / delta] ]], {j, i
> +1, Length[data]}], {i, 1, Length[data]-1}]
> where histogr is just a list whose index corresponds to the distance
> r.
> Unfortunately I have found that for lists of length >1,000, this way
> of calculating is very slow (it can take ~minutes), compared to the
> equivalent C code, which proceeds in a few seconds. I have also tried
> to "Compile" the function, but the speed does not increase...
> Does anybody know some fast way of calculating the pair distribution
> function in Mathematica?

  • Prev by Date: Re: Fast calculation of pair correlation function
  • Next by Date: Re: Re: Should I be using Mathematica at all?
  • Previous by thread: Re: Fast calculation of pair correlation function
  • Next by thread: Re: Fast calculation of pair correlation function