求解题目:
在这里插入图片描述

一、相关知识点

1. λ-矩阵(多项式矩阵)

定义:

λ-矩阵是指元素为λ的多项式的矩阵,形如:
A(λ)=[aij(λ)]m×n A(\lambda) = [a_{ij}(\lambda)]_{m×n}A(λ)=[aij(λ)]m×n
其中每个 aij(λ)a_{ij}(\lambda)aij(λ) 都是关于λλλ 的多项式。

含义:

  • 代数意义:可以看作是普通矩阵的推广,其中元素从数域扩展到了多项式环
  • 几何意义:在系统理论中,λ-矩阵常用于描述线性时不变架构的传递函数矩阵
  • 应用背景:在控制理论、振动分析、电路理论等领域有广泛应用

特点:

  • 可以进行类似普通矩阵的运算(加法、乘法)
  • 数就是但行列式的值是一个多项式,而不

2. Smith标准形

定义:

对于任意λ-矩阵A(λ)A(\lambda)A(λ),存在可逆的λ-矩阵P(λ)P(\lambda)P(λ)Q(λ)Q(\lambda)Q(λ),使得:
P(λ)A(λ)Q(λ)=diag(d1(λ),d2(λ),…,dr(λ),0,…,0) P(\lambda)A(\lambda)Q(\lambda) = \text{diag}(d_1(\lambda), d_2(\lambda), \dots, d_r(\lambda), 0, \dots, 0)P(λ)A(λ)Q(λ)=diag(d1(λ),d2(λ),,dr(λ),0,,0)
其中:

  • di(λ)d_i(\lambda)di(λ)是首一多项式(最高次项系数为1)
  • di(λ)∣di+1(λ)d_i(\lambda) \mid d_{i+1}(\lambda)di(λ)di+1(λ)(整除关系)
  • rrrA(λ)A(\lambda)A(λ) 的秩
补充:整除的定义
  • 对于多项式:设 f(λ)f(\lambda)f(λ)g(λ)g(\lambda)g(λ)是两个多项式,且g(λ)≠0g(\lambda) \neq 0g(λ)=0。假设存在另一个多项式h(λ)h(\lambda)h(λ) 使得:
    f(λ)=g(λ)⋅h(λ) f(\lambda) = g(\lambda) \cdot h(\lambda)f(λ)=g(λ)h(λ)
    则称 g(λ)g(\lambda)g(λ)整除f(λ)f(\lambda)f(λ) ,记作 g(λ)∣f(λ)g(\lambda) \mid f(\lambda)g(λ)f(λ)。否则,称g(λ)g(\lambda)g(λ) 不整除 f(λ)f(\lambda)f(λ)

在λ-矩阵的Smith标准形中,对角线上的非零元素称为不变因子,记作 d1(λ),d2(λ),…,dr(λ)d_1(\lambda), d_2(\lambda), \dots, d_r(\lambda)d1(λ),d2(λ),,dr(λ),它们必须满足整除关系:
d1(λ)∣d2(λ)∣⋯∣dr(λ) d_1(\lambda) \mid d_2(\lambda) \mid \dots \mid d_r(\lambda)d1(λ)d2(λ)dr(λ)
这意味着:
-d1(λ)d_1(\lambda)d1(λ)整除 d2(λ)d_2(\lambda)d2(λ)

  • d2(λ)d_2(\lambda)d2(λ) 整除 d3(λ)d_3(\lambda)d3(λ)
  • 依此类推,直到dr−1(λ)d_{r-1}(\lambda)dr1(λ) 整除 dr(λ)d_r(\lambda)dr(λ)

几何意义:

  • 标准化:将复杂的λ-矩阵转化为最方便的对角形式
  • 不变量:Smith标准形揭示了矩阵的本质特征,是矩阵在相似变换下的完全不变量
  • 结构分析:对角线元素反映了系统的模态结构和动态特性

重要性:

  • 唯一性:每个λ-矩阵有唯一的Smith标准形
  • 完全分类:两个λ-矩阵等价当且仅当它们有相同的Smith标准形

3. 初等变换

三种基本类型:

  1. 交换变换:交换两行(或两列)

    • 对应左乘(或右乘)置换矩阵
    • 不改变矩阵的代数结构
  2. 倍乘变换:某行(或列)乘以非零常数

    • 对应左乘(或右乘)对角矩阵
    • 保持多项式关系不变
  3. 消去变换:某行(或列)乘以多项式后加到另一行(或列)

    • 对应左乘(或右乘)单位矩阵的推广
    • 这是最核心的变换,用于化简矩阵

数学含义:

  • 等价关系:初等变换定义了λ-矩阵的等价关系
  • 可逆性可逆的就是:每个初等变换都
  • 不变量保持:初等变换不改变矩阵的行列式因子、不变因子等关键不变量

4. 不变因子与行列式因子

行列式因子:

k 阶行列式因子Dk(λ)D_k(\lambda)Dk(λ)是矩阵所有 k 阶子式的首一最大公因式。其中D0(λ)=1D_0(\lambda) = 1D0(λ)=1

不变因子:

从行列式因子可以计算出不变因子:
d1(λ)=D1(λ)D0(λ),d2(λ)=D2(λ)D1(λ),… d_1(\lambda) = \frac{D_1(\lambda)}{D_0(\lambda)},\quad d_2(\lambda) = \frac{D_2(\lambda)}{D_1(\lambda)},\quad \dotsd1(λ)=D0(λ)D1(λ),d2(λ)=D1(λ)D2(λ),
其中 D0(λ)=1D_0(\lambda) = 1D0(λ)=1

关系:

  • 不变因子就是Smith标准形对角线上的非零元素
  • 整除关系 di(λ)∣di+1(λ)d_i(\lambda) \mid d_{i+1}(\lambda)di(λ)di+1(λ)保证了标准形的唯一性

二、Smith 标准形的求解技巧

1. 用初等变换求λ-矩阵的 Smith 标准形

基本思路

通过对λ-矩阵进行初等行变换和初等列变换,逐步将矩阵化为对角形,并调整对角线元素使得后一个整除前一个,最终得到 Smith 标准形。

A(λ)A(\lambda)A(λ)用初等变换化为 Smith 标准形时,根据A(λ)A(\lambda)A(λ)的特点,共有 2 种情况:
(1)A(λ)A(\lambda)A(λ)的元素有公因子;
(2)A(λ)A(\lambda)A(λ)的元素无公因子。
对第(1)种情况,可以用初等变换将左上角元素变换成公因子,以便进一步化简;对第(2)种情况,若A(λ)A(\lambda)A(λ)的元素至少有一个非零常数,可利用非零常数进行化简;若无非零常数,可用初等变换先将某个元素化为非零常数,再利用非零常数化简。

核心步骤

第一步:进行初等变换

  • 允许三种初等行变换和三种初等列变换:
    • 交换变换:交换两行或两列。
    • 倍乘变换:用非零常数乘以某一行或某一列。
    • 倍加变换:将某一行(列)乘以一个多项式后加到另一行(列)上。
  • 目标是通过这些变换,将矩阵化为对角形,且对角线元素满足整除关系。

第二步:化左上角元素为最小

  • 通过行交换和列交换,将矩阵中次数最低的非零元素移动到左上角(1,1)位置。
  • 检查左上角元素是否能整除第一行和第一列的所有其他元素:
    • 倘若不能整除,则找到不能被整除的元素,采用多项式除法或行/列变换来减少左上角元素的次数或调整元素。
    • 具体操作:例如,如果第一列某个元素不能被左上角元素整除,则用该元素除以左上角元素得到余数,继而凭借行变换将余数移动到左上角位置,重复直到左上角元素能整除第一行和第一列的所有元素。

第三步:消去第一行和第一列的非对角元素

  • 利用左上角元素,消去第一行和第一列的其他所有元素(使其为零):
    • 对于第一行:将第一列乘以适当多项式后加到其他列,使第一行其他元素为零。
    • 对于第一列:将第一行乘以适当多项式后加到其他行,使第一列其他元素为零。
  • 此时,矩阵变为:
    [d1(λ)0⋯00⋮B(λ)0] \begin{bmatrix} d_1(\lambda) & 0 & \cdots & 0 \\ 0 & & & \\ \vdots & & B(\lambda) & \\ 0 & & & \\ \end{bmatrix}d1(λ)000B(λ)0
    其中 B(λ)B(\lambda)B(λ)是右下角的子矩阵。

第四步:递归处理子矩阵

  • 对子矩阵 B(λ)B(\lambda)B(λ)重复步骤二和三,直到整个矩阵化为对角形。
  • 在递归过程中,确保每次处理后的左上角元素能整除子矩阵中所有元素。

第五步:调整对角线元素以满足整除关系

  • 在对角形矩阵中,检查每个对角线元素是否能整除下一个对角线元素:
    • 如果不能,需要凭借行变换或列变换进行调整。例如,交换两行或两列,或者应用倍加变换来改变对角线元素。
  • 最终,通过倍乘变换(乘以非零常数)使每个对角线元素为首一多项式(即最高次项系数为1)。
  • 最终得到的矩阵就是 Smith 标准形:
    [d1(λ)00⋯00d2(λ)0⋯000d3(λ)⋯0⋮⋮⋮⋱⋮000⋯dr(λ)000⋯0] \begin{bmatrix} d_1(\lambda) & 0 & 0 & \cdots & 0 \\ 0 & d_2(\lambda) & 0 & \cdots & 0 \\ 0 & 0 & d_3(\lambda) & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & 0 & \cdots & d_r(\lambda) \\ 0 & 0 & 0 & \cdots & 0 \\ \end{bmatrix}d1(λ)00000d2(λ)00000d3(λ)00000dr(λ)0
    其中 ( r ) 是矩阵的秩,且d1(λ)∣d2(λ)∣⋯∣dr(λ)d_1(\lambda) \mid d_2(\lambda) \mid \cdots \mid d_r(\lambda)d1(λ)d2(λ)dr(λ)

2. 用行列式因子求λ-矩阵的 Smith 标准形

基本思路

通过计算矩阵的各阶行列式因子,继而推导出不变因子,从而直接得到 Smith 标准形。

核心步骤

第一步:计算各阶行列式因子

  • 计算矩阵 A(λ)A(\lambda)A(λ) 的所有 k 阶子式
  • 求这些 k 阶子式的首一最大公因式,即为 k 阶行列式因子Dk(λ)D_k(\lambda)Dk(λ)
  • 对 k = 1, 2, …, r (其中 r 是A(λ)A(\lambda)A(λ)的秩) 重复此过程,并规定D0(λ)=1D_0(\lambda) = 1D0(λ)=1
    • 一阶行列式因子D₁(λ):所有一阶子式(即单个元素)的首一最大公因式
    • 二阶行列式因子D₂(λ):所有二阶子式(2×2子矩阵行列式)的首一最大公因式
    • 三阶行列式因子D₃(λ):所有三阶子式(3x3子矩阵行列式)的首一最大公因式
    • 以此类推

第二步:求不变因子

  • 通过相邻阶数的行列式因子相除,得到不变因子dk(λ)d_k(\lambda)dk(λ)
    dk(λ)=Dk(λ)Dk−1(λ),k=1,2,...,r d_k(\lambda) = \frac{D_k(\lambda)}{D_{k-1}(\lambda)}, \quad k = 1, 2, ..., rdk(λ)=Dk1(λ)Dk(λ),k=1,2,...,r
  • 这些不变因子d1(λ),d2(λ),...,dr(λ)d_1(\lambda), d_2(\lambda), ..., d_r(\lambda)d1(λ),d2(λ),...,dr(λ)就是 Smith 标准形中主对角线上的非零元素,且满足后一个整除前一个的性质。
    • -d₁(λ) = D₁(λ)
    • d₂(λ) = D₂(λ) / D₁(λ)
    • d₃(λ) = D₃(λ) / D₂(λ)

第三步:写出 Smith 标准形
将不变因子按顺序排列在对角线上:
[d1(λ)000d2(λ)000d3(λ)] \begin{bmatrix} d_1(\lambda) & 0 & 0 \\ 0 & d_2(\lambda) & 0 \\ 0 & 0 & d_3(\lambda) \end{bmatrix}d1(λ)000d2(λ)000d3(λ)


三、例题具体求解方法

在这里插入图片描述

1. 解法一:初等变换法

(1)具体解题步骤

通过一系列初等行变换和列变换,将A(λ)A(\lambda)A(λ)化为 Smith 标准形。详细步骤如下:

  1. 行变换R2←R2+R1R_2 \leftarrow R_2 + R_1R2R2+R1
    目的:简化第二行。
    变换后矩阵:
    [1−λλ2λ1λ2+λ01+λ2λ2−λ2] \begin{bmatrix} 1-\lambda & \lambda^2 & \lambda \\ 1 & \lambda^2 + \lambda & 0 \\ 1+\lambda^2 & \lambda^2 & -\lambda^2 \end{bmatrix}1λ11+λ2λ2λ2+λλ2λ0λ2

  2. 行交换:交换 R1R_1R1R2R_2R2
    目的:使左上角元素为 1。
    变换后矩阵:
    [1λ2+λ01−λλ2λ1+λ2λ2−λ2] \begin{bmatrix} 1 & \lambda^2 + \lambda & 0 \\ 1-\lambda & \lambda^2 & \lambda \\ 1+\lambda^2 & \lambda^2 & -\lambda^2 \end{bmatrix}11λ1+λ2λ2+λλ2λ20λλ2

  3. 行变换R2←R2−(1−λ)R1R_2 \leftarrow R_2 - (1-\lambda) R_1R2R2(1λ)R1R3←R3−(1+λ2)R1R_3 \leftarrow R_3 - (1+\lambda^2) R_1R3R3(1+λ2)R1
    目的:消除第一列的其他元素。
    变换后矩阵:
    [1λ2+λ00λ3+λ2−λλ0−λ4−λ3−λ−λ2] \begin{bmatrix} 1 & \lambda^2 + \lambda & 0 \\ 0 & \lambda^3 + \lambda^2 - \lambda & \lambda \\ 0 & -\lambda^4 - \lambda^3 - \lambda & -\lambda^2 \end{bmatrix}100λ2+λλ3+λ2λλ4λ3λ0λλ2

  4. 列变换C2←C2−(λ2+λ)C1C_2 \leftarrow C_2 - (\lambda^2 + \lambda) C_1C2C2(λ2+λ)C1
    目的:消除第一行第二列元素。
    变换后矩阵:
    [1000λ3+λ2−λλ0−λ4−λ3−λ−λ2] \begin{bmatrix} 1 & 0 & 0 \\ 0 & \lambda^3 + \lambda^2 - \lambda & \lambda \\ 0 & -\lambda^4 - \lambda^3 - \lambda & -\lambda^2 \end{bmatrix}1000λ3+λ2λλ4λ3λ0λλ2

  5. 列变换C1←C1−(λ2+λ−1)C2C_1 \leftarrow C_1 - (\lambda^2 + \lambda - 1) C_2C1C1(λ2+λ1)C2(在右下角 2×2 子矩阵中操作)
    目的:简化右下角子矩阵。
    变换后矩阵:
    [10000λ0−λ(1+λ)0] \begin{bmatrix} 1 & 0 & 0 \\ 0 & 0 & \lambda \\ 0 & -\lambda(1+\lambda) & 0 \end{bmatrix}10000λ(1+λ)0λ0

  6. 列交换:交换 C2C_2C2C3C_3C3
    目的:使子矩阵左上角非零。
    变换后矩阵:
    [1000λ000−λ(1+λ)] \begin{bmatrix} 1 & 0 & 0 \\ 0 & \lambda & 0 \\ 0 & 0 & -\lambda(1+\lambda) \end{bmatrix}1000λ000λ(1+λ)

  7. 行变换R3←−R3R_3 \leftarrow -R_3R3R3
    目的:使第三行第三列元素为首一多项式。
    变换后矩阵:
    [1000λ000λ(1+λ)] \begin{bmatrix} 1 & 0 & 0 \\ 0 & \lambda & 0 \\ 0 & 0 & \lambda(1+\lambda) \end{bmatrix}1000λ000λ(1+λ)

最终 Smith 标准形为:
S(λ)=[1000λ000λ(1+λ)] S(\lambda) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \lambda & 0 \\ 0 & 0 & \lambda(1+\lambda) \end{bmatrix}S(λ)=1000λ000λ(1+λ)
其中 d1(λ)=1d_1(\lambda) = 1d1(λ)=1, d2(λ)=λd_2(\lambda) = \lambdad2(λ)=λ, d3(λ)=λ(1+λ)d_3(\lambda) = \lambda(1+\lambda)d3(λ)=λ(1+λ),满足 d1∣d2d_1 \mid d_2d1d2d2∣d3d_2 \mid d_3d2d3

(2)手写解题过程

在这里插入图片描述

2. 解法二:行列式因子法

(1)具体解题步骤

通过计算行列式因子和不变因子得到 Smith 标准形。详细步骤如下:

1. 计算矩阵的秩
计算行列式:
det⁡(A(λ))=det⁡[1−λλ2λλλ−λ1+λ2λ2−λ2]=−λ2(λ+1) \det(A(\lambda)) = \det \begin{bmatrix} 1-\lambda & \lambda^2 & \lambda \\ \lambda & \lambda & -\lambda \\ 1+\lambda^2 & \lambda^2 & -\lambda^2 \end{bmatrix} = -\lambda^2(\lambda + 1)det(A(λ))=det1λλ1+λ2λ2λλ2λλλ2=λ2(λ+1)
行列式非零,因此秩 (r = 3).

2. 计算行列式因子

(1) 计算D0(λ)D_0(\lambda)D0(λ)
D0(λ)=1D_0(\lambda) = 1D0(λ)=1(定义)

(2) 计算一阶行列式因子D1(λ)D_1(\lambda)D1(λ)
D1(λ)D_1(\lambda)D1(λ)是所有一阶子式(即矩阵元素)的首一最大公因式
元素有:1−λ,λ2,λ,λ,λ,−λ,1+λ2,λ2,−λ21-\lambda, \lambda^2, \lambda, \lambda, \lambda, -\lambda, 1+\lambda^2, \lambda^2, -\lambda^21λ,λ2,λ,λ,λ,λ,1+λ2,λ2,λ2
这些多项式的最大公因式为 1,故 (D1(λ)=1D_1(\lambda) = 1D1(λ)=1

(3) 计算二阶行列式因子D2(λ)D_2(\lambda)D2(λ)
D2(λ)D_2(\lambda)D2(λ)是所有二阶子式的首一最大公因式
计算所有二阶子式的行列式(略去零子式):

  • 行 1-2:λ−λ2−λ3\lambda - \lambda^2 - \lambda^3λλ2λ3 , −λ-\lambdaλ , −λ3−λ2-\lambda^3 - \lambda^2λ3λ2
  • 行 1-3:−λ3−λ4-\lambda^3 - \lambda^4λ3λ4, −λ2−λ-\lambda^2 - \lambdaλ2λ, −λ4−λ3-\lambda^4 - \lambda^3λ4λ3
  • 行 2-3:−λ-\lambdaλ, λ\lambdaλ

这些行列式都含有因子λ\lambdaλ,且括号内多项式的最大公因式为 1,故D2(λ)=λD_2(\lambda) = \lambdaD2(λ)=λ

(4) 计算三阶行列式因子D3(λ)D_3(\lambda)D3(λ)
D3(λ)D_3(\lambda)D3(λ)是矩阵的行列式
计算 detA(λ)A(\lambda)A(λ):
det⁡[1−λλ2λλλ−λ1+λ2λ2−λ2]=−λ3−λ2=−λ2(λ+1) \det \begin{bmatrix} 1-\lambda & \lambda^2 & \lambda \\ \lambda & \lambda & -\lambda \\ 1+\lambda^2 & \lambda^2 & -\lambda^2 \end{bmatrix} = -\lambda^3 - \lambda^2 = -\lambda^2(\lambda+1)det1λλ1+λ2λ2λλ2λλλ2=λ3λ2=λ2(λ+1)
取首一形式,故D3(λ)=λ2(λ+1)D_3(\lambda) = \lambda^2(\lambda+1)D3(λ)=λ2(λ+1)

3. 计算不变因子
d1(λ)=D1(λ)D0(λ)=11=1,d2(λ)=D2(λ)D1(λ)=λ1=λ,d3(λ)=D3(λ)D2(λ)=λ2(λ+1)λ=λ(λ+1). \begin{aligned} d_1(\lambda) &= \frac{D_1(\lambda)}{D_0(\lambda)} = \frac{1}{1} = 1, \\ d_2(\lambda) &= \frac{D_2(\lambda)}{D_1(\lambda)} = \frac{\lambda}{1} = \lambda, \\ d_3(\lambda) &= \frac{D_3(\lambda)}{D_2(\lambda)} = \frac{\lambda^2(\lambda+1)}{\lambda} = \lambda(\lambda+1). \end{aligned}d1(λ)d2(λ)d3(λ)=D0(λ)D1(λ)=11=1,=D1(λ)D2(λ)=1λ=λ,=D2(λ)D3(λ)=λλ2(λ+1)=λ(λ+1).

4. Smith 标准形
不变因子为 1,λ,λ(λ+1)1, \lambda, \lambda(\lambda+1)1,λ,λ(λ+1) ,满足1∣λ∣λ(λ+1)1 \mid \lambda \mid \lambda(\lambda+1)1λλ(λ+1)。因此矩阵 A(λ)A(\lambda)A(λ)的Smith 标准形为:
[1000λ000λ(λ+1)] \begin{bmatrix} 1 & 0 & 0 \\ 0 & \lambda & 0 \\ 0 & 0 & \lambda(\lambda+1) \end{bmatrix}1000λ000λ(λ+1)

(2)代码解题过程

import sympy as sp
def compute_smith_normal_form(A):
"""
使用行列式因子法计算λ-矩阵的Smith标准形
参数:
A: sympy矩阵,包含符号变量λ的矩阵
返回:
smith_form: Smith标准形矩阵
A: 原始矩阵
"""
# 定义符号变量λ
lamda = sp.symbols('λ')
print("原始λ-矩阵 A(λ):")
# 美观打印矩阵
sp.pprint(A)
print()
# 获取矩阵维度
n, m = A.shape
print(f"矩阵维度: {n}×{m}")
print()
# 计算各阶行列式因子
determinants = []
# 计算1阶行列式因子 D1(λ)————1阶子式就是矩阵元素本身
print("1. 计算1阶行列式因子 D₁(λ):")
minors_1 = []
for i in range(n):
for j in range(m):
minors_1.append(A[i, j])
# 找到所有1阶子式的最大公因式
gcd_1 = minors_1[0]
for minor in minors_1[1:]:
# sp.gcd: 计算多项式的最大公因式
# domain='ZZ': 在整数域上进行计算
gcd_1 = sp.gcd(gcd_1, minor, domain='ZZ')
print(f"   所有1阶子式: {minors_1}")
print(f"   最大公因式 D₁(λ) = {gcd_1}")
print()
determinants.append(gcd_1)
# 计算高阶行列式因子
for k in range(2, min(n, m) + 1):
print(f"{k}. 计算{k}阶行列式因子 D_{k}(λ):")
minors_k = []
# 生成所有k阶子矩阵的组合
# 导入组合生成器,用于生成所有可能的行、列组合
from itertools import combinations
# 选择k行和k列的所有组合
# combinations(range(n), k):
# range(n): 生成 [0, 1, 2, ..., n-1]
# combinations(序列, k): 从序列中取k个元素的所有组合
# e.g.如果 n=3, k=2
# list(combinations([0,1,2], 2)) = [(0,1), (0,2), (1,2)]
row_combinations = list(combinations(range(n), k))
col_combinations = list(combinations(range(m), k))
for rows in row_combinations:
for cols in col_combinations:
# extract(rows, cols): 从原矩阵提取指定行列的子矩阵
# det(): 计算行列式
submatrix = A.extract(rows, cols)  # 提取子矩阵
det = submatrix.det()  # 计算行列式
minors_k.append(det)
if k <= 3:  # 只显示前3阶的详细计算过程,避免输出过多
print(f"   子矩阵 {[i + 1 for i in rows]}×{[j + 1 for j in cols]} 的行列式: {det}")
# 找到所有k阶子式的最大公因式
if minors_k:
gcd_k = minors_k[0]
for minor in minors_k[1:]:
# sp.gcd(a, b): 计算a和b的最大公因式
# domain='ZZ': 指定在整数域上进行计算(多项式系数为整数)
gcd_k = sp.gcd(gcd_k, minor, domain='ZZ')
else:
gcd_k = 0
if k > 3:  # 对于高阶,只显示部分结果
print(f"   共 {len(minors_k)}{k}阶子式")
print(f"   最大公因式 D_{k}(λ) = {gcd_k}")
print()
determinants.append(gcd_k)
# 计算不变因子
print(f"{min(n, m) + 1}. 计算不变因子:")
def make_monic(poly, var):
"""
将多项式化为首一多项式
首一多项式:最高次项系数为1的多项式
poly: 多项式表达式
var: 符号变量(如 λ)
"""
if poly == 0:
return 0
# 提取系数
# sp.Poly(poly, var).all_coeffs():
# sp.Poly(): 将表达式转换为多项式对象
# all_coeffs(): 返回所有系数列表,按降幂排列
coeffs = sp.Poly(poly, var).all_coeffs()
if coeffs:
# 首项系数
leading_coeff = coeffs[0]
# 化为首一
monic_poly = poly / leading_coeff
# sp.simplify(monic_poly): 化简表达式
return sp.simplify(monic_poly)
return poly
# 计算不变因子 d_i(λ) = D_i(λ) / D_{i-1}(λ)
invariant_factors = []
for i in range(len(determinants)):
# 第一个不变因子: d₁(λ) = D₁(λ) (直接取1阶行列式因子)
if i == 0:
d_i = make_monic(determinants[i], lamda)
else:
# if determinants[i - 1] != 0:: 检查前一个行列式因子是否为零
# 如果为零,则当前不变因子设为0
# 如果不为零,进行多项式除法
if determinants[i - 1] != 0:
# 使用多项式除法
# sp.Poly(表达式, 变量): 创建多项式对象
# sp.div(被除数, 除数, domain='ZZ'): 多项式除法
# 返回商(quotient)和余数(remainder)
# domain='ZZ': 在整数域上进行计算
poly_current = sp.Poly(determinants[i], lamda)  # 当前行列式因子 D_i(λ)
poly_prev = sp.Poly(determinants[i - 1], lamda)  # 前一个行列式因子 D_{i-1}(λ)
quotient, remainder = sp.div(poly_current, poly_prev, domain='ZZ')
d_i = make_monic(quotient.as_expr(), lamda)
else:
d_i = 0
invariant_factors.append(d_i)
if i == 0:
print(f"   d₁(λ) = D₁(λ) = {d_i}")
else:
print(f"   d_{i + 1}(λ) = D_{i + 1}(λ)/D_{i}(λ) = {d_i}")
print()
# 验证不变因子的整除关系
print(f"{min(n, m) + 2}. 验证不变因子的整除关系:")
for i in range(1, len(invariant_factors)):
if invariant_factors[i - 1] != 0 and invariant_factors[i] != 0:
poly_prev = sp.Poly(invariant_factors[i - 1], lamda)
poly_current = sp.Poly(invariant_factors[i], lamda)
quotient, remainder = sp.div(poly_current, poly_prev, domain='ZZ')
if remainder == 0:
print(f"   ✓ d_{i}(λ) 整除 d_{i + 1}(λ)")
else:
print(f"   ✗ d_{i}(λ) 不整除 d_{i + 1}(λ)")
print()
# Smith标准形
print(f"{min(n, m) + 3}. Smith标准形:")
# 构建Smith标准形矩阵
smith_diag = []
for i in range(min(n, m)):
smith_diag.append(invariant_factors[i])
# 如果矩阵不是方阵,用0填充
if n > m:
smith_diag.extend([0] * (n - m))
elif m > n:
smith_diag.extend([0] * (m - n))
smith_form = sp.diag(*smith_diag)
print("Smith标准形为:")
sp.pprint(smith_form)
return smith_form, A
def main():
"""主函数 - 在这里自定义矩阵A"""
# 定义符号变量λ
lamda = sp.symbols('λ')
# 在这里自定义λ-矩阵
A = sp.Matrix([
[1 - lamda, lamda ** 2, lamda],
[lamda, lamda, -lamda],
[1 + lamda ** 2, lamda ** 2, -lamda ** 2]
])
print("使用行列式因子法计算λ-矩阵的Smith标准形")
print("=" * 60)
try:
smith_form, original_matrix = compute_smith_normal_form(A)
print("\n最终结果:")
print("λ-矩阵:")
sp.pprint(original_matrix)
print("\nSmith标准形:")
sp.pprint(smith_form)
except Exception as e:
print(f"计算过程中出现错误: {e}")
if __name__ == "__main__":
main()