有基本追求求解器的python实现吗?

时间:2019-06-03 09:58:27

标签: python optimization minimization

最初,我想使用YALL1 package来使L1最小化,但是它是用matlab编写的。经过一番研究,我在Python中找不到basis pursuit求解器,但是那里有吗?另外,我可以使用哪些现有库来解决此最小化问题?

这是原始问题(BP +):

Imgur

2 个答案:

答案 0 :(得分:2)

我认为您可以使用二次圆锥编程(quick reference)进行基础追踪。

在python中,您可以使用cvxopt to solve quadratic cone programs

编辑:甚至是one of their examples

答案 1 :(得分:1)

如关于基础追踪 (BP) 的原始论文 Atomic Decomposition by Basis Pursuit 所述,BP 可以等效地重新表述为线性规划 (LP) 问题,并且 LP 开发了非常有效的求解器。

this se.math site 中有一个讨论和一个公式,用于给定 BP 问题的 LP 问题的标准形式。回想一下,在 BP 中,您正在寻找形状为 x(x_dim, ),使得 A@x=yx 对 L1 范数而言是最小的。因此,您只需要一个脚本,它采用形状为 A 的数组 (y_dim, x_dim)、形状为 y(y_dim, ) 并返回标准形式。

这是采用 BP 问题并使用 LP 的标准形式返回最优 x 的函数(我以这种方式编写它以使其适合 that tutorial 中使用的术语)。该脚本使用 scipy.optimize.linprog 作为 LP 的后端。

import numpy as np
from scipy.optimize import linprog

def get_optimal_x_for_bp(A, y):
    x_dim, y_dim = A.shape[1], y.shape[0]
    eye = np.eye(x_dim)

    obj = np.concatenate([np.zeros(x_dim), np.ones(x_dim)])

    lhs_ineq = np.concatenate([np.concatenate([eye, -eye], axis=1), np.concatenate([-eye, -eye], axis=1)], axis=0)
    rhs_ineq = np.zeros(2 * x_dim)

    lhs_eq = np.concatenate([A, np.zeros((y_dim, x_dim))], axis=1)
    rhs_eq = y

    bnd = [*((None, None) for _ in range(x_dim)), *((0, None) for _ in range(x_dim))]

    res = linprog(c=obj, A_ub=lhs_ineq, b_ub=rhs_ineq, A_eq=lhs_eq, b_eq=rhs_eq, bounds=bnd, method="revised simplex")
    return res.x[:x_dim]

您可以在示例 2x_1-x_2=2 上检查它是否正常工作:

if __name__ == '__main__':
    A = np.array([[2, -1]])
    y = np.array([2])

    x = get_optimal_x_for_bp(A, y)
    print(x)
Output: [1. 0.]

输出表明 x_1=1, x_2=0 是最优的 x。从下图可以看出这是真的: enter image description here

您还可以将其应用于一些更复杂的问题:

if __name__ == '__main__':
    x_dim, y_dim = 6, 4

    A = np.random.rand(y_dim, x_dim)
    y = np.random.rand(y_dim)

    x = get_optimal_x_for_bp(A, y)
    print(x)
Output: [ 0.          1.55953519  0.50597071  0.          0.1724968  -1.86814744]

请记住,正如在关于 BP 的原始论文中所写的那样,系统 A@x=y 应该是过完备的。