我正在学习一个关于向量的类,并尝试在Python中实现向量操作,我在这个过程中正在学习。在规范化向量时,我得到了一个数学域错误。知道为什么吗?
我得到的错误是:
线67,与成角度升高(e)ValueError:数学域错误
import math
from decimal import Decimal, getcontext
getcontext().prec = 30
class Vector(object):
def __init__(self, coordinates):
try:
if not coordinates:
raise ValueError
self.coordinates = tuple([Decimal(x) for x in coordinates])
self.dim ension = len(coordinates)
except ValueError:
raise ValueError('The coordinates must be nonempty')
except TypeError:
raise TypeError('The coordinates must be an iterable')
def __str__(self):
return 'Vector: {}'.format(self.coordinates)
def plus(self, v):
new_coordinates = [x+y for x,y in zip(self.coordinates, v.coordinates)]
return Vector(new_coordinates)
def minus(self, v):
new_coordinates = [x-y for x,y in zip(self.coordinates, v.coordinates)]
return Vector(new_coordinates)
def times_scalar(self, c):
new_coordinates = [Decimal(c)*x for x in self.coordinates]
return Vector(new_coordinates)
def magnitude(self):
coordinates_squared = [x**2 for x in self.coordinates]
return Decimal(math.sqrt(sum(coordinates_squared)))
def normalized(self):
try:
magnitude = self.magnitude()
return self.times_scalar(Decimal('1.0')/magnitude)
except ZeroDivisionError:
raise Exception('Cannot normalize the zero vector')
def dot_product(self, v):
return sum([x*y for x,y in zip(self.coordinates, v.coordinates)])
def angle_with(self, v, in_degrees=False):
try:
u1 = self.normalized()
u2 = v.normalized()
angle_in_radians = math.acos(u1.dot_product(u2))
if in_degrees:
degrees_per_radian = 180 / math.pi
return angle_in_radians * degrees_per_radian
else:
return angle_in_radians
except Exception as e:
if str(e) == 'Cannot normalize the zero vector':
raise Exception('Cannot compute an angle with the zero vector')
else:
raise(e)
a = Vector(['-7.579', '-7.88'])
b = Vector(['22.737', '23.64'])
print a.is_parallel_to(b)
print a.is_orthogonal(b)
Łukasz Rogalski指出,如果u1和u2的点积在[-1,1]之外,acos将导致此错误。如果你对向量a和b进行归一化,并像现在这样以30的精度检查点积,你就会发现问题。
将您的精度更改为10左右以解决此错误。