1

I have this function which checks if a point (passed as pair of cartesian coordinates) is inside the trapezoid (passed as list of tuples of vertices coordinates)

def inside(point_coordinates, trapezoid_vertices):
    x,y = point_coordinates
    is_inside = False
    x_1, y_1 = trapezoid_vertices[0]
    for i in range(1, 4):
        x_2, y_2 = trapezoid_vertices[i]
        if y > min(y_1, y_2):
            if y <= max(y_1, y_2):
                if x <= max(x_1, x_2):
                    if y_1 != y_2:
                        x_intersect = (y - y_1) * (x_2 - x_1) / (y_2 -y_1) + x_1
                    if x_1 == x_2 or x <= x_intersect:
                        is_inside = not is_inside
        x_1, y_1 = x_2, y_2
    return is_inside

I want to make it accept a numpy array where each element of the array is a pair of its indices. Then I want it to return an array of bools where the each element is True if the point corresponding to its indices is inside the trapezoid, or False otherwise. For example, a 3x3 array of what I want to pass to the function looks like this:

a = [[[0 0]
      [0 1]
      [0 2]]

     [[1 0]
      [1 1]
      [1 2]]

     [[2 0]
      [2 1]
      [2 2]]]

And what I want the function to return is something like this:

[[ True  True False]
 [ True  True False]
 [False False False]]

I tried to vectorize the function with inside_vectorized=np.vectorize(inside), but it doesn't seem to work. Running inside_vectorized( a, [(0, 0), (0, 1), (1, 1), (1, 0)] ) gives me a TypeError.

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-6d5966fb40d4> in <module>()
----> 1 inside_vectorized(a, [(0, 0), (0, 1), (1, 1), (1, 0)])

/usr/lib/python3/dist-packages/numpy/lib/function_base.py in     __call__(self, *args, **kwargs)
   2205             vargs.extend([kwargs[_n] for _n in names])
   2206 
-> 2207         return self._vectorize_call(func=func, args=vargs)
   2208 
   2209     def _get_ufunc_and_otypes(self, func, args):

/usr/lib/python3/dist-packages/numpy/lib/function_base.py in _vectorize_call(self, func, args)
   2268             _res = func()
   2269         else:
-> 2270             ufunc, otypes =     self._get_ufunc_and_otypes(func=func, args=args)
   2271 
   2272             # Convert args to object arrays first

/usr/lib/python3/dist-packages/numpy/lib/function_base.py in _get_ufunc_and_otypes(self, func, args)
   2230             # arrays (the input values are not checked to ensure this)
   2231             inputs = [asarray(_a).flat[0] for _a in args]
-> 2232             outputs = func(*inputs)
   2233 
   2234             # Performance note: profiling indicates that -- for simple

<ipython-input-3-90f42f10d464> in inside(point_coordinates, trapezoid_vertices)
      9 
     10 def inside(point_coordinates, trapezoid_vertices):
---> 11     x,y = point_coordinates
     12 
     13     is_inside = False

TypeError: 'numpy.int64' object is not iterable

Can someone please give me a starting point to fix this?

Radusaurus
  • 83
  • 1
  • 6
  • If you want speed improvements, don't use `vectorize`. Figure out instead how to write `inside` so with works with the `a` kind of 3d array directly. – hpaulj Mar 07 '18 at 18:46
  • For short term that is a solution, but on the long term, as I learn more about parallel computing I want to adapt my code to run on GPU. And for that I need to have all functions vectorized, don't I? Plus, I would have to used nested for loops which are slower than vectorization. Are they not? – Radusaurus Mar 08 '18 at 16:01

0 Answers0