人工智慧必備數學知識學習筆記5:向量的高階話題
阿新 • • 發佈:2020-08-04
- 規範化和單位向量
單位向量:表示向量長度(向量模的最小組成單元)的單位
程式碼實現:
1.在 _global.py中編寫程式碼:
2.在Vector.py編寫程式碼
1 #向量類 2 #__values() 與 _values()區別更多體現在繼承上,如果是在類的內部使用時官方建議使用_values()發方法 3 from ._global import EPSILON 4 import math 5 6 7 class Vector: 8 9 def __init__(self,lst):10 self._values = list(lst)#將陣列賦值給向量類中(注:使用list方法將列表lst複製一份保證他的不被外界呼叫時修改) 11 12 #零向量類方法:引數1:為當前的類(cls) 引數2:維度(dim) 返回dim維的零向量 13 @classmethod 14 def zero(cls,dim): 15 return cls([0] * dim) 16 17 #返回向量的模(向量長度): 18 def norm(self): 19 return math.sqrt(sum(e**2 fore in self))#sqrt()方法為開平方根,sum()求和方法,e**2 e的平方 20 21 #返回向量的單位向量 22 def normalize(self): 23 if self.norm() < EPSILON: #此處判斷一個精度範圍(該精度範圍呼叫內部自定義全域性變數檔案 _global.py)(由於浮點數計算機含有誤差所以無法使用 == 0 的操作) 24 raise ZeroDivisionError("Normalize error! norm is zero.") #考慮零向量時報此處異常即可 25 #方案一:return Vector(1/self.norm() * [e for e in self])#迴圈遍歷向量中的每個元素分別除以該向量的模即為單位向量 26 #方案二:return 1/self.norm() * Vector(self._values)#當前向量除以模即為單位向量 27 return Vector(self._values) / self.norm() 28 29 #向量加法,返回結果向量 30 def __add__(self, another): 31 # assert判斷傳入的向量維度是否相等 32 assert len(self) == len(another),\ 33 "Error in adding. Length of vectors must be same." 34 return Vector([a+b for a,b in zip(self,another)])#使用zip()方法將兩個向量取出來 35 36 # 向量減法 37 def __sub__(self, another): 38 assert len(self) == len(another), \ 39 "Error in adding. Length of vectors must be same." 40 return Vector([a - b for a, b in zip(self, another)]) 41 42 # 向量乘法(數乘陣列),返回數量乘法的結果向量:self * k 43 def __mul__(self, k): 44 return Vector([k * e for e in self]) 45 46 # 向量乘法(陣列乘數),返回數量乘法的結果向量:k * self 47 def __rmul__(k, self): 48 return k * self #此處直接呼叫的是上方的乘法函式 49 50 # 向量除法:返回數量除法的結果向量 self / k 51 def __truediv__(self, k): 52 return (1 / k) * self 53 54 #返回向量取正的結果向量 55 def __pos__(self): 56 return 1 * self 57 58 # 返回向量取負的結果向量 59 def __neg__(self): 60 return -1 * self 61 62 #返回向量迭代器(當有迭代器時,zip()方法中就不用再次傳入兩個向量陣列,直接傳入向量物件即可<zip(self._values,another._values)>) 63 def __iter__(self): 64 return self._values.__iter__() 65 66 #取向量的index個元素 67 def __getitem__(self, index): 68 return self._values[index] 69 70 #返回向量的長度(有多少個元素) 71 def __len__(self): 72 return len(self._values) 73 74 # 向量展示(系統呼叫) 75 def __repr__(self): 76 return "Vector({})".format(self._values) 77 78 # 向量展示(使用者呼叫) 79 def __str__(self): 80 return "({})".format(", ".join(str(e) for e in self._values))#通過遍歷 self.__values 將e轉成字串通過逗號加空格來連結放入大括號中 81 82 # u = Vector([5,2]) 83 # print(u)
3.在main_vector.py展示中編寫:
1 from playLA.Vector import Vector 2 3 if __name__ == "__main__": 4 5 vec = Vector([5,2]) 6 print(vec) 7 print(len(vec))#列印向量的維度 8 print("vec[0] = {}, vec[1] = {}".format(vec[0],vec[1])) 9 10 #向量加法 11 vec2 = Vector([3,1]) 12 print("{} + {} = {}".format(vec,vec2,vec+vec2)) 13 #向量減法 14 print("{} - {} = {}".format(vec, vec2, vec - vec2)) 15 #向量乘法(向量乘以數) 16 print("{} * {} = {}".format(vec,3,vec * 3)) 17 # 向量乘法(數乘以向量) 18 print("{} * {} = {}".format(3, vec, 3 * vec)) 19 # 向量取正 20 print("+{} = {}".format(vec, +vec)) 21 # 向量取負 22 print("-{} = {}".format(vec, -vec)) 23 24 #零向量 25 zero2 = Vector.zero(2) 26 print(zero2) 27 #向量加上零向量 28 print("{} + {} = {}".format(vec, zero2, vec + zero2)) 29 30 #向量的模 31 print("norm({}) = {}".format(vec,vec.norm())) 32 print("norm({}) = {}".format(vec2,vec2.norm())) 33 print("norm({}) = {}".format(zero2, zero2.norm())) 34 35 #單位向量 36 print("normalize({}) is {}".format(vec,vec.normalize())) 37 print(vec.normalize().norm())#單位向量的模(長度)基本為數字1 38 print("normalize({}) is {}".format(vec2, vec2.normalize())) 39 print(vec2.normalize().norm()) # 單位向量的模(長度)基本為數字1(計算機中會有誤差0.9999...) 40 #print(zero2.normalize()) 41 #捕捉異常 ZeroDivisionError 42 try: 43 zero2.normalize() 44 except ZeroDivisionError: 45 print("Cannot normalize zero vector {}".format(zero2))
4.執行main_vector.py結果為:
1 /Users/liuxiaoming/PycharmProjects/LinearAlgebra/venv/bin/python /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevconsole.py --mode=client --port=57619 2 import sys; print('Python %s on %s' % (sys.version, sys.platform)) 3 sys.path.extend(['/Users/liuxiaoming/PycharmProjects/LinearAlgebra']) 4 PyDev console: starting. 5 Python 3.8.2 (v3.8.2:7b3ab5921f, Feb 24 2020, 17:52:18) 6 [Clang 6.0 (clang-600.0.57)] on darwin 7 runfile('/Users/liuxiaoming/PycharmProjects/LinearAlgebra/main_vector.py', wdir='/Users/liuxiaoming/PycharmProjects/LinearAlgebra') 8 (5, 2) 9 2 10 vec[0] = 5, vec[1] = 2 11 (5, 2) + (3, 1) = (8, 3) 12 (5, 2) - (3, 1) = (2, 1) 13 (5, 2) * 3 = (15, 6) 14 3 * (5, 2) = (15, 6) 15 +(5, 2) = (5, 2) 16 -(5, 2) = (-5, -2) 17 (0, 0) 18 (5, 2) + (0, 0) = (5, 2) 19 norm((5, 2)) = 5.385164807134504 20 norm((3, 1)) = 3.1622776601683795 21 norm((0, 0)) = 0.0 22 normalize((5, 2)) is (0.9284766908852593, 0.3713906763541037) 23 1.0 24 normalize((3, 1)) is (0.9486832980505138, 0.31622776601683794) 25 0.9999999999999999 26 Cannot normalize zero vector (0, 0)