Compare two coordinates represented as complex numbers if they are within (1,1) of each other

Question:

I have two arrays loaded with complex numbers that represent a position in a cartesian coordinate (x,y).

sensors= np.array([-1.6-0.8j,-1.1-0.8j])
cameras= np.array([-3.7-0.8j,-1.6+0.9j,-1.6-0.9j])

Where the real part represents X and the imaginary part represents Y. These numbers represent in meters. So 1.5-0.5j = 1.5 meters +X and 0.5 meters -Y.

Using the isclose function has issues when the position of the sensors gets further from 0.0.

def close_to_sensors(sensors, observations):
    tolerance = 0.6
    observe_indices = np.zeros(observations.size, dtype=bool)
    for sensor in sensors:
        closeness = np.isclose(observations, np.ones(observations.size, dtype=np.complex128)*sensor, rtol=tolerance, atol=tolerance)
        observe_indices = np.logical_or(observe_indices, closeness)
    print("Closeness       : ", closeness)
    return np.argwhere(observe_indices).flatten()

This returns

Closeness       :  [False False  True]
Likely Close:  [2]

The isclose function is the wrong function to use. I need to return the indices of the cameras that are within 1 meter of the sensors. What would be the best way to do this?

Asked By: boham

||

Answers:

To calculate distances from complex numbers, subtracting them and calculating the absolute value of the difference is a straight-forward approach to solve this problem:

import numpy as np

sensors = np.array([-1.6 - 0.8j, -1.1 - 0.8j])
cameras = np.array([-3.7 - 0.8j, -1.6 + 0.9j, -1.6 - 0.9j])
distance_limit = 1

# calculate difference of each sensor to each camera
# "None" is used to create a new axis, which enables broadcasting to a (sensors x cameras) matrix
complex_differences = sensors[:, None] - cameras
axis_sensor, axis_camera = (0,1)
distances = np.abs(complex_differences)

# check cameras which have any sensor within distance limit
within_range = distances < distance_limit
valid_cameras = np.any(within_range, axis=axis_sensor)

# show indices of valid cameras
print(np.where(valid_cameras)[0])
Answered By: Christian Karcher

Thank you all for your responses but those resulted in undesired results. I eventually decided to change the complex number arrays to [real, imag] lists, then load the sensors list to a KDTree and searched the tree for observations that were close; where 1 = 1 meter. This provided the results I needed.

EDIT: Added code with data

import numpy as np
import scipy.spatial as spatial

def close_to_sensors(bifrost_sensors, observations):
    sensors_x_y = []
    observations_x_y = []

    for i in range(bifrost_sensors.size):
        sensors_x_y.append((bifrost_sensors[i].real, bifrost_sensors[i].imag))

    for i in range(observations.size):
        observations_x_y.append((observations[i].real, observations[i].imag))

    observe_indices = np.zeros(observations.size, dtype=bool)
    #KDTree the sensor list
    sensor_tree = spatial.cKDTree(np.c_[sensors_x_y])
    for i in range(len(observations_x_y)):
        closeness = (sensor_tree.data[sensor_tree.query_ball_point(observations_x_y[i], 1)])
        if closeness.size == 0:
            observe_indices[i] = np.logical_or(observe_indices[i], 0)
        else:
            observe_indices[i] = np.logical_or(observe_indices[i], 1)

    #Find the indices of array elements that are non-zero, grouped by element.
    return np.argwhere(observe_indices).flatten() 


#Excel copied data into arrays - 12 entries
sensors = np.array([-0.6-0.8j,-0.8-1.2j,-0.9-1.2j,-1.-0.9j,-1.1-1.j,1.1+1.j,-1.5-1.5j,-1.6-1.1j,-1.7-1.5j,1.1+1.j,1.8+0.8j,-2.-1.6j])
cameras = np.array([-4.03-1.1j,-4.15-1.14j,-1.5-1.16j,-4.05-1.14j,-4.05-1.14j,4.03+2.19j,-4.08-1.13j,-4.06-1.14j,-1.15-0.98j,3.21+1.92j,3.9+1.65j,-4.08-1.13j])

likely_bifrost = close_to_sensors(sensors, cameras)
print("Likely bifrost  : ", likely_bifrost.size, " : ",likely_bifrost)
Answered By: boham
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.