Distances between points in periodic cube
I'm assuming here that x
is a list of points between which you want to calculate the distance. If so, then I think your code can be condensed to something like
PeriodicDistance[x_, size_: 1] := Outer[Norm@Mod[#2 - #1, size, -size/2] &, x, x, 1]
Edit
A faster version of the code above is something like
PeriodicDistance3[x_, size_: 1] :=
Map[Norm, Mod[Outer[Subtract, x, x, 1], size, -size/2], {-2}]
On my system this is about as efficient as the code in the original question, whereas the previous version is a factor 2 to 3 slower.
Very late to the party, but I'll show a method that's faster than anything posted so far and will be hard to beat.
First let's define our PeriodicDistance
:
PeriodicDistance = Compile[{{x, _Real, 1}, {y, _Real, 2}, {size, _Real}},
Sqrt@Total[((x - y) - size*Round[(x - y)/size])^2],
CompilationTarget :> "C", RuntimeOptions -> "Speed"];
Now our distance matrix:
PeriodicDistanceMatrix[dat_?MatrixQ, size_Real:1.0] :=
With[{tr = Transpose[dat]}, Map[PeriodicDistance[dat[[#]], tr, size] &, Range@Length@dat]]
Some Timings:
data = RandomReal[1, {2000, 3}];
(* This answer *)
PeriodicDistanceMatrix[data]; // AbsoluteTiming
(* 0.265632 *)
(* Heike's faster version *)
PeriodicDistanceB[data]; //AbsoluteTiming
(* 2.599099 *)
(* J.M.'s answer *)
PeriodicDistance[data]; // AbsoluteTiming
(* 6.246279 *)
(* O.P.'s version *)
PeriodicDistance2[data]; // AbsoluteTiming
(* 10.026386 *)
And yes, all the outputs are identical.
Edit
Needs["GeneralUtilities`"] (* for v10 *)
BenchmarkPlot[{RunnyKine, Heike, JM}, RandomReal[1, {#, 3}] &, 2^Range[6, 14]]
You want something like
PeriodicDistance[pts_, size_: 1] :=
Outer[EuclideanDistance, size*FractionalPart[pts/size],
size*FractionalPart[pts/size], 1]
But what you did is a bit different in terms of how you wrap things periodically. If it is really as you intended, replace size everywhere by 2*size.
PeriodicDistanceB[pts_, size_: 1] :=
Outer[EuclideanDistance, 2*size*FractionalPart[pts/(2*size)],
2*size*FractionalPart[pts/(2*size)], 1]