martineau

Get closest coordinate in 2D array

Nov 12th, 2018
204
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env python3
  2. # https://stackoverflow.com/questions/53257607/get-closest-coordinate-in-2d-array
  3.  
  4. from __future__ import print_function
  5. from collections import namedtuple
  6. import sys
  7. from random import seed, uniform
  8. from textwrap import dedent
  9. import timeit
  10. import traceback
  11.  
  12. N = 1000  # Number of executions of each "algorithm".
  13. R = 3  # Number of repetitions of those N executions.
  14. NUMPTS = 10000  # Number of points.
  15.  
  16. seed(42)  # Initialize random number so the results are reproducible.
  17.  
  18. #coordinates = [(-225.0, -299.5), (-150.0, 75.5), (0.0, 0.0), (225.0, 300.5)]
  19. #xy = (-222.4, -204.5)
  20.  
  21. coordinates = [(uniform(-100, 100), uniform(-100, 100)) for _ in range(NUMPTS)]
  22. xy = (uniform(-100, 100), uniform(-100, 100))
  23.  
  24.  
  25. # Common setup for all testcases (executed before any algorithm specific setup).
  26. COMMON_SETUP = dedent("""
  27.    from __main__ import coordinates, xy
  28. """)
  29.  
  30. class TestCase(namedtuple('CodeFragments', ['setup', 'test'])):
  31.     """ A test case is composed of separate setup and test code fragments. """
  32.     def __new__(cls, setup, test):
  33.         """ Dedent code fragment in each string argument. """
  34.         return tuple.__new__(cls, (dedent(setup), dedent(test)))
  35.  
  36. testcases = {
  37.     "schwobaseggl": TestCase("""
  38.        dist = lambda x, y: (x[0]-y[0])**2 + (x[1]-y[1])**2
  39.        """, """
  40.        min(coordinates, key=lambda co: dist(co, xy))
  41.        """
  42.     ),
  43.     "martineau (with hypot)": TestCase("""
  44.        from math import hypot
  45.        dist = lambda a, b: hypot(b[0]-a[0], b[0]-a[0])
  46.        """, """
  47.        min(coordinates, key=lambda co: dist(co, xy))
  48.        """
  49.     ),
  50. }
  51.  
  52. # Collect timing results of executing each testcase multiple times.
  53. try:
  54.     results = [
  55.         (label,
  56.          min(timeit.repeat(testcases[label].test,
  57.                            setup=COMMON_SETUP + testcases[label].setup,
  58.                            repeat=R, number=N)),
  59.         ) for label in testcases
  60.     ]
  61. except Exception:
  62.     traceback.print_exc(file=sys.stdout)  # direct output to stdout
  63.     sys.exit(1)
  64.  
  65. # Display results.
  66. print('Results for processing {:,d} points.'.format(NUMPTS))
  67. major, minor, micro = sys.version_info[:3]
  68. print('Fastest to slowest execution speeds using Python {}.{}.{}\n'
  69.       '({:,d} executions, best of {:d} repetitions)'.format(major, minor, micro, N, R))
  70. print()
  71.  
  72. longest = max(len(result[0]) for result in results)  # length of longest label
  73. ranked = sorted(results, key=lambda t: t[1]) # ascending sort by execution time
  74. fastest = ranked[0][1]
  75. for result in ranked:
  76.     print('{:>{width}} : {:9.6f} secs, rel speed {:5.2f}x, {:6.2f}% slower '
  77.           ''.format(
  78.                 result[0], result[1], round(result[1]/fastest, 2),
  79.                 round((result[1]/fastest - 1) * 100, 2),
  80.                 width=longest))
  81. print()
  82.  
  83. """
  84. Results:
  85.  
  86.    Results for processing 10,000 points.
  87.    Fastest to slowest execution speeds using Python 3.7.1
  88.    (1,000 executions, best of 3 repetitions)
  89.  
  90.    martineau (with hypot) :  6.311196 secs, rel speed  1.00x,   0.00% slower
  91.              schwobaseggl :  7.506378 secs, rel speed  1.19x,  18.94% slower
  92. """
RAW Paste Data