Установка ограничения на частичное транспонирование переменной матрицы в CVXPY - PullRequest
1 голос
/ 24 февраля 2020

Я вычисляю проблему SDP в Python, используя CVXPY, и я хочу установить ограничение, что не только моя переменная матрица является положительно-полуопределенной (psd), но и ее частичная транспонирование по определенной оси - psd. Я не знаю, как установить это требование. Мой код будет выглядеть следующим образом

#Set the variable matrix
P_0 = cp.Variable((d,d), symmetric=True)

Теперь я хотел бы определить что-то вроде

def PT(d1, d2, rho):
    """Return rho^{T_1}, the partial trace of the density operator rho on C^{d_1} \ot C^{d_2} along the first system."""
    assert rho.shape == (d1 * d2, d1 * d2)

    # reshape into a 4-tensor (2 ket indices and 2 bra indices)
    rho = rho.reshape(d1, d2, d1, d2)

    # transpose the first subsystem
    rho = rho.transpose((0,3,2,1))

    # reshape back into a density operator
    return rho.reshape(d1 * d2, d1 * d2)

И затем установить требование, что PT(3,3, P_0) >> 0, то есть, что это PSD. Но это не разрешено в cvxpy. Также я мог бы определить новую матрицу для моего конкретного c случая, например

P_0_tp = [[P_0[[0,0]], P_0[[1, 0]], P_0[[2, 0]], P_0[[0, 3]], P_0[[1, 3]], P_0[[2, 3]], 
  P_0[[0, 6]], P_0[[1, 6]], P_0[[2, 6]]], [P_0[[0, 1]], P_0[[1, 1]], P_0[[2, 1]], 
  P_0[[0, 4]], P_0[[1, 4]], P_0[[2, 4]], P_0[[0, 7]], P_0[[1, 7]], 
  P_0[[2, 7]]], [P_0[[0, 2]], P_0[[1, 2]], P_0[[2, 2]], P_0[[0, 5]], P_0[[1, 5]], 
  P_0[[2, 5]], P_0[[0, 8]], P_0[[1, 8]], P_0[[2, 8]]], [P_0[[3, 0]], P_0[[4, 0]], 
  P_0[[5, 0]], P_0[[3, 3]], P_0[[4, 3]], P_0[[5, 3]], P_0[[3, 6]], P_0[[4, 6]], 
  P_0[[5, 6]]], [P_0[[3, 1]], P_0[[4, 1]], P_0[[5, 1]], P_0[[3, 4]], P_0[[4, 4]], 
  P_0[[5, 4]], P_0[[3, 7]], P_0[[4, 7]], P_0[[5, 7]]], [P_0[[3, 2]], P_0[[4, 2]], 
  P_0[[5, 2]], P_0[[3, 5]], P_0[[4, 5]], P_0[[5, 5]], P_0[[3, 8]], P_0[[4, 8]], 
  P_0[[5, 8]]], [P_0[[6, 0]], P_0[[7, 0]], P_0[[8, 0]], P_0[[6, 3]], P_0[[7, 3]], 
  P_0[[8, 3]], P_0[[6, 6]], P_0[[7, 6]], P_0[[8, 6]]], [P_0[[6, 1]], P_0[[7, 1]], 
  P_0[[8, 1]], P_0[[6, 4]], P_0[[7, 4]], P_0[[8, 4]], P_0[[6, 7]], P_0[[7, 7]], 
  P_0[[8, 7]]], [P_0[[6, 2]], P_0[[7, 2]], P_0[[8, 2]], P_0[[6, 5]], P_0[[7, 5]], 
  P_0[[8, 5]], P_0[[6, 8]], P_0[[7, 8]], P_0[[8, 8]]]]

, которая является матрицей 9x9, которая теперь частично транспонирована во втором третьем измерении. Но как я могу установить это как переменную в cvxpy?

Заранее спасибо,

1 Ответ

1 голос
/ 27 февраля 2020

У меня была та же проблема, что и у вас сегодня: я хотел создать новую матрицу, состоящую из комбинаций переменных, которые я определил ранее. Я нашел ответ на свой вопрос в этом ответе . Проблема с вашим вторым подходом, массивом P_0_tp, заключается в том, что он не создан с использованием операций cvxpy. Вы можете создать его, используя, например, cvxpy.vstack и cvxpy.hstack или другие доступные функции, как вы можете найти здесь (кажется, что есть также функция reshape ...).

В вопросе, который я задаю здесь , вы можете увидеть, как я реализовал его. Я копирую его здесь для полноты:

import cvxpy as cp

X = cp.Variable((3,3), PSD=True)

row_1 = cp.hstack((0, 1, X[0,0]))
row_2 = cp.hstack((1, 0, X[1,2]))
row_3 = cp.hstack((X[0,0], X[1,2], 0))

W = cp.vstack((row_1, row_2, row_3))
constraint = [W >> 0]

Как видите, я не определял W как переменную, но теперь это объект cvxpy:

In [1] W
Out[1]: Expression(AFFINE, UNKNOWN, (3, 3))
...