Python線性代數學習筆記——規範化和單位向量,以及Python實現向量規範化

向量的長度,也就是向量的模

2維向量的向量長度:

3維向量的向量長度:

同理,拓展到n維向量:


單位向量(unit vector)

單位向量是指模等於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 | 線性代數 |