def solve_spectral(prob, *args, **kwargs):
"""Solve the spectral relaxation with lambda = 1.
"""
# TODO: do this efficiently without SDP lifting
# lifted variables and semidefinite constraint
X = cvx.Semidef(prob.n + 1)
W = prob.f0.homogeneous_form()
rel_obj = cvx.Minimize(cvx.sum_entries(cvx.mul_elemwise(W, X)))
W1 = sum([f.homogeneous_form() for f in prob.fs if f.relop == '<='])
W2 = sum([f.homogeneous_form() for f in prob.fs if f.relop == '=='])
rel_prob = cvx.Problem(
rel_obj,
[
cvx.sum_entries(cvx.mul_elemwise(W1, X)) <= 0,
cvx.sum_entries(cvx.mul_elemwise(W2, X)) == 0,
X[-1, -1] == 1
]
)
rel_prob.solve(*args, **kwargs)
if rel_prob.status not in [cvx.OPTIMAL, cvx.OPTIMAL_INACCURATE]:
raise Exception("Relaxation problem status: %s" % rel_prob.status)
(w, v) = LA.eig(X.value)
return np.sqrt(np.max(w))*np.asarray(v[:-1, np.argmax(w)]).flatten(), rel_prob.value
评论列表
文章目录