Skip to content
Advertisement

Fastest method of bilinear weighting of a 2D point cloud onto a grid

Given a point (0.8, 0.6) and an intensity (3), one can bi-linearly “reverse interpolate” a single point onto a 2×2 grid with integer indices (0,0) -> (1,1).

The points and grid are oriented with the first entry increasing downwards, and the second entry increasing towards the right.

On such a grid, the weight of just the coordinate above becomes:

JavaScript

and we can multiply by the intensity associated with the coordinate to give a 2×2 grid bilinearly weighted intensity:

JavaScript

And can be plotted like this:

Single bilinear weighting

For several points, one can weigh these onto the same array (full code below):

JavaScript

Weighting several points

For my work, I require both the weights and the intensity*weights as output arrays. I need to perform the above on a very large (10s of millions) number of coordinates, where the coordinates have values from 0.0 to 4095.0. I have written a numpy routine below, and while it is reasonably fast (1.25 sec) for 100_000 points, I would prefer it was faster as I need to call it several times on the 10_000_000 data points I have.

I considered vectorising the numpy code instead of a for loop, but then I’m generating a 4096×4096 mostly empty array for each point that I would then sum. That would require 1000 TB of ram.

I have also tried a naive implementation in cupy, but since I employ a for loop, it becomes far too slow.

In my code, I generate a 2×2 weighted array for each point, multiply the array by the intensity, and add those to the main arrays by slicing. Is there a better way?

JavaScript

For testing the code, I also offer the following plotting code – only use with a small (~10) number of points, or the scatter will cover the whole image.

JavaScript

Advertisement

Answer

Thanks @armamut for a good answer! It inspired me to look a bit, and I found np.bincount, which is also implemented in cupy. It turns out that the bincount implementation is faster, and the cupy implementation is really fast! The latter could probably be improved a bit further, since I had to juggle a few tuples to get it to work.

JavaScript

The numpy implementation:

JavaScript

And the cupy implementation:

JavaScript
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement