CVXPY 二次规划; ArpackNoConvergence 错误
CVXPY Quadratic Programming; ArpackNoConvergence error
我正在尝试使用 Python 包 CVXPY 在这里解决第一种形式的凸二次规划问题:https://www.cvxpy.org/examples/basic/quadratic_program.html,使用以下代码
x = np.variable(2 * N)
prob = cp.Problem(cp.Minimize((1/2) * cp.quad_form(x, P) + q @ x), [G @ x <= h, A @ x == b])
prob.solve(solver=cp.OSQP, verbose=True)
但是,对于某些数据,它给了我错误
ArpackNoConvergence: ARPACK error -1: No convergence (1001 iterations, 0/1 eigenvectors converged)
网上查了一下,好像可以通过增加ARPACK的迭代次数,或者增加容忍度来解决。 CVXPY 有针对 max_iters 和绝对精度的选项,但这些似乎不会影响 ARPACK 中的迭代次数,我假设它们适用于求解器的某些更高级别的部分。
我在网上找不到任何关于这个特定问题的参考资料,或者实际上是关于 ARPACK 与 CVXPY 的参考资料。我对此感到很困惑,非常感谢任何帮助。
没有运行这个(代码明显不完整),有两个候选:
- A: OSQP
- B:cvxpy 中的内部 PSD 检查(在将数据提交给求解器之前!)
我猜它是 B(您可能会切换到其他求解器来推理它)。
您设置的迭代参数与求解器有关,如果我猜对了,您甚至还没有达到这一点(规范化阶段出错)。
看来,您的矩阵在迭代特征值计算 (ARPACK) 方面引起了麻烦。也许这可以从它的条件号看出。
不确定,如果您的用例有一个简单的转换/扰动来改善这里的条件。
如果不从源代码重建 cvxpy,很多内部结构是不容易访问的,但在这种情况下 你可以通过更改 cvxpy.settings.settings.EIGVAL_TOL:
import cvxpy as cp
print(cp.settings.EIGVAL_TOL)
# 1e-10
cp.settings.EIGVAL_TOL = 1e-08
... do your work
(如果您的数据由于某些错误而没有完全损坏并且不保密,我认为 cvxpy-people 会很乐意以您的数据为例重新评估一些内部公差 -> github 可重现代码问题,包括数据)
这是因为ARPACK由于数值问题可能无法收敛到PSD矩阵,并且失败随机发生。查看
中的讨论
如果知道P是PSD,PSD校验失败,那么可以把P换成
P = cvxpy.atoms.affine.wraps.psd_wrap(P).
跳过 PSD 检查。
我正在尝试使用 Python 包 CVXPY 在这里解决第一种形式的凸二次规划问题:https://www.cvxpy.org/examples/basic/quadratic_program.html,使用以下代码
x = np.variable(2 * N)
prob = cp.Problem(cp.Minimize((1/2) * cp.quad_form(x, P) + q @ x), [G @ x <= h, A @ x == b])
prob.solve(solver=cp.OSQP, verbose=True)
但是,对于某些数据,它给了我错误
ArpackNoConvergence: ARPACK error -1: No convergence (1001 iterations, 0/1 eigenvectors converged)
网上查了一下,好像可以通过增加ARPACK的迭代次数,或者增加容忍度来解决。 CVXPY 有针对 max_iters 和绝对精度的选项,但这些似乎不会影响 ARPACK 中的迭代次数,我假设它们适用于求解器的某些更高级别的部分。
我在网上找不到任何关于这个特定问题的参考资料,或者实际上是关于 ARPACK 与 CVXPY 的参考资料。我对此感到很困惑,非常感谢任何帮助。
没有运行这个(代码明显不完整),有两个候选:
- A: OSQP
- B:cvxpy 中的内部 PSD 检查(在将数据提交给求解器之前!)
我猜它是 B(您可能会切换到其他求解器来推理它)。
您设置的迭代参数与求解器有关,如果我猜对了,您甚至还没有达到这一点(规范化阶段出错)。
看来,您的矩阵在迭代特征值计算 (ARPACK) 方面引起了麻烦。也许这可以从它的条件号看出。
不确定,如果您的用例有一个简单的转换/扰动来改善这里的条件。
如果不从源代码重建 cvxpy,很多内部结构是不容易访问的,但在这种情况下 你可以通过更改 cvxpy.settings.settings.EIGVAL_TOL:
import cvxpy as cp
print(cp.settings.EIGVAL_TOL)
# 1e-10
cp.settings.EIGVAL_TOL = 1e-08
... do your work
(如果您的数据由于某些错误而没有完全损坏并且不保密,我认为 cvxpy-people 会很乐意以您的数据为例重新评估一些内部公差 -> github 可重现代码问题,包括数据)
这是因为ARPACK由于数值问题可能无法收敛到PSD矩阵,并且失败随机发生。查看
中的讨论如果知道P是PSD,PSD校验失败,那么可以把P换成
P = cvxpy.atoms.affine.wraps.psd_wrap(P).
跳过 PSD 检查。