超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

一、简介

本文前半部分算法实现参考的为姚健康老师的论文,这篇论文在万方学术平台可以免费下载:http://d.g.wanfangdata.com.cn/Periodical_jxkx200701002.aspx

后半部分算法涉及到稀疏优化,我在之前的博客中介绍了实现原理并给出了代码,链接如下:稀疏优化L1范数最小化问题求解之基追踪准则(Basis Pursuit)——原理及其Python实现

2. 问题的重述

给定一个超定线性方程组超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

其中超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,找到超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,这样

超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

即求超定线性方程组超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现范数意义下的解,简称超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现范数极小化问题1。

定义:设超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现为问题超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现的解,称超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现为问题超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现的最小超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现模残差向量。如果能够得到最小的超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现-模残差向量超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,则一致线性方程组超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现的解就是问题超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现的解。

2.求最小模残差向量的性质和方法

依据文献2中的说明,我们得到如下定理:

定理:设有 2 个超定线性方程组超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,若存在可逆阵超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,使超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,则这 2 个超定线性方程组的极小超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现模剩余向量相同。

超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现阶可逆矩阵),则方程超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现可转化为公式超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

假设方程组超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现的最小超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现模残差向量为超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,则由上式超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现和方程组超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现具有相同的最小超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现模残差向量,所以超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现也是式超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现的最小超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现模残差向量,记为超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,所以

超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

如果我们订购

超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

那么最小超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现模残差向量超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现满足以下线性方程:

超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

具体转换过程可以参考姚老师的论文。因此,需要最小的超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现模残差向量超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,即需要满足公式超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,使得超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现最小。

3.一种基于基追踪准则的求解算法

从方程式。 超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,原超定线性方程组超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现的最小超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现模残差向量可以通过以下约束不可微优化问题得到:

超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

表示问题超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现的最优解超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,方程组超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现是原方程的一致线性方程组,其解超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现是问题超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现的解:

超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

在问题超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现中,如果我们定义超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

那么问题超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现变成如下问题:

超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

对于极小超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现模剩余向量超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,考虑到我们的求解应当尽可能逼近精确解,即极小超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现模剩余向量超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现中的元素应当尽可能为0。这样问题超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现的形式又回到了超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现范数最小化问题中的稀疏优化问题。

参考我的这篇博客求解上述稀疏优化问题:稀疏优化L1范数最小化问题求解之基追踪准则(Basis Pursuit)——原理及其Python实现

四、超定线性方程组极小超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现范数求解Python代码

采用 Python 中scipy模块内置的linprog函数求解线性方程组,编写代码如下:

import numpy as np 
from scipy import optimize as op

def OLE_linprog(A, b):
    '''
    Ax = b (Given A & b, try to derive x)
    
    Parameters
    ----------
    A : matrix like.
    b : array like.

    Returns
    -------
    x : array
        Minimal L1 norm solution of the system of equations.
        
    Reference
    ---------
    YAO Jian-kang. An Algorithm for Minimizing l1-Norm to Overdetermined Linear Eguations[J]. 
    JIANGXI SCE7NICE, 2007, 25(1): 1-4.(Available at: 
    http://d.g.wanfangdata.com.cn/Periodical_jxkx200701002.aspx)
        
    Version: 1.0 writen by z.q.feng @2022.03.13
    '''
    A, b = np.array(A), np.array(b)
    if np.size(A, 0) < np.size(A, 1):
        raise ValueError('Matrix A rows must greater than columns!')
    m, n = A.shape
    # Trans A into two matrix(n x n and (m - n) x n)
    A1, A2 = A[:n, :], A[n:, :]
    if np.linalg.matrix_rank(A) >= n:
        # inverse of A1 
        A1_ = np.linalg.inv(A1)
    else:
        # Generalized inverse of A1 
        A1_ = np.linalg.pinv(A1)
    # c_ij = A2 * A1_
    c = np.dot(A2, A1_)
    # r(n+1:m) = A2*inv(A1)*r(1:n) + d
    d = np.dot(c, b[:n]) - b[n:]
    # Basic-Pursuit, target function = sum(u, v)
    t = np.ones([2 * m, 1])
    # Aeq_ = [c I(m-n)]
    Aeq_ = np.hstack([-c, np.eye(m - n, m - n)])
    # Aeq[u v] = Aeq_ * (u - v)
    Aeq = np.hstack([Aeq_, -Aeq_])
    # u, v > 0
    bounds = [(0, None) for i in range(2 * m)]
    # r0 = [u; v]
    r0 = op.linprog(t, A_eq = Aeq, b_eq = d, bounds = bounds,
                    method='revised simplex')['x']
    # Minimal L1-norm residual vector, r = u - v
    r = np.array([r0[:m] - r0[m:]])
    # Solving compatible linear equations Ax = b + r
    # Generalized inverse solution
    x = np.linalg.pinv(A).dot(b + r.T)
    return x

采用 MATLAB 求解的由于篇幅问题我就不放了,私信我。

五、检验检测

1. 矩阵A满秩情况

对于线性方程超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,通过生成给定的超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,并制作超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,我们可以认为超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现是问题超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现的最优解。然后我们用上面的函数求解得到它的经验解超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,用超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现定义它的恢复残差,用plot来确定解的精度。

if __name__ == '__main__':
    m, n = 256, 128
    # 256x128矩阵,每个元素服从Gauss随机分布
    A = np.random.randn(m, n)
    # 128x1矩阵,每个元素服从Gauss随机分布
    # b = A * u, 则 Au - b = 0,u 即为我们要求的精确解
    u = np.random.randn(n, 1)
    b = np.dot(A, u)
    alpha = OLE_linprog(A, b)
    # 恢复残差 
    print('\n恢复残差:', np.linalg.norm(alpha - u, 2))
    # 绘图
    plt.figure(figsize = (8, 6))
    # 绘制原信号
    plt.plot(u, 'r', linewidth = 2, label = 'Original')
    # 绘制恢复信号
    plt.plot(alpha, 'b--', linewidth = 2, label = 'Recovery')
    plt.grid() 
    plt.legend()
    plt.show()

得到恢复残差为6.0407e-14,恢复信号图如图所示(信号随机生成,每次结果均不一样)。

超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

2. 矩阵A列缺秩情况

根据式超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现可以看出,若矩阵超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现行不满秩,即超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现,我们的方法是不需要做对应改变的,而若矩阵超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现列缺秩,则需要使用矩阵超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现的Moore-Penrose逆矩阵超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现替代超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现在式超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现中构造超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

下面我们通过代码让矩阵超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现列秩亏缺1:

A(:, n) = zeros(m, 1);

运行代码,得到恢复残差为0.2551,恢复信号图如图所示(信号随机生成,每次结果均不一样)。可以看到,虽然误差增大了,但是还在允许范围内。

超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现

6.总结

目前解决问题超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现的方法很多,主要有:

  • 线性规划方法;
  • 投影下降法;
  • 有效的设置方法;
  • 区间法等

上述方法各有优缺点。比如线性规划法增加尺度,投影下降算法太复杂难以被工程技术人员掌握,有效集法比其他方法更直观,算法简单,区间法太复杂,并且没有最优解区间。检查难度更大。本文利用最小的超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现模残差向量将问题超定线性方程组Ax=b极小L1范数求解——MATLAB/Python实现转化为有约束的不可微优化问题,进而求解出一致的线性方程组。该算法具有不扩大规模、简单易操作的优点。

姚健康. 超定线性方程组极小 ℓ1 范数解的一个算法[J/OL]. 江西科学, 2007
(1): 1-3.http://d.g.wanfangdata.com.cn/Periodical_jxkx200701002.aspx.↩︎王嘉松,权日光。不相容线性方程组极小极大解的一种新算法[J]。1996: 04.↩︎

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2022年4月7日
下一篇 2022年4月7日

相关推荐