CVXR中DCP规则的问题

2024-05-21 04:35:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用CVXR建模包来解决一个凸优化问题。我确信问题是凸的,并且它遵循DCP规则,但是如果我使用CVXR检查DCP规则,它将返回False。但是,如果我处理完全相同的问题并使用CVXPY检查它,它将返回True(如预期的那样)

这里发生了什么?我附上一个在R和Python中这种行为的最小可复制示例:

使用CVXR

library(splines2)
library(CVXR)
deriv_basis = splines2::dbs(seq(0, 1, length.out=100), degree=3, intercept=T, df=30, derivs=2)
R = t(deriv_basis) %*% deriv_basis
beta_var = CVXR::::Variable(nrow(R))
q = CVXR::quad_form(beta_var, R)
CVXR::is_dcp(q)

[1] FALSE

write.table(x=R, file='R.csv'), row.names=F, sep=';')

使用CVXPY

import cvxpy
import pandas as pd

R = pd.read_csv('R.csv', sep=';').values
beta_var = cvxpy.Variable(R.shape[1])
q = cvxpy.quad_form(beta_var, R)
q.is_dcp()

Out[1]: True

有人能解释一下这里发生了什么,以及如何解决它,以便我可以使用CVXR吗


Tags: csvtrue规则varlibrarybasisvariablebeta
2条回答

cvxpy应该给出与G.Grothendieck所暗示的CVXR相同的结果,因为DCP规则是相同的。最近版本的cvxpy似乎出现了一些问题。我在cvxpy github上开了一期

问题是R矩阵中的负特征值。如果您通过将其设置为零来解决这个问题,那么它满足dcp条件。我还修复了问题代码中的语法错误,并删除了多余的::。另一种可能性(未显示)是在pracma包中使用nearest_spd来调整R矩阵

library(splines2)
library(CVXR)

deriv_basis <- dbs(seq(0, 1, length.out=100), degree = 3, 
  intercept = TRUE, df = 30, derivs = 2)
R <- t(deriv_basis) %*% deriv_basis
e <- eigen(R)

# check decomposition
all.equal(R, e$vectors %*% diag(e$values) %*% t(e$vectors), 
 check.attributes = FALSE)
## [1] TRUE

e$values  # note negative value
##  [1]  1.095213e+08  1.095213e+08  1.056490e+07  1.055430e+07  1.052481e+07
##  [6]  1.046063e+07  1.034247e+07  1.015017e+07  9.866358e+06  9.485145e+06
## [11]  8.643220e+06  8.280963e+06  7.549803e+06  6.731472e+06  5.853402e+06
## [16]  4.949804e+06  4.056714e+06  3.209045e+06  2.437320e+06  1.759963e+06
## [21]  1.214976e+06  7.785251e+05  4.590441e+05  2.428199e+05  1.107300e+05
## [26]  4.060476e+04  1.040537e+04  1.320942e+03  7.239578e-09 -5.019224e-09

# zap negative eigenvalues making them zero
R <- with(e, vectors %*% diag(pmax(values, 0)) %*% t(vectors))

beta_var <- Variable(nrow(R))
q <- quad_form(beta_var, R)
is_dcp(q)
## [1] TRUE

相关问题 更多 >