【问题标题】:CVXPY: DCPError: Problem does not follow DCP rulesCVXPY:DCPError:问题不遵循 DCP 规则
【发布时间】:2020-04-24 20:06:56
【问题描述】:

我正在尝试编写一个在 LMI 约束下解决 B(2,1) 的问题。

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

【问题讨论】:

  • 假设目标函数是 DCP =True 并且 ----- LMI 块是 DCP=True ----- const1 DCP is = False 虽然?!
  • 矩阵中出现了变量的平方。这不符合 DCP。
  • 感谢您的回复! @MichalAdamaszek,我在LMI块中替换了变量Vc而不是它的正方形,它返回了一个有效的DCP问题..不幸的是,出现了以下错误:Anaconda3\lib\site-packages\cvxpy\reductions\complex2real\ complex2real.py",第 146 行,在 canonicalize_expr 中断言所有(对于 imag_args 中的 v 而言,v 是 None)AssertionError
  • 据我所知,要获得 LMI,您应该写 LMI>>0 而不是 LMI>=0。您现在所做的只是说所有条目都是非负数,这可以解释错误(虚部非零)。
  • @MichalAdamaszek 我试过LMI>>0,但它给出了相同的AssertionError。可能是因为我使用的是复杂变量吗?
    到现在为止,我真的被这个问题困扰了好几个星期。我是机械工程师而不是程序员,但这段代码对工作很有帮助。

标签: python optimization cvxpy convex-optimization


【解决方案1】:

在 @MichalAdamaszek 的帮助下,下一个代码可以正常工作。
问题是 CVXPY 无法在约束内处理 .real 和 .imag 函数。
因此,所需的操作是将复杂变量 B 分解为两个实变量,然后在 .solve 之后将它们组合使用B=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('The residule',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)))

【讨论】:

  • kktsolver=cp.ROBUST_KKTSOLVER 如果您想要更健壮且没有错误,这很重要。虽然这是一个较慢的选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多