import cvxpy as cp
import numpy as np

n = 3
PP = cp.Variable((n,n),"PP")
KK = [[2,1,3],[1,2,1],[3,1,2]]
s = np.array([[.1, .4, .5]]).T
t = np.array([[.4, .2, .4]]).T
e = np.ones((n,1))
x = PP.T@e - s
y = PP@e - t
for b in range(1,21):
    obj = (1/4/b) * (cp.quad_form(x,KK) + cp.quad_form(y,KK)) - cp.trace(KK@PP) 
    prob = cp.Problem(cp.Minimize(obj),[PP>=0,cp.sum(PP)==1])
    obj=prob.solve()
    print("status:",prob.status)
    print("obj:",obj)
    print(PP.value)

Kiedy to prowadzę, dostaję

cvxpy.error.DCPError: Problem does not follow DCP rules. Specifically:
The objective is not DCP. Its following subexpressions are not:
QuadForm(PP.T * [[1.]
 [1.]
 [1.]] + -[[0.1]
 [0.4]
 [0.5]], [[2. 1. 3.]
 [1. 2. 1.]
 [3. 1. 2.]])

Nie widzę, dlaczego otrzymuję ten błąd, gdy moja macierzy KK jest wyraźnie PSD. Dlaczego to się dzieje?

Duplikat tutaj https://scicomp.stackexchange.com/q/34657/34383

-1
Glassjawed 18 marzec 2020, 21:51

1 odpowiedź

Najlepsza odpowiedź

Edytuj: Mówiłem zbyt wcześnie. Twoja matryca KK nie jest PSD (ma wartość EIGENVALUE -1). Dla osób, które widzą ten problem z matrycą, która powinna matematycznie być PSD, zostawiłem moją pierwotną odpowiedź poniżej.

Twoja matryca prawdopodobnie prawdopodobnie jest prawdopodobna, numerycznie, nie dość PSD, nawet jeśli jest to matematycznie. Jest to ograniczenie z quadem CVXpy's Atom (że możemy spróbować zająć się później).

Na razie możesz wziąć (matryca) pierwiastek kwadratowy sqrt_K k (używając, np. Scipy.Linalg.SQRTM ) i wymień Atom quad_form za pomocą cp.sum_squares(sqrt_K @ y).

1
Akshay Agrawal 19 marzec 2020, 15:46