Home > Enterprise >  acos getting error math domain error, not getting solved using Decimal function
acos getting error math domain error, not getting solved using Decimal function

Time:10-10

I'm getting ValueError: math domain error for some points in dataframe. I know acos takes value from -1 to 1. I tried solving the error using decimal.Decimal function. But it is still throwing the error for the same points.

def angle(p1,p2,p3):
    dot_product = np.dot(p2-p1,p3-p2)
    vec1 = np.linalg.norm(p2-p1)
    vec2 = np.linalg.norm(p3-p2)
    x = dot_product /(vec1 * vec2)
    return round(math.degrees(math.acos(x)),2)

def get_angle(points):
    return [[angle(point1[0], point1[1], point2[1]) for point2 in points.values] for point1 in points.values]

# this is the column on which i'm apply the function
# this is one of the sample group
# I have to find angle between the co-ordinates
# function return a list of angles w.r.t other points

points
[[-140.78063986473717, 91.91634474415332], [-142.34375254437327, 87.6819673711434]]
[[-141.25677946582437, 94.60493099503219], [-142.7676919612568, 90.44367777556181]]
[[-138.125714250491, 86.75676850322634], [-139.46260946977418, 82.95679492782801]]
[[-137.67089835880324, 74.81029774621129], [-139.08569156355225, 70.57744785398245]]

For example,

p1 = np.array([-138.125714250491, 86.75676850322634])
p2 = np.array([-139.46260946977418, 82.95679492782801])
p3 = np.array([-132.35878855874762, 95.67247487790883])

math.degrees(math.acos(np.dot(p2-p1,p3-p2)/(np.linalg.norm(p2-p1) * np.linalg.norm(p3-p2))))

>>> 170.19212016382508

adding x = Decimal(dot_product /(vec1 * vec2)) does not solve the problem

I think the culprit is multiplication and division operation, which is leaving the results above 1 and below -1 for some points in the dataframe. How to solve this problem?

CodePudding user response:

If the values of x are out of the interval [-1, 1] by just a tiny amount--as the result of normal floating point imprecision--you could clip the values to the interval before passing them to acos. Something like acos(max(min(x, 1), -1)) should work.

  • Related