# lsqminnorm
线性方程的最小范数最小二乘解
函数库: TyMath
# 语法
X = lsqminnorm(A, B)
X = lsqminnorm(A, B, tol)
X = lsqminnorm(___; rankWarn="nowarn")
# 说明
X = lsqminnorm(A, B) 返回可以求解线性方程 AX = B 并使 norm(A*X-B) 的值最小化的数组 X。如果此问题有多个解,则 lsqminnorm 返回能使 norm(X) 最小化的解。如果 B 有多列,则前面的语句分别适用于 X 和 B 的每列。示例
X = lsqminnorm(A, B, tol) 还指定 lsqminnorm 用来确定 A 的秩的容差。示例
X = lsqminnorm(___;rankWarn="nowarn") 指定一个可选标志,如果 A 的秩较低,则显示警告。您可以使用上述语法中的任何输入参量组合。rankWarn 可以为 "nowarn"(默认值)或 "warn"。示例
# 示例
求解具有无限个解的线性方程组
使用反斜杠 \ 和 lsqminnorm 求解具有无限多个解的线性方程组。使用解的 2-范数比较结果。
当 Ax=b 有无限多个解时,每个解都会使 ||Ax−b|| 最小化。反斜杠命令 \ 也可以计算出一个这样的解,但此解通常不会使 ||x|| 最小化。lsqminnorm 计算出的解不仅会使 norm(A*x-b) 最小,还会使 norm(x) 最小。
假设有一个简单的线性方程组
using TyMath
A = [2 3]
b = 8
x_a = A .\ b
x_b = lsqminnorm(A,b)
2×1 Matrix{Float64}:
1.2307692307692304
1.8461538461538454
指定容差以减少含噪数据的影响
说明如何在 lsqminnorm 中指定用于计算秩的容差,才能有助于定义问题的范围,以使随机噪声不会破坏解。
创建秩为 5 的低秩矩阵和右侧向量 b。
using TyMath
using TyPlot
rng = MT19937ar(5489)
U = randn(rng, 200, 5)
V = randn(rng, 100, 5)
A = U * V'
b = U * randn(rng, 5, 1) + 1e-4 * randn(rng, 200, 1);
使用 lsqminnorm 求解线性方程组 Ax=b。计算 A*x-b 和 x 的范数,以检查解的质量。
x = lsqminnorm(A,b);
norm(A*x-b)
ans = 0.0014269732022207675
norm(x)
ans = 0.1740825019653325
现在,在矩阵 A 中添加少量噪声,然后再次求解线性方程组。噪声对线性方程组的解向量 x 的影响不成比例。
Anoise = A + 1e-12 * randn(rng, 200, 100)
xnoise = lsqminnorm(Anoise, b)
norm(Anoise*xnoise - b)
ans = 0.0010311860337026686
在 CentOS 结果会不一致。
norm(xnoise)
ans = 1.1146068885378948e8
在 CentOS 结果会不一致。
解之间的巨大差异是因为噪声影响 A 的低秩逼近。换句话说,lsqminnorm 认为在 A 的 QR 分解中,位于 R 矩阵对角线上的小值很重要,而实际上这些值并没有那么重要。理想情况下,R 对角线上的这些小值应视为零。
绘制 Anoise 的 QR 分解中 R 矩阵的对角线元素。有大量对角线元素位于阶次 1e-10 处。
Q,R = qr(Anoise);
Q = Q[:,1:100]
semilogy(abs.(diag(R)),"o")
此问题的解决方案是增大 lsqminnorm 使用的容差,以便在计算中使用误差小于 1e-8 的 Anoise 低秩逼近。这样将使噪声对结果的影响大大减小。使用容差的解非常接近原来的解 x。
xnoise = lsqminnorm(Anoise, b, 1e-8);
norm(Anoise*xnoise - b)
ans = 0.0014269732021304816
norm(xnoise)
ans = 0.17408250196533148
norm(x - xnoise)
ans = 1.0832310678715417e-14
不同芯片得到的结果可能存在差异。
切换显示低秩矩阵警告
在打开警告的情况下求解涉及低秩系数矩阵的线性方程组。
创建一个秩为 2 的 3×3 矩阵。在此矩阵中,可以通过将前两列相加得出第三列。
using TyMath
A = [1 2 3; 4 5 9; 6 7 13]
A = 3×3 Matrix{Int64}:
1 2 3
4 5 9
6 7 13
求问题 Ax=b 的最小范数最小二乘解,其中 b 等于 A 中的第二列。为 lsqminnorm 指定 "warn" 标志,以便在检测到 A 为低秩时显示警告。
b = A[:,2]
x = lsqminnorm(A,b,rankWarn = "warn")
┌ Warning: Warning: Rank deficient, rank = 2, tol = nothing.
└ @ TyMathCore D:\数学库GitLab\TyMathCore.jl\src\Linear Algebra\Linear Equations\ty_LinearEquations.jl:200
x = 3-element Vector{Float64}:
-0.33333333333333326
0.6666666666666666
0.33333333333333354
# 输入参数
A - 系数矩阵矩阵
系数矩阵。系数矩阵显示在线性方程组的左侧,如 Ax = B。系数矩阵可以是满矩阵或稀疏矩阵。
数据类型: Int | Float
复数支持: 是
B - 输入数组向量 | 矩阵
输入数组,指定为向量或矩阵。B 显示在线性方程组的右侧,如 Ax = B。如果 B 是矩阵,则矩阵中的每一列代表右侧一个不同的向量。
数据类型: Int | Float
复数支持: 是
tol - 秩容差非负标量
秩容差,指定为非负标量。指定容差有助于减少系数矩阵中随机噪声对解的干扰。默认情况下,lsqminnorm 基于 A 的 QR 分解来计算 tol。
lsqminnorm 将 A 的秩计算为 QR 分解 [Q,R,p] = qr(A,0) 的 R 矩阵中的对角线元素数,绝对值大于 tol。如果 A 的秩是 k,则函数通过将 Q 的前 k 列乘以 R 的前 k 行来形成 A 的低秩逼近。更改容差会影响 A 的低秩逼近。
示例: X = lsqminnorm(A,B,1e-2)
数据类型: Int | Float
# 关键字参数
rankWarn - 切换显示低秩矩阵警告"nowarn" (默认) | "warn"
切换显示低秩矩阵警告,指定为 'nowarn' 或 'warn'。指定 'warn' 将指示 lsqminnorm 在系数矩阵 A 秩亏时生成警告。
示例: X = lsqminnorm(A,B,"warn")
# 输出参数
X - 解向量 | 矩阵
解,以向量或矩阵形式返回。 x 与 B 的大小相同。
数据类型: Float
# 提示
当有多个解时,lsqminnorm 计算的最小范数解具有特别的意义。只要 A 欠定(行数少于列数)或低秩,方程 Ax = b 就有多个解;
在计算线性方程组的最小范数最小二乘解时,lsqminnorm(A,B,tol) 的效率通常高于 pinv(A,tol)*B。lsqminnorm 使用完全正交分解 (COD) 来计算 A 的低秩逼近,而 pinv 使用的是奇异值分解 (SVD)。因此,pinv 和 lsqminnorm 的结果不完全一致。