什么是矩阵
矩阵是一个二维数组,和向量包含的元素一样。 矩阵可以包含 m 行和 n 列。
如果矩阵包含 m 行和 n 列,则称之为 m x n 矩阵:
矩阵元素的下标从1开始。
矩阵加法
要将一个矩阵与另一个矩阵相加,我们需要:
- 验证确保两个矩阵的维度相同
- 按照相应的正确索引将元素相加
矩阵标量乘法
要将矩阵与标量相乘,我们不需要验证维度或指数。
- 只需将矩阵中的每个元素与标量相乘即可!
方形矩阵乘法
将两个矩阵相乘时,我们需要考虑每个矩阵的维度,如果维度不能合理匹配,则无法相乘。最简单的乘法是两个具有相同维度 nxn 的方形矩阵相乘。
方形矩阵是行数和列数相同的矩阵。
下面是一个 mxm 方形矩阵。它有 m 行和 m 列。
A =
矩阵 A 可以与其他维度相同的矩阵 mxm 相乘。结果是一个维度相同的新方形矩阵。
注意在乘法结果中查找每个元素的规律。PxQ 中的每个元素 ij 是将矩阵 P 的行 i中的所有元素与矩阵 Q 的列 j 中的相应元素相乘的结果。
square.png
矩阵乘法
矩阵乘法不限于方形矩阵乘法。
这里的顺序很重要,因为矩阵乘法是不满足交换律的
如果 A 是一个 n × m 矩阵,B 是一个 m × p 矩阵,它们的矩阵积 AB 是一个 n × p 矩阵,其中 A 的行上的 m 个元素与 B 的列上的 m 个元素相乘,得出矩阵积 AB。如果用矩阵表示两个线性变换,则矩阵积表示两个变换的合成结果。
换句话说,如果 P 是一个维度为 t x m 的矩阵,Q 是一个维度为 m x v 的矩阵,那么:
- PxQ 是可行的,因为维度匹配。(P 有 m 列,Q 有 m 行)。
- PxQ 将是一个 txv 矩阵。(有 t 行和 v 列)。
矩阵转置
一个矩阵倾斜了 。
A =
AT =
python演示
import numpy as np
import pandas as pd
# Creates numpy vector from a list to represent money (inputs) vector.
money = np.asarray([70, 100, 20, 80, 40, 70, 60, 100])
# Creates pandas dataframe with column labels(currency_label) from the numpy vector for printing.
currency_label = ["USD", "EUR", "JPY", "GBP", "CHF", "CAD", "AUD", "HKD"]
money_df = pd.DataFrame(data=money, index=currency_label, columns=["Amounts"])
print("Inputs Vector:")
money_df.T
线性变换
为了更好的说明线性变换,这里将问题简化,仅考虑2维数组。
线性变换 vs 函数
我们可以将线性变换理解成为一个函数,输入变量是一个向量,线性变换对其进行处理,并将处理后的向量作为结果输出。这里用变换而不是函数,是因为变换一词能更加直观的体现输入与输出的关系。这种变换,最好是用运动来理解,也就是说可以将变换的过程想象为输入向量运动到输出向量的过程。
向量变换 vs 点在网格上的运动
如果将向量看作是一个个的箭头,那么可视化的结果将非常拥挤,一种简单明了的方式是将向量表示成点,每个点对应箭头所在的位置。由此,将任意可能的输入向量移动到相应的输出向量的变换过程,可以表示为空间中各点移动到另一个点所处位置的情景。在二维条件下,可以将将变换过程想象为各个点在无限网格上做运动:
input.png
--->
output.png为了同时说明运动的起点和终点,我们将原始网格保存在背景里:
background.png
线性变换的特点
线性代数中涉及到的变换都很特殊,可以成为线性变换,即必须满足三个特点:
- 所有的网格线必须是直线。
- 原点是不变的。
- 所有的网格线必须是平行等距的。
线性变换数字化
有时候,我们需要将向量输入计算机以便于演示和计算,但是该如何用数字表示向量呢。通常,只需要知道向量的基向量,和所在的位置就行了。例如,对于向量
,可以在网格内表示为:
现在,我们对这三个点(即向量)进行变换,并观察他们的落点,注意到这里变换后的网格满足前面的三个特性,变换后的向量依然是:
-1 * 变换后的 + 2 * 变换后的
也就是说,向量从一开始是和某种线性组合,变换后依然是变换后的和的相同线性组合。因此,只需知道变换后和的落点,就能推导出会运动到哪里。
具体到我们的例子:
变换后落在[1,-2]处,而落在了[3,0]处,因此原向量变换为 -1 * [1,-2] + 2 * [3,0],即变换后的落在了[5,2]。
将上面的过程一般化,对于任意向量[x,y],对其进行相同线性变换后的落点都可以确定为:
x + y =
也就是说,任意一个二维线性变换都可以用4个数字描述,即向量和变换后的坐标。通常,我们将这两个变换之后的向量组合为一个矩阵。这里,这个矩阵就是:
进一步,得出适用于所有情况的公式:
= x + y =
特殊的线性变换
极端情况下,当线性变换的两个基向量线性相关的时候,该线性变换会把整个二维空间压缩成这两个向量所在的那条直线,即这两个线性相关向量的一维张成空间。
dep.png
python演示
上一节介绍了
- 向量可以如何分解为基向量 和 。
- 如何转换向量:将该向量的 和 值乘以转换的基向量 和 ,并对结果求和:
方程 1
这种通过使用转换的基向量转换向量的方法与矩阵乘法一样:
方程 2
接下来,用python演示这一过程。
- 绘制一个分解为基向量和的向量
# Import NumPy and Matplotlib
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
# Define vector v
v = np.array([-1,2])
# Define basis vector i_hat as unit vector
i_hat = np.array([1,0])
# Define basis vector j_hat as unit vector
j_hat = np.array([0,1])
# Define v_ihat - as v[0](x) multiplied by basis vector ihat
v_ihat = v[0] * i_hat
# Define v_jhat_t - as v[1](y) multiplied by basis vector jhat
v_jhat = v[1] * j_hat
# Plot that graphically shows vector v (color='b') - whose position can be
# decomposed into v_ihat and v_jhat
# Creates axes of plot referenced 'ax'
ax = plt.axes()
# Plots red dot at origin (0,0)
ax.plot(0,0,'or')
# Plots vector v_ihat as dotted green arrow starting at origin 0,0
ax.arrow(0, 0, *v_ihat, color='g', linestyle='dotted', linewidth=2.5, head_width=0.30,
head_length=0.35)
# Plots vector v_jhat as dotted red arrow starting at origin defined by v_ihat
ax.arrow(v_ihat[0], v_ihat[1], *v_jhat, color='r', linestyle='dotted', linewidth=2.5,
head_width=0.30, head_length=0.35)
# Plots vector v as blue arrow starting at origin 0,0
ax.arrow(0, 0, *v, color='b', linewidth=2.5, head_width=0.30, head_length=0.35)
# Sets limit for plot for x-axis
plt.xlim(-4, 2)
# Set major ticks for x-axis
major_xticks = np.arange(-4, 2)
ax.set_xticks(major_xticks)
# Sets limit for plot for y-axis
plt.ylim(-2, 4)
# Set major ticks for y-axis
major_yticks = np.arange(-2, 4)
ax.set_yticks(major_yticks)
# Creates gridlines for only major tick marks
plt.grid(b=True, which='major')
# Displays final plot
plt.show()
- 绘制一个利用方程1的向量转换过程
在此部分,我们将绘制使用转换的向量 和 转换向量 的结果。向量 、 和 的定义如下所示。
# Define vector v
v = np.array([-1, 2])
# TODO 1.: Define vector i_hat as transformed vector i_hat(ihat_t)
# where x=3 and y=1 instead of x=1 and y=0
ihat_t = np.array([3, 1])
# TODO 2.: Define vector j_hat as transformed vector j_hat(jhat_t)
# where x=1 and y=2 instead of x=0 and y=1
jhat_t = np.array([1, 2])
# Define v_ihat_t - as v[0](x) multiplied by transformed vector ihat
v_ihat_t = v[0] * ihat_t
# Define v_jhat_t - as v[1](y) multiplied by transformed vector jhat
v_jhat_t = v[1] * jhat_t
# TODO 3.: Define transformed vector v (v_t) as
# vector v_ihat_t added to vector v_jhat_t
v_t = v_ihat_t + v_jhat_t
# Plot that graphically shows vector v (color='skyblue') can be transformed
# into transformed vector v (v_trfm - color='b') by adding v[0]*transformed
# vector ihat to v[0]*transformed vector jhat
# Creates axes of plot referenced 'ax'
ax = plt.axes()
# Plots red dot at origin (0,0)
ax.plot(0,0,'or')
# Plots vector v_ihat_t as dotted green arrow starting at origin 0,0
ax.arrow(0, 0, *v_ihat_t, color='g', linestyle='dotted', linewidth=2.5, head_width=0.30,
head_length=0.35)
# Plots vector v_jhat_t as dotted red arrow starting at origin defined by v_ihat
ax.arrow(v_ihat_t[0], v_ihat_t[1], *v_jhat_t, color='r', linestyle='dotted', linewidth=2.5,
head_width=0.30, head_length=0.35)
# Plots vector v as blue arrow starting at origin 0,0
ax.arrow(0, 0, *v, color='skyblue', linewidth=2.5, head_width=0.30, head_length=0.35)
# TODO 4.: Plot transformed vector v (v_t) a blue colored vector(color='b') using
# vector v's ax.arrow() statement above as template for the plot
ax.arrow(0, 0, *v_t, color='b', linewidth=2.5, head_width=0.30, head_length=0.35)
# Sets limit for plot for x-axis
plt.xlim(-4, 2)
# Set major ticks for x-axis
major_xticks = np.arange(-4, 2)
ax.set_xticks(major_xticks)
# Sets limit for plot for y-axis
plt.ylim(-2, 4)
# Set major ticks for y-axis
major_yticks = np.arange(-2, 4)
ax.set_yticks(major_yticks)
# Creates gridlines for only major tick marks
plt.grid(b=True, which='major')
# Displays final plot
plt.show()
- 展示可以通过矩阵乘法实现同一向量转换(方程 2)
在此部分,我们将演示可以通过矩阵实现上述部分的相同向量转换结果(方程 2)。向量 和 的定义如下所示。
# Define vector v
v = np.array([-1,2])
# Define 2x2 matrix ij
ij = np.array([[3, 1],[1, 2]])
# TODO 1.: Demonstrate getting v_trfm by matrix multiplication
# by using matmul function to multiply 2x2 matrix ij by vector v
# to compute the transformed vector v (v_t)
v_t = np.matmul(ij, v)
# Prints vectors v, ij, and v_t
print("\nMatrix ij:", ij, "\nVector v:", v, "\nTransformed Vector v_t:", v_t, sep="\n")
参考:
函数 matmul
网友评论