2維向量的向量長度:
3維向量的向量長度:
同理,拓展到n維向量:
單位向量是指模等於1的向量
一個非零向量除以它的模,可得所需單位向量。一個單位向量的平面直角坐標繫上的坐標表示可以是:(n,k) ,則有n2+k2=1。
根據向量求出該向量的單位向量的過程稱為:歸一化,規範化(normalize)
單位向量有無數個
標準單位向量(Standard unit vector)
拓展到n維中的標準單位向量:
使用Python實現向量規範化:
接著在之前的Vector類中,添加方法:
測試效果:
全部代碼:
import math from ._globals import EPSILON
class Vector:
def __init__(self, lst): self._values = list(lst)
@classmethod def zero(cls, dim): """返回一個dim維的零向量""" return cls([0] * dim)
def __add__(self, another): """向量加法,返回結果向量""" assert len(self) == len(another), "Error in adding. Length of vectors must be same."
return Vector([a + b for a, b in zip(self, another)])
def __sub__(self, another): """向量減法,返回結果向量""" assert len(self) == len(another), "Error in subtracting. Length of vectors must be same."
return Vector([a - b for a, b in zip(self, another)])
def norm(self): """返迴向量的模""" return math.sqrt(sum(e**2 for e in self))
def normalize(self): """返迴向量的單位向量""" if self.norm() < EPSILON: raise ZeroDivisionError("Normalize error! norm is zero.") return Vector(self._values) / self.norm() # return 1 / self.norm() * Vector(self._values) # return Vector([e / self.norm() for e in self])
def __mul__(self, k): """返回數量乘法的結果向量:self * k""" return Vector([k * e for e in self])
def __rmul__(self, k): """返回數量乘法的結果向量:k * self""" return self * k
def __truediv__(self, k): """返回數量除法的結果向量:self / k""" return (1 / k) * self
def __pos__(self): """返迴向量取正的結果向量""" return 1 * self
def __neg__(self): """返迴向量取負的結果向量""" return -1 * self
def __iter__(self): """返迴向量的迭代器""" return self._values.__iter__()
def __getitem__(self, index): """取向量的第index個元素""" return self._values[index]
def __len__(self): """返迴向量長度(有多少個元素)""" return len(self._values)
def __repr__(self): return "Vector({})".format(self._values)
def __str__(self): return "({})".format(", ".join(str(e) for e in self._values))
定義一個內部使用的文件_globals,用來存儲全局使用的變數 EPSILON,用來判斷精度用的
EPSILON = 1e-8
測試代碼:
from playLA.Vector import Vector
if __name__ == "__main__":
vec = Vector([5, 2]) print(vec) print("len(vec) = {}".format(len(vec))) print("vec[0] = {}, vec[1] = {}".format(vec[0], vec[1]))
vec2 = Vector([3, 1]) print("{} + {} = {}".format(vec, vec2, vec + vec2)) print("{} - {} = {}".format(vec, vec2, vec - vec2))
print("{} * {} = {}".format(vec, 3, vec * 3)) print("{} * {} = {}".format(3, vec, 3 * vec))
print("+{} = {}".format(vec, +vec)) print("-{} = {}".format(vec, -vec))
zero2 = Vector.zero(2) print(zero2) print("{} + {} = {}".format(vec, zero2, vec + zero2))
print("norm({}) = {}".format(vec, vec.norm())) print("norm({}) = {}".format(vec2, vec2.norm())) print("norm({}) = {}".format(zero2, zero2.norm()))
print("normalize {} is {}".format(vec, vec.normalize())) print(vec.normalize().norm())
print("normalize {} is {}".format(vec2, vec2.normalize())) print(vec2.normalize().norm())
try: zero2.normalize() except ZeroDivisionError: print("Cannot normalize zero vector {}.".format(zero2))
推薦閱讀:
※爬蟲界又出神器|一款比selenium更高效的利器※慢學演算法 / Leetcode (Python3) - 第四周※Python教程:17個冷門但實用的小技巧※python高準確率滑動驗證破解平台,提供免費api介面,解決反爬蟲※Python 數據結構之列表(list)
TAG:Python | 線性代數 |