线性代数(五)特征值与特征向量¶
章节概述¶
特征值与特征向量是线性代数的重要概念,在量子力学、振动分析、图像处理等领域有广泛应用。本章将介绍特征值与特征向量的概念、计算方法、对角化以及应用。
学习目标¶
- 理解特征值与特征向量的定义
- 掌握特征值与特征向量的计算方法
- 学会矩阵的对角化
- 理解二次型的概念
- 了解特征值与特征向量的应用
(一)特征值与特征向量的定义¶
定义¶
对于 n×n 矩阵 A,如果存在非零向量 v 和标量 λ,使得
则称 λ 为 A 的特征值,v 为对应的特征向量。特征方程¶
从定义出发,我们有
由于 v ≠ 0,必须有
这就是特征方程,也称为特征多项式。
几何意义¶
特征向量在矩阵变换下只改变长度,不改变方向(或反向)。特征值表示长度改变的倍数。
Python 实现¶
def characteristic_polynomial(A, tolerance=1e-10):
"""
计算特征多项式(使用 NumPy)
参数:
A: n×n 矩阵
tolerance: 容差
返回:
numpy.poly1d: 特征多项式
示例:
>>> A = [[1, 2], [2, 1]]
>>> characteristic_polynomial(A)
poly1d([ 1., -2., -3.])
"""
import numpy as np
A_np = np.array(A, dtype=float)
return np.poly(A_np)
def eigenvalues(A, tolerance=1e-10):
"""
计算特征值
参数:
A: n×n 矩阵
tolerance: 容差
返回:
list: 特征值列表
示例:
>>> A = [[1, 2], [2, 1]]
>>> eigenvalues(A)
[3.0, -1.0]
"""
import numpy as np
A_np = np.array(A, dtype=float)
eigenvals = np.linalg.eigvals(A_np)
return [float(val.real if abs(val.imag) < tolerance else val) for val in eigenvals]
def eigenvectors(A, tolerance=1e-10):
"""
计算特征值和特征向量
参数:
A: n×n 矩阵
tolerance: 容差
返回:
dict: {特征值: [特征向量列表]}
示例:
>>> A = [[1, 2], [2, 1]]
>>> eigenvectors(A)
{3.0: [[1.0, 1.0]], -1.0: [[1.0, -1.0]]}
"""
import numpy as np
A_np = np.array(A, dtype=float)
eigenvals, eigenvecs = np.linalg.eig(A_np)
result = {}
for val, vec in zip(eigenvals, eigenvecs.T):
# 处理复数
if abs(val.imag) < tolerance:
val_real = float(val.real)
else:
val_real = complex(val)
# 归一化特征向量
vec_real = []
for component in vec:
if abs(component.imag) < tolerance:
vec_real.append(float(component.real))
else:
vec_real.append(component)
# 添加到结果
if val_real not in result:
result[val_real] = []
result[val_real].append(vec_real)
return result
实例分析¶
实例1:计算特征值
实例2:计算特征向量
A = [[1, 2],
[2, 1]]
vecs = eigenvectors(A)
for val, vec_list in vecs.items():
print(f"特征值 {val} 对应的特征向量:")
for vec in vec_list:
print(f" {vec}")
实例3:验证特征值和特征向量
A = [[1, 2],
[2, 1]]
vals = eigenvalues(A)
vecs = eigenvectors(A)
# 验证 A·v = λ·v
for val, vec_list in vecs.items():
for vec in vec_list:
# 计算 A·v
Av = [sum(A[i][j] * vec[j] for j in range(len(vec))) for i in range(len(A))]
# 计算 λ·v
lambda_v = [val * v for v in vec]
print(f"特征值 {val}, 特征向量 {vec}")
print(f"A·v = {Av}")
print(f"λ·v = {lambda_v}")
print(f"相等: {all(abs(a - b) < 1e-10 for a, b in zip(Av, lambda_v))}")
(二)特征值的性质¶
性质1:迹与特征值¶
矩阵 A 的迹(trace)等于其特征值之和:
性质2:行列式与特征值¶
矩阵 A 的行列式等于其特征值的乘积:
性质3:特征多项式的次数¶
n×n 矩阵的特征多项式是 n 次多项式,最多有 n 个特征值(可能有重根)。
性质4:实对称矩阵的特征值¶
实对称矩阵的特征值都是实数,且不同特征值对应的特征向量正交。
性质5:逆矩阵的特征值¶
如果 A 可逆,则 A⁻¹ 的特征值是 A 的特征值的倒数。
Python 实现¶
def trace(A):
"""
计算矩阵的迹
参数:
A: n×n 矩阵
返回:
float: 迹
"""
return sum(A[i][i] for i in range(len(A)))
def verify_properties(A, tolerance=1e-10):
"""
验证特征值的性质
参数:
A: n×n 矩阵
tolerance: 容差
返回:
dict: 验证结果
"""
import numpy as np
A_np = np.array(A, dtype=float)
# 计算特征值
vals = eigenvalues(A)
# 性质1:迹
tr = trace(A)
sum_eigenvals = sum(vals)
property1 = abs(tr - sum_eigenvals) < tolerance
# 性质2:行列式
det = np.linalg.det(A_np)
product_eigenvals = 1
for val in vals:
product_eigenvals *= val
property2 = abs(det - product_eigenvals) < tolerance
return {
"trace": tr,
"sum_eigenvalues": sum_eigenvals,
"property1": property1,
"determinant": det,
"product_eigenvalues": product_eigenvals,
"property2": property2
}
实例分析¶
实例:验证特征值的性质
A = [[1, 2, 3],
[2, 1, 4],
[3, 4, 1]]
result = verify_properties(A)
print(f"迹: {result['trace']}")
print(f"特征值之和: {result['sum_eigenvalues']}")
print(f"性质1 (迹 = 特征值之和): {result['property1']}")
print(f"\n行列式: {result['determinant']}")
print(f"特征值之积: {result['product_eigenvalues']}")
print(f"性质2 (行列式 = 特征值之积): {result['property2']}")
(三)矩阵的对角化¶
对角化的定义¶
如果存在可逆矩阵 P 和对角矩阵 D,使得
则称 A 可对角化。对角化的条件¶
定理:n×n 矩阵 A 可对角化的充分必要条件是 A 有 n 个线性无关的特征向量。
推论:如果 A 有 n 个不同的特征值,则 A 可对角化。
对角化的步骤¶
- 求 A 的特征值 λ₁, λ₂, ..., λₙ
- 对每个特征值,求对应的特征空间
- 如果所有特征空间的维数之和等于 n,则 A 可对角化
- 构造 P(特征向量作为列)和 D(特征值作为对角元)
Python 实现¶
def diagonalize(A, tolerance=1e-10):
"""
对角化矩阵
参数:
A: n×n 矩阵
tolerance: 容差
返回:
dict: {P: P矩阵, D: 对角矩阵, diagonalizable: 是否可对角化}
示例:
>>> A = [[1, 2], [2, 1]]
>>> diagonalize(A)
{'P': [...], 'D': [...], 'diagonalizable': True}
"""
import numpy as np
A_np = np.array(A, dtype=float)
# 计算特征值和特征向量
eigenvals, eigenvecs = np.linalg.eig(A_np)
# 检查是否可对角化
P = eigenvecs
det_P = np.linalg.det(P)
if abs(det_P) < tolerance:
return {
"P": None,
"D": None,
"diagonalizable": False,
"reason": "特征向量线性相关"
}
# 构造对角矩阵
D = np.diag(eigenvals)
# 验证 A = P·D·P⁻¹
P_inv = np.linalg.inv(P)
reconstruction = P @ D @ P_inv
if not np.allclose(reconstruction, A_np, atol=tolerance):
return {
"P": None,
"D": None,
"diagonalizable": False,
"reason": "对角化失败"
}
return {
"P": P.tolist(),
"D": D.tolist(),
"diagonalizable": True
}
def matrix_power(A, k, tolerance=1e-10):
"""
使用对角化计算矩阵的幂
参数:
A: n×n 矩阵
k: 幂次
tolerance: 容差
返回:
list: A^k
示例:
>>> A = [[1, 2], [2, 1]]
>>> matrix_power(A, 10)
"""
import numpy as np
# 对角化
diag_result = diagonalize(A, tolerance)
if not diag_result["diagonalizable"]:
raise ValueError("矩阵不可对角化")
P = np.array(diag_result["P"])
D = np.array(diag_result["D"])
P_inv = np.linalg.inv(P)
# 计算 D^k
D_power = np.diag(np.diag(D) ** k)
# 计算 A^k = P·D^k·P⁻¹
A_power = P @ D_power @ P_inv
return A_power.tolist()
实例分析¶
实例1:对角化矩阵
A = [[1, 2],
[2, 1]]
result = diagonalize(A)
if result["diagonalizable"]:
print("矩阵可对角化")
print(f"P = {result['P']}")
print(f"D = {result['D']}")
else:
print(f"矩阵不可对角化: {result['reason']}")
实例2:计算矩阵的幂
实例3:验证对角化
import numpy as np
A = [[1, 2],
[2, 1]]
result = diagonalize(A)
if result["diagonalizable"]:
P = np.array(result["P"])
D = np.array(result["D"])
P_inv = np.linalg.inv(P)
# 验证 A = P·D·P⁻¹
reconstruction = P @ D @ P_inv
print(f"原始矩阵 A:")
print(A)
print(f"\n重构矩阵 P·D·P⁻¹:")
print(np.round(reconstruction, 10))
(四)二次型¶
二次型的定义¶
关于 n 个变量 x₁, x₂, ..., xₙ 的二次齐次多项式称为二次型:
矩阵表示¶
二次型可以表示为:
其中 A 是对称矩阵。
二次型的标准化¶
通过正交变换,可以将二次型化为标准形:
其中 λᵢ 是 A 的特征值。
Python 实现¶
def quadratic_form(A, x):
"""
计算二次型的值
参数:
A: 对称矩阵
x: 向量
返回:
float: 二次型的值
示例:
>>> A = [[1, 1], [1, 1]]
>>> x = [1, 1]
>>> quadratic_form(A, x)
4.0
"""
import numpy as np
A_np = np.array(A, dtype=float)
x_np = np.array(x, dtype=float)
return float(x_np.T @ A_np @ x_np)
def standardize_quadratic_form(A, tolerance=1e-10):
"""
将二次型化为标准形
参数:
A: 对称矩阵
tolerance: 容差
返回:
dict: {eigenvalues: 特征值, transformation: 变换矩阵}
示例:
>>> A = [[1, 1], [1, 1]]
>>> standardize_quadratic_form(A)
"""
import numpy as np
A_np = np.array(A, dtype=float)
# 确保矩阵是对称的
if not np.allclose(A_np, A_np.T, atol=tolerance):
raise ValueError("矩阵必须是对称的")
# 计算特征值和特征向量
eigenvals, eigenvecs = np.linalg.eigh(A_np)
return {
"eigenvalues": eigenvals.tolist(),
"transformation": eigenvecs.tolist()
}
def is_positive_definite(A, tolerance=1e-10):
"""
判断矩阵是否正定
参数:
A: 对称矩阵
tolerance: 容差
返回:
bool: 如果正定返回 True
"""
import numpy as np
A_np = np.array(A, dtype=float)
# 检查是否对称
if not np.allclose(A_np, A_np.T, atol=tolerance):
return False
# 所有特征值必须为正
vals = np.linalg.eigvals(A_np)
return all(val > tolerance for val in vals)
def is_positive_semidefinite(A, tolerance=1e-10):
"""
判断矩阵是否半正定
参数:
A: 对称矩阵
tolerance: 容差
返回:
bool: 如果半正定返回 True
"""
import numpy as np
A_np = np.array(A, dtype=float)
# 检查是否对称
if not np.allclose(A_np, A_np.T, atol=tolerance):
return False
# 所有特征值必须非负
vals = np.linalg.eigvals(A_np)
return all(val >= -tolerance for val in vals)
实例分析¶
实例1:计算二次型
实例2:标准化二次型
A = [[2, 1],
[1, 2]]
result = standardize_quadratic_form(A)
print(f"特征值: {result['eigenvalues']}")
print(f"变换矩阵: {result['transformation']}")
实例3:判断正定性
A1 = [[2, 0],
[0, 2]]
A2 = [[-1, 0],
[0, -1]]
A3 = [[1, 0],
[0, 0]]
print(f"A1 是否正定: {is_positive_definite(A1)}") # True
print(f"A2 是否正定: {is_positive_definite(A2)}") # False
print(f"A3 是否半正定: {is_positive_semidefinite(A3)}") # True
(五)特征值与特征向量的应用¶
1. 主成分分析(PCA)¶
PCA 使用协方差矩阵的特征向量来找到数据的主成分。
def pca(data, n_components):
"""
主成分分析
参数:
data: 数据矩阵 (n_samples × n_features)
n_components: 主成分个数
返回:
dict: {components: 主成分, explained_variance: 解释方差}
"""
import numpy as np
# 中心化数据
data_centered = data - np.mean(data, axis=0)
# 计算协方差矩阵
cov_matrix = np.cov(data_centered.T)
# 计算特征值和特征向量
eigenvals, eigenvecs = np.linalg.eigh(cov_matrix)
# 按特征值降序排序
idx = np.argsort(eigenvals)[::-1]
eigenvals = eigenvals[idx]
eigenvecs = eigenvecs[:, idx]
# 选择前 n_components 个主成分
components = eigenvecs[:, :n_components]
explained_variance = eigenvals[:n_components]
return {
"components": components,
"explained_variance": explained_variance.tolist()
}
# 示例
data = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
result = pca(data, n_components=1)
print(f"主成分: {result['components']}")
print(f"解释方差: {result['explained_variance']}")
2. 振动分析¶
特征值对应振动系统的固有频率,特征向量对应振型。
3. PageRank 算法¶
PageRank 使用转移矩阵的主特征向量来计算网页的重要性。
def pagerank(adjacency_matrix, damping_factor=0.85, max_iter=100, tolerance=1e-10):
"""
PageRank 算法
参数:
adjacency_matrix: 邻接矩阵
damping_factor: 阻尼因子
max_iter: 最大迭代次数
tolerance: 容差
返回:
list: PageRank 值
"""
import numpy as np
n = len(adjacency_matrix)
A = np.array(adjacency_matrix, dtype=float)
# 计算出度
out_degree = np.sum(A, axis=1)
# 构造转移矩阵
P = np.zeros((n, n))
for i in range(n):
if out_degree[i] > 0:
P[i, :] = A[i, :] / out_degree[i]
else:
P[i, :] = 1 / n # 处理悬空节点
# PageRank 矩阵
M = damping_factor * P + (1 - damping_factor) / n * np.ones((n, n))
# 幂法求主特征向量
r = np.ones(n) / n # 初始向量
for _ in range(max_iter):
r_new = M @ r
r_new = r_new / np.sum(r_new)
if np.linalg.norm(r_new - r) < tolerance:
break
r = r_new
return r.tolist()
# 示例
adj_matrix = [[0, 1, 1],
[0, 0, 1],
[1, 0, 0]]
rank = pagerank(adj_matrix)
print(f"PageRank 值: {rank}")
4. 图像压缩¶
使用奇异值分解(SVD)对图像进行压缩。
实战练习¶
练习1:计算特征值和特征向量¶
计算下列矩阵的特征值和特征向量:
A = [[2, 1],
[1, 2]]
vals = eigenvalues(A)
vecs = eigenvectors(A)
print(f"特征值: {vals}")
print(f"特征向量: {vecs}")
练习2:对角化矩阵¶
对下列矩阵进行对角化:
A = [[3, 1],
[0, 2]]
result = diagonalize(A)
if result["diagonalizable"]:
print(f"P = {result['P']}")
print(f"D = {result['D']}")
else:
print(f"不可对角化: {result['reason']}")
练习3:二次型标准化¶
将下列二次型化为标准形:
A = [[2, 1],
[1, 2]]
result = standardize_quadratic_form(A)
print(f"标准形系数: {result['eigenvalues']}")
章节小结¶
本章介绍了特征值与特征向量:
- 特征值与特征向量的定义:理解特征值和特征向量的概念
- 特征值的性质:掌握迹、行列式与特征值的关系
- 矩阵的对角化:学会对角化矩阵和应用
- 二次型:理解二次型的标准化和正定性
- 应用:了解在 PCA、振动分析、PageRank 等领域的应用
特征值与特征向量是线性代数的重要概念,在科学计算和工程应用中有广泛用途。
总结¶
恭喜你完成了线性代数教程的学习!
你现在已经掌握了: - 行列式的定义、性质和计算 - 矩阵的运算、逆矩阵和秩 - 线性方程组的解法和结构 - 向量空间的概念和线性变换 - 特征值与特征向量的理论
继续深入学习: - 数值线性代数 - 矩阵分析 - 抽象代数 - 泛函分析
重点提醒: - 特征值和特征向量是成对出现的 - 实对称矩阵的特征值都是实数 - 可对角化的矩阵有 n 个线性无关的特征向量 - 二次型的标准形使用特征值表示 - 特征值理论在实际问题中有广泛应用