我正在使用CVXR建模软件包来解决一个凸优化问题。我确信这个问题是凸的,并且它遵循DCP规则,但是如果我使用CVXR检查DCP规则,它将返回False。但是,如果我处理完全相同的问题并使用CVXPY检查它,它将返回True (如预期的那样)。
这里发生了什么事?我在R和Python中附加了一个这种行为的最小可复制示例:
使用CVXR的r码
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的Python代码
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了吗?
发布于 2021-06-07 15:25:04
问题是R矩阵中的负特征值。如果通过将它设置为零来修正,那么它满足dcp条件。我还修正了问题中代码中的语法错误,并删除了冗余的::。另一种可能(未显示)是使用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发布于 2021-07-28 21:49:15
cvxpy应该给出与G. Grothendieck所暗示的CVXR相同的结果,因为DCP规则是相同的。cvxpy的最新版本似乎出现了一些问题。我在cvxpy github上打开了一个问题。
https://stackoverflow.com/questions/67874107
复制相似问题