CVXPY: DCPError: Проблема не соответствует правилам DCP

Я пытаюсь написать код, который решает B(2,1) проблему с ограничениями LMI.

R(2,1)=R0(2,1)+H(2,2)*B(2,1)

Vc - скалярная переменная

Это продолжает становиться

> "DCPError: Проблема не соответствует правилам DCP."

    import numpy as np
    import cvxpy as cp

    H = np.random.rand(2,2)
    R0 = np.random.rand(2,1)

    B=cp.Variable((2,1), complex=True)  
    Rf=cp.diag(R0+H*B)




    RRf=cp.real(Rf)
    IRf=cp.imag(Rf)


    Vc=cp.Variable()
    Vc2= (Vc**2)


    z=np.zeros((Rf.shape[0],Rf.shape[1]))
    I=np.eye(Rf.shape[0])
    objective3=cp.Minimize(Vc2)

    LMI =cp.bmat( [   
                            [Vc2*I,        RRf,    z,        -IRf],
                            [RRf,          I,      IRf,          z],
                            [z,            IRf,    Vc2*I,        RRf],
                            [-IRf,         z,       RRf,          I]      
                                                                                ]) 
    const1 = LMI  >=0
    const2 = Vc   >=0        

    prob=cp.Problem(objective3,[const1,const2])
    print(prob.is_dcp())   




  [1]: https://i.stack.imgur.com/IQpxh.png

person Maged Eltorkoman    schedule 24.04.2020    source источник
comment
При условии, что целевая функция имеет значение DCP = True и ----- LMI-блок имеет значение DCP = True ----- const1 Хотя DCP = False ?!   -  person Maged Eltorkoman    schedule 27.04.2020
comment
У вас есть квадрат переменной, появляющейся внутри матрицы. Это несовместимо с DCP.   -  person Michal Adamaszek    schedule 28.04.2020
comment
Спасибо за ответ! @MichalAdamaszek, я заменил переменную Vc вместо ее квадрата в блоке LMI, и он вернул действительную проблему DCP ... к сожалению, появилась следующая ошибка: Anaconda3 \ lib \ site-packages \ cvxpy \ reductions \ complex2real \ complex2real.py, строка 146, в canonicalize_expr assert all (v is None for v in imag_args) AssertionError   -  person Maged Eltorkoman    schedule 28.04.2020
comment
Насколько я знаю, чтобы получить LMI, вы должны писать LMI>>0, а не LMI>=0. Теперь вы просто сказали, что все записи неотрицательны, что может объяснить ошибку (мнимые части не равны нулю).   -  person Michal Adamaszek    schedule 28.04.2020
comment
@MichalAdamaszek Я пробовал LMI>>0, но он выдает то же AssertionError. Может быть, потому, что я использую сложную переменную? ‹Br/› Я действительно застрял в этой проблеме уже несколько недель. Я инженер-механик, а не программист, но этот код мне очень поможет в работе.   -  person Maged Eltorkoman    schedule 28.04.2020
comment
Я запустил ваш код сейчас, и вы правы, что что-то не так. Возможно, это ошибка в операторах real / imag для сложных переменных, о которых следует сообщить cvxpy. Во всяком случае, у меня это сработало, когда я определил реальную и мнимую части по отдельности: BR=cp.Variable((2,1)) BI=cp.Variable((2,1)) RRf=cp.diag(R0+H@BR) IRf=cp.diag(H@BI)   -  person Michal Adamaszek    schedule 28.04.2020
comment
@MichalAdamaszek Вы абсолютно правы, код работает так, а математика - нет !! Но ваше предложение было большим подспорьем в правильном направлении ... СПАСИБО !!!   -  person Maged Eltorkoman    schedule 29.04.2020
comment
Вы были правы с самого начала. Это должно быть LMI>>0, а не LMI >=0, но когда вы указываете это >>, стандартный решатель SCS не обрабатывает размер матрицы. Итак, я загрузил решатель CVXOPT, и до сих пор он работал нормально. Я надеюсь, что ошибок больше не будет, и я смогу завершить все это.   -  person Maged Eltorkoman    schedule 29.04.2020


Ответы (1)


С помощью @MichalAdamaszek следующий код работает.
Проблема заключалась в том, что CVXPY не может обрабатывать функции .real и .imag внутри ограничений.
Таким образом, необходимо было разбить сложную переменную B на две реальные переменные, а затем объединить их после .solve usingB=BR.value+1j*BI.value
Другая ошибка в вопросе заключалась в установке ограничения как LMI>=0. Для SDP следует использовать LMI>>0. Последнее, что нужно было использовать решатель CVXOPT вместо стандартногоSCS, поскольку он не может обрабатывать матрицы более 2x2. Код оказывается математически правильным, поскольку он всегда минимизирует остаточную функцию.

R(2,1)=R0(2,1)+H(2,2)*B(2,1)

print ('Остаток', abs (R0 + np.matmul (H, B))) каждый раз приближается к 0.
Правильный код:

import numpy as np
import cvxpy as cp

H = np.random.rand(2,2)
R0 = np.random.rand(2,1)

BR=cp.Variable((2,1))
BI=cp.Variable((2,1))  




RRf=cp.diag((np.real(R0)+np.real(H)@BR-np.imag(H)@BI))
IRf=cp.diag((np.imag(R0)+np.imag(H)@BR+np.real(H)@BI))

Vc2=cp.Variable()


z=np.zeros((RRf.shape[0],RRf.shape[1]))
I=np.eye(RRf.shape[0])
objective3=cp.Minimize(Vc2)


LMI =cp.bmat( [   
                        [Vc2*I,        RRf,    z,        -IRf],
                        [RRf,          I,      IRf,          z],
                        [z,            IRf,    Vc2*I,        RRf],
                        [-IRf,         z,       RRf,          I]      
                                                                            ]) 
const1 = LMI  >>0



prob=cp.Problem(objective3,[const1])
prob.solve(solver=cp.CVXOPT, kktsolver=cp.ROBUST_KKTSOLVER)
B=BR.value+1j*BI.value

print(abs(B),Vc2.value)
print('The residule',abs(R0+np.matmul(H,B)))
person Maged Eltorkoman    schedule 29.04.2020
comment
kktsolver=cp.ROBUST_KKTSOLVER важен, если вы хотите быть более надежным без ошибок. Однако это более медленный вариант. - person Maged Eltorkoman; 01.05.2020