[英]Solving this convex optimization problem in Python, using only SciPy
我正在尝试解决python中的以下凸优化问题,仅使用(理想情况下) scipy package。 目标是恢复矩阵 . 矩阵ₘ , ₖ , , 和整数ℳ , , , 和是已知的和固定的。
J_M = eye(M) - 1/M*ones(M);
J_K = eye(K) - 1/K*ones(K);
S_row = [eye(M) zeros(M, K)];
S_col = [zeros(M, K); eye(K)];
cvx_begin sdp quiet
cvx_precision low
cvx_solver sedumi
variable G(N, N) symmetric;
variable B(M, K);
DofG = diag(G)*ones(N, 1)' - 2*G + ones(N, 1)*diag(G)';
LofG = S_row*DofG*S_col;
G >= 0;
G*ones(N, 1) == 0;
L = cell(M, K);
for m = 1:M
for k = 1:K
L{m, k} = [LofG(m, k) B(m, k); B(m, k) 1];
L{m, k} >= 0;
end
end
B(:) >= 0;
minimize square_pos(norm(J_M*(B - T)*J_K, 'fro'))
cvx_end
不幸的是,我对复杂优化技术的了解有限(尽管问题本身原则上相当简单),而且我没有matlab经验。 有些翻译很直截了当,而另一些我很难理解。
我编写了一个(诚然非常稀疏的)框架,试图重新创建matlab代码的一些片段。
from scipy.optimize import minimize
import numpy as np
def loss(...):
# M and K are given by size of T
J_M = eye(M) - 1/M * ones(M)
J_K = eye(K) - 1/K * ones(K)
DofG = diag(G) @ ones(N, 1) - 2 * G + ones(N, 1) @ diag(G)
LofG = S_row @ DofG @ S_col
return np.linalg.norm(J_M @ (B - T) @ J_K, 'fro')**2
res = minimize(loss, ...)
我不确定G(N, N); symmetric
G(N, N); symmetric
和B(M, K)
可以,也不能在python代码中复制。 我似乎在CVXR
文档中找不到简单的解释。
我也不确定如何复制B
和G
上的约束,我不确定如何复制“迭代约束”:
for m = 1:M
for k = 1:K
L{m, k} = [LofG(m, k) B(m, k); B(m, k) 1];
L{m, k} >= 0;
end
end
使用 cvxpy 直接翻译
import cvxpy as cp
import numpy as np
def solve(T, verbose=True):
M,K = T.shape
N = M + K
J_M = np.eye(M) - np.ones((M,M))/M
J_K = np.eye(K) - np.ones((K,K))/K
S_row = np.eye(M, M+K)
S_col = np.roll(np.eye(M+K,K), M, axis=0)
G = cp.Variable((N,N), symmetric=True)
B = cp.Variable((M,K))
# Here I am assuming that the product of diag(G)*ones(N,1) is broadcasting
Gd = cp.reshape(cp.diag(G), (N, 1))
DofG = Gd + Gd.T - 2*G
# Imposes N = M + K
LofG = S_row @ DofG @ S_col
constraints = [G >> 0, cp.sum(G, axis=1) == 0]
for m in range(M):
for k in range(K):
L = cp.bmat([[LofG[m,k], B[m,k]], [B[m,k],1]])
constraints.append(L >> 0)
constraints.append(B >= 0)
obj = cp.norm(J_M @ (B - T) @ J_K, 'fro')
prob = cp.Problem(cp.Minimize(obj), constraints)
prob.solve(verbose=verbose)
return G.value, B.value, obj.value
如果您熟悉 numpy,上面的代码应该很容易理解。 唯一的区别是,我没有使用 numpy 函数,而是使用可以操作变量的相应 cvxpy 函数。 对象存储变量和它们之间的关系,当prob.solve
被调用时,它会将问题转换为标准形式并提交给某个求解器。
solve(np.eye(3, 2) + 1)
(array([[ 0.68113622, -0.22048912, -0.10273289, -0.55665717, 0.19874296],
[-0.22048912, 0.68113622, -0.10273289, 0.19874296, -0.55665717],
[-0.10273289, -0.10273289, 0.08445099, 0.0605074 , 0.0605074 ],
[-0.55665717, 0.19874296, 0.0605074 , 0.48298721, -0.1855804 ],
[ 0.19874296, -0.55665717, 0.0605074 , -0.1855804 , 0.48298721]]),
array([[ 1.17174172e+00, 1.71742424e-01],
[ 1.71742424e-01, 1.17174172e+00],
[ 1.50334549e-15, -1.47036515e-16]]),
6.988985781497536e-07)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.