python 自定義 計算向量投影 正交 函式
阿新 • • 發佈:2019-02-08
# coding=utf-8 from math import sqrt, acos, pi class Vector(object): """docstring for Vector""" """根據座標軸列表輸入 建立向量, 並建立該向量所處的空間維度""" CANNOT_NORMALIZE_ZERO_VECTOR_MSG = 'Cannot normalize the zero vector' def __init__(self, coordinates): super(Vector, self).__init__() try: if not coordinates: raise ValueError self.coordinates = tuple(coordinates) self.dimension = len(coordinates) except ValueError: raise ValueError('The coordinates must be nonempty') except TypeError: raise TypeError('The coordinates must be an iterable') # '''能夠使python的內建print函式 輸出向量座標軸''' def __str__(self): return 'Vector: {}'.format(self.coordinates) def scalarMultiply(self,num): new_corrdinate =[num * x for x in self.coordinates] return Vector(new_corrdinate) def minus(self,v): new_corrdinate = [x-y for x,y in zip(self.coordinates, v.coordinates)] return Vector(new_corrdinate) # 將向量歸一化 def normalized(self): try: magnitude = self.magnitude() return Vector([x *1.0/ magnitude for x in self.coordinates]) except ZeroDivisionError: raise Exception('Cannot normalized the zero myVector2') # 點積 def dot(self, v): # print([x*y for x,y in zip(self.coordinates, v.coordinates)]) return sum([round(x*y,3) for x,y in zip(self.coordinates, v.coordinates)]) # 投影 def projection(self, b): ub = b.normalized() dot_num = self.dot(ub) new_cordinates = ub.scalarMultiply(dot_num) return new_cordinates # 垂直 def vertical(self,b): projection_v = self.projection(b) new_cordinates = self.minus(projection_v) return new_cordinates v1 = Vector([3.039, 1.879]) v2 = Vector([0.825, 2.036]) print v1.projection(v2) v3 = Vector([-9.88, -3.264, -8.159]) v4 = Vector([-2.155, -9.353, -9.473]) print v3.vertical(v4) v5 = Vector([3.009,-6.172,3.692,-2.51]) v6 = Vector([6.404,-9.144,2.759,8.718]) print v5.projection(v6) print v5.vertical(v6) # 輸出 # Vector: (1.0823253260174353, 2.671047713662422) # Vector: (-8.350069611957737, 3.3761108674521076, -1.4336957930745413) # Vector: (1.968617063395022, -2.810904813817002, 0.8481284319030084, 2.679950586926578) # Vector: (1.040382936604978, -3.3610951861829976, 2.8438715680969917, -5.189950586926578) # [Finished in 0.2s]
優化後
def component_parallel_to(self, basis): try: u = basis.normalized() weight = self.dot(u) return u.scalarMultiply(weight) except Exception as e: if str(e) == self.CANNOT_NORMALIZE_ZERO_VECTOR_MSG: raise Exception(self.CANNOT_NORMALIZE_ZERO_VECTOR_MSG) else: raise e def component_orthogonal_to(self, basis): try: projection = self.component_parallel_to(basis) return self.minus(projection) except Exception, e: if str(e) == self.NO_UNIQUE_ORTHOGONAL_COMPONENT_MSG: raise Exception(self.NO_UNIQUE_ORTHOGONAL_COMPONENT_MSG) else: raise e