这是Udacity线性代数复习课程中的一项作业,我已经按照我的方式解决了这个问题,虽然有一个可用于此作业的解决方案我试图以我的方式解决它。但是在找到vectore v1和v2的2向量之间的角度时,我遇到了错误。
这个程序要求解决2个问题。但即使有相同的。但是对于程序而言,即使存在"角度"功能相同。
import math
from decimal import Decimal,getcontext
getcontext().prec = 30
class Vector(object):
def __init__(self,coordinates):
try:
if not coordinates:
raise ValueError
#if coordinates is not passed then it will rise Value Error
self.coordinates = tuple([Decimal(x)for x in coordinates])
#Outside Class :-Vector.coordinates will give print vectors in tuple form
#Inside Class :- self.coordinates will print vectors in tuple form
self.dimension = len(coordinates)
#Outside Class :-Vector.dimension will print vectors dimension/size
#Inside Class :- self.dimension will print vectors dimension/size
except ValueError:
raise ValueError('The coordinates must be non empty')
except TypeError:
raise TypeError('The coordinates must be itterable')
def __str__(self):
return 'Vector:{}'.format(self,coordinates)
def __eq__(self,v):
return self.coordinates == v.coordinates
def add (self,v):
coordinates=[]
for i in range(0,self.dimension):
i=self.coordinates[i]+v.coordinates[i]
coordinates.append(i)
return coordinates
def mul(self,v):
coordinates=[]
for i in range(0,self.dimension):
i=self.coordinates[i]*v.coordinates[i]
coordinates.append(i)
return coordinates
def sub (self,v):
coordinates=[]
for i in range(0,self.dimension):
i=self.coordinates[i]-v.coordinates[i]
coordinates.append(i)
return coordinates
def scal_mul(self,s):
coordinates=[]
for i in self.coordinates:
i=i*Decimal(s)
coordinates.append(i)
return coordinates
def magnitude(self):
mag = 0
for i in self.coordinates:
i=i*i
mag =mag+i
return math.sqrt(mag)
def magnitude1(self):
mag = 0
coordinate_squre=[i*i for i in self.coordinates]
return math.sqrt(sum(coordinate_squre))
# def normalize(self):
# try:
# recip = Decimal(1)/self.magnitude()
# return Vector(self.scal_mul(recip))
# except ZeroDivisionError:
# raise Exception("Can not Normalize Zero Vector")
def normalize(self):
try:
recip = 1/self.magnitude()
return self.scal_mul(recip)
except ZeroDivisionError:
raise Exception("Can not Normalize Zero Vector")
def dot_product(self,v):
mul = self.mul(v)
return sum(mul)
def dot_product2(self,v):
self.mul = [x*y for x,y in zip(self.coordinates,v.coordinates)]
return sum(self.mul)
#-----------------angle functionn is giving wrong answer-------------
def angle_rad(self,v):
norm = self.normalize()
angle = 1/ math.cos(norm.dot_product2(v))
return angle
def angle(self,v,in_degree=False):
nrm_self = self.normalize()
nrm_v = v.normalize()
angle_rad = math.acos(nrm_self.dot_product2(nrm_v))
if in_degree:
angle_in_degree = angle_rad * 180./math.pi
return angle_in_degree
else:
return angle_rad
v1 = Vector([7.887,4.138])
v2 = Vector([-8.802,6.776])
print(v1.angle(v2))
v1 = Vector([-7.579,-7.88])
v2 = Vector([22.737,23.64])
v2.angle(v1)
此代码提供错误如下
AttributeError Traceback (most recent call last)
<ipython-input-44-2087e4f0ca26> in <module>()
101 v1 = Vector([7.887,4.138])
102 v2 = Vector([-8.802,6.776])
--> 103 print(v1.angle(v2))
104 v1 = Vector([-7.579,-7.88])
105 v2 = Vector([22.737,23.64])
<ipython-input-44-2087e4f0ca26> in angle(self, v, in_degree)
92 nrm_self = self.normalize()
93 nrm_v = v.normalize()
---> 94 angle_rad = math.acos(nrm_self.dot_product2(nrm_v))
95 if in_degree:
96 angle_in_degree = angle_rad * 180./math.pi
AttributeError: 'list' object has no attribute 'dot_product2'
另一个角度函数完全相同的程序是
import math
class Vector(object):
def __init__(self,coordinates):
try:
if not coordinates:
raise ValueError
#if coordinates is not passed then it will rise Value Error
self.coordinates = tuple(coordinates)
#Outside Class :-Vector.coordinates will give print vectors in tuple form
#Inside Class :- self.coordinates will print vectors in tuple form
self.dimension = len(coordinates)
#Outside Class :-Vector.dimension will print vectors dimension/size
#Inside Class :- self.dimension will print vectors dimension/size
except ValueError:
raise ValueError('The coordinates must be non empty')
except TypeError:
raise TypeError('The coordinates must be itterable')
def __str__(self):
return 'Vector:{}'.format(self,coordinates)
def __eq__(self,v):
return self.coordinates == v.coordinates
def add (self,v):
coordinates=[]
for i in range(0,self.dimension):
i=self.coordinates[i]+v.coordinates[i]
coordinates.append(i)
return coordinates
def mul(self,v):
coordinates=[]
for i in range(0,self.dimension):
i=self.coordinates[i]*v.coordinates[i]
coordinates.append(i)
return coordinates
def sub (self,v):
coordinates=[]
for i in range(0,self.dimension):
i=self.coordinates[i]-v.coordinates[i]
coordinates.append(i)
return coordinates
def scal_mul(self,s):
coordinates=[]
for i in self.coordinates:
i=i*s
coordinates.append(i)
return coordinates
def magnitude(self):
mag = 0
for i in self.coordinates:
i=i*i
mag =mag+i
return math.sqrt(mag)
def magnitude1(self):
mag = 0
coordinate_squre=[i*i for i in self.coordinates]
return math.sqrt(sum(coordinate_squre))
def normalize(self):
try:
recip = 1/self.magnitude()
return Vector(self.scal_mul(recip))
except ZeroDivisionError:
raise Exception("Can not Normalize Zero Vector")
def dot_product(self,v):
mul = self.mul(v)
return sum(mul)
def dot_product2(self,v):
self.mul = [x*y for x,y in zip(self.coordinates,v.coordinates)]
return sum(self.mul)
#-----------------angle functionn is giving wrong answer-------------
def angle_rad(self,v):
norm = self.normalize()
angle = 1/ math.cos(norm.dot_product2(v))
return angle
def angle(self,v,in_degree=False):
nrm_self = self.normalize()
nrm_v = v.normalize()
angle_rad = math.acos(nrm_self.dot_product2(nrm_v))
if in_degree:
angle_in_degree = angle_rad * 180./math.pi
return angle_in_degree
else:
return angle_rad
v1 = Vector([7.887,4.138])
v2 = Vector([-8.802,6.776])
print(v1.angle(v2))
v1 = Vector([-7.579,-7.88])
v2 = Vector([22.737,23.64])
v2.angle(v1)
它将错误提供如下
2.0023426999774925
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-214-2e3bee12967a> in <module>()
95 v1 = Vector([-7.579,-7.88])
96 v2 = Vector([22.737,23.64])
---> 97 v2.angle(v1)
98
<ipython-input-214-2e3bee12967a> in angle(self, v, in_degree)
82 nrm_self = self.normalize()
83 nrm_v = v.normalize()
---> 84 angle_rad = math.acos(nrm_self.dot_product2(nrm_v))
85 if in_degree:
86 angle_in_degree = angle_rad * 180./math.pi
ValueError: math domain error
我们可以看到它们具有相同的角度功能
答案 0 :(得分:0)
你的第一个程序的问题是normalize方法返回一个坐标列表return self.scal_mul(recip)
,但不会将该列表转换为Vector对象,就像第二个程序一样,而不是return Vector(self.scal_mul(recip))
。当您调用nrm_self.dot_product2(nrm_v)
时,对象nrm_self是一个列表,而不是Vector,并且它没有dot_product2方法。您需要向构造函数Vector()添加显式调用,就像在第二个程序中一样,以便能够从norm_self对象调用方法。
由于dot_product2返回的值大于1(不幸的是,1.0000000000000002),因此抛出了数学域错误,并且反余弦值acos(x)仅定义为介于-1和1之间的值。这是由于数值错误在归一化中,可以通过总是略微向上舍入来纠正。