mathematics.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # -*- coding: utf-8 -*-
  2. #!/usr/bin/env python
  3. # Francisco Mota, 2011-11-09
  4. # http://fmota.eu/blog/monoids-in-python.html
  5. # see also: http://arxiv.org/abs/1304.7544
  6. import math
  7. class Monoid(object):
  8. def __init__(self, null, lift, op):
  9. self.null = null
  10. self.lift = lift
  11. self.op = op
  12. def fold(self, xs):
  13. if hasattr(xs, "__fold__"):
  14. return xs.__fold__(self)
  15. else:
  16. return reduce(self.op, (self.lift(x) for x in xs), self.null)
  17. def __call__(self, *args):
  18. return self.fold(args)
  19. def star(self):
  20. return Monoid(self.null, self.fold, self.op)
  21. summ = Monoid(0, lambda x: x, lambda a, b: a + b)
  22. joinm = Monoid('', lambda x: str(x), lambda a, b: a + b)
  23. listm = Monoid([], lambda x: [x], lambda a, b: a + b)
  24. tuplem = Monoid((), lambda x: (x,), lambda a, b: a + b)
  25. lenm = Monoid(0, lambda x: 1, lambda a, b: a + b)
  26. prodm = Monoid(1, lambda x: x, lambda a, b: a * b)
  27. ## extended to define a monoid for folding Python `dict`
  28. def dict_op(a, b):
  29. for key, val in b.items():
  30. if not key in a:
  31. a[key] = val
  32. else:
  33. if isinstance(val, dict):
  34. a[key] = dict_op(a[key], val)
  35. else:
  36. a[key] += val
  37. return a
  38. dictm = Monoid({}, lambda x: x, lambda a, b: dict_op(a, b))
  39. class Haversine(object):
  40. """
  41. half of the versed sine
  42. use the haversine class to calculate the distance between
  43. two lon/lat coordinate pairs.
  44. output distance available in kilometers, meters, miles, and feet.
  45. example usage: Haversine([lon1,lat1],[lon2,lat2]).feet
  46. """
  47. def __init__(self, coord1, coord2):
  48. lon1, lat1 = coord1
  49. lon2, lat2 = coord2
  50. R = 6371000 # radius of Earth in meters
  51. phi_1 = math.radians(lat1)
  52. phi_2 = math.radians(lat2)
  53. delta_phi = math.radians(lat2 - lat1)
  54. delta_lambda = math.radians(lon2 - lon1)
  55. a = math.sin(delta_phi / 2.0) ** 2 + \
  56. math.cos(phi_1) * math.cos(phi_2) * \
  57. math.sin(delta_lambda / 2.0) ** 2
  58. c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
  59. self.meters = R * c # output distance in meters
  60. self.km = self.meters / 1000.0 # output distance in kilometers
  61. self.miles = self.meters * 0.000621371 # output distance in miles
  62. self.feet = self.miles * 5280 # output distance in feet
  63. def get_haversine_by_km(point1, point2):
  64. """
  65. :param point1:
  66. :param point2:
  67. :return:
  68. """
  69. return Haversine(point1, point2).km
  70. if __name__=='__main__':
  71. xs = [{ "a": i, "b": i + 1 } for i in range(0, 1000)]
  72. ys = [{ "a": i, "b": i } for i in range(0, 1000)]
  73. x1 = { "a": 2, "b": 3 }
  74. x2 = { "b": 2, "c": 7 }
  75. print x1, x2
  76. print dictm.fold(xs + ys)