Skip to content

Instantly share code, notes, and snippets.

@kain88-de
Created May 27, 2018 10:46
Show Gist options
  • Save kain88-de/5002b18630e89c8ce839c2841ebe441d to your computer and use it in GitHub Desktop.
Save kain88-de/5002b18630e89c8ce839c2841ebe441d to your computer and use it in GitHub Desktop.
Benchmark Collision Detector
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from tqdm import tqdm_notebook"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook severs as a benchmark reference for distance calculations. In my current application I have a fixed set of particles that all have the same size. I need to find out quickly if a new particle will overlap with any of the existing particles. This means in any algorithm that uses the distance calculations the following two things happens.\n",
"\n",
"- Data structures are created once\n",
"- queries of single particles are done often.\n",
"\n",
"Therefore my optimal data structure has the **fastest possible query speed**. The construction time is almost negelebile for me.\n",
"\n",
"# Test Data\n",
"\n",
"As test data I chose to use points distributed evenly in a box. My actual data won't be so uniform distributed and the final results may vary."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"BOX = np.ones(3).astype(np.float32) * 100\n",
"CUTOFF = 10\n",
"\n",
"def get_coords(box, N):\n",
" return np.random.uniform(0, box[0], size=(N, 3)).astype(np.float32)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Data structures\n",
"\n",
"The most common data structures that I have implementations for are KDTrees and Cell-Lists. My own celllist implementation and the KDTree in MDAnalysis can both deal with periodic boundary conditions. As an extra benchmark I will try the BallTree and KDTree implemented in scikit-learn. "
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"from MDAnalysis.lib.pkdtree import PeriodicKDTree as KDTree\n",
"from sklearn import neighbors"
]
},
{
"cell_type": "code",
"execution_count": 99,
"metadata": {},
"outputs": [],
"source": [
"from collections import defaultdict\n",
"from MDAnalysis.lib import distances\n",
"import itertools\n",
"\n",
"\n",
"class CellList(object):\n",
" \"\"\"Generate cell list object\n",
"\n",
" The cell list is stored as a sparse hash-map. Hashes are the 3d coordinates.\n",
" The goal for this implementation is to quickly find neighbors to a single point.\n",
" Using the dict ensures that we only create 'cells' that are actually occupied.\n",
" \"\"\"\n",
" nei = [-1, 0, 1]\n",
" NEIGHBORS = list(itertools.product(nei, nei, nei))\n",
"\n",
" def __init__(self, box, coords, cell_size):\n",
" self._box = np.asarray(box)\n",
" # pack coords into box\n",
" self._coords = distances.apply_PBC(coords.astype(np.float32), self._box.astype(np.float32))\n",
" self._cell_size = np.ones(3) * cell_size\n",
"\n",
" self._ncells = (self._box // self._cell_size).astype(int) + 1\n",
"\n",
" cells = (self._coords // self._cell_size).astype(int)\n",
" cell_map = defaultdict(list)\n",
" for i, cell in enumerate(cells):\n",
" cell_map[tuple(cell)].append(i)\n",
" self._cell_map = cell_map\n",
"\n",
" def candidates(self, pos):\n",
" \"\"\"return all candidate coordinates for pos\n",
"\n",
" This means all coordinates of the cell in which pos is and all it's\n",
" neighboring cells.\n",
"\n",
" \"\"\"\n",
" cell = (pos // self._cell_size).astype(int)\n",
" indices = []\n",
" for neighbor_shift in self.NEIGHBORS:\n",
" neighbor_cell = cell + neighbor_shift\n",
" if not (np.all(0 <= cell) and np.all(cell < self._ncells)):\n",
" continue\n",
" indices.extend(self._cell_map[tuple(neighbor_cell)])\n",
"\n",
" return self._coords[indices]\n",
" \n",
" def search(self, pos, cutoff):\n",
" pos = np.array(pos, dtype=np.float32)\n",
" cand = self.candidates(pos)\n",
" dist = distances.distance_array(pos[:, np.newaxis], cand, box=box)[0]\n",
" return cand[dist < cutoff]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# check for correctness\n",
"\n",
"First I check if I can use all algorithms correctly. For this we calculate the neighbors from the center of the box with all algorithms and compare the results"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"coords = get_coords(BOX, 10000)\n",
"pos = BOX / 2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**MDA KDTree**"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"kdt = KDTree(BOX)\n",
"kdt.set_coords(coords)\n",
"kdt.search(pos, CUTOFF)\n",
"indices = kdt.get_indices()\n",
"mda_coords = coords[indices]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**CellList**"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [],
"source": [
"cl = CellList(BOX, coords, CUTOFF)\n",
"cl_coords = cl.search(pos, CUTOFF)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Scikit Learn BallTree**"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [],
"source": [
"bt = neighbors.BallTree(coords)\n",
"indices = bt.query_radius([pos], CUTOFF)[0]\n",
"bt_coords = coords[indices]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Scikit Learn KDTree**"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [],
"source": [
"skdt = neighbors.KDTree(coords)\n",
"indices = skdt.query_radius([pos], CUTOFF)[0]\n",
"skdt_coords = coords[indices]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now that have all coordinates we can compare them"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"True\n",
"True\n",
"True\n",
"True\n",
"True\n",
"True\n"
]
}
],
"source": [
"for a, b in itertools.combinations([mda_coords, cl_coords, bt_coords, skdt_coords], 2):\n",
" a = np.sort(a, axis=0)\n",
" b = np.sort(b, axis=0)\n",
" print(np.allclose(a, b))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Run benchmarks for querying and different sizes\n",
"\n",
"Here I only want to know if there is an overlap. The small helper functions here will return a boolean telling me if there is an overlap or not"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {},
"outputs": [],
"source": [
"def pkdtree(struct, pos, cutoff=CUTOFF):\n",
" struct.search(pos, cutoff)\n",
" return struct.get_indices() is None\n",
"\n",
"def celllist(struct, pos, cutoff=CUTOFF):\n",
" cand = struct.candidates(pos)\n",
" if len(cand) == 0:\n",
" return True\n",
" dist = cdist([pos], cand)\n",
" return np.all(dist > cutoff)\n",
"\n",
"def sklearn(struct, pos, cutoff=CUTOFF):\n",
" return struct.query_radius([pos], CUTOFF)[0] == 0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To measure the performance with increasing number of particles I could keep the box volume constant. This will mean though that the density is increased and therefore the chance of an overlap increases as well. I would rather have the density constant during my tests. This means the box dimensions have to be adjusted. As density I use the particle density\n",
"$$\n",
"d = \\frac{N}{V}\n",
"$$\n",
"from this the box len can be calculated\n",
"$$\n",
"l = \\left(\\frac{N}{d}\\right)^{1/3}\n",
"$$\n",
"As density I chose arbitrarly 0.1. "
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {},
"outputs": [],
"source": [
"def get_box_size(N, density=0.1):\n",
" return (np.ones(3) * np.cbrt(N/density)).astype(np.float32)"
]
},
{
"cell_type": "code",
"execution_count": 109,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "5dbf8b8a716d4f5fa5d2f82c08306255",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(IntProgress(value=0, max=15), HTML(value='')))"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
}
],
"source": [
"CUTOFF = 1\n",
"res = defaultdict(list)\n",
"res_build = defaultdict(list)\n",
"\n",
"for N in tqdm_notebook(np.unique(np.logspace(2, 5, num=15).astype(int))):\n",
"\n",
" box = get_box_size(N)\n",
" coords = get_coords(box, N)\n",
" pos = box / 2\n",
"\n",
" # Query test\n",
" \n",
" pkdt = KDTree(box)\n",
" pkdt.set_coords(coords)\n",
" cl = CellList(box, coords, CUTOFF)\n",
" bt = neighbors.BallTree(coords)\n",
" kdt = neighbors.KDTree(coords)\n",
" \n",
" res_pkdt = %timeit -o -q pkdtree(pkdt, pos, cutoff=CUTOFF)\n",
" res_cl = %timeit -o -q celllist(cl, pos, cutoff=CUTOFF)\n",
" res_bt = %timeit -o -q sklearn(bt, pos, cutoff=CUTOFF)\n",
" res_kdt = %timeit -o -q sklearn(kdt, pos, cutoff=CUTOFF)\n",
" \n",
" res['pkdt'].append(res_pkdt.average)\n",
" res['cl'].append(res_cl.average)\n",
" res['bt'].append(res_bt.average)\n",
" res['kdt'].append(res_kdt.average)\n",
" res['N'].append(N)\n",
" \n",
" # Building test\n",
" \n",
" res_pkdt = %timeit -o -q _pkdt=KDTree(box); _pkdt.set_coords(coords)\n",
" res_cl = %timeit -o -q CellList(box, coords, CUTOFF)\n",
" res_bt = %timeit -o -q neighbors.BallTree(coords)\n",
" res_kdt = %timeit -o -q neighbors.KDTree(coords)\n",
" \n",
" res_build['pkdt'].append(res_pkdt.average)\n",
" res_build['cl'].append(res_cl.average)\n",
" res_build['bt'].append(res_bt.average)\n",
" res_build['kdt'].append(res_kdt.average)\n",
" res_build['N'].append(N)"
]
},
{
"cell_type": "code",
"execution_count": 111,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 576x288 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, axes = plt.subplots(ncols=2, figsize=plt.figaspect(1/2))\n",
"\n",
"ax = axes[0]\n",
"ax.plot(res['N'], res['pkdt'], 'o-', label='PeriodicKDT')\n",
"ax.plot(res['N'], res['cl'], 'o-', label='Cell List')\n",
"ax.plot(res['N'], res['bt'], 'o-', label='BallTree')\n",
"ax.plot(res['N'], res['kdt'], 'o-', label='KDTree')\n",
"ax.set(xlabel='N particles', ylabel='time [s]', xscale='log', yscale='log', title='Query')\n",
"ax.legend()\n",
"\n",
"ax = axes[1]\n",
"ax.plot(res['N'], res_build['pkdt'], 'o-', label='PeriodicKDT')\n",
"ax.plot(res['N'], res_build['cl'], 'o-', label='Cell List')\n",
"ax.plot(res['N'], res_build['bt'], 'o-', label='BallTree')\n",
"ax.plot(res['N'], res_build['kdt'], 'o-', label='KDTree')\n",
"ax.set(xlabel='N particles', ylabel='time [s]', xscale='log', yscale='log', title='Build')\n",
"ax.grid(True)\n",
"ax.legend()\n",
"\n",
"fig.tight_layout()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The Tree based method are always an order of magnitude faster then the celllist method. Interestingly in this application the number of points doesn't influence the runtime much. This is expected since the area that is searched for neighbors should always have roughly the same number of particles. The scikit learn based algorithms experience an increase in query time if more then 10k particles are used. Maybe this could be optimized with the leaf_size parameter. Note that we expect a brute force algorithm would scale linearly.\n",
"\n",
"Though I haven't made any benchmarks here I expect that the query time depends on the density and not the number of particles. This means if I keep the box size constant the query time should increase with increasing number of particles.\n",
"\n",
"To construct the data structures used for distance querying we can see a clear trend with particles numbers. For the period KDTree and the cell list the time to build is increasing linearly with the period KDTree faster up to ~100k particles. The tree's implemented in scikit learn have two separete phases for construction. After more then 1k particles the time to construct a tree increases significantly.\n",
"\n",
"# Conclusion\n",
"\n",
"The PeriodicKDTree as implemented in MDAnalysis is my optimal choice of algorithm. It would be nice to make use of the reduced setup time in the scikit learn implementations but they don't support periodic boundary conditions. The implementation of the collision detector is then straight forward"
]
},
{
"cell_type": "code",
"execution_count": 112,
"metadata": {},
"outputs": [],
"source": [
"from MDAnalysis.lib.pkdtree import PeriodicKDTree as PKDTree\n",
"\n",
"import numpy as np\n",
"\n",
"\n",
"class CollisionDetector(object):\n",
" \"\"\"Given a set of N particles this class allows to query if any new particle\n",
" will overlap. If particles overlap this is called a collision\n",
"\n",
" Example\n",
" -------\n",
" >>> cd = CollisionDetector(coords, 3.81, [100, 100, 100])\n",
" >>> cd.collision([50, 50, 50])\n",
"\n",
" \"\"\"\n",
" def __init__(self, coords, diameter, box):\n",
" \"\"\"\n",
" Parameters\n",
" ----------\n",
" coords : array_like (N, 3)\n",
" coordinates of N particles\n",
" diameter : float\n",
" diameter of particles\n",
" box : array_like (3)\n",
" box dimensions\n",
" \"\"\"\n",
" box = np.asarray(box, dtype=np.float32)\n",
" self._kdt = PKDTree(box)\n",
" self._kdt.set_coords(coords)\n",
" self._diameter = diameter\n",
"\n",
" def collision(self, pos):\n",
" \"\"\"check is there is a collision\n",
"\n",
" Parameters\n",
" ----------\n",
" pos : array_like (3)\n",
" coordinates of new particles\n",
"\n",
" Returns\n",
" -------\n",
" collision : bool\n",
" ``True`` if there is a collision,\n",
" \"\"\"\n",
" self._kdt.search(pos, self._diameter)\n",
" indices = self._kdt.get_indices()\n",
" return len(indices) != 0\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# APPENDIX Changing density test\n",
"\n",
"Let's see if my assumption is correct that access times won't stay constant with regard to particle number if the density is increased"
]
},
{
"cell_type": "code",
"execution_count": 120,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "75a11cc1e5094c58a3cb75beb77c3c49",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(IntProgress(value=0, max=15), HTML(value='')))"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
}
],
"source": [
"CUTOFF = 1\n",
"res = defaultdict(list)\n",
"res_build = defaultdict(list)\n",
"# This is a particle density of .8 at 100k particles\n",
"BOX = np.array([50, 50, 50]).astype(np.float32)\n",
"\n",
"for N in tqdm_notebook(np.unique(np.logspace(2, 5, num=15).astype(int))):\n",
"\n",
" box = BOX.copy()\n",
" coords = get_coords(box, N)\n",
" pos = box / 2\n",
"\n",
" # Query test\n",
" \n",
" pkdt = KDTree(box)\n",
" pkdt.set_coords(coords)\n",
" cl = CellList(box, coords, CUTOFF)\n",
" bt = neighbors.BallTree(coords)\n",
" kdt = neighbors.KDTree(coords)\n",
" \n",
" res_pkdt = %timeit -o -q pkdtree(pkdt, pos, cutoff=CUTOFF)\n",
" res_cl = %timeit -o -q celllist(cl, pos, cutoff=CUTOFF)\n",
" res_bt = %timeit -o -q sklearn(bt, pos, cutoff=CUTOFF)\n",
" res_kdt = %timeit -o -q sklearn(kdt, pos, cutoff=CUTOFF)\n",
" \n",
" res['pkdt'].append(res_pkdt.average)\n",
" res['cl'].append(res_cl.average)\n",
" res['bt'].append(res_bt.average)\n",
" res['kdt'].append(res_kdt.average)\n",
" res['N'].append(N)\n",
" \n",
" # Building test\n",
" \n",
" res_pkdt = %timeit -o -q _pkdt=KDTree(box); _pkdt.set_coords(coords)\n",
" res_cl = %timeit -o -q CellList(box, coords, CUTOFF)\n",
" res_bt = %timeit -o -q neighbors.BallTree(coords)\n",
" res_kdt = %timeit -o -q neighbors.KDTree(coords)\n",
" \n",
" res_build['pkdt'].append(res_pkdt.average)\n",
" res_build['cl'].append(res_cl.average)\n",
" res_build['bt'].append(res_bt.average)\n",
" res_build['kdt'].append(res_kdt.average)\n",
" res_build['N'].append(N)"
]
},
{
"cell_type": "code",
"execution_count": 121,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 576x288 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, axes = plt.subplots(ncols=2, figsize=plt.figaspect(1/2))\n",
"\n",
"ax = axes[0]\n",
"ax.plot(res['N'], res['pkdt'], 'o-', label='PeriodicKDT')\n",
"ax.plot(res['N'], res['cl'], 'o-', label='Cell List')\n",
"ax.plot(res['N'], res['bt'], 'o-', label='BallTree')\n",
"ax.plot(res['N'], res['kdt'], 'o-', label='KDTree')\n",
"ax.set(xlabel='N particles', ylabel='time [s]', xscale='log', yscale='log', title='Query')\n",
"ax.legend()\n",
"\n",
"ax = axes[1]\n",
"ax.plot(res['N'], res_build['pkdt'], 'o-', label='PeriodicKDT')\n",
"ax.plot(res['N'], res_build['cl'], 'o-', label='Cell List')\n",
"ax.plot(res['N'], res_build['bt'], 'o-', label='BallTree')\n",
"ax.plot(res['N'], res_build['kdt'], 'o-', label='KDTree')\n",
"ax.set(xlabel='N particles', ylabel='time [s]', xscale='log', yscale='log', title='Build')\n",
"ax.grid(True)\n",
"ax.legend()\n",
"\n",
"fig.tight_layout()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python [default]",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment