线性代数:
真实的世界是多维度的,单变量不足以描述这个世界。将单变量变为向量,就是线性代数了
一:向量
向量是一组数的表示方式,线性代数研究的基本元素,最初用于表示从原点到某个点的一个方向 :
在向量的研究领域,只考虑起点为原点的向量,因为如果起点不是原点,我们也可以通过坐标变换,把起点变为原点。也可以这么理解,在数字的研究领域中,我们只考虑数字到0的距离和方向(数的方向就是正负),而不考虑数字到其他数字如 -2、3之间的距离,那么作为线性代数中的数——向量,我们也只考虑到原点的距离和方向。
在物理世界中,如果只是用于表示方向,最多三个维度就够了,后续提出的n维向量、n维空间,实际上和物理世界是无关的。
如使用向量来表示一个房间:
向量的一些数学定义:
由于向量都是基于原点的,因此可以有两个视角:
- 有向线段
- 数据点
向量分为行向量和列向量,但通常的教材和论文中,如果提到了向量,那就是列向量。
二:向量的加法和乘法
向量的乘法定义为标量和向量的乘法,乘法的本质是多次相加,因此乘法用于向量可以如下计算:
三:向量运算的基本性质
小时候学习数学,先有数的运算的相关性质,之后才敢进行更加复杂的运算,如加法交换律、乘法交换律、加法结合律、乘法结合律等等。对于向量运算,我们也要这么做!!!
向量运算分为向量和向量的运算和向量和标量的运算。
这些性质,都可以使用前面说的加法和数量乘法的定义来证明。
四:向量世界的0——零向量
什么是0?在数值运算中,对于任意数n,如果一个数a满足 n+a = n,那么这个数a就是零。
注意 O 向量的表示没有箭头,因为它没有方向。
上面使用反证法(数学证明两大法宝:反证法和数学归纳法)。
五:规范化和单位向量
将向量看成一个有向线段,那么无法逃避的一个问题就是,向量的长度是多少?
为什么向量的模用双竖线呢?这其实是因为向量的模表示该点到原点的欧拉距离,在数学上还有一个称呼 —— 二范数。
模值为1的向量,就是单位向量了,用于表示向量的方向:
标准单位向量:只由0、1组成的单位向量,它指向坐标轴的正方向。
可以认为,空间坐标系就是由标准单位向量组成。
六:向量的点乘
也叫内积
结果是一个数。
以二维空间中的情况证明:
其中余弦定理可以这样理解,如果一个三角形三条边都确定了,那么这个三角形也就确定了,三角形的三个角自然可以用数学的方式计算出来,比如 —— 余弦定理。
向量的点乘为什么要这么计算呢?
本质是向量投影后,模的乘积。由于向量是有方向的,直接相乘没有意义,但是其中一个向量投影后,方向就一致了,乘积也就有意义了。
七:向量的python实现
下面是向量类的python实现:
import math
from ._global import MINIMAL_NUM
# 在数学相关类的设计时,类本身应该是不可更改的,因此这里类的任何操作
# 如加法,会返回新的对象,而不是改变类本身,lst对象传入后,也会先复制,再作为成员变量使用
class Vector:
def __init__(self,lst):
# python的命名很有意思,单下划线是 protect,双下划线是 private
self._vector = list(lst)
@classmethod
def zero(cls,dim):
return cls([0] * dim)
def norm(self):
return math.sqrt(sum(e**2 for e in self._vector))
def normalize(self):
if self.norm() - 0 < MINIMAL_NUM:
raise ZeroDivisionError("0向量无法被单位化")
return Vector(self._vector) / self.norm()
def dot(self,other):
return sum(a * b for a,b in zip(self,other))
def __add__(self, other):
assert len(self) == len(other),"错误:相加向量的维度必须相等"
return Vector([a+b for a,b in zip(self,other)])
def __sub__(self, other):
assert len(self) == len(other), "错误:相减向量的维度必须相等"
return Vector([a-b for a,b in zip(self,other)])
def __mul__(self, k): #右乘
return Vector([k * e for e in self])
def __rmul__(self, k): #左乘
return self * k
# 数量除法,非整组除法
def __truediv__(self, k):
return (1/k) * self
def __pos__(self): #取正
return self
def __neg__(self): #取负
return -1 * self
def __iter__(self):
return self._vector.__iter__()
def __getitem__(self, index):
return self._vector[index]
def __len__(self):
return len(self._vector)
# 在交互式环境中,直接输出的对象信息会走这个函数
def __repr__(self):
return "Vector({})".format(self._vector)
# print对象会走这个
def __str__(self):
return "({})".format(", ".join(str(e) for e in self._vector))
numpy中向量的使用:
vector = np.array([1,2,3,4,5]) #numpy构造的向量只能保存一种类型的元素(默认是浮点型)
np.zeros(5) # [0.,0.,0.,0.,0.]
np.ones(5) # [1. 1. 1. 1. 1.]
np.full(5,777) # [777,777,777,777,777,777]
print(vector.size)
print(vector[0])
print(vector[-1]) # 最后一个元素
print(vector[0: 2]) # 切片
#基本运算
vector2 = np.array([2,3,4,5,6]);
print(vector + vector2)
print(vector - vector2)
print(2 * vector)
print(vector * 2)
print(vector.dot(vector2))
print(vector * vector2) # 逐个元素相乘(没有数学意义)
print(np.linalg.norm(vector)) # 求模
print(vector / np.linalg.norm(vector)) # 单位向量