From 9f84f71db41b4bcb7eefee067edfe4be4dfca694 Mon Sep 17 00:00:00 2001 From: satej soman Date: Tue, 5 Mar 2019 13:03:21 -0600 Subject: [PATCH 1/2] fix perf test timing --- tests/legacy_util_tests.py | 200 +++++++++++++++++++++++++++++++++++++ tests/perf_test_data | 14 +-- tests/perf_tests.py | 13 ++- 3 files changed, 215 insertions(+), 12 deletions(-) create mode 100644 tests/legacy_util_tests.py diff --git a/tests/legacy_util_tests.py b/tests/legacy_util_tests.py new file mode 100644 index 0000000..9bd3b6a --- /dev/null +++ b/tests/legacy_util_tests.py @@ -0,0 +1,200 @@ +import unittest +import numpy as np +import random +from graph import my_graph as mg +from graph import my_graph_helpers as mgh + +# myG geometry functions +def legacy_distance(mynode0, mynode1): + return np.sqrt(legacy_distance_squared(mynode0, mynode1)) + + +def legacy_distance_squared(mynode0, mynode1): + return (mynode0.x-mynode1.x)**2+(mynode0.y-mynode1.y)**2 + + +def legacy_sq_distance_point_to_segment(target, myedge): + """returns the square of the minimum distance between mynode + target and myedge. """ + n1 = myedge.nodes[0] + n2 = myedge.nodes[1] + + if myedge.length == 0: + sq_dist = distance_squared(target, n1) + elif target == n1 or target == n2: + sq_dist = 0 + else: + px = float(n2.x - n1.x) + py = float(n2.y - n1.y) + u = float((target.x - n1.x)*px + (target.y - n1.y)*py)/(px*px + py*py) + if u > 1: + u = 1 + elif u < 0: + u = 0 + x = n1.x + u*px + y = n1.y + u*py + + dx = x - target.x + dy = y - target.y + + sq_dist = (dx * dx + dy * dy) + return sq_dist + + +def legacy_intersect(e1, e2): + """ returns true if myedges e1 and e2 intersect """ + # fails for lines that perfectly overlap. + def legacy_ccw(a, b, c): + return (c.y-a.y)*(b.x-a.x) > (b.y-a.y)*(c.x-a.x) + + a = e1.nodes[0] + b = e1.nodes[1] + c = e2.nodes[0] + d = e2.nodes[1] + + return ccw(a, c, d) != ccw(b, c, d) and ccw(a, b, c) != ccw(a, b, d) + + +def legacy_are_parallel(e1, e2): + """ returns true if myedges e1 and e2 are parallel """ + a = e1.nodes[0] + b = e1.nodes[1] + c = e2.nodes[0] + d = e2.nodes[1] + + # check if parallel; handling divide by zero errors + if a.x == b.x and c.x == d.x: # check if both segments are flat + parallel = True + # if one is flat and other is not + elif (a.x - b.x)*(c.x - d.x) == 0 and (a.x - b.x) + (c.x - d.x) != 0: + parallel = False + # if neither segment is flat and slopes are equal + elif (a.y-b.y)/(a.x-b.x) == (c.y-d.y)/(c.x-d.x): + parallel = True + # n either segment is flat, slopes are not equal + else: + parallel = False + return parallel + + +def legacy_segment_distance_sq(e1, e2): + """returns the square of the minimum distance between myedges e1 and e2.""" + # check different + if e1 == e2: + sq_distance = 0 + # check parallel/colinear: + # lines are not parallel/colinear and intersect + if not are_parallel(e1, e2) and intersect(e1, e2): + sq_distance = 0 + # lines don't intersect, aren't parallel + else: + d1 = sq_distance_point_to_segment(e1.nodes[0], e2) + d2 = sq_distance_point_to_segment(e1.nodes[1], e2) + d3 = sq_distance_point_to_segment(e2.nodes[0], e1) + d4 = sq_distance_point_to_segment(e2.nodes[1], e1) + sq_distance = min(d1, d2, d3, d4) + + return sq_distance + + +# vector math +def legacy_bisect_angle(a, b, c, epsilon=0.2, radius=1): + """ finds point d such that bd bisects the lines ab and bc.""" + ax = a.x - b.x + ay = a.y - b.y + + cx = c.x - b.x + cy = c.y - b.y + + a1 = mg.MyNode(((ax, ay))/np.linalg.norm((ax, ay))) + c1 = mg.MyNode(((cx, cy))/np.linalg.norm((cx, cy))) + + # if vectors are close to parallel, find vector that is perpendicular to ab + # if they are not, then find the vector that bisects a and c + if abs(np.cross(a1.loc, c1.loc)) < 0 + epsilon: + # print("vectors {0}{1} and {1}{2} are close to //)".format(a,b,c) + dx = -ay + dy = ax + else: + dx = (a1.x + c1.x)/2 + dy = (a1.y + c1.y)/2 + + # convert d values into a vector of length radius + dscale = ((dx, dy)/np.linalg.norm((dx, dy)))*radius + myd = mg.MyNode(dscale) + + # make d a node in space, not vector around b + d = mg.MyNode((myd.x + b.x, myd.y + b.y)) + + return d + + +def legacy_find_negative(d, b): + """finds the vector -d when b is origin """ + negx = -1*(d.x - b.x) + b.x + negy = -1*(d.y - b.y) + b.y + dneg = mg.MyNode((negx, negy)) + return dneg + + +# clean up and probability functions +def legacy_WeightedPick(d): + """picks an item out of the dictionary d, with probability proportional to + the value of that item. e.g. in {a:1, b:0.6, c:0.4} selects and returns + "a" 5/10 times, "b" 3/10 times and "c" 2/10 times. """ + r = random.uniform(0, sum(d.values())) + s = 0.0 + for k, w in d.items(): + s += w + if r < s: + return k + return k + +class LegacyUtilTests(unittest.TestCase): + def test_distance(self): + node_a = mg.MyNode((0, 1)) + node_b = mg.MyNode((2, 3)) + + assert legacy_distance(node_a, node_b) == mgh.distance(node_a, node_b) + + def test_distance_squared(self): + node_a = mg.MyNode((0, 1)) + node_b = mg.MyNode((2, 3)) + + assert legacy_distance_squared(node_a, node_b) == mgh.distance_squared(node_a, node_b) + + def _test_sq_distance_point_to_segment(self): + pass + + def _test_intersect(self): + pass + + def _test_ccw(self): + pass + + def _test_are_parallel(self): + pass + + def _test_segment_distance_sq(self): + pass + + def _test_bisect_angle(self): + pass + + def _test_find_negative(self): + pass + + def test_WeightedPick(self): + distribution = {'a':1, 'b':0.6, 'c':0.4} + + random.seed(11235813) + legacy_value = legacy_WeightedPick(distribution) + + np.random.seed(11235813) + builtin_value = mgh.WeightedPick(distribution) + + assert legacy_value == builtin_value + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/tests/perf_test_data b/tests/perf_test_data index a5c93b0..ceb5917 100644 --- a/tests/perf_test_data +++ b/tests/perf_test_data @@ -1,7 +1,7 @@ -e64c0d8 Phule_Nagar_v6 199 12.2950041294 16.1854358002 -e64c0d8 CapeTown 3 181.267705917 0.016550107394 -e64c0d8 Epworth_Before 350 269.279039145 1.29976696705 -e64c0d8 Epworth_demo 1 0.602538108826 1.6596460628 -e64c0d8 Las_Vegas 1 164.061764956 0.00609526540368 -e64c0d8 NYC 1 0.413594961166 2.41782442702 -e64c0d8 Prague 2 0.226563930511 8.82753047003 +1d11d71 Phule_Nagar_v6 199 4.16134309769 47.8210989405 +1d11d71 CapeTown 3 63.7222030163 0.0470793515917 +1d11d71 Epworth_Before 350 92.179418087 3.79694304069 +1d11d71 Epworth_demo 1 0.218091011047 4.58524170803 +1d11d71 Las_Vegas 1 61.8313698769 0.0161730202968 +1d11d71 NYC 1 0.142737150192 7.00588458333 +1d11d71 Prague 2 0.0788838863373 25.353720422 diff --git a/tests/perf_tests.py b/tests/perf_tests.py index 96684a5..7c2289e 100644 --- a/tests/perf_tests.py +++ b/tests/perf_tests.py @@ -4,6 +4,7 @@ from graph import my_graph as mg from graph import my_graph_helpers as mgh +NUMBER_RUNS = 10 DEFAULT_THRESHOLD = 1 DEFAULT_BLOCKING = True @@ -25,19 +26,21 @@ def main(names): for name in names: print git_hash, name, blocks = test_case("data/" + name, name) - time_taken = timeit.timeit('test_case("data/" + name, name)', + time_taken = min(timeit.repeat( + 'test_case("data/" + name, name)', setup='from __main__ import test_case; name = "%s"' % name, - number=3) + repeat=NUMBER_RUNS, + number=1)) print blocks, time_taken, blocks/time_taken if __name__ == '__main__': names = [ 'Phule_Nagar_v6', - 'CapeTown', 'Epworth_Before', 'Epworth_demo', 'Las_Vegas', 'NYC', - 'Prague' + 'Prague', + 'CapeTown' ] - main(names) \ No newline at end of file + main(names) From 631a9955c0b2f3baa48d4279488b7a5e4fd984d0 Mon Sep 17 00:00:00 2001 From: satej soman Date: Tue, 5 Mar 2019 13:04:56 -0600 Subject: [PATCH 2/2] consistent ordering in data --- tests/perf_test_data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/perf_test_data b/tests/perf_test_data index ceb5917..864d5be 100644 --- a/tests/perf_test_data +++ b/tests/perf_test_data @@ -1,7 +1,7 @@ 1d11d71 Phule_Nagar_v6 199 4.16134309769 47.8210989405 -1d11d71 CapeTown 3 63.7222030163 0.0470793515917 1d11d71 Epworth_Before 350 92.179418087 3.79694304069 1d11d71 Epworth_demo 1 0.218091011047 4.58524170803 1d11d71 Las_Vegas 1 61.8313698769 0.0161730202968 1d11d71 NYC 1 0.142737150192 7.00588458333 1d11d71 Prague 2 0.0788838863373 25.353720422 +1d11d71 CapeTown 3 63.7222030163 0.0470793515917