def optim_lambdas(gradients, lambda0):
    epsilon = 0.5
    n = len(gradients)
    J_t = [grad.numpy() for grad in gradients]
    J_t = np.array(J_t)
    Q = (2 * np.dot(J_t, J_t.T))
    q = np.array([[0] for i in range(n)])
    A = np.ones(n).T
    b = np.array([1])
    lb = np.array([max(0, (lambda0[i] - epsilon)) for i in range(n)])
    ub = np.array([min(1, (lambda0[i] + epsilon)) for i in range(n)])
    G = np.zeros(((2 * n), n))
    for i in range(n):
        G[i][i] = (- 1)
        G[(n + i)][i] = 1
    h = np.zeros(((2 * n), 1))
    for i in range(n):
        h[i] = (- lb[i])
        h[(n + i)] = ub[i]
    res = quadprog(Q, q, G, h, A, b)
    return res
def optim_lambdas(gradients, lambda0):
    epsilon = 0.5
    n = len(gradients)
    J_t = [grad.numpy() for grad in gradients]
    J_t = np.array(J_t)
    Q = (2 * np.dot(J_t, J_t.T))
    q = np.array([[0] for i in range(n)])
    A = np.ones(n).T
    b = np.array([1])
    lb = np.array([max(0, (lambda0[i] - epsilon)) for i in range(n)])
    ub = np.array([min(1, (lambda0[i] + epsilon)) for i in range(n)])
    G = np.zeros(((2 * n), n))
    for i in range(n):
        G[i][i] = (- 1)
        G[(n + i)][i] = 1
    h = np.zeros(((2 * n), 1))
    for i in range(n):
        h[i] = (- lb[i])
        h[(n + i)] = ub[i]
    res = quadprog(Q, q, G, h, A, b)
    return res