Проблемы с правилами DCP в CVXR

#python #r #cvxpy #cvx #cvxr

Вопрос:

Я использую CVXR пакет моделирования для решения задачи выпуклой оптимизации. Я точно знаю, что проблема выпуклая и что она следует правилам DCP, но если я проверю правила DCP, используя CVXR их, она вернется False . Однако, если я возьму точно такую же проблему и проверю ее с помощью CVXPY , она вернется True (как и ожидалось)

Что здесь происходит? Я прилагаю минимальный воспроизводимый пример такого поведения в R и Python:

Код R с использованием 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=';')
 

Код на Python с использованием 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?

Ответ №1:

Проблема заключается в отрицательном собственном значении в матрице R. Если вы исправите это, установив его, скажем, на ноль, то это удовлетворит условию dcp. Я также исправил синтаксические ошибки в коде в вопросе и удалил избыточное :: . Еще одна возможность (не показана) — использовать nearest_spd в пакете pracma для настройки матрицы 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
 

Комментарии:

1. Спасибо вам за ответ! И знаете ли вы, почему существует разница в правилах DCP между R и python?

2. Нельзя предположить, что правила DCP ведут себя по-другому. Вполне возможно, что программное обеспечение Python создает матрицу PSD R. Проверьте собственные значения на стороне Python, как мы сделали в ответе на стороне R.

Ответ №2:

cvxpy должно дать те же результаты, CVXR что и подразумевается Г. Гротендиком, поскольку правила DCP одинаковы. Кажется, что-то сломалось в последних версиях cvxpy . Я открыл проблему на cvxpy github.