def sls_synth(Q, R, Ahat, Bhat, eps_A, eps_B, T, gamma, alpha, logger=None):
    '\n    Solves the SLS synthesis problem for length T FIR filters\n    using CVXPY\n\n    '
    assert ((len(Q.shape) == 2) and (Q.shape[0] == Q.shape[1]))
    assert ((len(R.shape) == 2) and (R.shape[0] == R.shape[1]))
    assert ((len(Ahat.shape) == 2) and (Ahat.shape[0] == Ahat.shape[1]))
    assert ((len(Bhat.shape) == 2) and (Bhat.shape[0] == Ahat.shape[0]))
    assert (Q.shape[0] == Ahat.shape[0])
    assert (R.shape[0] == Bhat.shape[1])
    assert (eps_A >= 0)
    assert (eps_B >= 0)
    assert (T >= 1)
    assert ((gamma > 0) and (gamma < 1))
    assert ((alpha > 0) and (alpha < 1))
    if (logger is None):
        logger = logging.getLogger(__name__)
    (n, p) = Bhat.shape
    Q_sqrt = utils.psd_sqrt(Q)
    R_sqrt = utils.psd_sqrt(R)
    Phi_x = cvx.Variable((T * n), n, name='Phi_x')
    Phi_u = cvx.Variable((T * p), n, name='Phi_u')
    htwo_cost = cvx.Variable(name='htwo_cost')
    constr = []
    constr.append((Phi_x[:n, :] == np.eye(n)))
    for k in range((T - 1)):
        constr.append((Phi_x[(n * (k + 1)):(n * ((k + 1) + 1)), :] == ((Ahat * Phi_x[(n * k):(n * (k + 1)), :]) + (Bhat * Phi_u[(p * k):(p * (k + 1)), :]))))
    constr.append((((Ahat * Phi_x[(n * (T - 1)):, :]) + (Bhat * Phi_u[(p * (T - 1)):, :])) == 0))
    constr.append((cvx.norm(cvx.bmat(([[(Q_sqrt * Phi_x[(n * k):(n * (k + 1)), :])] for k in range(T)] + [[(R_sqrt * Phi_u[(p * k):(p * (k + 1)), :])] for k in range(T)])), 'fro') <= htwo_cost))
    mult_x = (eps_A / np.sqrt(alpha))
    mult_u = (eps_B / np.sqrt((1 - alpha)))
    Hbar = cvx.bmat(([[np.zeros((n, n)), np.zeros((n, p))]] + [[(mult_x * Phi_x[(n * k):(n * (k + 1)), :].T), (mult_u * Phi_u[(p * k):(p * (k + 1)), :].T)] for k in range(T)]))
    Q = cvx.Semidef((n * (T + 1)), name='Q')
    gamma_sq = (gamma ** 2)
    constr.append((sum([Q[(n * t):(n * (t + 1)), (n * t):(n * (t + 1))] for t in range((T + 1))]) == (gamma_sq * np.eye(n))))
    for k in range(1, (T + 1)):
        constr.append((sum([Q[(n * t):(n * (t + 1)), (n * (t + k)):(n * ((t + 1) + k))] for t in range(((T + 1) - k))]) == np.zeros((n, n))))
    constr.append((cvx.bmat([[Q, Hbar], [Hbar.T, np.eye((n + p))]]) == cvx.Semidef(((n * (T + 1)) + (n + p)))))
    prob = cvx.Problem(cvx.Minimize(htwo_cost), constr)
    prob.solve(solver=cvx.SCS)
    if (prob.status == cvx.OPTIMAL):
        logging.debug('successfully solved!')
        Phi_x = np.array(Phi_x.value)
        Phi_u = np.array(Phi_u.value)
        return (True, prob.value, Phi_x, Phi_u)
    else:
        logging.debug('could not solve: {}'.format(prob.status))
        return (False, None, None, None)
Solves the SLS synthesis problem for length T FIR filters
using CVXPY
def sls_synth(Q, R, Ahat, Bhat, eps_A, eps_B, T, gamma, alpha, logger=None):
    '\n    Solves the SLS synthesis problem for length T FIR filters\n    using CVXPY\n\n    '
    assert ((len(Q.shape) == 2) and (Q.shape[0] == Q.shape[1]))
    assert ((len(R.shape) == 2) and (R.shape[0] == R.shape[1]))
    assert ((len(Ahat.shape) == 2) and (Ahat.shape[0] == Ahat.shape[1]))
    assert ((len(Bhat.shape) == 2) and (Bhat.shape[0] == Ahat.shape[0]))
    assert (Q.shape[0] == Ahat.shape[0])
    assert (R.shape[0] == Bhat.shape[1])
    assert (eps_A >= 0)
    assert (eps_B >= 0)
    assert (T >= 1)
    assert ((gamma > 0) and (gamma < 1))
    assert ((alpha > 0) and (alpha < 1))
    if (logger is None):
        logger = logging.getLogger(__name__)
    (n, p) = Bhat.shape
    Q_sqrt = utils.psd_sqrt(Q)
    R_sqrt = utils.psd_sqrt(R)
    Phi_x = cvx.Variable((T * n), n, name='Phi_x')
    Phi_u = cvx.Variable((T * p), n, name='Phi_u')
    htwo_cost = cvx.Variable(name='htwo_cost')
    constr = []
    constr.append((Phi_x[:n, :] == np.eye(n)))
    for k in range((T - 1)):
        constr.append((Phi_x[(n * (k + 1)):(n * ((k + 1) + 1)), :] == ((Ahat * Phi_x[(n * k):(n * (k + 1)), :]) + (Bhat * Phi_u[(p * k):(p * (k + 1)), :]))))
    constr.append((((Ahat * Phi_x[(n * (T - 1)):, :]) + (Bhat * Phi_u[(p * (T - 1)):, :])) == 0))
    constr.append((cvx.norm(cvx.bmat(([[(Q_sqrt * Phi_x[(n * k):(n * (k + 1)), :])] for k in range(T)] + [[(R_sqrt * Phi_u[(p * k):(p * (k + 1)), :])] for k in range(T)])), 'fro') <= htwo_cost))
    mult_x = (eps_A / np.sqrt(alpha))
    mult_u = (eps_B / np.sqrt((1 - alpha)))
    Hbar = cvx.bmat(([[np.zeros((n, n)), np.zeros((n, p))]] + [[(mult_x * Phi_x[(n * k):(n * (k + 1)), :].T), (mult_u * Phi_u[(p * k):(p * (k + 1)), :].T)] for k in range(T)]))
    Q = cvx.Semidef((n * (T + 1)), name='Q')
    gamma_sq = (gamma ** 2)
    constr.append((sum([Q[(n * t):(n * (t + 1)), (n * t):(n * (t + 1))] for t in range((T + 1))]) == (gamma_sq * np.eye(n))))
    for k in range(1, (T + 1)):
        constr.append((sum([Q[(n * t):(n * (t + 1)), (n * (t + k)):(n * ((t + 1) + k))] for t in range(((T + 1) - k))]) == np.zeros((n, n))))
    constr.append((cvx.bmat([[Q, Hbar], [Hbar.T, np.eye((n + p))]]) == cvx.Semidef(((n * (T + 1)) + (n + p)))))
    prob = cvx.Problem(cvx.Minimize(htwo_cost), constr)
    prob.solve(solver=cvx.SCS)
    if (prob.status == cvx.OPTIMAL):
        logging.debug('successfully solved!')
        Phi_x = np.array(Phi_x.value)
        Phi_u = np.array(Phi_u.value)
        return (True, prob.value, Phi_x, Phi_u)
    else:
        logging.debug('could not solve: {}'.format(prob.status))
        return (False, None, None, None)