稀疏约束线性最小二乘求解器

时间:2010-06-10 03:17:40

标签: c++ math linear-algebra linear-programming sparse-matrix

This great SO answer指向Ax=b的稀疏解算器,但我对x有约束,x中的每个元素都是>=0 <=N

此外,A 巨大(约2e6x2e6),但每行<=4元素非常稀疏。

任何想法/建议?我正在寻找类似于MATLAB的lsqlin但有大量稀疏矩阵的东西。

我实际上是在尝试解决稀疏矩阵上的大规模bounded variable least squares problem

alt text

修改CVX

cvx_begin
    variable x(n)
    minimize( norm(A*x-b) );
    subject to 
        x <= N;
        x >= 0;
cvx_end

6 个答案:

答案 0 :(得分:3)

您的问题类似于非负最小二乘问题(NNLS),可以表述为

$$ \ min_x || Ax-b || _2 ^ 2 \ text {subject to} x \ ge 0 $$,

似乎存在许多算法。

实际上,如果除了原始的非负变量$ x $之外,你可以或多或少地将问题转换为NNLS问题,你可以创建额外的变量$ x'$并用线性约束链接它们$ x_i + x_i'= N $。这种方法的问题在于,在最小二乘解决方案中可能无法完全满足这些额外的线性约束 - 然后尝试用大数量加权它们可能是合适的。

答案 1 :(得分:3)

您正在尝试使用框约束来解决最小二乘法。标准稀疏最小二乘算法包括LSQR,最近还包括LSMR。这些只需要您应用矩阵矢量产品。要添加约束,请注意如果您位于框的内部(没有任何约束是“活动”),那么您将继续使用您选择的任何内部点方法。对于所有活动约束,您执行的下一次迭代将停用约束,或约束您沿约束超平面移动。通过对您选择的算法进行一些(概念上相对简单的)适当修改,您可以实现这些约束。

但是,一般情况下,您可以使用任何凸优化包。我亲自使用Matlab软件包CVX解决了这个确切类型的问题,它使用SDPT3 / SeDuMi作为后端。 CVX只是围绕这些半定程序求解器的非常方便的包装器。

答案 2 :(得分:1)

你的矩阵A ^ T A是正半正定的,所以你的问题是凸的;在设置求解器时一定要充分利用它。

大多数首选的QP求解器都是Fortran和/或非自由的;但是我听说过OOQP(http://www.mcs.anl.gov/research/projects/otc/Tools/OOQP/OoqpRequestForm.html)的好东西,虽然获得副本有点痛苦。

答案 3 :(得分:1)

如果你有Matlab,这可以用TFOCS来做。这是您将用于解决问题的语法:

x = tfocs( smooth_quad, { A, -b }, proj_box( 0, N ) );

如果A太大而无法放入内存,则可以将A作为函数句柄传递。

答案 4 :(得分:1)

如果您将模型重新表述为:

min
受制于:

那么它是一个标准的二次规划问题。这是一种常见的模型,可以通过CPLEX或Gurobi等商业解算器轻松解决。 (免责声明:我目前在Gurobi Optimization工作,之前曾在提供CPLEX的ILOG工作过。)

答案 5 :(得分:0)

CVXOPT怎么样?它适用于稀疏矩阵,似乎有些锥形编程求解器可能会有所帮助:

http://abel.ee.ucla.edu/cvxopt/userguide/coneprog.html#quadratic-cone-programs

这是对上述文档中代码的简单修改,以解决您的问题:

from cvxopt import matrix, solvers
A = matrix([ [ .3, -.4,  -.2,  -.4,  1.3 ],
             [ .6, 1.2, -1.7,   .3,  -.3 ],
             [-.3,  .0,   .6, -1.2, -2.0 ] ])
b = matrix([ 1.5, .0, -1.2, -.7, .0])
N = 2;
m, n = A.size
I = matrix(0.0, (n,n))
I[::n+1] = 1.0
G = matrix([-I, I])
h = matrix(n*[0.0]  + n*[N])
print G
print h
dims = {'l': n, 'q': [n+1], 's': []}
x = solvers.coneqp(A.T*A, -A.T*b, G, h)['x']#, dims)['x']
print x

CVXOPT支持稀疏矩阵,因此对您有用。

相关问题