简介:一份矩阵论期末考试参考答案,内容围绕特征值、特征向量、若尔当标准形、史密斯标准形、QR分解、正交投影与矩阵幂运算等核心考点展开,适合本科高年级及研究生期末复习或考研数学进阶学习。文档包含四道解答题,均给出完整推导过程:第一题计算给定矩阵的若尔当标准形并构造相似变换矩阵;第二题对四个向量作施密特正交化并完成QR分解;第三题证明矩阵一范数与无穷范数之间的不等式关系;第四题借助矩阵指数求解非齐次线性微分方程组初值问题。整个资源为一份PDF文档,压缩包大小约284KB,内容排版规整、步骤清晰,便于对照演算和查漏补缺。目前已有六百一十九人学习,尤其适合需要系统掌握矩阵分解、标准形与矩阵函数应用的备考者。
1. 矩阵论期末参考答案:五类题型背后的计算链
矩阵论期末考试里,Jordan标准形、QR分解、矩阵范数、非齐次微分方程组和Moore-Penrose广义逆这五类题型几乎年年出现,但参考答案里每一步都藏着符号、顺序和约分上的坑。这份资源是一套完整的5题参考答案,覆盖了从λI−A的Smith标准形到广义逆的经典计算链,每一题都给出了中间矩阵和最终结果。适合正在备考的工科生,也适合工作中需要手推矩阵分解的从业者。它解决的核心问题是:当你面对一个具体的矩阵,如何一步步得到Jordan块、正交因子和最小范数解,而不是只停留在概念层面。
2. Jordan标准形:从Smith标准形到P矩阵的完整计算链
2.1 Smith标准形的操作顺序与不变因子
第一题的目标是把矩阵A化为Jordan标准形J,同时求出变换矩阵P。这里的核心入口并不是直接算特征向量,而是先对λI−A做Smith标准形。很多人在这一步容易把行变换和列变换混着用,结果得到一个形式上很乱、但没法读出不变因子的矩阵。
正确做法是:把λI−A作为多项式矩阵,反复使用初等行变换和初等列变换,目标是把它化为对角形式diag(d1(λ), d2(λ), d3(λ)),并且要求d1(λ) | d2(λ) | d3(λ),也就是整除链必须成立。参考答案中给出的约化过程,本质上是先把第一列和第二列里的常数项消掉,再把第一行和第二行里的多项式项消掉,最后得到一个对角阵。中间出现过的(−λ)(−λ²+5λ−5)这类乘积形式,是在做行变换时把公因子提取出来,但最终必须回到标准形式。
这个题里最终结果是diag(1, 1, (λ−2)³),所以不变因子就是{1, 1, (λ−2)³},初等因子只有{(λ−2)³}。这里有一个很容易困惑的点:为什么不变因子里有一个三次方,而不是三个(λ−2)?因为不变因子之间必须满足整除关系,1|1|(λ−2)³是合法的,而1|(λ−2)|(λ−2)²虽然也满足整除,但初等因子会变成三个一次因式,对应的Jordan块就完全不一样了。所以要养成一个习惯:写出不变因子后,先检查整除链,再拆初等因子。
import sympy as sp lam = sp.symbols('lam') A = sp.Matrix([[5, 5, -2], [-2, -1, -1], [-1, -1, 2]]) M = lam * sp.eye(3) - A # 如果sympy版本支持,可以直接调用Smith标准形 from sympy.matrices.normalforms import smith_normal_form S = smith_normal_form(M, domain=sp.QQ[lam]) print("Smith标准形:", S.tolist())这段代码的作用是自动完成多项式矩阵的Smith标准形计算。domain=sp.QQ[lam]意味着系数域是有理数多项式环,这样除法不会丢精度。如果你用的sympy版本没有smith_normal_form,可以手动做行变换和列变换,但最终结果应该一致。验证的标准是:对角元依次为1, 1, (λ−2)³,且满足整除关系。
从初等因子(λ−2)³可以直接读出Jordan块:一个3阶Jordan块,主对角线全为2,超对角线全为1。所以J = [[2,1,0],[0,2,1],[0,0,2]]。注意Jordan块里主对角线是特征值2,超对角线是1,不是次对角线。这一步如果写反,后面的P矩阵整体都会跟着错。
2.2 反推Jordan链:为什么先求P3而不是P1
得到J之后,下一步是求P。这里P按列分块为[P1, P2, P3],满足AP = PJ,等价于三个方程:
AP1 = 2P1 AP2 = P1 + 2P2 AP3 = P2 + 2P3
移项后得到广义特征向量链:
(A−2I)P1 = 0 (A−2I)P2 = P1 (A−2I)P3 = P2
这个方程组看起来是从P1开始解,但实际操作时必须反着来。从前往后解的典型困境是:先解(A−2I)P1 = 0得到一个特征向量,然后解(A−2I)P2 = P1,发现这个非齐次方程组可能无解——因为你随便选的特征向量不一定落在(A−2I)的值域里。正确顺序是先找P3,让P3满足(A−2I)²P3 = 0但(A−2I)P3 ≠ 0,然后令P2 = (A−2I)P3,P1 = (A−2I)P2。这样得到的P1一定是特征向量,而且链的长度正好是3。
参考答案里给出的P3 = [1,0,0]^T,P2 = [3,−2,−1]^T,P1 = [1,−1,−1]^T。你可以验证:P1同时满足(A−2I)P1 = 0,这意味着P1确实是特征值2对应的特征向量。三个向量线性无关,所以P可逆。
import numpy as np A = np.array([[5, 5, -2], [-2, -1, -1], [-1, -1, 2]], dtype=float) A2 = A - 2 * np.eye(3) P3 = np.array([1, 0, 0], dtype=float) P2 = A2 @ P3 P1 = A2 @ P2 print("P1 =", P1) print("P2 =", P2) print("P3 =", P3) P = np.column_stack([P1, P2, P3]) J = np.linalg.inv(P) @ A @ P print("Jordan形:\n", np.round(J, 6))这段代码验证了Jordan链的反推顺序。A2就是A−2I。P3先给定,然后逐级向前乘,得到P2和P1。最终np.linalg.inv(P) @ A @ P应该得到上三角Jordan形。注意这里P的列顺序是[P1, P2, P3],对应J的超对角线在右上方。如果列顺序变成[P3, P2, P1],得到的J会变成下三角形式的Jordan块,虽然相似,但不符合通常约定。
2.3 用sympy验证对角化结果
手算完成后,强烈建议用符号计算做一次交叉验证。因为浮点数计算会有舍入误差,Jordan形里的1可能显示成0.999999或1.000001。用sympy的Rational类型可以避免这个问题。
import sympy as sp A = sp.Matrix([[5, 5, -2], [-2, -1, -1], [-1, -1, 2]]) P = sp.Matrix([[1, 3, 1], [-1, -2, 0], [-1, -1, 0]]) J_sym = P.inv() * A * P print(J_sym)这里P的行是按[P1, P2, P3]作为列向量拼接的,也就是P的第一列是P1。输出应该是[[2,1,0],[0,2,1],[0,0,2]]。如果输出里出现分数或非零的额外元素,说明P的某一列不满足Jordan链方程,需要检查到底是P2还是P3错了。我通常的做法是再额外检查一下A@P vs P@J,两边逐列对比,这样定位错误更快。
3. QR分解与范数不等式:正交化细节与双重求和证明
3.1 Gram-Schmidt正交化中每个系数怎么算
第二题给的矩阵A是一个4×4的Vandermonde型矩阵,列向量依次为[1,1,1,1]^T、[1,2,4,8]^T、[1,3,9,27]^T、[1,4,16,64]^T。QR分解用修改的Gram-Schmidt过程完成。这里最容易错的是内积和模长的计算,尤其当β2带了分数因子后,后续投影系数会被放大。
整个过程的顺序是:先正交化得β1到β4,再单位化得γ1到γ4。β1 = α1 = [1,1,1,1]^T。β2 = α2 − (⟨α2,β1⟩/⟨β1,β1⟩)β1。其中⟨α2,β1⟩ = 1+2+4+8 = 15,⟨β1,β1⟩ = 4,所以投影系数是15/4,β2 = [−11/4, −7/4, 1/4, 17/4]^T。参考答案把它写成1/4[−11,−7,1,17]^T,这是关键习惯——先提取公因子再继续算,否则β3会变成带大分母的复杂分数。
β3的计算需要减去在β1和β2两个方向上的投影。这里要用到⟨β2,β2⟩,它是460/16=115/4,而⟨α3,β2⟩这里是关键:因为β2带1/4因子,所以内积是原内积的1/4。算完投影后得到β3 = 21/15[82,−21,−112,51]^T,参考答案里的写法是21/15,注意这个分数可以约成7/5,但保留21/15是为了后续R矩阵里和模长表达式对齐。实际做题时建议先约分,减少后续乘除的数值压力。
import numpy as np A = np.array([ [1, 1, 1, 1], [1, 2, 3, 4], [1, 4, 9, 16], [1, 8, 27, 64] ], dtype=float) Q, R = np.linalg.qr(A) print("Q:\n", Q) print("R:\n", np.round(R, 6))用numpy直接验证,Q的第一列应该是[0.5,0.5,0.5,0.5]^T,R的对角元素依次是2、√460/2、21/15·√22310、3/97·√194,非对角元素对应参考答案里的上三角矩阵。numpy的QR分解默认用Householder变换,符号约定和Gram-Schmidt略有不同,但R的上三角结构和模长数值应该一致。如果发现某一列的符号反了,不影响正交性,但对不齐参考答案时需要自己调整符号。
3.2 R矩阵的填法与分数约分
R矩阵在QR分解中扮演的角色是坐标变换的系数记录。具体来说,A = QR,而Q的列是单位正交向量γ1到γ4,所以R = Q^T A,R的(i,j)元素等于γi^T αj。这意味着R是一个上三角矩阵,对角线元素是γi与αi的内积,而γi是βi的单位化,所以R[i][i] = |βi|。非对角线元素R[i][j]是γi与αj的内积,这个值在Gram-Schmidt过程中已经出现过了。
参考答案里R矩阵的第一行是[2, 15/2, 8, 85/2],这些值是怎么来的?第一行是γ1与αj的内积,γ1 = [1/2,1/2,1/2,1/2]^T,所以R[0][0] = (1+1+1+1)/2 = 2,R[0][1] = (1+2+3+4)/2 = 5,不是15/2。这里需要特别注意:R矩阵和手工算的β系数之间不是直接相等,因为γ1和β1差一个模长因子2。R[0][1]应该是γ1^T α2 = 15/2,也就是5。参考答案里写的是15/2,所以是7.5,对应α2 = [1,2,4,8]^T的内积(1+2+4+8)=15除以2,正确。
填R矩阵时最常见的错误是把Gram-Schmidt里的投影系数直接填进去。投影系数是⟨αj,βi⟩/⟨βi,βi⟩,而R的非对角元是γi^T αj = ⟨βi,αj⟩/|βi|,两者差一个|βi|因子。所以必须回到定义,不要照抄中间量。一个实用的自查方法是:验证A的第一列等于Q第一列乘R[0][0],即α1 = γ1·2,这显然成立。
3.3 范数不等式的双重求和证明
第三题不是计算题,而是证明题:1/n·‖A‖₁ ≤ ‖A‖∞ ≤ n·‖A‖₁。这里‖A‖₁是列绝对值求和的最大值,‖A‖∞是行绝对值求和的最大值。很多同学只记住了定义,但不知道这两个范数之间的桥是全体元素绝对值之和∑|aij|。
证明核心分三步。第一步,‖A‖₁ ≤ ∑|aij| ≤ n·‖A‖∞。左边成立是因为列和的最大值不可能超过所有列的和;右边是因为每一行的绝对值和不大于n·‖A‖∞,所以全体元素之和不大于∑(行和) ≤ n²·‖A‖∞?这里要小心,实际上∑|aij| ≤ n·‖A‖∞是按行求和,每一行有n个元素,每个元素不超过‖A‖∞,所以∑|aij| ≤ n²‖A‖∞,这不是想要的界。正确的证法应该是:‖A‖₁ = max_j ∑|aij|,全体元素和∑|aij| = ∑_j(∑_i|aij|) ≤ n·max_j(∑_i|aij|) = n‖A‖₁,同时全体元素和也可以按行拆,∑|aij| = ∑_i(∑_j|aij|) ≤ n·max_i(∑_j|aij|) = n‖A‖∞。
所以实际上应该先建立两个方向的夹逼:‖A‖₁ ≤ ∑|aij| ≤ n‖A‖₁,以及‖A‖∞ ≤ ∑|aij| ≤ n‖A‖∞。然后结合这两个不等式,得到1/n·‖A‖₁ ≤ ‖A‖∞,以及‖A‖∞ ≤ n·‖A‖₁。因为它们的中间量都是∑|aij|,但上下界系数不同,需要通过这个公共的中间量来传递。
import numpy as np rng = np.random.default_rng(1) passed = True for _ in range(1000): A = rng.normal(size=(5, 5)) n = A.shape[0] n1 = np.linalg.norm(A, 1) ninf = np.linalg.norm(A, np.inf) if not ((1/n) * n1 <= ninf <= n * n1): passed = False break print("1000个随机矩阵全部通过:", passed)这段代码随机生成1000个5×5矩阵,逐个验证不等式。注意np.linalg.norm(A, 1)是列范数,np.linalg.norm(A, np.inf)是行范数,命名刚好和数学记号相反,容易记混。如果把参数写反,验证结果会直接失败。这也是一个值得记录的点:编程接口的命名习惯和教材不同,用之前先查文档。
4. 非齐次方程组与广义逆:两个必考计算模型
4.1 用矩阵指数求解微分方程组
第四题是非齐次线性微分方程组dx/dt = Ax + f(t),其中A是上三角Jordan块结构,特征值全为1。求解的关键是利用矩阵指数和积分因子。
做法是先把方程改写成d/dt[e^{−tA}x(t)] = e^{−tA}f(t),然后两边从0到t积分。左边积出来是e^{−tA}x(t) − x(0),右边是对向量函数逐分量积分。这个技巧在教材里叫积分因子法,本质上是把矩阵指数当成积分因子,把导数算子变成对e^{−tA}x(t)的普通导数。
其中最重要的一步是计算e^{tA}。因为A的特征值全为1,所以(A−I)³ = 0(Hamilton-Cayley定理),这说明e^{tA}的Taylor展开在二次项处截断:
e^{tA} = e^t · [I + t(A−I) + (t²/2)(A−I)²]
这是整道题的核心。如果特征值不是1,而是λ,就要把e^{tA}写成e^{λt}e^{t(A−λI)}再展开。参考答案里e^{tA}展开到二次项,得到上三角矩阵[[1, t, t+t²/2], [0, 1, t], [0, 0, 1]]乘以e^t。
import sympy as sp t = sp.symbols('t') A = sp.Matrix([[1, 1, 1], [0, 1, 1], [0, 0, 1]]) I3 = sp.eye(3) N = A - I3 print("(A-I)^2:", (N**2).tolist()) print("(A-I)^3:", (N**3).tolist()) etA = sp.exp(t) * (I3 + t * N + t**2 / 2 * N**2) print("e^(tA):", etA.tolist())输出里(A−I)²不是零矩阵,而(A−I)³是零矩阵,说明截断到二次项是正确的。如果特征值不是1,N的幂次不会消失,就不能这样截断。这是这个方法成立的前提。
积分那一步需要特别小心。参考答案里积分结果是[(1/2t² − t)e^t积分, −te^t积分, e^t积分]。注意这里积分的是e^{−tA}f(t),而f(t) = [0,0,e^{2t}]^T,所以被积函数的前两个分量都含e^t因子。积分下限是0,上限是t,所以常数项是代入t=0后的值的相反数。
4.2 Moore-Penrose广义逆的满秩分解法
第五题给出了一个4×4奇异矩阵A,要求Moore-Penrose广义逆G,并用G求线性方程组Ax=b的最小范数解。这里A的秩是3,所以不能直接求逆。参考答案用的方法是满秩分解:把A分解成B和C的乘积,其中B是4×3列满秩,C是3×4行满秩。
满秩分解的构造方式是:先对A做初等行变换,找出三个线性无关的行(在参考答案里是第1、2、3行?需要看分解情况。),然后B取这三个行对应的列组合,C取A中线性无关的行。具体到这道题,A = [[1,1,0,0],[0,1,1,0],[0,0,1,1],[1,0,0,1]],秩为3。初等行变换后可以看出第1、2、3列线性无关,第4列是前3列的线性组合,所以B取前三列,C是变换后的行阶梯矩阵的非零行。参考答案给出的分解是B = [[1,1,0],[0,1,1],[0,0,1],[1,0,0]](注意这里B是4×3,行是4行,列是3列),C = [[1,0,0,1],[0,1,0,−1],[0,0,1,1]]。
Moore-Penrose广义逆的满秩分解公式是:
G = C^T(C C^T)^{-1}(B^T B)^{-1}B^T
这个公式的结构有规律可循:C在左边,B在右边,中间夹着两个逆矩阵。C C^T是3×3矩阵,B^T B也是3×3矩阵,只要B列满秩、C行满秩,这两个矩阵就一定可逆。
import numpy as np A = np.array([ [1, 1, 0, 0], [0, 1, 1, 0], [0, 0, 1, 1], [1, 0, 0, 1] ], dtype=float) G = np.linalg.pinv(A) print("pinv结果:\n", G) B = np.array([[1, 1, 0], [0, 1, 1], [0, 0, 1], [1, 0, 0]], dtype=float) C = np.array([[1, 0, 0, 1], [0, 1, 0, -1], [0, 0, 1, 1]], dtype=float) G2 = C.T @ np.linalg.inv(C @ C.T) @ np.linalg.inv(B.T @ B) @ B.T print("满秩分解结果:\n", G2)用numpy的pinv直接算,再和满秩分解公式对比。两者结果应该完全一致,都是1/8乘以一个4×4矩阵。numpy的pinv基于SVD,数值上稳定,但不会告诉你结构。满秩分解的好处是能看清G的内部结构,以及后续判断解存在的条件。
4.3 解存在的条件与最小范数解的结构
Ax=b有解的充要条件是AGb=b,也就是(I−AG)b=0。注意这里不是检查G的某一行,而是检查b是否落在A的列空间里。参考答案计算得到I−AG是一个秩1矩阵,等于1/4乘以[1,−1,1,−1]^T[1,−1,1,−1]/4?准确说是(I−AG)b = 0等价于[1,−1,1,−1]b = 0,即a−b+c−d=0。
当条件满足时,通解是x = Gb + (I−GA)z,其中z是任意向量。这里(I−GA)是零空间投影矩阵,作用是把任意z投影到A的零空间。最小范数解(同时也是最小二乘解)是x₀ = Gb,它的范数在所有解里最小。
b = np.array([1, 2, 3, 2], dtype=float) cond = np.array([1, -1, 1, -1]) @ b print("解存在条件:", cond) # 0 x0 = G @ b print("最小范数解:", x0) print("残差:", A @ x0 - b)这里b=[1,2,3,2]满足1−2+3−2=0,所以方程组有解。残差接近0说明Gb确实是一个解。如果条件不满足,比如b=[1,0,0,0],则Ax=b无解,Gb只能给出最小二乘意义下的近似解。做题时第一步就要验条件,否则后面的通解表达式全是错的。
5. 避坑:符号、顺序、约分与截断的四个翻车点
5.1 现象:Jordan链解到一半无解
按照P1、P2、P3的顺序从前往后解,先求得一个特征向量P1,但代入(A−2I)P2 = P1后发现非齐次方程组无解。
原因:P1虽然满足(A−2I)P1=0,但它不一定落在A−2I的值域里。Jordan链的入口应该是链尾的P3,即满足(A−2I)²P3=0但(A−2I)P3≠0的向量。从这个向量出发,P2和P1都是被唯一确定的。
解决:无论题目给出的Jordan块是几阶,都从最高阶广义特征向量开始反推。如果Jordan块是k阶,就先求解(A−λI)ᵏx=0且(A−λI)^{k−1}x≠0,再逐级向前乘。
5.2 现象:QR分解中β2带着分数因子导致后续系数膨胀
Gram-Schmidt过程里β2算出来是1/4[−11,−7,1,17]^T,如果不在进入下一步之前约分,直接在β3的计算里用带1/4的β2做内积,那么⟨α3,β2⟩和⟨β2,β2⟩都会出现16倍的分母,后面的β3和β4会越来越难算。
原因:修改的Gram-Schmidt要求每步都对当前正交化向量做归一化或至少提取公因子。如果不约分,内积计算会携带多余的分母,最终R矩阵的数值也对不齐。
解决:每得到一个βi,先提取公因子写成最简形式,再进入下一步。尤其是在Vandermonde矩阵这类数值尺度差异大的矩阵上,这个习惯能显著降低手算出错率。
5.3 现象:矩阵指数展开少了一项
计算e^{tA}时只展开到一次项e^t[I + t(A−I)],得到的结果代入积分后,最终解的分量对不上参考答案里的2e^{2t}。
原因:虽然(A−I)³=0,但(A−I)²不是零矩阵,所以Taylor展开必须保留到二次项。少一项t²/2(A−I)²,矩阵指数上三角矩阵的右上角元素就会缺失t²/2部分,导致积分结果错误。
解决:先算出(A−I)²,确认它非零后再决定截断阶数。更稳妥的做法是计算(A−I)的幂次序列,从0次开始逐个检查,直到出现零矩阵为止。
5.4 现象:Moore-Penrose广义逆中乘法顺序颠倒
把公式误写为(B^T B)^{-1}B^T C^T(C C^T)^{-1},这样算出来矩阵维度都不匹配,或者结果根本不是G。
原因:满秩分解A=BC中,B在左、C在右,所以广义逆公式里左侧因子必须对应C的转置,右侧因子必须对应B的转置。公式G = C^T(C C^T)^{-1}(B^T B)^{-1}B^T的顺序不是随意定的,它来自对四个Penrose条件的验证。
解决:记忆口诀是"先C后B"。写出G之后,立刻验证AGA=A和GAG=G这两条,用数值矩阵乘一遍,如果不满足就说明顺序或逆矩阵的配对错了。
5.5 现象:解存在性条件符号搞反
判断Ax=b有解的条件时,把(I−AG)b=0等价地改写成了(GA−I)b=0,得到a+b+c+d=0之类的错误条件。
原因:A和G不一定可交换,AG和GA是完全不同的投影矩阵。AG是列空间投影,(I−AG)b=0才是b在列空间里的条件。换成GA就变成了零空间投影,含义完全不同。
解决:每次写出条件前,先明确AG是m×m还是n×n。这里的A是4×4,G也是4×4,AG作用在b上,所以条件是(I−AG)b=0,这个结论可以直接从AGA=A推导出来。
6. 拿结果前先做数值复核:一套五步自查习惯
完成手算后,我习惯用一整套数值交叉验证来兜底。第一步,验证Jordan分解:计算P^{-1}AP和J对比,允许的误差在1e−6以内。第二步,验证QR分解:检查Q^TQ是否接近单位矩阵,R是否严格上三角,A−QR的F范数是否接近0。第三步,验证范数不等式:随机生成100个矩阵,用numpy的范数函数跑一遍,确认不等式没有破界。第四步,验证微分方程解:把x(t)代入原方程,分别计算dx/dt和Ax+f(t),对比差值。第五步,验证广义逆:检查AGA=A、GAG=G、AG和GA的对称性,这四条是Moore-Penrose逆的充要条件,比看单个矩阵元素快得多。
import numpy as np # 以Jordan分解为例 A = np.array([[5, 5, -2], [-2, -1, -1], [-1, -1, 2]], dtype=float) P = np.array([[1, 3, 1], [-1, -2, 0], [-1, -1, 0]], dtype=float) J = np.linalg.inv(P) @ A @ P print("Jordan验证误差:", np.max(np.abs(J - np.array([[2,1,0],[0,2,1],[0,0,2]]))))这套流程的关键在于分步输出中间结果,不要只看最后一个结论。如果Jordan分解验证误差大,先打印P的每一列是否满足链方程;如果QR分解对不上,先检查Q的列是否单位正交,再检查R的对角元素。从那以后,我每次拿到类似的矩阵计算题,都强制走一遍"特征多项式→整除链→Jordan链→数值验证"的完整流程,哪怕参考答案已经写得很清楚,也会自己跑一遍数值核对。矩阵计算里符号和顺序的错误太隐蔽了,只有数值验证能兜住。希望帮到你。
本文还有配套的精品资源,点击获取