I'm trying to speed up a function that looks in the neighborhood of each 3D point in a large dataset and finds all the points within 1 unit in each direction, x, y, z.
I've started by using Select to find the points around a specified point and then Map this function over the dataset.
First, lets make up some "data" and then define the findpoints function.
data = RandomReal[10, {10^4, 3}];
findpoints[data_, pt_]:= Block[{x = pt[[1]], y = pt[[2]], z = pt[[3]]},
Select[data,
x - 1 <= #[[1]] <= x + 1 && y - 1 <= #[[2]] <= y + 1 &&
z - 1 <= #[[3]] <= z + 1 &]
]
Now lets map it over the random data.
Map[findpoints[data, #] &, data]; // AbsoluteTiming
This is quite slow, I gave up waiting, so I started by compiling the findpoint function.
findpointsC =
Compile[{{data, _Real, 2}, {pt, _Real, 1}},
Block[{x = pt[[1]], y = pt[[2]], z = pt[[3]]},
Select[data,
x - 1 <= #[[1]] <= x + 1 && y - 1 <= #[[2]] <= y + 1 &&
z - 1 <= #[[3]] <= z + 1 &]
], CompilationTarget -> "C", RuntimeAttributes -> {Listable},
Parallelization -> True, RuntimeOptions -> "Speed"];
output= Map[findpointsC[data, #] &, data]; // AbsoluteTiming
(*{3.7542147, Null}*)
Much faster, great.
Now I figured since compiling was so beneficial here and in other functions I found that by compiling the Map function I can gain some more speed, lets compile the whole thing.
mapfindpointsC =
Compile[{{data, _Real, 2}}, Map[findpointsC[data, #] &, data],
CompilationTarget -> "C", RuntimeAttributes -> {Listable},
Parallelization -> True, RuntimeOptions -> "Speed"];
mapfindpointsC[data]
(*CompiledFunction::cflist: Nontensor object generated; proceeding with uncompiled evaluation. >>*)
However, as per the error message, in this case the output is ragged.
TensorQ[output]
(*False*)
I've tried to flatten the output from map but nothing I can think of works. Is it possible to compile this expression.
CompilePrint[mapfindpointsC]and you'll see that, becausefindpointsCis defined externally, this doesn't really compile everything (or anything really). – acl Dec 02 '12 at 21:15